// [DEF:sidebar:Store] // @COMPLEXITY: 3 // @PURPOSE: Manage sidebar visibility and navigation state // @LAYER: UI // @INVARIANT: isExpanded state is always synced with localStorage // // @UX_STATE: Idle -> Sidebar visible with current state // @UX_STATE: Toggling -> Animation plays for 200ms import { writable } from 'svelte/store'; import { browser } from '$app/environment'; // Load from localStorage on initialization const STORAGE_KEY = 'sidebar_state'; const loadState = () => { if (!browser) return null; try { const saved = localStorage.getItem(STORAGE_KEY); if (saved) { return JSON.parse(saved); } } catch (e) { console.error('[SidebarStore] Failed to load state:', e); } return null; }; const saveState = (state) => { if (!browser) return; try { localStorage.setItem(STORAGE_KEY, JSON.stringify(state)); } catch (e) { console.error('[SidebarStore] Failed to save state:', e); } }; const initialState = loadState() || { isExpanded: true, activeCategory: 'dashboards', activeItem: '/dashboards', isMobileOpen: false }; export const sidebarStore = writable(initialState); /** * Toggle sidebar expansion state * @UX_STATE: Toggling -> Animation plays for 200ms */ export function toggleSidebar() { sidebarStore.update(state => { const newState = { ...state, isExpanded: !state.isExpanded }; saveState(newState); return newState; }); } /** * Set active category and item * @param {string} category - Category name (dashboards, datasets, storage, admin) * @param {string} item - Route path */ export function setActiveItem(category, item) { sidebarStore.update(state => { const newState = { ...state, activeCategory: category, activeItem: item }; saveState(newState); return newState; }); } /** * Toggle mobile overlay mode * @param {boolean} isOpen - Whether the mobile overlay should be open */ export function setMobileOpen(isOpen) { sidebarStore.update(state => ({ ...state, isMobileOpen: isOpen })); } /** * Close mobile overlay */ export function closeMobile() { sidebarStore.update(state => ({ ...state, isMobileOpen: false })); } /** * Toggle mobile sidebar (for hamburger menu) */ export function toggleMobileSidebar() { sidebarStore.update(state => ({ ...state, isMobileOpen: !state.isMobileOpen })); } // [/DEF:sidebar:Store]