fix(mui): review fixes — Select string contract, DataTable aria-sort, sx/page-clamp/dev-warn
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) <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,10 @@
|
|||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
import MuiAlert from "@mui/material/Alert";
|
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({
|
export default function Alert({
|
||||||
severity = "info",
|
severity = "info",
|
||||||
children,
|
children,
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ export default function DataTable<T>({
|
|||||||
sortDir,
|
sortDir,
|
||||||
onSort,
|
onSort,
|
||||||
}: DataTableProps<T>) {
|
}: DataTableProps<T>) {
|
||||||
|
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}</>;
|
if (rows.length === 0 && empty) return <>{empty}</>;
|
||||||
return (
|
return (
|
||||||
<TableContainer sx={{ borderRadius: 2 }}>
|
<TableContainer sx={{ borderRadius: 2 }}>
|
||||||
@@ -54,7 +57,7 @@ export default function DataTable<T>({
|
|||||||
key={c.key}
|
key={c.key}
|
||||||
align={c.align}
|
align={c.align}
|
||||||
sortDirection={
|
sortDirection={
|
||||||
c.sortKey && sortBy === c.sortKey ? sortDir : false
|
c.sortKey && sortBy === c.sortKey ? (sortDir ?? "asc") : false
|
||||||
}
|
}
|
||||||
sx={{
|
sx={{
|
||||||
textTransform: "uppercase",
|
textTransform: "uppercase",
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export default function Pagination({
|
|||||||
return (
|
return (
|
||||||
<Box sx={{ display: "flex", justifyContent: "center", mt: 2 }}>
|
<Box sx={{ display: "flex", justifyContent: "center", mt: 2 }}>
|
||||||
<MuiPagination
|
<MuiPagination
|
||||||
page={page}
|
page={Math.min(Math.max(page, 1), pageCount)}
|
||||||
count={pageCount}
|
count={pageCount}
|
||||||
onChange={(_, p) => onChange(p)}
|
onChange={(_, p) => onChange(p)}
|
||||||
color="primary"
|
color="primary"
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ import MuiTextField, { type TextFieldProps } from "@mui/material/TextField";
|
|||||||
import MenuItem from "@mui/material/MenuItem";
|
import MenuItem from "@mui/material/MenuItem";
|
||||||
|
|
||||||
export interface SelectOption {
|
export interface SelectOption {
|
||||||
value: string | number;
|
value: string;
|
||||||
label: string;
|
label: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
type SelectProps = Omit<TextFieldProps, "onChange" | "select" | "value"> & {
|
type SelectProps = Omit<TextFieldProps, "onChange" | "select" | "value"> & {
|
||||||
value: string | number;
|
value: string;
|
||||||
onChange: (value: string) => void;
|
onChange: (value: string) => void;
|
||||||
options?: SelectOption[];
|
options?: SelectOption[];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export default function StatusChip({
|
|||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
sx={[
|
sx={[
|
||||||
{ fontWeight: 600, ...(onClick ? { cursor: "pointer" } : {}) },
|
{ fontWeight: 600, ...(onClick ? { cursor: "pointer" } : {}) },
|
||||||
...(Array.isArray(sx) ? sx : [sx]),
|
...(Array.isArray(sx) ? sx : sx ? [sx] : []),
|
||||||
]}
|
]}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user