Files
2026-04-23 18:58:13 +08:00

85 lines
2.0 KiB
TypeScript

'use client';
import { create } from 'zustand';
export type SidebarMode = 'classic' | 'icon';
const MODE_KEY = 'smart_sidebar_mode';
const RAIL_COLLAPSED_KEY = 'smart_classic_nav_rail_collapsed';
function loadRailCollapsed(): boolean {
if (typeof window === 'undefined') {
return false;
}
try {
return localStorage.getItem(RAIL_COLLAPSED_KEY) === '1';
} catch {
return false;
}
}
function persistRailCollapsed(collapsed: boolean) {
if (typeof window === 'undefined') {
return;
}
try {
localStorage.setItem(RAIL_COLLAPSED_KEY, collapsed ? '1' : '0');
} catch {
/* ignore */
}
}
function loadMode(): SidebarMode {
if (typeof window === 'undefined') {
return 'classic';
}
try {
const v = localStorage.getItem(MODE_KEY);
return v === 'icon' ? 'icon' : 'classic';
} catch {
return 'classic';
}
}
type LayoutStoreState = {
sidebarMode: SidebarMode;
/** 经典布局:窄轨仅一级 + 悬停浮层(true);false 为完整侧栏树 */
classicNavRailCollapsed: boolean;
perms: string[];
setSidebarMode: (mode: SidebarMode) => void;
setClassicNavRailCollapsed: (collapsed: boolean) => void;
toggleClassicNavRail: () => void;
setPerms: (perms: string[]) => void;
};
export const useLayoutStore = create<LayoutStoreState>((set) => ({
sidebarMode: typeof window !== 'undefined' ? loadMode() : 'classic',
classicNavRailCollapsed: typeof window !== 'undefined' ? loadRailCollapsed() : false,
perms: [],
setSidebarMode: (mode) => {
set({ sidebarMode: mode });
if (typeof window !== 'undefined') {
try {
localStorage.setItem(MODE_KEY, mode);
} catch {
/* ignore */
}
}
},
setClassicNavRailCollapsed: (collapsed) => {
persistRailCollapsed(collapsed);
set({ classicNavRailCollapsed: collapsed });
},
toggleClassicNavRail: () =>
set((s) => {
const next = !s.classicNavRailCollapsed;
persistRailCollapsed(next);
return { classicNavRailCollapsed: next };
}),
setPerms: (perms) => set({ perms }),
}));