diff --git a/apps/web-antd/package.json b/apps/web-antd/package.json index dfa72983..4b1f5500 100644 --- a/apps/web-antd/package.json +++ b/apps/web-antd/package.json @@ -35,7 +35,7 @@ "@vben/styles": "workspace:*", "@vben/types": "workspace:*", "@vben/utils": "workspace:*", - "@vueuse/core": "^10.10.0", + "@vueuse/core": "^10.10.1", "ant-design-vue": "^4.2.3", "axios": "^1.7.2", "dayjs": "^1.11.11", diff --git a/internal/lint-configs/commitlint-config/package.json b/internal/lint-configs/commitlint-config/package.json index 0e1bec40..d3ff985b 100644 --- a/internal/lint-configs/commitlint-config/package.json +++ b/internal/lint-configs/commitlint-config/package.json @@ -34,7 +34,7 @@ "@commitlint/cli": "^19.3.0", "@commitlint/config-conventional": "^19.2.2", "@vben/node-utils": "workspace:*", - "cz-git": "^1.9.2", - "czg": "^1.9.2" + "cz-git": "^1.9.3", + "czg": "^1.9.3" } } diff --git a/internal/lint-configs/prettier-config/package.json b/internal/lint-configs/prettier-config/package.json index 5a36e412..ee46aa23 100644 --- a/internal/lint-configs/prettier-config/package.json +++ b/internal/lint-configs/prettier-config/package.json @@ -32,6 +32,6 @@ }, "dependencies": { "prettier": "3.3.0", - "prettier-plugin-tailwindcss": "^0.6.2" + "prettier-plugin-tailwindcss": "^0.6.3" } } diff --git a/internal/vite-config/package.json b/internal/vite-config/package.json index 55c7c4ce..177a5b6a 100644 --- a/internal/vite-config/package.json +++ b/internal/vite-config/package.json @@ -46,7 +46,7 @@ "dayjs": "^1.11.11", "dotenv": "^16.4.5", "rollup-plugin-visualizer": "^5.12.0", - "sass": "^1.77.4", + "sass": "^1.77.5", "unplugin-turbo-console": "^1.8.6", "vite": "6.0.0-alpha.17", "vite-plugin-compression": "^0.5.1", diff --git a/packages/@core/forward/helpers/src/find-menu-by-path.test.ts b/packages/@core/forward/helpers/src/find-menu-by-path.test.ts new file mode 100644 index 00000000..81527839 --- /dev/null +++ b/packages/@core/forward/helpers/src/find-menu-by-path.test.ts @@ -0,0 +1,88 @@ +import { describe, expect, it } from 'vitest'; + +import { findMenuByPath, findRootMenuByPath } from './find-menu-by-path'; + +// 示例菜单数据 +const menus: any[] = [ + { path: '/', children: [] }, + { path: '/about', children: [] }, + { + path: '/contact', + children: [ + { path: '/contact/email', children: [] }, + { path: '/contact/phone', children: [] }, + ], + }, + { + path: '/services', + children: [ + { path: '/services/design', children: [] }, + { + path: '/services/development', + children: [{ path: '/services/development/web', children: [] }], + }, + ], + }, +]; + +describe('menu Finder Tests', () => { + it('finds a top-level menu', () => { + const menu = findMenuByPath(menus, '/about'); + expect(menu).toBeDefined(); + expect(menu?.path).toBe('/about'); + }); + + it('finds a nested menu', () => { + const menu = findMenuByPath(menus, '/services/development/web'); + expect(menu).toBeDefined(); + expect(menu?.path).toBe('/services/development/web'); + }); + + it('returns null for a non-existent path', () => { + const menu = findMenuByPath(menus, '/non-existent'); + expect(menu).toBeNull(); + }); + + it('handles empty menus list', () => { + const menu = findMenuByPath([], '/about'); + expect(menu).toBeNull(); + }); + + it('handles menu items without children', () => { + const menu = findMenuByPath( + [{ path: '/only', children: undefined }] as any[], + '/only', + ); + expect(menu).toBeDefined(); + expect(menu?.path).toBe('/only'); + }); + + it('finds root menu by path', () => { + const { findMenu, rootMenu, rootMenuPath } = findRootMenuByPath( + menus, + '/services/development/web', + ); + + expect(findMenu).toBeDefined(); + expect(rootMenu).toBeUndefined(); + expect(rootMenuPath).toBeUndefined(); + expect(findMenu?.path).toBe('/services/development/web'); + }); + + it('returns null for undefined or empty path', () => { + const menuUndefinedPath = findMenuByPath(menus); + const menuEmptyPath = findMenuByPath(menus, ''); + expect(menuUndefinedPath).toBeNull(); + expect(menuEmptyPath).toBeNull(); + }); + + it('checks for root menu when path does not exist', () => { + const { findMenu, rootMenu, rootMenuPath } = findRootMenuByPath( + menus, + '/non-existent', + ); + expect(findMenu).toBeNull(); + expect(rootMenu).toBeUndefined(); + expect(rootMenuPath).toBeUndefined(); + }); +}); diff --git a/packages/business/layouts/src/basic/menu/helper.ts b/packages/@core/forward/helpers/src/find-menu-by-path.ts similarity index 81% rename from packages/business/layouts/src/basic/menu/helper.ts rename to packages/@core/forward/helpers/src/find-menu-by-path.ts index ab9b8296..29813a9e 100644 --- a/packages/business/layouts/src/basic/menu/helper.ts +++ b/packages/@core/forward/helpers/src/find-menu-by-path.ts @@ -8,11 +8,9 @@ function findMenuByPath( if (menu.path === path) { return menu; } - if (menu?.children?.length) { - const findMenu = findMenuByPath(menu.children, path); - if (findMenu) { - return findMenu; - } + const findMenu = menu.children && findMenuByPath(menu.children, path); + if (findMenu) { + return findMenu; } } return null; diff --git a/packages/@core/forward/helpers/src/index.ts b/packages/@core/forward/helpers/src/index.ts index 7f47ba14..d96c46e3 100644 --- a/packages/@core/forward/helpers/src/index.ts +++ b/packages/@core/forward/helpers/src/index.ts @@ -1,3 +1,4 @@ +export * from './find-menu-by-path'; export * from './flatten-object'; export * from './generator-menus'; export * from './generator-routes'; diff --git a/packages/@core/forward/preferences/package.json b/packages/@core/forward/preferences/package.json index 8e82c7c2..0342a15f 100644 --- a/packages/@core/forward/preferences/package.json +++ b/packages/@core/forward/preferences/package.json @@ -36,7 +36,7 @@ "@vben-core/helpers": "workspace:*", "@vben-core/toolkit": "workspace:*", "@vben-core/typings": "workspace:*", - "@vueuse/core": "^10.10.0", + "@vueuse/core": "^10.10.1", "vue": "3.4.27" } } diff --git a/packages/@core/forward/preferences/src/config.ts b/packages/@core/forward/preferences/src/config.ts index f721fd85..85daed91 100644 --- a/packages/@core/forward/preferences/src/config.ts +++ b/packages/@core/forward/preferences/src/config.ts @@ -12,7 +12,7 @@ const defaultPreferences: Preferences = { 'https://cdn.jsdelivr.net/npm/@vbenjs/static-source@0.1.0/source/avatar-v1.webp', dynamicTitle: true, isMobile: false, - layout: 'side-nav', + layout: 'sidebar-nav', locale: 'zh-CN', name: 'Vben Admin Pro', semiDarkMenu: true, @@ -47,8 +47,8 @@ const defaultPreferences: Preferences = { }, shortcutKeys: { enable: true }, sidebar: { - collapse: false, - collapseShowTitle: true, + collapsed: false, + collapsedShowTitle: true, enable: true, expandOnHover: true, extraCollapse: true, diff --git a/packages/@core/forward/preferences/src/types.ts b/packages/@core/forward/preferences/src/types.ts index fffb1f5d..2a577a77 100644 --- a/packages/@core/forward/preferences/src/types.ts +++ b/packages/@core/forward/preferences/src/types.ts @@ -94,9 +94,9 @@ interface NavigationPreferences { interface SidebarPreferences { /** 侧边栏是否折叠 */ - collapse: boolean; + collapsed: boolean; /** 侧边栏折叠时,是否显示title */ - collapseShowTitle: boolean; + collapsedShowTitle: boolean; /** 侧边栏是否可见 */ enable: boolean; /** 菜单自动展开状态 */ diff --git a/packages/@core/forward/preferences/src/use-preferences.ts b/packages/@core/forward/preferences/src/use-preferences.ts index 27c923d2..6c20dae4 100644 --- a/packages/@core/forward/preferences/src/use-preferences.ts +++ b/packages/@core/forward/preferences/src/use-preferences.ts @@ -33,7 +33,7 @@ function usePreferences() { * @zh_CN 布局方式 */ const layout = computed(() => - appPreferences.value.isMobile ? 'side-nav' : appPreferences.value.layout, + appPreferences.value.isMobile ? 'sidebar-nav' : appPreferences.value.layout, ); /** @@ -46,13 +46,15 @@ function usePreferences() { /** * @zh_CN 是否侧边导航模式 */ - const isSideNav = computed(() => appPreferences.value.layout === 'side-nav'); + const isSideNav = computed( + () => appPreferences.value.layout === 'sidebar-nav', + ); /** * @zh_CN 是否侧边混合模式 */ const isSideMixedNav = computed( - () => appPreferences.value.layout === 'side-mixed-nav', + () => appPreferences.value.layout === 'sidebar-mixed-nav', ); /** diff --git a/packages/@core/shared/typings/src/app.d.ts b/packages/@core/shared/typings/src/app.d.ts index ec6155dd..a2b2c463 100644 --- a/packages/@core/shared/typings/src/app.d.ts +++ b/packages/@core/shared/typings/src/app.d.ts @@ -4,8 +4,8 @@ type LayoutType = | 'full-content' | 'header-nav' | 'mixed-nav' - | 'side-mixed-nav' - | 'side-nav'; + | 'sidebar-mixed-nav' + | 'sidebar-nav'; type ThemeModeType = 'auto' | 'dark' | 'light'; diff --git a/packages/@core/uikit/layout-ui/package.json b/packages/@core/uikit/layout-ui/package.json index a45c75a4..51e72573 100644 --- a/packages/@core/uikit/layout-ui/package.json +++ b/packages/@core/uikit/layout-ui/package.json @@ -41,12 +41,10 @@ } }, "dependencies": { - "@vben-core/design": "workspace:*", "@vben-core/iconify": "workspace:*", "@vben-core/shadcn-ui": "workspace:*", - "@vben-core/toolkit": "workspace:*", "@vben-core/typings": "workspace:*", - "@vueuse/core": "^10.10.0", + "@vueuse/core": "^10.10.1", "vue": "3.4.27" } } diff --git a/packages/@core/uikit/layout-ui/src/components/index.ts b/packages/@core/uikit/layout-ui/src/components/index.ts index 71366f39..f17826dd 100644 --- a/packages/@core/uikit/layout-ui/src/components/index.ts +++ b/packages/@core/uikit/layout-ui/src/components/index.ts @@ -1,5 +1,5 @@ export { default as LayoutContent } from './layout-content.vue'; export { default as LayoutFooter } from './layout-footer.vue'; export { default as LayoutHeader } from './layout-header.vue'; -export { default as LayoutSide } from './layout-side.vue'; -export { default as LayoutTabs } from './layout-tabs.vue'; +export { default as LayoutSidebar } from './layout-sidebar.vue'; +export { default as LayoutTabbar } from './layout-tabbar.vue'; diff --git a/packages/@core/uikit/layout-ui/src/components/layout-content.vue b/packages/@core/uikit/layout-ui/src/components/layout-content.vue index 7d3aef76..146fe7b6 100644 --- a/packages/@core/uikit/layout-ui/src/components/layout-content.vue +++ b/packages/@core/uikit/layout-ui/src/components/layout-content.vue @@ -42,8 +42,6 @@ interface Props { paddingTop?: number; } -defineOptions({ name: 'LayoutContent' }); - const props = withDefaults(defineProps(), { contentCompact: 'wide', contentCompactWidth: 1200, @@ -65,7 +63,9 @@ const style = computed((): CSSProperties => { } = props; const compactStyle: CSSProperties = - contentCompact === 'compact' ? { margin: '0 auto', width: `1200px` } : {}; + contentCompact === 'compact' + ? { margin: '0 auto', width: `${props.contentCompactWidth}px` } + : {}; return { ...compactStyle, flex: 1, diff --git a/packages/@core/uikit/layout-ui/src/components/layout-footer.vue b/packages/@core/uikit/layout-ui/src/components/layout-footer.vue index 409d26f5..c3834a91 100644 --- a/packages/@core/uikit/layout-ui/src/components/layout-footer.vue +++ b/packages/@core/uikit/layout-ui/src/components/layout-footer.vue @@ -2,8 +2,6 @@ import type { CSSProperties } from 'vue'; import { computed } from 'vue'; -import { useNamespace } from '@vben-core/toolkit'; - interface Props { /** * 背景颜色 @@ -36,8 +34,6 @@ interface Props { zIndex?: number; } -defineOptions({ name: 'LayoutFooter' }); - const props = withDefaults(defineProps(), { backgroundColor: 'hsl(var(--color-background))', fixed: true, @@ -47,8 +43,6 @@ const props = withDefaults(defineProps(), { zIndex: 0, }); -const { b } = useNamespace('footer'); - const style = computed((): CSSProperties => { const { backgroundColor, fixed, height, show, width, zIndex } = props; return { @@ -63,11 +57,7 @@ const style = computed((): CSSProperties => { diff --git a/packages/@core/uikit/layout-ui/src/components/layout-header.vue b/packages/@core/uikit/layout-ui/src/components/layout-header.vue index feb01454..218557a7 100644 --- a/packages/@core/uikit/layout-ui/src/components/layout-header.vue +++ b/packages/@core/uikit/layout-ui/src/components/layout-header.vue @@ -41,15 +41,12 @@ interface Props { * @default true */ showToggleBtn?: boolean; - /** - * 侧边是否显示 - */ - sideHidden?: boolean; + /** * 侧边菜单宽度 * @default 0 */ - sideWidth?: number; + sidebarWidth?: number; /** * 宽度 * @default 100% @@ -62,8 +59,6 @@ interface Props { zIndex?: number; } -defineOptions({ name: 'LayoutHeader' }); - const props = withDefaults(defineProps(), { backgroundColor: 'hsl(var(--color-background))', // fixed: true, @@ -71,12 +66,12 @@ const props = withDefaults(defineProps(), { isMixedNav: false, show: true, showToggleBtn: false, - sideWidth: 0, + sidebarWidth: 0, width: '100%', zIndex: 0, }); -const emit = defineEmits<{ openMenu: []; toggleMenu: [] }>(); +const emit = defineEmits<{ openMenu: []; toggleSidebar: [] }>(); const slots = useSlots(); @@ -95,16 +90,16 @@ const style = computed((): CSSProperties => { const logoStyle = computed((): CSSProperties => { return { - minWidth: `${props.isMobile ? 40 : props.sideWidth}px`, + minWidth: `${props.isMobile ? 40 : props.sidebarWidth}px`, }; }); function handleToggleMenu() { - emit('toggleMenu'); -} - -function handleOpenMenu() { - emit('openMenu'); + if (props.isMobile) { + emit('openMenu'); + } else { + emit('toggleSidebar'); + } } @@ -117,21 +112,12 @@ function handleOpenMenu() { - - - - - diff --git a/packages/@core/uikit/layout-ui/src/components/layout-side.vue b/packages/@core/uikit/layout-ui/src/components/layout-sidebar.vue similarity index 70% rename from packages/@core/uikit/layout-ui/src/components/layout-side.vue rename to packages/@core/uikit/layout-ui/src/components/layout-sidebar.vue index 0e5d398b..a5c8cb7b 100644 --- a/packages/@core/uikit/layout-ui/src/components/layout-side.vue +++ b/packages/@core/uikit/layout-ui/src/components/layout-sidebar.vue @@ -1,12 +1,10 @@ diff --git a/packages/@core/uikit/layout-ui/src/components/layout-tabs.vue b/packages/@core/uikit/layout-ui/src/components/layout-tabbar.vue similarity index 93% rename from packages/@core/uikit/layout-ui/src/components/layout-tabs.vue rename to packages/@core/uikit/layout-ui/src/components/layout-tabbar.vue index faafb12b..9f996cce 100644 --- a/packages/@core/uikit/layout-ui/src/components/layout-tabs.vue +++ b/packages/@core/uikit/layout-ui/src/components/layout-tabbar.vue @@ -14,8 +14,6 @@ interface Props { height?: number; } -defineOptions({ name: 'LayoutTabs' }); - const props = withDefaults(defineProps(), { backgroundColor: 'hsl(var(--color-background))', fixed: true, @@ -34,7 +32,6 @@ const style = computed((): CSSProperties => { return { ...hiddenStyle.value, backgroundColor, - display: 'flex', }; }); diff --git a/packages/@core/uikit/layout-ui/src/components/widgets/index.ts b/packages/@core/uikit/layout-ui/src/components/widgets/index.ts index 4597fc4f..8dfbe6c3 100644 --- a/packages/@core/uikit/layout-ui/src/components/widgets/index.ts +++ b/packages/@core/uikit/layout-ui/src/components/widgets/index.ts @@ -1,2 +1,2 @@ -export { default as SideCollapseButton } from './side-collapse-button.vue'; -export { default as SidePinButton } from './side-pin-button.vue'; +export { default as SidebarCollapseButton } from './sidebar-collapse-button.vue'; +export { default as SidebarFixedButton } from './sidebar-fixed-button.vue'; diff --git a/packages/@core/uikit/layout-ui/src/components/widgets/side-collapse-button.vue b/packages/@core/uikit/layout-ui/src/components/widgets/side-collapse-button.vue deleted file mode 100644 index 6396a789..00000000 --- a/packages/@core/uikit/layout-ui/src/components/widgets/side-collapse-button.vue +++ /dev/null @@ -1,63 +0,0 @@ - - - - - diff --git a/packages/@core/uikit/layout-ui/src/components/widgets/side-pin-button.vue b/packages/@core/uikit/layout-ui/src/components/widgets/side-pin-button.vue deleted file mode 100644 index b2526063..00000000 --- a/packages/@core/uikit/layout-ui/src/components/widgets/side-pin-button.vue +++ /dev/null @@ -1,64 +0,0 @@ - - - - - diff --git a/packages/@core/uikit/layout-ui/src/components/widgets/sidebar-collapse-button.vue b/packages/@core/uikit/layout-ui/src/components/widgets/sidebar-collapse-button.vue new file mode 100644 index 00000000..16b32315 --- /dev/null +++ b/packages/@core/uikit/layout-ui/src/components/widgets/sidebar-collapse-button.vue @@ -0,0 +1,26 @@ + + + diff --git a/packages/@core/uikit/layout-ui/src/components/widgets/sidebar-fixed-button.vue b/packages/@core/uikit/layout-ui/src/components/widgets/sidebar-fixed-button.vue new file mode 100644 index 00000000..33b5a3ae --- /dev/null +++ b/packages/@core/uikit/layout-ui/src/components/widgets/sidebar-fixed-button.vue @@ -0,0 +1,26 @@ + + + diff --git a/packages/@core/uikit/layout-ui/src/vben-layout.ts b/packages/@core/uikit/layout-ui/src/vben-layout.ts index 23efbb0d..0d96a4b2 100644 --- a/packages/@core/uikit/layout-ui/src/vben-layout.ts +++ b/packages/@core/uikit/layout-ui/src/vben-layout.ts @@ -99,64 +99,64 @@ interface VbenLayoutProps { isMobile?: boolean; /** * 布局方式 - * side-nav 侧边菜单布局 + * sidebar-nav 侧边菜单布局 * header-nav 顶部菜单布局 * mixed-nav 侧边&顶部菜单布局 - * side-mixed-nav 侧边混合菜单布局 + * sidebar-mixed-nav 侧边混合菜单布局 * full-content 全屏内容布局 - * @default side-nav + * @default sidebar-nav */ layout?: LayoutType; - /** - * 侧边菜单折叠状态 - * @default false - */ - sideCollapse?: boolean; - /** - * 侧边菜单是否折叠时,是否显示title - * @default true - */ - sideCollapseShowTitle?: boolean; /** * 侧边菜单折叠宽度 * @default 48 */ sideCollapseWidth?: number; /** - * 侧边栏是否隐藏 + * 侧边菜单折叠状态 * @default false */ - sideHidden?: boolean; + sidebarCollapse?: boolean; /** - * 混合侧边扩展区域是否可见 - * @default false + * 侧边菜单是否折叠时,是否显示title + * @default true */ - sideMixedExtraVisible?: boolean; - /** - * 混合侧边栏宽度 - * @default 80 - */ - sideMixedWidth?: number; - /** - * 侧边栏是否半深色 - * @default false - */ - sideSemiDark?: boolean; - /** - * 侧边栏 - * @default dark - */ - sideTheme?: ThemeModeType; + sidebarCollapseShowTitle?: boolean; /** * 侧边栏是否可见 * @default true */ - sideVisible?: boolean; + sidebarEnable?: boolean; + /** + * 侧边栏是否隐藏 + * @default false + */ + sidebarHidden?: boolean; + /** + * 混合侧边栏宽度 + * @default 80 + */ + sidebarMixedWidth?: number; + /** + * 侧边栏是否半深色 + * @default false + */ + sidebarSemiDark?: boolean; + /** + * 侧边栏 + * @default dark + */ + sidebarTheme?: ThemeModeType; /** * 侧边栏宽度 * @default 210 */ - sideWidth?: number; + sidebarWidth?: number; + /** + * tab是否可见 + * @default true + */ + tabbarEnable?: boolean; /** * footer背景颜色 * @default #fff @@ -167,11 +167,6 @@ interface VbenLayoutProps { * @default 30 */ tabsHeight?: number; - /** - * tab是否可见 - * @default true - */ - tabsVisible?: boolean; /** * zIndex * @default 100 diff --git a/packages/@core/uikit/layout-ui/src/vben-layout.vue b/packages/@core/uikit/layout-ui/src/vben-layout.vue index fdff3d12..3d74b369 100644 --- a/packages/@core/uikit/layout-ui/src/vben-layout.vue +++ b/packages/@core/uikit/layout-ui/src/vben-layout.vue @@ -8,8 +8,8 @@ import { LayoutContent, LayoutFooter, LayoutHeader, - LayoutSide, - LayoutTabs, + LayoutSidebar, + LayoutTabbar, } from './components'; import { VbenLayoutProps } from './vben-layout'; @@ -38,27 +38,27 @@ const props = withDefaults(defineProps(), { headerMode: 'fixed', headerVisible: true, isMobile: false, - layout: 'side-nav', - sideCollapseShowTitle: false, + layout: 'sidebar-nav', // sideCollapse: false, sideCollapseWidth: 60, - sideHidden: false, - sideMixedWidth: 80, - sideSemiDark: true, - sideTheme: 'dark', - sideWidth: 180, + sidebarCollapseShowTitle: false, + sidebarHidden: false, + sidebarMixedWidth: 80, + sidebarSemiDark: true, + sidebarTheme: 'dark', + sidebarWidth: 180, + tabbarEnable: true, // tabsBackgroundColor: 'hsl(var(--color-background))', tabsHeight: 36, - tabsVisible: true, zIndex: 200, }); -const emit = defineEmits<{ sideMouseLeave: [] }>(); -const sideCollapse = defineModel('sideCollapse'); -const sideExtraVisible = defineModel('sideExtraVisible'); -const sideExtraCollapse = defineModel('sideExtraCollapse'); -const sideExpandOnHover = defineModel('sideExpandOnHover'); -const sideVisible = defineModel('sideVisible', { default: true }); +const emit = defineEmits<{ sideMouseLeave: []; toggleSidebar: [] }>(); +const sidebarCollapse = defineModel('sidebarCollapse'); +const sidebarExtraVisible = defineModel('sidebarExtraVisible'); +const sidebarExtraCollapse = defineModel('sidebarExtraCollapse'); +const sidebarExpandOnHover = defineModel('sidebarExpandOnHover'); +const sidebarEnable = defineModel('sidebarEnable', { default: true }); const { arrivedState, @@ -69,12 +69,12 @@ const { const { y: mouseY } = useMouse({ type: 'client' }); // side是否处于hover状态展开菜单中 -const sideExpandOnHovering = ref(false); +const sidebarExpandOnHovering = ref(false); // const sideHidden = ref(false); const headerIsHidden = ref(false); const realLayout = computed(() => { - return props.isMobile ? 'side-nav' : props.layout; + return props.isMobile ? 'sidebar-nav' : props.layout; }); /** @@ -85,7 +85,9 @@ const fullContent = computed(() => realLayout.value === 'full-content'); /** * 是否侧边混合模式 */ -const isSideMixedNav = computed(() => realLayout.value === 'side-mixed-nav'); +const isSidebarMixedNav = computed( + () => realLayout.value === 'sidebar-mixed-nav', +); /** * 是否为头部导航模式 @@ -123,25 +125,25 @@ const headerWrapperHeight = computed(() => { if (props.headerVisible && !props.headerHidden) { height += getHeaderHeight.value; } - if (props.tabsVisible) { + if (props.tabbarEnable) { height += props.tabsHeight; } - return height; }); const getSideCollapseWidth = computed(() => { - const { sideCollapseShowTitle, sideCollapseWidth, sideMixedWidth } = props; - return sideCollapseShowTitle || isSideMixedNav - ? sideMixedWidth + const { sideCollapseWidth, sidebarCollapseShowTitle, sidebarMixedWidth } = + props; + return sidebarCollapseShowTitle || isSidebarMixedNav.value + ? sidebarMixedWidth : sideCollapseWidth; }); /** * 动态获取侧边区域是否可见 */ -const sideVisibleState = computed(() => { - return !isHeaderNav.value && sideVisible.value; +const sidebarEnableState = computed(() => { + return !isHeaderNav.value && sidebarEnable.value; }); /** @@ -155,27 +157,27 @@ const sidePaddingTop = computed(() => { /** * 动态获取侧边宽度 */ -const getSideWidth = computed(() => { - const { isMobile, sideHidden, sideMixedWidth, sideWidth } = props; +const getSidebarWidth = computed(() => { + const { isMobile, sidebarHidden, sidebarMixedWidth, sidebarWidth } = props; let width = 0; - if (sideHidden) { + if (sidebarHidden) { return width; } if ( - !sideVisibleState.value || - (sideHidden && !isSideMixedNav.value && !isMixedNav.value) + !sidebarEnableState.value || + (sidebarHidden && !isSidebarMixedNav.value && !isMixedNav.value) ) { return width; } - if (isSideMixedNav.value && !isMobile) { - width = sideMixedWidth; - } else if (sideCollapse.value) { + if (isSidebarMixedNav.value && !isMobile) { + width = sidebarMixedWidth; + } else if (sidebarCollapse.value) { width = isMobile ? 0 : getSideCollapseWidth.value; } else { - width = sideWidth; + width = sidebarWidth; } return width; }); @@ -184,37 +186,37 @@ const getSideWidth = computed(() => { * 获取扩展区域宽度 */ const getExtraWidth = computed(() => { - const { sideWidth } = props; - return sideExtraCollapse.value ? getSideCollapseWidth.value : sideWidth; + const { sidebarWidth } = props; + return sidebarExtraCollapse.value ? getSideCollapseWidth.value : sidebarWidth; }); /** * 是否侧边栏模式,包含混合侧边 */ const isSideMode = computed(() => - ['mixed-nav', 'side-mixed-nav', 'side-nav'].includes(realLayout.value), + ['mixed-nav', 'sidebar-mixed-nav', 'sidebar-nav'].includes(realLayout.value), ); -const showSide = computed(() => { +const showSidebar = computed(() => { // if (isMixedNav.value && !props.sideHidden) { // return false; // } - return isSideMode.value && sideVisible.value; + return isSideMode.value && sidebarEnable.value; }); -const sideFace = computed(() => { - const { sideSemiDark, sideTheme } = props; - const isDark = sideTheme === 'dark' || sideSemiDark; +const sidebarFace = computed(() => { + const { sidebarSemiDark, sidebarTheme } = props; + const isDark = sidebarTheme === 'dark' || sidebarSemiDark; let backgroundColor = ''; let extraBackgroundColor = ''; if (isDark) { - backgroundColor = isSideMixedNav.value + backgroundColor = isSidebarMixedNav.value ? 'hsl(var(--color-menu-dark-darken))' : 'hsl(var(--color-menu-dark))'; } else { - backgroundColor = isSideMixedNav.value + backgroundColor = isSidebarMixedNav.value ? 'hsl(var(--color-menu-darken))' : 'hsl(var(--color-menu))'; } @@ -233,7 +235,7 @@ const sideFace = computed(() => { /** * 遮罩可见性 */ -const maskVisible = computed(() => !sideCollapse.value && props.isMobile); +const maskVisible = computed(() => !sidebarCollapse.value && props.isMobile); /** * header fixed值 @@ -247,53 +249,55 @@ const headerFixed = computed(() => { const mainStyle = computed(() => { let width = '100%'; - let sidebarWidth = 'unset'; + let sidebarAndExtraWidth = 'unset'; if ( headerFixed.value && !['header-nav', 'mixed-nav'].includes(realLayout.value) && - showSide.value && + showSidebar.value && !props.isMobile ) { - // pin模式下生效 + // fixed模式下生效 const isSideNavEffective = - isSideMixedNav.value && sideExpandOnHover.value && sideExtraVisible.value; + isSidebarMixedNav.value && + sidebarExpandOnHover.value && + sidebarExtraVisible.value; if (isSideNavEffective) { - const sideCollapseWidth = sideCollapse.value + const sideCollapseWidth = sidebarCollapse.value ? getSideCollapseWidth.value - : props.sideMixedWidth; - const sideWidth = sideExtraCollapse.value + : props.sidebarMixedWidth; + const sideWidth = sidebarExtraCollapse.value ? getSideCollapseWidth.value - : props.sideWidth; + : props.sidebarWidth; // 100% - 侧边菜单混合宽度 - 菜单宽度 - sidebarWidth = `${sideCollapseWidth + sideWidth}px`; - width = `calc(100% - ${sidebarWidth})`; + sidebarAndExtraWidth = `${sideCollapseWidth + sideWidth}px`; + width = `calc(100% - ${sidebarAndExtraWidth})`; } else { - sidebarWidth = - sideExpandOnHovering.value && !sideExpandOnHover.value + sidebarAndExtraWidth = + sidebarExpandOnHovering.value && !sidebarExpandOnHover.value ? `${getSideCollapseWidth.value}px` - : `${getSideWidth.value}px`; - width = `calc(100% - ${sidebarWidth})`; + : `${getSidebarWidth.value}px`; + width = `calc(100% - ${sidebarAndExtraWidth})`; } } return { - sidebarWidth, + sidebarAndExtraWidth, width, }; }); -const tabsStyle = computed((): CSSProperties => { +const tabbarStyle = computed((): CSSProperties => { let width = ''; let marginLeft = 0; if (!isMixedNav.value) { width = '100%'; - } else if (sideVisible.value) { - marginLeft = sideCollapse.value + } else if (sidebarEnable.value) { + marginLeft = sidebarCollapse.value ? getSideCollapseWidth.value - : props.sideWidth; - width = `calc(100% - ${getSideWidth.value}px)`; + : props.sidebarWidth; + width = `calc(100% - ${getSidebarWidth.value}px)`; } else { width = '100%'; } @@ -304,14 +308,6 @@ const tabsStyle = computed((): CSSProperties => { }; }); -const footerWidth = computed(() => { - if (!props.footerFixed) { - return '100%'; - } - - return mainStyle.value.width; -}); - const contentStyle = computed((): CSSProperties => { const fixed = headerFixed.value; @@ -337,7 +333,7 @@ const headerWrapperStyle = computed((): CSSProperties => { const fixed = headerFixed.value; return { height: fullContent.value ? '0' : `${headerWrapperHeight.value}px`, - left: isMixedNav.value ? 0 : mainStyle.value.sidebarWidth, + left: isMixedNav.value ? 0 : mainStyle.value.sidebarAndExtraWidth, position: fixed ? 'fixed' : 'static', top: headerIsHidden.value || fullContent.value @@ -351,26 +347,31 @@ const headerWrapperStyle = computed((): CSSProperties => { /** * 侧边栏z-index */ -const sideZIndex = computed(() => { +const sidebarZIndex = computed(() => { const { isMobile, zIndex } = props; const offset = isMobile || isSideMode.value ? 1 : -1; return zIndex + offset; }); +const footerWidth = computed(() => { + if (!props.footerFixed) { + return '100%'; + } + + return mainStyle.value.width; +}); + const maskStyle = computed((): CSSProperties => { - return { - zIndex: props.zIndex, - }; + return { zIndex: props.zIndex }; }); const showHeaderToggleButton = computed(() => { return ( isSideMode.value && - !isSideMixedNav.value && + !isSidebarMixedNav.value && !isMixedNav.value && !props.isMobile ); - // return false; }); const showHeaderLogo = computed(() => { @@ -380,7 +381,7 @@ const showHeaderLogo = computed(() => { watch( () => props.isMobile, (val) => { - sideCollapse.value = val; + sidebarCollapse.value = val; }, ); @@ -445,49 +446,48 @@ watch( } function handleClickMask() { - sideCollapse.value = true; + sidebarCollapse.value = true; } -function handleToggleMenu() { - // sideVisible.value = !sideVisible.value; - // sideHidden.value = !sideHidden.value; +function handleToggleSidebar() { + emit('toggleSidebar'); } function handleOpenMenu() { - sideCollapse.value = false; + sidebarCollapse.value = false; }