31 lines
1.2 KiB
TypeScript
31 lines
1.2 KiB
TypeScript
import {
|
|
atomWithLocalStorage,
|
|
getLocalStorageItem,
|
|
setLocalStorageItem,
|
|
} from './utils/atomWithLocalStorage';
|
|
|
|
export const SIDEBAR_WIDTH_KEY = 'vojo_sidebar_width';
|
|
// Floor must fit the StreamHeader tabs row in full: 3 segment buttons
|
|
// (Личные/Каналы/Роботы — RU is the widest locale) plus the two
|
|
// action icons (Plus / Search) plus the row's 8px horizontal padding.
|
|
// Measured at ≈378px in RU; 384 gives a few px of breathing room and
|
|
// keeps the icon cluster from clipping at the curtain's right edge.
|
|
export const SIDEBAR_WIDTH_MIN = 384;
|
|
export const SIDEBAR_WIDTH_DEFAULT = 416;
|
|
|
|
const readSidebarWidth = (key: string): number => {
|
|
const raw = getLocalStorageItem<unknown>(key, SIDEBAR_WIDTH_DEFAULT);
|
|
const value = typeof raw === 'number' && Number.isFinite(raw) ? raw : SIDEBAR_WIDTH_DEFAULT;
|
|
return Math.max(SIDEBAR_WIDTH_MIN, Math.round(value));
|
|
};
|
|
|
|
export const sidebarWidthAtom = atomWithLocalStorage<number>(
|
|
SIDEBAR_WIDTH_KEY,
|
|
readSidebarWidth,
|
|
setLocalStorageItem
|
|
);
|
|
|
|
export const clampSidebarWidth = (px: number, viewportWidth: number): number => {
|
|
const max = Math.max(SIDEBAR_WIDTH_MIN, Math.floor(viewportWidth / 3));
|
|
return Math.max(SIDEBAR_WIDTH_MIN, Math.min(max, Math.round(px)));
|
|
};
|