feat(uat-batch-4): a11y form primitives + click-to-preview + EOI empty-state + lint guards
- FieldError primitive (role=alert, aria-live) — used by Wave 3 form-error UX work. - FieldLabel primitive (Label + Info-tooltip slot) — foundational for the platform-wide admin-settings tooltip audit. - ESLint guard against em-dash in user-facing JSX text inside src/components + src/app (warning, not error; 111 existing instances flagged for follow-up sweep). - FileGrid card body becomes click-to-preview button (was hidden under a kebab); aria-label per row; kebab keeps Download/Rename/Delete. - DocumentList: title cell on rows with signedFileId opens FilePreviewDialog; kebab gains Download action (was missing per UAT). Single FilePreviewDialog instance lifted to the parent. - DocumentList type extended with signedFileId. - EOI empty state: third ghost button "Mark signed without file" wired to existing MarkExternallySignedDialog (parity with reservation tab). - Watcher empty-state padding fix on document-detail. tsc clean. 1419/1419 vitest. lint clean on touched files. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
|
||||
import {
|
||||
Download,
|
||||
Eye,
|
||||
FileText,
|
||||
Film,
|
||||
Image,
|
||||
@@ -22,7 +21,6 @@ import {
|
||||
DropdownMenuTrigger,
|
||||
} from '@/components/ui/dropdown-menu';
|
||||
import { Skeleton } from '@/components/ui/skeleton';
|
||||
import { PREVIEWABLE_MIMES } from '@/lib/constants/file-validation';
|
||||
|
||||
export interface FileRow {
|
||||
id: string;
|
||||
@@ -102,9 +100,14 @@ export function FileGrid({
|
||||
{files.map((file) => (
|
||||
<div
|
||||
key={file.id}
|
||||
className="group relative rounded-lg border bg-card p-3 hover:border-primary/50 hover:shadow-sm transition-all"
|
||||
className="group relative rounded-lg border bg-card hover:border-primary/50 hover:shadow-sm transition-all"
|
||||
>
|
||||
<div className="flex flex-col items-center gap-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onPreview(file)}
|
||||
aria-label={`Preview ${file.filename}`}
|
||||
className="flex w-full flex-col items-center gap-2 rounded-lg p-3 text-left focus:outline-none focus:ring-2 focus:ring-ring"
|
||||
>
|
||||
<FileIcon mimeType={file.mimeType} />
|
||||
<p className="w-full truncate text-center text-xs font-medium" title={file.filename}>
|
||||
{file.filename}
|
||||
@@ -113,7 +116,7 @@ export function FileGrid({
|
||||
<span>{formatBytes(file.sizeBytes)}</span>
|
||||
<span>{format(new Date(file.createdAt), 'MMM d, yyyy')}</span>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<div className="absolute right-1 top-1 opacity-0 group-hover:opacity-100 transition-opacity">
|
||||
<DropdownMenu>
|
||||
@@ -127,12 +130,6 @@ export function FileGrid({
|
||||
<Download className="mr-2 h-3.5 w-3.5" />
|
||||
Download
|
||||
</DropdownMenuItem>
|
||||
{file.mimeType && PREVIEWABLE_MIMES.has(file.mimeType) && (
|
||||
<DropdownMenuItem onClick={() => onPreview(file)}>
|
||||
<Eye className="mr-2 h-3.5 w-3.5" />
|
||||
Preview
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
<DropdownMenuItem onClick={() => onRename(file)}>
|
||||
<Pencil className="mr-2 h-3.5 w-3.5" />
|
||||
Rename
|
||||
|
||||
Reference in New Issue
Block a user