- TreeLibraryPage: split categories into a mount-only fetch so filter changes only re-fetch trees (not categories every time) - Add safeGetItem/safeSetItem/safeRemoveItem helpers in utils.ts to prevent crashes in private browsing or when storage is unavailable - Replace raw localStorage calls in ScratchpadSidebar, TreeNavigationPage, TreeEditorPage, and treeEditorStore with safe wrappers - Add aria-label to 20 icon-only buttons across 8 component files for screen reader accessibility Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
32 lines
724 B
TypeScript
32 lines
724 B
TypeScript
import { type ClassValue, clsx } from 'clsx'
|
|
import { twMerge } from 'tailwind-merge'
|
|
|
|
export function cn(...inputs: ClassValue[]) {
|
|
return twMerge(clsx(inputs))
|
|
}
|
|
|
|
/** Safe localStorage access — returns null on error (e.g. private browsing) */
|
|
export function safeGetItem(key: string): string | null {
|
|
try {
|
|
return localStorage.getItem(key)
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|
|
|
|
export function safeSetItem(key: string, value: string): void {
|
|
try {
|
|
localStorage.setItem(key, value)
|
|
} catch {
|
|
// Storage full or unavailable — silently fail
|
|
}
|
|
}
|
|
|
|
export function safeRemoveItem(key: string): void {
|
|
try {
|
|
localStorage.removeItem(key)
|
|
} catch {
|
|
// Storage unavailable — silently fail
|
|
}
|
|
}
|