13e7a4c602
sidebar-collapse 提供阈值/宽高常量、toggle、localStorage 偏好读写(失败容忍)、 initialCollapsed(持久化优先,窄屏自动收起);AdminLayout 接入并持久化折叠状态。
57 lines
1.9 KiB
TypeScript
57 lines
1.9 KiB
TypeScript
/** 侧边栏折叠与窄屏布局状态(任务 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<Storage, 'getItem' | 'setItem'> | 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
|
|
}
|