fix: fix known problems
This commit is contained in:
125
packages/@core/shared/design/src/css/global.css
Normal file
125
packages/@core/shared/design/src/css/global.css
Normal file
@@ -0,0 +1,125 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer base {
|
||||
*,
|
||||
::after,
|
||||
::before {
|
||||
@apply border-border;
|
||||
|
||||
box-sizing: border-box;
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
@apply text-foreground bg-background font-sans text-[100%];
|
||||
|
||||
font-variation-settings: normal;
|
||||
line-height: 1.15;
|
||||
text-size-adjust: 100%;
|
||||
font-synthesis-weight: none;
|
||||
scroll-behavior: smooth;
|
||||
text-rendering: optimizelegibility;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
html.invert-mode {
|
||||
@apply invert;
|
||||
}
|
||||
|
||||
html.grayscale-mode {
|
||||
@apply grayscale;
|
||||
}
|
||||
|
||||
#app,
|
||||
body,
|
||||
html {
|
||||
@apply size-full overscroll-none;
|
||||
}
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
a,
|
||||
a:active,
|
||||
a:hover,
|
||||
a:link,
|
||||
a:visited {
|
||||
@apply no-underline;
|
||||
}
|
||||
|
||||
::view-transition-new(root),
|
||||
::view-transition-old(root) {
|
||||
@apply animate-none mix-blend-normal;
|
||||
}
|
||||
|
||||
::view-transition-old(root) {
|
||||
@apply z-[1];
|
||||
}
|
||||
|
||||
::view-transition-new(root) {
|
||||
@apply z-[2147483646];
|
||||
}
|
||||
|
||||
html.dark::view-transition-old(root) {
|
||||
@apply z-[2147483646];
|
||||
}
|
||||
|
||||
html.dark::view-transition-new(root) {
|
||||
@apply z-[1];
|
||||
}
|
||||
|
||||
input::placeholder,
|
||||
textarea::placeholder {
|
||||
@apply opacity-100;
|
||||
}
|
||||
|
||||
input:-webkit-autofill {
|
||||
@apply border-none;
|
||||
|
||||
box-shadow: 0 0 0 1000px transparent inset;
|
||||
}
|
||||
|
||||
input[type='number']::-webkit-inner-spin-button,
|
||||
input[type='number']::-webkit-outer-spin-button {
|
||||
@apply m-0 appearance-none;
|
||||
}
|
||||
}
|
||||
|
||||
@layer components {
|
||||
.flex-center {
|
||||
@apply flex items-center justify-center;
|
||||
}
|
||||
|
||||
.flex-col-center {
|
||||
@apply flex flex-col items-center justify-center;
|
||||
}
|
||||
|
||||
.outline-box {
|
||||
@apply outline-border relative cursor-pointer rounded-md p-1 outline outline-1;
|
||||
}
|
||||
|
||||
.outline-box::after {
|
||||
@apply absolute left-1/2 top-1/2 z-20 h-0 w-[1px] rounded-sm opacity-0 outline outline-2 outline-transparent transition-all duration-300 content-[""];
|
||||
}
|
||||
|
||||
.outline-box.outline-box-active {
|
||||
@apply outline-primary outline outline-2;
|
||||
}
|
||||
|
||||
.outline-box.outline-box-active::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.outline-box:not(.outline-box-active):hover::after {
|
||||
@apply outline-primary left-0 top-0 h-full w-full p-1 opacity-100;
|
||||
}
|
||||
|
||||
.card-box {
|
||||
@apply bg-card text-card-foreground border-border rounded-xl border shadow;
|
||||
}
|
||||
}
|
@@ -1,26 +1,16 @@
|
||||
/* Make clicks pass-through */
|
||||
#nprogress {
|
||||
pointer-events: none;
|
||||
@apply pointer-events-none;
|
||||
}
|
||||
|
||||
#nprogress .bar {
|
||||
@apply bg-primary;
|
||||
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1031;
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
@apply bg-primary fixed left-0 top-0 z-[1031] h-[2px] w-full;
|
||||
}
|
||||
|
||||
/* Fancy blur effect */
|
||||
#nprogress .peg {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
display: block;
|
||||
width: 100px;
|
||||
height: 100%;
|
||||
@apply absolute right-0 block h-full w-[100px];
|
||||
|
||||
box-shadow:
|
||||
0 0 10px hsl(var(--primary)),
|
||||
0 0 5px hsl(var(--primary));
|
||||
@@ -30,32 +20,22 @@
|
||||
|
||||
/* Remove these to get rid of the spinner */
|
||||
#nprogress .spinner {
|
||||
position: fixed;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
z-index: 1031;
|
||||
display: block;
|
||||
@apply fixed right-4 top-4 z-[1031] block;
|
||||
}
|
||||
|
||||
#nprogress .spinner-icon {
|
||||
box-sizing: border-box;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border: solid 2px transparent;
|
||||
border-top-color: hsl(var(--primary));
|
||||
border-left-color: hsl(var(--primary));
|
||||
border-radius: 50%;
|
||||
@apply border-t-primary border-l-primary size-4 rounded-full border-[2px] border-solid border-transparent;
|
||||
|
||||
animation: nprogress-spinner 400ms linear infinite;
|
||||
}
|
||||
|
||||
.nprogress-custom-parent {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
@apply relative overflow-hidden;
|
||||
}
|
||||
|
||||
.nprogress-custom-parent #nprogress .spinner,
|
||||
.nprogress-custom-parent #nprogress .bar {
|
||||
position: absolute;
|
||||
@apply absolute;
|
||||
}
|
||||
|
||||
@keyframes nprogress-spinner {
|
||||
|
@@ -1,43 +0,0 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer base {
|
||||
html {
|
||||
@apply font-sans;
|
||||
}
|
||||
}
|
||||
|
||||
@layer components {
|
||||
.flex-center {
|
||||
@apply flex items-center justify-center;
|
||||
}
|
||||
|
||||
.flex-col-center {
|
||||
@apply flex flex-col items-center justify-center;
|
||||
}
|
||||
|
||||
.outline-box {
|
||||
@apply outline-border relative cursor-pointer rounded-md p-1 outline outline-1;
|
||||
}
|
||||
|
||||
.outline-box::after {
|
||||
@apply absolute left-1/2 top-1/2 z-20 h-0 w-[1px] rounded-sm opacity-0 outline outline-2 outline-transparent transition-all duration-300 content-[""];
|
||||
}
|
||||
|
||||
.outline-box.outline-box-active {
|
||||
@apply outline-primary outline outline-2;
|
||||
}
|
||||
|
||||
.outline-box.outline-box-active::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.outline-box:not(.outline-box-active):hover::after {
|
||||
@apply outline-primary left-0 top-0 h-full w-full p-1 opacity-100;
|
||||
}
|
||||
|
||||
.card-box {
|
||||
@apply bg-card text-card-foreground border-border rounded-xl border shadow;
|
||||
}
|
||||
}
|
@@ -87,6 +87,7 @@
|
||||
|
||||
--sidebar: 222.34deg 10.43% 12.27%;
|
||||
--sidebar-deep: 220deg 13.06% 9%;
|
||||
--menu: var(--sidebar);
|
||||
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
@@ -90,6 +90,7 @@
|
||||
/* menu */
|
||||
--sidebar: 0 0% 100%;
|
||||
--sidebar-deep: 210 11.11% 96.47%;
|
||||
--menu: var(--sidebar);
|
||||
|
||||
accent-color: var(--primary);
|
||||
color-scheme: light;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import './scss/index.scss';
|
||||
import './css/tailwind.css';
|
||||
import './css/global.css';
|
||||
import './css/nprogress.css';
|
||||
import './design-tokens';
|
||||
|
||||
|
@@ -1,90 +0,0 @@
|
||||
#app,
|
||||
body,
|
||||
html {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overscroll-behavior: none;
|
||||
}
|
||||
|
||||
*,
|
||||
::after,
|
||||
::before {
|
||||
@apply border-border;
|
||||
|
||||
box-sizing: border-box;
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
html.invert-mode {
|
||||
@apply invert;
|
||||
}
|
||||
|
||||
html.grayscale-mode {
|
||||
@apply grayscale;
|
||||
}
|
||||
|
||||
html {
|
||||
@apply text-foreground bg-background;
|
||||
|
||||
font-size: 100%;
|
||||
font-variation-settings: normal;
|
||||
line-height: 1.15;
|
||||
text-size-adjust: 100%;
|
||||
font-synthesis-weight: none;
|
||||
scroll-behavior: smooth;
|
||||
text-rendering: optimizelegibility;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
a,
|
||||
a:active,
|
||||
a:hover,
|
||||
a:link,
|
||||
a:visited {
|
||||
/* color: inherit; */
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
::view-transition-new(root),
|
||||
::view-transition-old(root) {
|
||||
mix-blend-mode: normal;
|
||||
animation: none;
|
||||
}
|
||||
|
||||
::view-transition-old(root) {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
::view-transition-new(root) {
|
||||
z-index: 2147483646;
|
||||
}
|
||||
|
||||
html.dark::view-transition-old(root) {
|
||||
z-index: 2147483646;
|
||||
}
|
||||
|
||||
html.dark::view-transition-new(root) {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
input::placeholder,
|
||||
textarea::placeholder {
|
||||
/* color: hsl(var(--color-input-placeholder)) !important; */
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
input:-webkit-autofill {
|
||||
border: none;
|
||||
box-shadow: 0 0 0 1000px transparent inset;
|
||||
}
|
||||
|
||||
input[type='number']::-webkit-inner-spin-button,
|
||||
input[type='number']::-webkit-outer-spin-button {
|
||||
margin: 0;
|
||||
appearance: none;
|
||||
}
|
@@ -1,4 +1,3 @@
|
||||
/** css 样式重置 */
|
||||
@import 'modern-normalize/modern-normalize.css';
|
||||
@import './base';
|
||||
@import './transition';
|
||||
|
@@ -272,9 +272,17 @@ const tabbarStyle = computed((): CSSProperties => {
|
||||
if (!isMixedNav.value) {
|
||||
width = '100%';
|
||||
} else if (sidebarEnable.value) {
|
||||
const hoverWidth =
|
||||
sidebarExpandOnHovering.value && !sidebarExpandOnHover.value
|
||||
? props.sidebarWidth
|
||||
: getSideCollapseWidth.value;
|
||||
|
||||
const runtimeWidth = isMixedNav.value ? hoverWidth : props.sidebarWidth;
|
||||
|
||||
marginLeft = sidebarCollapse.value
|
||||
? getSideCollapseWidth.value
|
||||
: props.sidebarWidth;
|
||||
: runtimeWidth;
|
||||
|
||||
width = `calc(100% - ${getSidebarWidth.value}px)`;
|
||||
} else {
|
||||
width = '100%';
|
||||
|
@@ -30,7 +30,7 @@ const isTopLevelMenuItem = computed(
|
||||
() => parentMenu.value?.type.name === 'Menu',
|
||||
);
|
||||
|
||||
const getCollapseShowTitle = computed(
|
||||
const collapseShowTitle = computed(
|
||||
() =>
|
||||
rootMenu.props?.collapseShowTitle &&
|
||||
isTopLevelMenuItem.value &&
|
||||
@@ -78,20 +78,25 @@ onBeforeUnmount(() => {
|
||||
<template>
|
||||
<li
|
||||
:class="[
|
||||
rootMenu.theme,
|
||||
b(),
|
||||
is('active', active),
|
||||
is('disabled', disabled),
|
||||
is('collapse-show-title', getCollapseShowTitle),
|
||||
is('collapse-show-title', collapseShowTitle),
|
||||
]"
|
||||
role="menuitem"
|
||||
@click.stop="handleClick"
|
||||
>
|
||||
<VbenTooltip v-if="showTooltip" side="right">
|
||||
<VbenTooltip
|
||||
v-if="showTooltip"
|
||||
:content-class="[rootMenu.theme]"
|
||||
side="right"
|
||||
>
|
||||
<template #trigger>
|
||||
<div :class="[nsMenu.be('tooltip', 'trigger')]">
|
||||
<VbenIcon :class="nsMenu.e('icon')" :icon="icon" fallback />
|
||||
<slot></slot>
|
||||
<span v-if="getCollapseShowTitle" :class="nsMenu.e('name')">
|
||||
<span v-if="collapseShowTitle" :class="nsMenu.e('name')">
|
||||
<slot name="title"></slot>
|
||||
</span>
|
||||
</div>
|
||||
@@ -99,9 +104,11 @@ onBeforeUnmount(() => {
|
||||
<slot name="title"></slot>
|
||||
</VbenTooltip>
|
||||
<div v-show="!showTooltip" :class="[e('content')]">
|
||||
<VbenMenuBadge v-bind="props" />
|
||||
<VbenMenuBadge
|
||||
v-if="rootMenu.props.mode !== 'horizontal'"
|
||||
v-bind="props"
|
||||
/>
|
||||
<VbenIcon :class="nsMenu.e('icon')" :icon="icon" fallback />
|
||||
|
||||
<slot></slot>
|
||||
<slot name="title"></slot>
|
||||
</div>
|
||||
|
@@ -437,20 +437,18 @@ $namespace: vben;
|
||||
--menu-item-radius: 0px;
|
||||
--menu-item-indent: 16px;
|
||||
--menu-font-size: 14px;
|
||||
--menu-dark-background: 0deg 0% 100% / 10%;
|
||||
--menu-light-background: 192deg 1% 93%;
|
||||
|
||||
&.is-dark {
|
||||
--menu-background-color: hsl(var(--menu-dark));
|
||||
--menu-background-color: hsl(var(--menu));
|
||||
// --menu-submenu-opened-background-color: hsl(var(--menu-opened-dark));
|
||||
--menu-item-background-color: var(--menu-background-color);
|
||||
--menu-item-color: hsl(var(--foreground) / 80%);
|
||||
--menu-item-hover-color: hsl(var(--primary-foreground));
|
||||
--menu-item-hover-background-color: hsl(var(--menu-dark-background));
|
||||
--menu-item-hover-background-color: hsl(var(--accent));
|
||||
--menu-item-active-color: hsl(var(--foreground));
|
||||
--menu-item-active-background-color: hsl(var(--menu-dark-background));
|
||||
--menu-item-active-background-color: hsl(var(--accent));
|
||||
--menu-submenu-hover-color: hsl(var(--foreground));
|
||||
--menu-submenu-hover-background-color: hsl(var(--menu-dark-background));
|
||||
--menu-submenu-hover-background-color: hsl(var(--accent));
|
||||
--menu-submenu-active-color: hsl(var(--foreground));
|
||||
--menu-submenu-active-background-color: transparent;
|
||||
--menu-submenu-background-color: var(--menu-background-color);
|
||||
@@ -462,11 +460,11 @@ $namespace: vben;
|
||||
--menu-item-background-color: var(--menu-background-color);
|
||||
--menu-item-color: hsl(var(--foreground));
|
||||
--menu-item-hover-color: var(--menu-item-color);
|
||||
--menu-item-hover-background-color: hsl(var(--menu-light-background));
|
||||
--menu-item-hover-background-color: hsl(var(--accent));
|
||||
--menu-item-active-color: hsl(var(--primary));
|
||||
--menu-item-active-background-color: hsl(var(--primary) / 15%);
|
||||
--menu-submenu-hover-color: hsl(var(--primary));
|
||||
--menu-submenu-hover-background-color: hsl(var(--menu-light-background));
|
||||
--menu-submenu-hover-background-color: hsl(var(--accent));
|
||||
--menu-submenu-active-color: hsl(var(--primary));
|
||||
--menu-submenu-active-background-color: transparent;
|
||||
--menu-submenu-background-color: var(--menu-background-color);
|
||||
@@ -499,24 +497,24 @@ $namespace: vben;
|
||||
|
||||
&.is-dark {
|
||||
--menu-item-hover-color: var(--foreground);
|
||||
--menu-item-hover-background-color: hsl(var(--menu-dark-background));
|
||||
--menu-item-hover-background-color: hsl(var(--accent));
|
||||
--menu-item-active-color: hsl(var(--foreground));
|
||||
--menu-item-active-background-color: hsl(var(--menu-dark-background));
|
||||
--menu-item-active-background-color: hsl(var(--accent));
|
||||
--menu-submenu-active-color: hsl(var(--foreground));
|
||||
--menu-submenu-active-background-color: hsl(var(--menu-dark-background));
|
||||
--menu-submenu-active-background-color: hsl(var(--accent));
|
||||
--menu-submenu-hover-color: hsl(var(--foreground));
|
||||
--menu-submenu-hover-background-color: hsl(var(--menu-dark-background));
|
||||
--menu-submenu-hover-background-color: hsl(var(--accent));
|
||||
}
|
||||
|
||||
&.is-light {
|
||||
--menu-item-active-color: hsl(var(--foreground));
|
||||
--menu-item-active-background-color: hsl(var(--menu-light-background));
|
||||
--menu-item-hover-background-color: hsl(var(--menu-light-background));
|
||||
--menu-item-active-color: hsl(var(--primary));
|
||||
--menu-item-active-background-color: hsl(var(--primary) / 15%);
|
||||
--menu-item-hover-background-color: hsl(var(--accent));
|
||||
--menu-item-hover-color: hsl(var(--primary));
|
||||
--menu-submenu-active-color: hsl(var(--primary));
|
||||
--menu-submenu-active-background-color: hsl(var(--primary) / 15%);
|
||||
--menu-submenu-hover-color: hsl(var(--primary));
|
||||
--menu-submenu-hover-background-color: hsl(var(--menu-light-background));
|
||||
--menu-submenu-hover-background-color: hsl(var(--accent));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -203,6 +203,7 @@ onBeforeUnmount(() => {
|
||||
<template v-if="rootMenu.isMenuPopup">
|
||||
<VbenHoverCard
|
||||
:content-class="[
|
||||
rootMenu.theme,
|
||||
nsMenu.e('popup-container'),
|
||||
is(rootMenu.theme, true),
|
||||
opened ? '' : 'hidden',
|
||||
|
@@ -1,4 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue';
|
||||
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
@@ -9,6 +11,7 @@ import {
|
||||
import { TooltipContentProps } from 'radix-vue';
|
||||
|
||||
interface Props {
|
||||
contentClass?: HTMLAttributes['class'];
|
||||
delayDuration?: number;
|
||||
side: TooltipContentProps['side'];
|
||||
}
|
||||
@@ -26,6 +29,7 @@ withDefaults(defineProps<Props>(), {
|
||||
<slot name="trigger"></slot>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent
|
||||
:class="contentClass"
|
||||
:side="side"
|
||||
class="side-content text-popover-foreground bg-popover"
|
||||
>
|
||||
|
@@ -3,7 +3,7 @@ import type { TabDefinition } from '@vben-core/typings';
|
||||
|
||||
import type { TabConfig, TabsProps } from '../../types';
|
||||
|
||||
import { computed, nextTick, onMounted, ref, watch } from 'vue';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
|
||||
import { IcRoundClose, MdiPin } from '@vben-core/icons';
|
||||
import { VbenContextMenu, VbenIcon, VbenScrollbar } from '@vben-core/shadcn-ui';
|
||||
@@ -30,7 +30,7 @@ const active = defineModel<string>('active');
|
||||
|
||||
const contentRef = ref();
|
||||
const tabRef = ref();
|
||||
const tabWidth = ref<number>(0);
|
||||
const tabWidth = ref<number>(props.maxWidth);
|
||||
|
||||
const style = computed(() => {
|
||||
const { gap } = props;
|
||||
@@ -39,22 +39,22 @@ const style = computed(() => {
|
||||
};
|
||||
});
|
||||
|
||||
const layout = () => {
|
||||
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 = maxWidth;
|
||||
};
|
||||
// const layout = () => {
|
||||
// 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 = maxWidth;
|
||||
// };
|
||||
|
||||
const tabsView = computed((): TabConfig[] => {
|
||||
return props.tabs.map((tab) => {
|
||||
@@ -71,19 +71,23 @@ const tabsView = computed((): TabConfig[] => {
|
||||
});
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.tabs,
|
||||
() => {
|
||||
nextTick(() => {
|
||||
layout();
|
||||
});
|
||||
},
|
||||
);
|
||||
// watch(
|
||||
// () => props.tabs,
|
||||
// () => {
|
||||
// nextTick(() => {
|
||||
// layout();
|
||||
// });
|
||||
// },
|
||||
// );
|
||||
|
||||
onMounted(() => {
|
||||
layout();
|
||||
watch(active, () => {
|
||||
scrollIntoView();
|
||||
});
|
||||
|
||||
// onMounted(() => {
|
||||
// layout();
|
||||
// });
|
||||
|
||||
function handleClose(key: string) {
|
||||
emit('close', key);
|
||||
}
|
||||
@@ -91,6 +95,16 @@ function handleClose(key: string) {
|
||||
function handleUnpinTab(tab: TabConfig) {
|
||||
emit('unpin', tab);
|
||||
}
|
||||
|
||||
function scrollIntoView() {
|
||||
setTimeout(() => {
|
||||
const element = document.querySelector(`.tabs-chrome__item.is-active`);
|
||||
|
||||
if (element) {
|
||||
element.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -100,7 +114,7 @@ function handleUnpinTab(tab: TabConfig) {
|
||||
<div
|
||||
ref="contentRef"
|
||||
:class="contentClass"
|
||||
class="relative !flex h-full w-max"
|
||||
class="relative !flex h-[calc(100%-1px)] w-max"
|
||||
>
|
||||
<TransitionGroup name="slide-down">
|
||||
<div
|
||||
@@ -110,6 +124,7 @@ function handleUnpinTab(tab: TabConfig) {
|
||||
:class="[
|
||||
{ 'is-active': tab.key === active, dragable: !tab.affixTab },
|
||||
]"
|
||||
:data-active-tab="active"
|
||||
:data-index="i"
|
||||
:style="{
|
||||
width: `${tabWidth}px`,
|
||||
@@ -138,14 +153,14 @@ function handleUnpinTab(tab: TabConfig) {
|
||||
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"
|
||||
class="tabs-chrome__background-before absolute bottom-0 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"
|
||||
class="tabs-chrome__background-after absolute bottom-0 right-[-1px] fill-transparent transition-all duration-150"
|
||||
height="7"
|
||||
width="7"
|
||||
>
|
||||
@@ -198,7 +213,7 @@ function handleUnpinTab(tab: TabConfig) {
|
||||
</TransitionGroup>
|
||||
</div>
|
||||
<!-- footer -->
|
||||
<div class="bg-background h-1"></div>
|
||||
<!-- <div class="bg-background h-1"></div> -->
|
||||
</VbenScrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<script lang="ts" setup>
|
||||
import type { TabConfig, TabsProps } from '../../types';
|
||||
|
||||
import { computed } from 'vue';
|
||||
import { computed, watch } from 'vue';
|
||||
|
||||
import { IcRoundClose, MdiPin } from '@vben-core/icons';
|
||||
import { VbenContextMenu, VbenIcon, VbenScrollbar } from '@vben-core/shadcn-ui';
|
||||
@@ -55,6 +55,10 @@ const tabsView = computed((): TabConfig[] => {
|
||||
});
|
||||
});
|
||||
|
||||
watch(active, () => {
|
||||
scrollIntoView();
|
||||
});
|
||||
|
||||
function handleClose(key: string) {
|
||||
emit('close', key);
|
||||
}
|
||||
@@ -62,6 +66,16 @@ function handleClose(key: string) {
|
||||
function handleUnpinTab(tab: TabConfig) {
|
||||
emit('unpin', tab);
|
||||
}
|
||||
|
||||
function scrollIntoView() {
|
||||
setTimeout(() => {
|
||||
const element = document.querySelector(`.tabs-chrome__item.is-active`);
|
||||
|
||||
if (element) {
|
||||
element.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -83,7 +97,7 @@ function handleUnpinTab(tab: TabConfig) {
|
||||
typeWithClass.content,
|
||||
]"
|
||||
:data-index="i"
|
||||
class="[&:not(.is-active)]:hover:bg-accent group relative flex cursor-pointer select-none transition-all duration-300"
|
||||
class="tabs-chrome__item [&:not(.is-active)]:hover:bg-accent group relative flex cursor-pointer select-none transition-all duration-300"
|
||||
@click="active = tab.key"
|
||||
>
|
||||
<VbenContextMenu
|
||||
|
@@ -76,7 +76,7 @@ function search(searchKey: string) {
|
||||
// the scroll bar needs to scroll automatically
|
||||
function scrollIntoView() {
|
||||
const element = document.querySelector(
|
||||
`[data-search-item="${activeIndex.value}"`,
|
||||
`[data-search-item="${activeIndex.value}"]`,
|
||||
);
|
||||
|
||||
if (element) {
|
||||
|
Reference in New Issue
Block a user