mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-26 16:46:19 +08:00
fix: 修复tabs已知问题
This commit is contained in:
@@ -48,7 +48,7 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
sideTheme: 'dark',
|
||||
sideWidth: 180,
|
||||
// tabsBackgroundColor: 'hsl(var(--color-background))',
|
||||
tabsHeight: 38,
|
||||
tabsHeight: 36,
|
||||
tabsVisible: true,
|
||||
zIndex: 200,
|
||||
});
|
||||
|
@@ -12,7 +12,7 @@ interface Props extends MenuProps {
|
||||
}
|
||||
|
||||
defineOptions({
|
||||
name: 'MenuUi',
|
||||
name: 'MenuView',
|
||||
});
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
|
@@ -1,29 +1,28 @@
|
||||
@import '@vben-core/design/global';
|
||||
|
||||
@include b('tabs-ui') {
|
||||
@include b('chrome-tabs') {
|
||||
--tabs-background: hsl(var(--color-background));
|
||||
--tabs-gap: 10px;
|
||||
--tabs-gap: 7px;
|
||||
--tabs-divider: hsl(var(--color-border));
|
||||
--tabs-hover: hsl(var(--color-heavy));
|
||||
--tabs-active-background: hsl(var(--color-primary) / 15%);
|
||||
--tabs-active: hsl(var(--color-primary));
|
||||
--tabs-active-background: hsl(var(--color-primary) / 100%);
|
||||
--tabs-active: hsl(var(--color-primary-foreground));
|
||||
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding-top: 2px;
|
||||
padding-top: 4px;
|
||||
background-color: var(--tabs-background);
|
||||
|
||||
@include e('content') {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
height: 32px;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
@include b('tab') {
|
||||
@include b('chrome-tab') {
|
||||
position: absolute;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
@@ -32,24 +31,24 @@
|
||||
user-select: none;
|
||||
|
||||
@include is('active') {
|
||||
z-index: 1;
|
||||
z-index: 2;
|
||||
color: var(--tabs-active);
|
||||
|
||||
.#{$namespace}-tab__extra:not(.is-pin) {
|
||||
.#{$namespace}-chrome-tab__extra:not(.is-pin) {
|
||||
background-color: var(--tabs-active-background);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.#{$namespace}-tab-background__divider {
|
||||
.#{$namespace}-chrome-tab-background__divider {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.#{$namespace}-tab-background__content {
|
||||
.#{$namespace}-chrome-tab-background__content {
|
||||
background-color: var(--tabs-active-background);
|
||||
}
|
||||
|
||||
.#{$namespace}-tab-background__before,
|
||||
.#{$namespace}-tab-background__after {
|
||||
.#{$namespace}-chrome-tab-background__before,
|
||||
.#{$namespace}-chrome-tab-background__after {
|
||||
fill: var(--tabs-active-background);
|
||||
}
|
||||
}
|
||||
@@ -58,8 +57,7 @@
|
||||
position: absolute;
|
||||
right: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
box-sizing: border-box;
|
||||
// z-index: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
@@ -73,19 +71,18 @@
|
||||
@include e('extra') {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: calc(var(--tabs-gap) * 1.5);
|
||||
right: calc(var(--tabs-gap) * 2);
|
||||
z-index: 1;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 50%;
|
||||
opacity: 0;
|
||||
|
||||
// transition: all 0.15s ease;
|
||||
transition: 0.15s;
|
||||
transform: translateY(-50%);
|
||||
|
||||
&:hover {
|
||||
// background-color: hsl(var(--color-accent));
|
||||
}
|
||||
// &:hover {
|
||||
// background-color: hsl(var(--color-accent));
|
||||
// }
|
||||
}
|
||||
|
||||
@include e('extra-icon') {
|
||||
@@ -116,14 +113,26 @@
|
||||
|
||||
@include e('label') {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
flex: 1;
|
||||
margin-right: px;
|
||||
margin-right: 8px;
|
||||
margin-left: 5%;
|
||||
overflow: hidden;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
mask-image: linear-gradient(
|
||||
90deg,
|
||||
#000 0%,
|
||||
#000 calc(100% - 20px),
|
||||
transparent
|
||||
);
|
||||
|
||||
// &.no-close {
|
||||
// margin-right: 0;
|
||||
// }
|
||||
|
||||
// &.no-icon {
|
||||
// margin-left: 0;
|
||||
// }
|
||||
}
|
||||
|
||||
@include is('hidden-icon') {
|
||||
@@ -131,51 +140,44 @@
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.#{$namespace}-tab__extra.is-pin {
|
||||
.#{$namespace}-chrome-tab__extra.is-pin {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.is-active):hover {
|
||||
z-index: 10;
|
||||
z-index: 1;
|
||||
|
||||
.#{$namespace}-tab__extra {
|
||||
.#{$namespace}-chrome-tab__extra {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.#{$namespace}-tab-background__divider {
|
||||
.#{$namespace}-chrome-tab-background__divider {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.#{$namespace}-tab-background__content {
|
||||
.#{$namespace}-chrome-tab-background__content {
|
||||
background-color: var(--tabs-hover);
|
||||
}
|
||||
|
||||
.#{$namespace}-tab-background__before,
|
||||
.#{$namespace}-tab-background__after {
|
||||
.#{$namespace}-chrome-tab-background__before,
|
||||
.#{$namespace}-chrome-tab-background__after {
|
||||
fill: var(--tabs-hover);
|
||||
}
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
.#{$namespace}-tab-background__divider::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:first-of-type {
|
||||
.#{$namespace}-tab-background__divider::before {
|
||||
.#{$namespace}-chrome-tab-background__divider::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include b('tab-background') {
|
||||
@include b('chrome-tab-background') {
|
||||
position: absolute;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0 calc(var(--tabs-gap) - 1px);
|
||||
padding: 0 calc(var(--tabs-gap) + 0px);
|
||||
|
||||
@include e('divider') {
|
||||
position: absolute;
|
||||
@@ -184,45 +186,47 @@
|
||||
height: 100%;
|
||||
margin: 0 7px;
|
||||
|
||||
// &::before {
|
||||
// position: absolute;
|
||||
// top: 20%;
|
||||
// right: 100%;
|
||||
// width: 1px;
|
||||
// height: 60%;
|
||||
// content: '';
|
||||
// background-color: var(--tabs-divider);
|
||||
// }
|
||||
&::before {
|
||||
position: absolute;
|
||||
top: 20%;
|
||||
right: 100%;
|
||||
width: 1px;
|
||||
height: 60%;
|
||||
content: '';
|
||||
background-color: var(--tabs-divider);
|
||||
}
|
||||
|
||||
// &::after {
|
||||
// position: absolute;
|
||||
// top: 20%;
|
||||
// left: calc(100% - 1px);
|
||||
// width: 1px;
|
||||
// height: 60%;
|
||||
// content: '';
|
||||
// background-color: var(--tabs-divider);
|
||||
// }
|
||||
&::after {
|
||||
position: absolute;
|
||||
top: 20%;
|
||||
left: calc(100% - 1px);
|
||||
width: 1px;
|
||||
height: 60%;
|
||||
content: '';
|
||||
background-color: var(--tabs-divider);
|
||||
}
|
||||
}
|
||||
|
||||
@include e('content') {
|
||||
height: 100%;
|
||||
border-top-left-radius: 8px;
|
||||
border-top-right-radius: 8px;
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
transition: background 0.15s ease;
|
||||
}
|
||||
|
||||
@include e('before') {
|
||||
position: absolute;
|
||||
bottom: -1px;
|
||||
left: -1px;
|
||||
left: -3px;
|
||||
fill: transparent;
|
||||
transition: 0.15s;
|
||||
}
|
||||
|
||||
@include e('after') {
|
||||
position: absolute;
|
||||
right: -1px;
|
||||
right: -3px;
|
||||
bottom: -1px;
|
||||
fill: transparent;
|
||||
transition: 0.15s;
|
||||
}
|
||||
}
|
@@ -2,10 +2,10 @@
|
||||
import { useNamespace } from '@vben-core/toolkit';
|
||||
|
||||
defineOptions({
|
||||
name: 'TabBackground',
|
||||
name: 'ChromeTabBackground',
|
||||
});
|
||||
|
||||
const { b, e } = useNamespace('tab-background');
|
||||
const { b, e } = useNamespace('chrome-tab-background');
|
||||
</script>
|
||||
|
||||
<template>
|
@@ -19,7 +19,7 @@ interface Props {
|
||||
}
|
||||
|
||||
defineOptions({
|
||||
name: 'Tab',
|
||||
name: 'ChromeTab',
|
||||
});
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
@@ -27,7 +27,7 @@ withDefaults(defineProps<Props>(), {
|
||||
});
|
||||
const emit = defineEmits<{ close: []; unPushPin: [] }>();
|
||||
|
||||
const { b, e, is } = useNamespace('tab');
|
||||
const { b, e, is } = useNamespace('chrome-tab');
|
||||
|
||||
function handleClose() {
|
||||
emit('close');
|
@@ -1,23 +1,18 @@
|
||||
<script setup lang="ts">
|
||||
import type { IContextMenuItem } from '@vben-core/shadcn-ui';
|
||||
import type { TabItem } from '@vben-core/typings';
|
||||
|
||||
import { useNamespace } from '@vben-core/toolkit';
|
||||
import { TabItem } from '@vben-core/typings';
|
||||
|
||||
import { computed, nextTick, onMounted, ref, watch } from 'vue';
|
||||
|
||||
import Tab from './tab.vue';
|
||||
|
||||
interface Props {
|
||||
maxWidth?: number;
|
||||
menus?: (data: any) => IContextMenuItem[];
|
||||
minWidth?: number;
|
||||
showIcon?: boolean;
|
||||
tabs?: TabItem[];
|
||||
}
|
||||
import type { TabsProps } from '../../interface';
|
||||
|
||||
interface Props extends TabsProps {}
|
||||
|
||||
defineOptions({
|
||||
name: 'Tabs',
|
||||
name: 'ChromeTabs',
|
||||
});
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
@@ -29,10 +24,10 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
|
||||
const emit = defineEmits<{ close: [string]; unPushPin: [TabItem] }>();
|
||||
|
||||
const gap = 6;
|
||||
const gap = 7;
|
||||
|
||||
const active = defineModel<string>('active');
|
||||
const { b, e, is } = useNamespace('tabs-ui');
|
||||
const { b, e, is } = useNamespace('chrome-tabs');
|
||||
|
||||
const contentRef = ref();
|
||||
const tabWidth = ref<number>(0);
|
||||
@@ -115,5 +110,5 @@ function handleUnPushPin(tab: TabItem) {
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss">
|
||||
@import '../styles/tabs.scss';
|
||||
@import './chrome-tabs.scss';
|
||||
</style>
|
@@ -1,3 +1,3 @@
|
||||
export { default as Tabs } from './tabs.vue';
|
||||
export { default as ChromeTabs } from './chrome-tabs/tabs.vue';
|
||||
export { default as TabsMore } from './tabs-more.vue';
|
||||
export { default as TabsScreen } from './tabs-screen.vue';
|
||||
|
@@ -0,0 +1,5 @@
|
||||
<script lang="ts" setup></script>
|
||||
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
@@ -1,2 +1,3 @@
|
||||
export { Tabs as TabsView, TabsMore, TabsScreen } from './components';
|
||||
export { TabsMore, TabsScreen } from './components';
|
||||
export { default as TabsView } from './tabs-view.vue';
|
||||
export type { IContextMenuItem } from '@vben-core/shadcn-ui';
|
||||
|
12
packages/@vben-core/uikit/tabs-ui/src/interface.ts
Normal file
12
packages/@vben-core/uikit/tabs-ui/src/interface.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import type { IContextMenuItem } from '@vben-core/shadcn-ui';
|
||||
import type { TabItem } from '@vben-core/typings';
|
||||
|
||||
interface TabsProps {
|
||||
maxWidth?: number;
|
||||
menus?: (data: any) => IContextMenuItem[];
|
||||
minWidth?: number;
|
||||
showIcon?: boolean;
|
||||
tabs?: TabItem[];
|
||||
}
|
||||
|
||||
export type { TabsProps };
|
24
packages/@vben-core/uikit/tabs-ui/src/tabs-view.vue
Normal file
24
packages/@vben-core/uikit/tabs-ui/src/tabs-view.vue
Normal file
@@ -0,0 +1,24 @@
|
||||
<script setup lang="ts">
|
||||
import type { TabItem } from '@vben-core/typings';
|
||||
|
||||
import { useForwardPropsEmits } from '@vben-core/shadcn-ui';
|
||||
|
||||
import { ChromeTabs } from './components';
|
||||
import { TabsProps } from './interface';
|
||||
|
||||
interface Props extends TabsProps {}
|
||||
|
||||
defineOptions({
|
||||
name: 'TabsView',
|
||||
});
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {});
|
||||
|
||||
const emit = defineEmits<{ close: [string]; unPushPin: [TabItem] }>();
|
||||
|
||||
const forward = useForwardPropsEmits(props, emit);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ChromeTabs v-bind="forward" />
|
||||
</template>
|
Reference in New Issue
Block a user