From 1398d4b4dcf61d0701ed244480c2b692d4f5ac7a Mon Sep 17 00:00:00 2001 From: BOHA Date: Sat, 6 Jun 2026 21:34:15 +0200 Subject: [PATCH] =?UTF-8?q?fix(mui):=20review=20fixes=20=E2=80=94=20Select?= =?UTF-8?q?=20string=20contract,=20DataTable=20aria-sort,=20sx/page-clamp/?= =?UTF-8?q?dev-warn?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Select value/option restricted to string (MUI sets the literal child value; string|number + onChange:string was a type lie). DataTable sortDirection uses ?? 'asc' so aria-sort is never undefined on the active column. StatusChip sx-merge drops undefined; Pagination clamps page into range; DataTable dev-warns on sortKey without onSort; Alert onClose JSDoc. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/admin/ui/Alert.tsx | 5 ++++- src/admin/ui/DataTable.tsx | 5 ++++- src/admin/ui/Pagination.tsx | 2 +- src/admin/ui/Select.tsx | 4 ++-- src/admin/ui/StatusChip.tsx | 2 +- 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/admin/ui/Alert.tsx b/src/admin/ui/Alert.tsx index 1e09f9e..c62aec2 100644 --- a/src/admin/ui/Alert.tsx +++ b/src/admin/ui/Alert.tsx @@ -1,7 +1,10 @@ import type { ReactNode } from "react"; import MuiAlert from "@mui/material/Alert"; -/** Inline contextual alert (form/section feedback) — distinct from the global toast. */ +/** + * Inline contextual alert (form/section feedback) — distinct from the global toast. + * `onClose` is simplified to take no arguments (MUI's close SyntheticEvent is omitted). + */ export default function Alert({ severity = "info", children, diff --git a/src/admin/ui/DataTable.tsx b/src/admin/ui/DataTable.tsx index c0b2173..bdc1def 100644 --- a/src/admin/ui/DataTable.tsx +++ b/src/admin/ui/DataTable.tsx @@ -43,6 +43,9 @@ export default function DataTable({ sortDir, onSort, }: DataTableProps) { + if (import.meta.env.DEV && columns.some((c) => c.sortKey) && !onSort) { + console.warn("DataTable: columns with sortKey require an onSort prop."); + } if (rows.length === 0 && empty) return <>{empty}; return ( @@ -54,7 +57,7 @@ export default function DataTable({ key={c.key} align={c.align} sortDirection={ - c.sortKey && sortBy === c.sortKey ? sortDir : false + c.sortKey && sortBy === c.sortKey ? (sortDir ?? "asc") : false } sx={{ textTransform: "uppercase", diff --git a/src/admin/ui/Pagination.tsx b/src/admin/ui/Pagination.tsx index 03e26c1..efad908 100644 --- a/src/admin/ui/Pagination.tsx +++ b/src/admin/ui/Pagination.tsx @@ -15,7 +15,7 @@ export default function Pagination({ return ( onChange(p)} color="primary" diff --git a/src/admin/ui/Select.tsx b/src/admin/ui/Select.tsx index 7b1f70b..2a3ecee 100644 --- a/src/admin/ui/Select.tsx +++ b/src/admin/ui/Select.tsx @@ -2,12 +2,12 @@ import MuiTextField, { type TextFieldProps } from "@mui/material/TextField"; import MenuItem from "@mui/material/MenuItem"; export interface SelectOption { - value: string | number; + value: string; label: string; } type SelectProps = Omit & { - value: string | number; + value: string; onChange: (value: string) => void; options?: SelectOption[]; }; diff --git a/src/admin/ui/StatusChip.tsx b/src/admin/ui/StatusChip.tsx index d048bbe..82c0137 100644 --- a/src/admin/ui/StatusChip.tsx +++ b/src/admin/ui/StatusChip.tsx @@ -19,7 +19,7 @@ export default function StatusChip({ onClick={onClick} sx={[ { fontWeight: 600, ...(onClick ? { cursor: "pointer" } : {}) }, - ...(Array.isArray(sx) ? sx : [sx]), + ...(Array.isArray(sx) ? sx : sx ? [sx] : []), ]} {...props} />