fix: split category fetch, safe localStorage, aria-labels on icon buttons
- 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>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useState, useEffect, useRef, useCallback } from 'react'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { cn, safeGetItem, safeSetItem } from '@/lib/utils'
|
||||
import { MarkdownContent } from '@/components/ui/MarkdownContent'
|
||||
import { StickyNote, X, Eye, Pencil, Loader2 } from 'lucide-react'
|
||||
|
||||
@@ -14,7 +14,7 @@ export function ScratchpadSidebar({ sessionId, initialContent, onSave, onOpenCha
|
||||
const [content, setContent] = useState(initialContent)
|
||||
const [lastSaved, setLastSaved] = useState(initialContent)
|
||||
const [isCollapsed, setIsCollapsed] = useState(() => {
|
||||
return localStorage.getItem('scratchpad-collapsed') !== 'false'
|
||||
return safeGetItem('scratchpad-collapsed') !== 'false'
|
||||
})
|
||||
const [isSaving, setIsSaving] = useState(false)
|
||||
const [showPreview, setShowPreview] = useState(false)
|
||||
@@ -43,7 +43,7 @@ export function ScratchpadSidebar({ sessionId, initialContent, onSave, onOpenCha
|
||||
|
||||
// Persist collapse state and notify parent
|
||||
useEffect(() => {
|
||||
localStorage.setItem('scratchpad-collapsed', String(isCollapsed))
|
||||
safeSetItem('scratchpad-collapsed', String(isCollapsed))
|
||||
onOpenChange?.(!isCollapsed)
|
||||
}, [isCollapsed, onOpenChange])
|
||||
|
||||
@@ -130,6 +130,7 @@ export function ScratchpadSidebar({ sessionId, initialContent, onSave, onOpenCha
|
||||
isCollapsed ? 'opacity-100' : 'pointer-events-none opacity-0'
|
||||
)}
|
||||
title="Open scratchpad (Ctrl+/)"
|
||||
aria-label="Open scratchpad (Ctrl+/)"
|
||||
>
|
||||
<StickyNote className="h-5 w-5" />
|
||||
{hasUnsavedChanges && (
|
||||
@@ -176,6 +177,7 @@ export function ScratchpadSidebar({ sessionId, initialContent, onSave, onOpenCha
|
||||
onClick={() => setIsCollapsed(true)}
|
||||
className="rounded p-1 text-white/40 hover:bg-white/10 hover:text-white"
|
||||
title="Close scratchpad"
|
||||
aria-label="Close scratchpad"
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user