fix: fix known problems

This commit is contained in:
vince
2024-07-16 00:14:24 +08:00
parent cf16c7bdde
commit 09fa2af23d
21 changed files with 242 additions and 697 deletions

View 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;
}
}

View File

@@ -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 {

View File

@@ -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;
}
}

View File

@@ -87,6 +87,7 @@
--sidebar: 222.34deg 10.43% 12.27%;
--sidebar-deep: 220deg 13.06% 9%;
--menu: var(--sidebar);
color-scheme: dark;
}

View File

@@ -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;

View File

@@ -1,5 +1,5 @@
import './scss/index.scss';
import './css/tailwind.css';
import './css/global.css';
import './css/nprogress.css';
import './design-tokens';

View File

@@ -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;
}

View File

@@ -1,4 +1,3 @@
/** css 样式重置 */
@import 'modern-normalize/modern-normalize.css';
@import './base';
@import './transition';

View File

@@ -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%';

View File

@@ -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>

View File

@@ -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));
}
}
}

View File

@@ -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',

View File

@@ -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"
>

View File

@@ -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>

View File

@@ -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

View File

@@ -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) {