diff --git a/docs/src/guide/in-depth/theme.md b/docs/src/guide/in-depth/theme.md index 49bd9af5..83aafa23 100644 --- a/docs/src/guide/in-depth/theme.md +++ b/docs/src/guide/in-depth/theme.md @@ -239,9 +239,11 @@ css 变量内的颜色,必须使用 `hsl` 格式,如 `0 0% 100%`,不需要 ```css /* */ -:root { +.dark, +.dark[data-theme='custom'], +.dark[data-theme='default'] { /* Background color for */ - --card: 0 0% 30%; + --card: 222.34deg 10.43% 12.27%; } ``` diff --git a/internal/node-utils/src/spinner.ts b/internal/node-utils/src/spinner.ts index 9f05a515..f07cc256 100644 --- a/internal/node-utils/src/spinner.ts +++ b/internal/node-utils/src/spinner.ts @@ -1,4 +1,4 @@ -import ora, { Ora } from 'ora'; +import ora, { type Ora } from 'ora'; interface SpinnerOptions { failedText?: string; diff --git a/packages/@core/base/design/src/design-tokens/dark/index.css b/packages/@core/base/design/src/design-tokens/dark/index.css index 92a60f06..a038c556 100644 --- a/packages/@core/base/design/src/design-tokens/dark/index.css +++ b/packages/@core/base/design/src/design-tokens/dark/index.css @@ -52,12 +52,12 @@ --secondary-foreground: 0 0% 98%; /* Used for accents such as hover effects on , ...etc */ - --accent: 240 3.7% 15.9%; - --accent-hover: 240 3.7% 20.9%; + --accent: 216 5% 19%; + --accent-hover: 216 5% 24%; --accent-foreground: 0 0% 98%; /* Darker color */ - --heavy: 240 3.7% 20.9%; + --heavy: 216 5% 24%; --heavy-foreground: var(--accent-foreground); /* Default border color */ diff --git a/packages/@core/base/design/src/design-tokens/default/index.css b/packages/@core/base/design/src/design-tokens/default/index.css index 8ea8a575..bd73cbc2 100644 --- a/packages/@core/base/design/src/design-tokens/default/index.css +++ b/packages/@core/base/design/src/design-tokens/default/index.css @@ -89,7 +89,7 @@ /* menu */ --sidebar: 0 0% 100%; - --sidebar-deep: 210 11.11% 96.47%; + --sidebar-deep: 0 0% 100%; --menu: var(--sidebar); accent-color: var(--primary); diff --git a/packages/@core/ui-kit/layout-ui/src/components/layout-header.vue b/packages/@core/ui-kit/layout-ui/src/components/layout-header.vue index 1614f03c..4a01ca41 100644 --- a/packages/@core/ui-kit/layout-ui/src/components/layout-header.vue +++ b/packages/@core/ui-kit/layout-ui/src/components/layout-header.vue @@ -84,7 +84,7 @@ function handleToggleMenu() { diff --git a/packages/@core/ui-kit/layout-ui/src/components/layout-sidebar.vue b/packages/@core/ui-kit/layout-ui/src/components/layout-sidebar.vue index c24c2eca..0de22d29 100644 --- a/packages/@core/ui-kit/layout-ui/src/components/layout-sidebar.vue +++ b/packages/@core/ui-kit/layout-ui/src/components/layout-sidebar.vue @@ -24,9 +24,8 @@ interface Props { domVisible?: boolean; /** * 扩展区域宽度 - * @default 180 */ - extraWidth?: number; + extraWidth: number; /** * 固定扩展区域 * @default false @@ -69,13 +68,12 @@ interface Props { /** * 主题 */ - theme?: string; + theme: string; /** * 宽度 - * @default 180 */ - width?: number; + width: number; /** * zIndex * @default 0 @@ -87,7 +85,6 @@ const props = withDefaults(defineProps(), { collapseHeight: 42, collapseWidth: 48, domVisible: true, - extraWidth: 180, fixedExtra: false, isSidebarMixed: false, marginTop: 0, @@ -95,8 +92,6 @@ const props = withDefaults(defineProps(), { paddingTop: 0, show: true, showCollapseButton: true, - theme: 'dark', - width: 180, zIndex: 0, }); @@ -181,10 +176,8 @@ const extraContentStyle = computed((): CSSProperties => { }); const collapseStyle = computed((): CSSProperties => { - const { collapseHeight } = props; - return { - height: `${collapseHeight}px`, + height: `${props.collapseHeight}px`, }; }); diff --git a/packages/@core/ui-kit/layout-ui/src/hooks/use-layout.ts b/packages/@core/ui-kit/layout-ui/src/hooks/use-layout.ts new file mode 100644 index 00000000..354fcb44 --- /dev/null +++ b/packages/@core/ui-kit/layout-ui/src/hooks/use-layout.ts @@ -0,0 +1,41 @@ +import type { LayoutType } from '@vben-core/typings'; + +import type { VbenLayoutProps } from '../vben-layout'; + +import { computed } from 'vue'; + +export function useLayout(props: VbenLayoutProps) { + const currentLayout = computed(() => + props.isMobile ? 'sidebar-nav' : (props.layout as LayoutType), + ); + + /** + * 是否全屏显示content,不需要侧边、底部、顶部、tab区域 + */ + const isFullContent = computed(() => currentLayout.value === 'full-content'); + + /** + * 是否侧边混合模式 + */ + const isSidebarMixedNav = computed( + () => currentLayout.value === 'sidebar-mixed-nav', + ); + + /** + * 是否为头部导航模式 + */ + const isHeaderNav = computed(() => currentLayout.value === 'header-nav'); + + /** + * 是否为混合导航模式 + */ + const isMixedNav = computed(() => currentLayout.value === 'mixed-nav'); + + return { + currentLayout, + isFullContent, + isHeaderNav, + isMixedNav, + isSidebarMixedNav, + }; +} diff --git a/packages/@core/ui-kit/layout-ui/src/vben-layout.ts b/packages/@core/ui-kit/layout-ui/src/vben-layout.ts index 8c07ed81..06f8fe1d 100644 --- a/packages/@core/ui-kit/layout-ui/src/vben-layout.ts +++ b/packages/@core/ui-kit/layout-ui/src/vben-layout.ts @@ -62,12 +62,6 @@ interface VbenLayoutProps { * @default 48 */ headerHeight?: number; - /** - * header高度增加高度 - * 在顶部存在导航时,额外加高header高度 - * @default 10 - */ - headerHeightOffset?: number; /** * 顶栏是否隐藏 * @default false @@ -133,11 +127,7 @@ interface VbenLayoutProps { * @default 80 */ sidebarMixedWidth?: number; - /** - * 侧边栏是否半深色 - * @default false - */ - sidebarSemiDark?: boolean; + /** * 侧边栏 * @default dark diff --git a/packages/@core/ui-kit/layout-ui/src/vben-layout.vue b/packages/@core/ui-kit/layout-ui/src/vben-layout.vue index f86734c9..16870620 100644 --- a/packages/@core/ui-kit/layout-ui/src/vben-layout.vue +++ b/packages/@core/ui-kit/layout-ui/src/vben-layout.vue @@ -13,6 +13,7 @@ import { LayoutSidebar, LayoutTabbar, } from './components'; +import { useLayout } from './hooks/use-layout'; interface Props extends VbenLayoutProps {} @@ -32,7 +33,6 @@ const props = withDefaults(defineProps(), { footerFixed: true, footerHeight: 32, headerHeight: 50, - headerHeightOffset: 10, headerHidden: false, headerMode: 'fixed', headerToggleSidebarButton: true, @@ -43,7 +43,6 @@ const props = withDefaults(defineProps(), { sidebarExtraCollapsedWidth: 60, sidebarHidden: false, sidebarMixedWidth: 80, - sidebarSemiDark: true, sidebarTheme: 'dark', sidebarWidth: 180, sideCollapseWidth: 60, @@ -73,57 +72,23 @@ const { const { y: mouseY } = useMouse({ target: contentRef, type: 'client' }); -const realLayout = computed(() => - props.isMobile ? 'sidebar-nav' : props.layout, -); - -/** - * 是否全屏显示content,不需要侧边、底部、顶部、tab区域 - */ -const fullContent = computed(() => realLayout.value === 'full-content'); - -/** - * 是否侧边混合模式 - */ -const isSidebarMixedNav = computed( - () => realLayout.value === 'sidebar-mixed-nav', -); - -/** - * 是否为头部导航模式 - */ -const isHeaderNav = computed(() => realLayout.value === 'header-nav'); - -/** - * 是否为混合导航模式 - */ -const isMixedNav = computed(() => realLayout.value === 'mixed-nav'); +const { + currentLayout, + isFullContent, + isHeaderNav, + isMixedNav, + isSidebarMixedNav, +} = useLayout(props); /** * 顶栏是否自动隐藏 */ const isHeaderAutoMode = computed(() => props.headerMode === 'auto'); -/** - * header区域高度 - */ -const getHeaderHeight = computed(() => { - const { headerHeight, headerHeightOffset } = props; - - // if (!headerVisible) { - // return 0; - // } - - // 顶部存在导航时,增加10 - const offset = isMixedNav.value || isHeaderNav.value ? headerHeightOffset : 0; - - return headerHeight + offset; -}); - const headerWrapperHeight = computed(() => { let height = 0; if (props.headerVisible && !props.headerHidden) { - height += getHeaderHeight.value; + height += props.headerHeight; } if (props.tabbarEnable) { height += props.tabbarHeight; @@ -151,8 +116,8 @@ const sidebarEnableState = computed(() => { * 侧边区域离顶部高度 */ const sidebarMarginTop = computed(() => { - const { isMobile } = props; - return isMixedNav.value && !isMobile ? getHeaderHeight.value : 0; + const { headerHeight, isMobile } = props; + return isMixedNav.value && !isMobile ? headerHeight : 0; }); /** @@ -195,30 +160,13 @@ const sidebarExtraWidth = computed(() => { /** * 是否侧边栏模式,包含混合侧边 */ -const isSideMode = computed(() => - ['mixed-nav', 'sidebar-mixed-nav', 'sidebar-nav'].includes(realLayout.value), +const isSideMode = computed( + () => + currentLayout.value === 'mixed-nav' || + currentLayout.value === 'sidebar-mixed-nav' || + currentLayout.value === 'sidebar-nav', ); -const showSidebar = computed(() => { - // if (isMixedNav.value && !props.sideHidden) { - // return false; - // } - return isSideMode.value && sidebarEnable.value; -}); - -const sidebarFace = computed(() => { - const { sidebarSemiDark, sidebarTheme } = props; - const isDark = sidebarTheme === 'dark' || sidebarSemiDark; - return { - theme: isDark ? 'dark' : 'light', - }; -}); - -/** - * 遮罩可见性 - */ -const maskVisible = computed(() => !sidebarCollapse.value && props.isMobile); - /** * header fixed值 */ @@ -232,13 +180,25 @@ const headerFixed = computed(() => { ); }); +const showSidebar = computed(() => { + // if (isMixedNav.value && !props.sideHidden) { + // return false; + // } + return isSideMode.value && sidebarEnable.value; +}); + +/** + * 遮罩可见性 + */ +const maskVisible = computed(() => !sidebarCollapse.value && props.isMobile); + const mainStyle = computed(() => { let width = '100%'; let sidebarAndExtraWidth = 'unset'; if ( headerFixed.value && - realLayout.value !== 'header-nav' && - realLayout.value !== 'mixed-nav' && + currentLayout.value !== 'header-nav' && + currentLayout.value !== 'mixed-nav' && showSidebar.value && !props.isMobile ) { @@ -253,7 +213,7 @@ const mainStyle = computed(() => { ? getSideCollapseWidth.value : props.sidebarMixedWidth; const sideWidth = sidebarExtraCollapse.value - ? getSideCollapseWidth.value + ? props.sidebarExtraCollapsedWidth : props.sidebarWidth; // 100% - 侧边菜单混合宽度 - 菜单宽度 @@ -312,7 +272,7 @@ const contentStyle = computed((): CSSProperties => { return { marginTop: fixed && - !fullContent.value && + !isFullContent.value && !headerIsHidden.value && (!isHeaderAutoMode.value || scrollY.value < headerWrapperHeight.value) ? `${headerWrapperHeight.value}px` @@ -330,11 +290,11 @@ const headerZIndex = computed(() => { const headerWrapperStyle = computed((): CSSProperties => { const fixed = headerFixed.value; return { - height: fullContent.value ? '0' : `${headerWrapperHeight.value}px`, + height: isFullContent.value ? '0' : `${headerWrapperHeight.value}px`, left: isMixedNav.value ? 0 : mainStyle.value.sidebarAndExtraWidth, position: fixed ? 'fixed' : 'static', top: - headerIsHidden.value || fullContent.value + headerIsHidden.value || isFullContent.value ? `-${headerWrapperHeight.value}px` : 0, width: mainStyle.value.width, @@ -403,7 +363,10 @@ watch( watch( [() => props.headerMode, () => mouseY.value], () => { - if (!isHeaderAutoMode.value || isMixedNav.value || fullContent.value) { + if (!isHeaderAutoMode.value || isMixedNav.value || isFullContent.value) { + if (props.headerMode !== 'auto-scroll') { + headerIsHidden.value = false; + } return; } headerIsHidden.value = true; @@ -439,7 +402,7 @@ watch( if ( props.headerMode !== 'auto-scroll' || isMixedNav.value || - fullContent.value + isFullContent.value ) { return; } @@ -465,8 +428,6 @@ function handleOpenMenu() {