perf+style: grid subscription hygiene, a11y, shadcn-style consistency
Perf / a11y (high-impact review items) - Timeline arrow-key handler binds once per (viewMode, currentSection) and reads fresh state via navStateRef instead of an 8-element dep array of new-each-render values. - usePhotosQuery collapses 14 individual Zustand selectors into one useShallow selector returning the params object. - PhotoThumbnail no longer subscribes to the search query directly; Timeline subscribes once and passes it down as a prop. - PhotoThumbnail gains role="button", tabIndex, aria-label, aria-pressed, Enter/Space key handlers and a focus-visible ring. Timeline marked role="grid"; RightSidebar marked role="region". Style consistency - Swap clsx for cn (tailwind-merge aware) across 17 files so conflicting utility classes collapse correctly. - New Badge primitive (ui/badge.tsx) with default/neutral/overlay/ outline variants; adopted in ColorsView, RatedView, TagsView for the repeated count overlay pill. - Fix palette drift: text-amber-400 -> text-star, text-green-* -> text-pick, text-red-* -> text-reject (5 files). - Button gains an xs size (h-6 px-1.5 text-[11px]) for the repeated compact-button pattern. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -9,7 +9,7 @@ import {
|
||||
CheckCircle2,
|
||||
AlertCircle,
|
||||
} from 'lucide-react'
|
||||
import clsx from 'clsx'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { useQueryClient } from '@tanstack/react-query'
|
||||
import { uploads, type FolderTreeNode } from '../../services/api'
|
||||
import { useFolderTreeQuery } from '../../hooks/useFolderTreeQuery'
|
||||
@@ -400,7 +400,7 @@ export function UploadModal({ isOpen, onClose, initialFolderId }: UploadModalPro
|
||||
}}
|
||||
onDragLeave={() => setDragOver(false)}
|
||||
onDrop={handleDrop}
|
||||
className={clsx(
|
||||
className={cn(
|
||||
'flex flex-col items-center justify-center rounded border-2 border-dashed px-4 py-6 text-center transition-colors',
|
||||
dragOver
|
||||
? 'border-primary bg-primary/10'
|
||||
@@ -478,7 +478,7 @@ export function UploadModal({ isOpen, onClose, initialFolderId }: UploadModalPro
|
||||
)}
|
||||
</div>
|
||||
<div className="shrink-0">
|
||||
{item.status === 'done' && <CheckCircle2 className="h-4 w-4 text-green-500" />}
|
||||
{item.status === 'done' && <CheckCircle2 className="h-4 w-4 text-pick" />}
|
||||
{item.status === 'error' && <AlertCircle className="h-4 w-4 text-reject" />}
|
||||
{item.status !== 'done' && !isUploading && (
|
||||
<button
|
||||
@@ -552,7 +552,7 @@ function FolderTreeRow({
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={clsx(
|
||||
className={cn(
|
||||
'flex cursor-pointer items-center gap-1 rounded px-1 py-1 text-sm',
|
||||
isSelected ? 'bg-primary/20 text-text' : 'text-text-muted hover:bg-surface-2 hover:text-text'
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user