/** 侧边栏折叠与窄屏布局状态(任务 14):宽高常量、阈值、偏好持久化。 */ export const SIDEBAR_EXPANDED_WIDTH = 248 export const SIDEBAR_COLLAPSED_WIDTH = 64 export const SIDEBAR_NARROW_THRESHOLD = 900 /** 视口窄到需要自动收起侧边栏。 */ export function isNarrowScreen(width: number): boolean { return width > 0 && width <= SIDEBAR_NARROW_THRESHOLD } /** 反转折叠状态。 */ export function toggleCollapsed(current: boolean): boolean { return !current } export type CollapseStorage = Pick | null const PREFERENCE_KEY = 'admin.sidebar.collapsed' function parsePreference(raw: string | null): boolean | null { return raw === 'true' ? true : raw === 'false' ? false : null } /** 读取持久化偏好;无存储或值非法返回 null。 */ export function readCollapsePreference(storage: CollapseStorage): boolean | null { try { return parsePreference(storage?.getItem(PREFERENCE_KEY) ?? null) } catch { return null } } /** 写入折叠偏好;存储不可用时静默失败(不阻断交互)。 */ export function writeCollapsePreference(storage: CollapseStorage, collapsed: boolean): void { try { storage?.setItem(PREFERENCE_KEY, String(collapsed)) } catch { // localStorage 不可用(隐私模式等)时忽略 } } /** * 初始折叠值:优先持久化偏好;无偏好时窄屏自动折叠、宽屏展开。 * width<=0(如 SSR/未知)视为无法判定,回退 false。 */ export function initialCollapsed(width: number, storage: CollapseStorage): boolean { const preference = readCollapsePreference(storage) if (preference !== null) return preference return isNarrowScreen(width) } /** 侧边栏应占用的像素宽(用于宽度计算/测试,不直接改 CSS)。 */ export function sidebarPixelWidth(collapsed: boolean): number { return collapsed ? SIDEBAR_COLLAPSED_WIDTH : SIDEBAR_EXPANDED_WIDTH }