- Replaced @TIER: TRIVIAL with @COMPLEXITY: 1 - Replaced @TIER: STANDARD with @COMPLEXITY: 3 - Replaced @TIER: CRITICAL with @COMPLEXITY: 5 - Manually elevated specific critical/complex components to levels 2 and 4 - Ignored legacy, specs, and node_modules directories - Updated generated semantic map
95 lines
2.3 KiB
JavaScript
95 lines
2.3 KiB
JavaScript
// [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]
|