perf: improve overall theme color matching

This commit is contained in:
vince
2024-07-15 23:53:58 +08:00
parent caf1fc4375
commit f95d9aa609
39 changed files with 525 additions and 843 deletions

View File

@@ -6,7 +6,7 @@ import type { TabConfig, TabsProps } from '../../types';
import { computed, nextTick, onMounted, ref, watch } from 'vue';
import { IcRoundClose, MdiPin } from '@vben-core/icons';
import { VbenContextMenu, VbenIcon } from '@vben-core/shadcn-ui';
import { VbenContextMenu, VbenIcon, VbenScrollbar } from '@vben-core/shadcn-ui';
interface Props extends TabsProps {}
@@ -21,7 +21,7 @@ const props = withDefaults(defineProps<Props>(), {
contextMenus: () => [],
gap: 7,
maxWidth: 150,
minWidth: 40,
minWidth: 80,
tabs: () => [],
});
@@ -40,20 +40,20 @@ const style = computed(() => {
});
const layout = () => {
const { gap, maxWidth, minWidth, tabs } = props;
const { maxWidth, minWidth } = props;
if (!contentRef.value) {
return Math.max(maxWidth, minWidth);
}
const contentWidth = contentRef.value.clientWidth - gap * 3;
let width = contentWidth / tabs.length;
width += gap * 2;
if (width > maxWidth) {
width = maxWidth;
}
if (width < minWidth) {
width = minWidth;
}
tabWidth.value = width;
// const contentWidth = contentRef.value.clientWidth - gap * 3;
// let width = contentWidth / tabs.length;
// width += gap * 2;
// if (width > maxWidth) {
// width = maxWidth;
// }
// if (width < minWidth) {
// width = minWidth;
// }
tabWidth.value = maxWidth;
};
const tabsView = computed((): TabConfig[] => {
@@ -95,121 +95,115 @@ function handleUnpinTab(tab: TabConfig) {
<template>
<div :style="style" class="tabs-chrome size-full flex-1 overflow-hidden pt-1">
<!-- footer -> 4px -->
<div
ref="contentRef"
:class="contentClass"
class="relative h-full overflow-hidden"
>
<TransitionGroup name="slide-down">
<div
v-for="(tab, i) in tabsView"
:key="tab.key"
ref="tabRef"
:class="[
{ 'is-active': tab.key === active, dragable: !tab.affixTab },
]"
:data-index="i"
:style="{
width: `${tabWidth}px`,
left: `${(tabWidth - gap * 2) * i}px`,
}"
class="tabs-chrome__item group absolute flex h-full select-none items-center transition-all"
@click="active = tab.key"
>
<VbenContextMenu
:handler-data="tab"
:menus="contextMenus"
:modal="false"
item-class="pr-6"
<VbenScrollbar class="h-full" horizontal>
<!-- footer -> 4px -->
<div
ref="contentRef"
:class="contentClass"
class="relative !flex h-full w-max"
>
<TransitionGroup name="slide-down">
<div
v-for="(tab, i) in tabsView"
:key="tab.key"
ref="tabRef"
:class="[
{ 'is-active': tab.key === active, dragable: !tab.affixTab },
]"
:data-index="i"
:style="{
width: `${tabWidth}px`,
left: `${(tabWidth - gap * 2) * i}px`,
}"
class="tabs-chrome__item group absolute flex h-full select-none items-center transition-all"
@click="active = tab.key"
>
<div class="size-full">
<!-- divider -->
<div
v-if="i !== 0"
class="tabs-chrome__divider bg-foreground/80 absolute left-[var(--gap)] top-1/2 z-0 h-4 w-[1px] translate-y-[-50%] transition-all"
></div>
<!-- background -->
<div
class="tabs-chrome__background absolute z-[1] size-full px-[calc(var(--gap)-1px)] py-0 transition-opacity duration-150"
>
<VbenContextMenu
:handler-data="tab"
:menus="contextMenus"
:modal="false"
item-class="pr-6"
>
<div class="size-full">
<!-- divider -->
<div
class="tabs-chrome__background-content h-full rounded-tl-[var(--gap)] rounded-tr-[var(--gap)] duration-150"
v-if="i !== 0 && tab.key !== active"
class="tabs-chrome__divider bg-foreground/80 absolute left-[var(--gap)] top-1/2 z-0 h-4 w-[1px] translate-y-[-50%] transition-all"
></div>
<svg
class="tabs-chrome__background-before absolute bottom-[-1px] left-[-1px] fill-transparent transition-all duration-150"
height="7"
width="7"
<!-- background -->
<div
class="tabs-chrome__background absolute z-[1] size-full px-[calc(var(--gap)-1px)] py-0 transition-opacity duration-150"
>
<path d="M 0 7 A 7 7 0 0 0 7 0 L 7 7 Z" />
</svg>
<svg
class="tabs-chrome__background-after absolute bottom-[-1px] right-[-1px] fill-transparent transition-all duration-150"
height="7"
width="7"
>
<path d="M 0 0 A 7 7 0 0 0 7 7 L 0 7 Z" />
</svg>
</div>
<div
class="tabs-chrome__background-content h-full rounded-tl-[var(--gap)] rounded-tr-[var(--gap)] duration-150"
></div>
<svg
class="tabs-chrome__background-before absolute bottom-[-1px] left-[-1px] fill-transparent transition-all duration-150"
height="7"
width="7"
>
<path d="M 0 7 A 7 7 0 0 0 7 0 L 7 7 Z" />
</svg>
<svg
class="tabs-chrome__background-after absolute bottom-[-1px] right-[-1px] fill-transparent transition-all duration-150"
height="7"
width="7"
>
<path d="M 0 0 A 7 7 0 0 0 7 7 L 0 7 Z" />
</svg>
</div>
<!-- extra -->
<div
class="tabs-chrome__extra absolute right-[calc(var(--gap)*2)] top-1/2 z-[3] size-4 translate-y-[-50%]"
>
<!-- <div
<!-- extra -->
<div
class="tabs-chrome__extra absolute right-[calc(var(--gap)*1.5)] top-1/2 z-[3] size-4 translate-y-[-50%]"
>
<!-- <div
class="tabs-chrome__extra absolute right-[calc(var(--gap)*2)] top-1/2 z-[3] size-4 translate-y-[-50%] opacity-0 transition-opacity group-hover:opacity-100"
> -->
<!-- close-icon -->
<IcRoundClose
v-show="!tab.affixTab && tabsView.length > 1 && tab.closable"
class="hover:bg-accent stroke-accent-foreground/80 hover:stroke-accent-foreground group-[.is-active]:text-primary mt-[2px] size-3 cursor-pointer rounded-full transition-all"
@click.stop="handleClose(tab.key)"
/>
<MdiPin
v-show="tab.affixTab && tabsView.length > 1 && tab.closable"
class="hover:bg-accent hover:stroke-accent-foreground group-[.is-active]:text-primary mt-[2px] size-3.5 cursor-pointer rounded-full transition-all"
@click.stop="handleUnpinTab(tab)"
/>
</div>
<!-- close-icon -->
<IcRoundClose
v-show="
!tab.affixTab && tabsView.length > 1 && tab.closable
"
class="hover:bg-accent stroke-accent-foreground/80 hover:stroke-accent-foreground group-[.is-active]:text-primary mt-[2px] size-3 cursor-pointer rounded-full transition-all"
@click.stop="handleClose(tab.key)"
/>
<MdiPin
v-show="tab.affixTab && tabsView.length > 1 && tab.closable"
class="hover:bg-accent hover:stroke-accent-foreground group-[.is-active]:text-primary mt-[2px] size-3.5 cursor-pointer rounded-full transition-all"
@click.stop="handleUnpinTab(tab)"
/>
</div>
<!-- tab-item-main -->
<div
class="tabs-chrome__item-main group-[.is-active]:text-primary text-accent-foreground absolute left-0 right-0 z-[2] mx-[calc(var(--gap)*2)] my-0 flex h-full items-center overflow-hidden rounded-tl-[5px] rounded-tr-[5px] pr-4 duration-150 group-hover:pr-3 group-[.is-active]:font-semibold"
>
<VbenIcon
v-if="showIcon"
:icon="tab.icon"
class="ml-[var(--gap)] flex size-4 items-center overflow-hidden"
fallback
/>
<span
class="tabs-chrome__label ml-[var(--gap)] flex-1 overflow-hidden whitespace-nowrap"
<!-- tab-item-main -->
<div
class="tabs-chrome__item-main group-[.is-active]:text-primary text-accent-foreground absolute left-0 right-0 z-[2] mx-[calc(var(--gap)*2)] my-0 flex h-full items-center overflow-hidden rounded-tl-[5px] rounded-tr-[5px] pr-4 duration-150 group-hover:pr-3"
>
{{ tab.title }}
</span>
<VbenIcon
v-if="showIcon"
:icon="tab.icon"
class="ml-[var(--gap)] flex size-4 items-center overflow-hidden"
fallback
/>
<span
class="tabs-chrome__label ml-[var(--gap)] flex-1 overflow-hidden whitespace-nowrap"
>
{{ tab.title }}
</span>
</div>
</div>
</div>
</VbenContextMenu>
</div>
</TransitionGroup>
</div>
<!-- footer -->
<div class="bg-background h-1"></div>
</VbenContextMenu>
</div>
</TransitionGroup>
</div>
<!-- footer -->
<div class="bg-background h-1"></div>
</VbenScrollbar>
</div>
</template>
<style scoped>
/* html.dark {
.tabs-chrome {
.is-active {
.tabs-chrome__item-main {
@apply text-accent-foreground;
}
}
}
} */
.tabs-chrome {
.dragging {
.tabs-chrome__item-main {
@@ -222,7 +216,7 @@ function handleUnpinTab(tab: TabConfig) {
}
&__item {
&:hover {
&:hover:not(.is-active) {
& + .tabs-chrome__item {
.tabs-chrome__divider {
@apply opacity-0;
@@ -235,12 +229,12 @@ function handleUnpinTab(tab: TabConfig) {
.tabs-chrome__background {
&-content {
@apply bg-heavy;
@apply bg-primary/10 mx-1 rounded-md pb-2;
}
&-before,
&-after {
@apply fill-heavy;
@apply fill-primary/0;
}
}
}
@@ -248,16 +242,22 @@ function handleUnpinTab(tab: TabConfig) {
&.is-active {
@apply z-[2];
& + .tabs-chrome__item {
.tabs-chrome__divider {
@apply opacity-0 !important;
}
}
.tabs-chrome__background {
@apply opacity-100;
&-content {
@apply bg-background-content;
@apply bg-primary/15;
}
&-before,
&-after {
@apply fill-background-content;
@apply fill-primary/15;
}
}
}

View File

@@ -26,14 +26,14 @@ const active = defineModel<string>('active');
const typeWithClass = computed(() => {
const typeClasses: Record<string, { content: string }> = {
brisk: {
content: `h-full after:content-[''] after:absolute after:bottom-0 after:left-0 after:w-full after:h-[1.5px] after:bg-primary after:scale-x-0 after:transition-[transform] after:ease-out after:duration-300 hover:after:scale-x-100 after:origin-left [&.is-active]:after:scale-x-100`,
content: `h-full after:content-[''] after:absolute after:bottom-0 after:left-0 after:w-full after:h-[1.5px] after:bg-primary after:scale-x-0 after:transition-[transform] after:ease-out after:duration-300 hover:after:scale-x-100 after:origin-left [&.is-active]:after:scale-x-100 border-l border-border`,
},
card: {
content:
'h-[calc(100%-6px)] rounded-md mr-2 border-border [&.is-active]:border-primary border transition-all',
'h-[calc(100%-6px)] rounded-md ml-2 border border-border transition-all',
},
plain: {
content: 'h-full',
content: 'h-full border-l border-border',
},
};
@@ -77,7 +77,7 @@ function handleUnpinTab(tab: TabConfig) {
:key="tab.key"
:class="[
{
'tabs-item is-active bg-background-content': tab.key === active,
'is-active bg-primary/15': tab.key === active,
dragable: !tab.affixTab,
},
typeWithClass.content,
@@ -110,14 +110,14 @@ function handleUnpinTab(tab: TabConfig) {
/>
<MdiPin
v-show="tab.affixTab && tabsView.length > 1 && tab.closable"
class="hover:bg-accent hover:stroke-accent-foreground group-[.is-active]:text-primary mt-[2px] size-3.5 cursor-pointer rounded-full transition-all"
class="hover:bg-heavy hover:stroke-accent-foreground group-[.is-active]:text-primary mt-[2px] size-3.5 cursor-pointer rounded-full transition-all"
@click.stop="handleUnpinTab(tab)"
/>
</div>
<!-- tab-item-main -->
<div
class="tabs-item__main group-[.is-active]:text-primary text-accent-foreground mx-3 mr-4 flex h-full items-center overflow-hidden rounded-tl-[5px] rounded-tr-[5px] pr-3 transition-all duration-300"
class="group-[.is-active]:text-primary text-accent-foreground mx-3 mr-4 flex h-full items-center overflow-hidden rounded-tl-[5px] rounded-tr-[5px] pr-3 transition-all duration-300"
>
<!-- <div
class="mx-3 ml-3 mr-2 flex h-full items-center overflow-hidden rounded-tl-[5px] rounded-tr-[5px] transition-all duration-300 group-hover:mr-2 group-hover:pr-4 group-[.is-active]:pr-4"
@@ -141,15 +141,3 @@ function handleUnpinTab(tab: TabConfig) {
</VbenScrollbar>
</div>
</template>
<style scoped>
/* html.dark {
.tabs-item {
&.is-active {
.tabs-item__main {
@apply text-accent-foreground;
}
}
}
} */
</style>