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:
Michael Chihlas
2026-02-10 18:41:46 -05:00
parent 0c9fbdc90b
commit d155c83ef0
14 changed files with 81 additions and 28 deletions

View File

@@ -53,6 +53,7 @@ export function DynamicArrayField<T>({
disabled={index === 0}
className="rounded p-0.5 text-white/50 hover:bg-white/[0.06] hover:text-white disabled:opacity-30"
title="Move up"
aria-label="Move up"
>
<ChevronUp className="h-3 w-3" />
</button>
@@ -62,6 +63,7 @@ export function DynamicArrayField<T>({
disabled={index === items.length - 1}
className="rounded p-0.5 text-white/50 hover:bg-white/[0.06] hover:text-white disabled:opacity-30"
title="Move down"
aria-label="Move down"
>
<ChevronDown className="h-3 w-3" />
</button>
@@ -78,6 +80,7 @@ export function DynamicArrayField<T>({
onClick={() => onRemove(index)}
className="mt-1 rounded p-1 text-white/50 hover:bg-red-400/20 hover:text-red-400"
title="Remove"
aria-label="Remove"
>
<Trash2 className="h-4 w-4" />
</button>