feat(mui): kit — Select, StatusChip, CheckboxField, Alert
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
19
src/admin/ui/Alert.tsx
Normal file
19
src/admin/ui/Alert.tsx
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import type { ReactNode } from "react";
|
||||||
|
import MuiAlert from "@mui/material/Alert";
|
||||||
|
|
||||||
|
/** Inline contextual alert (form/section feedback) — distinct from the global toast. */
|
||||||
|
export default function Alert({
|
||||||
|
severity = "info",
|
||||||
|
children,
|
||||||
|
onClose,
|
||||||
|
}: {
|
||||||
|
severity?: "success" | "error" | "warning" | "info";
|
||||||
|
children: ReactNode;
|
||||||
|
onClose?: () => void;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<MuiAlert severity={severity} onClose={onClose} sx={{ borderRadius: 2 }}>
|
||||||
|
{children}
|
||||||
|
</MuiAlert>
|
||||||
|
);
|
||||||
|
}
|
||||||
26
src/admin/ui/Checkbox.tsx
Normal file
26
src/admin/ui/Checkbox.tsx
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import type { ReactNode } from "react";
|
||||||
|
import FormControlLabel from "@mui/material/FormControlLabel";
|
||||||
|
import MuiCheckbox from "@mui/material/Checkbox";
|
||||||
|
|
||||||
|
/** Boolean checkbox with a label (distinct from SwitchField's toggle semantics). */
|
||||||
|
export function CheckboxField({
|
||||||
|
label,
|
||||||
|
checked,
|
||||||
|
onChange,
|
||||||
|
}: {
|
||||||
|
label: ReactNode;
|
||||||
|
checked: boolean;
|
||||||
|
onChange: (v: boolean) => void;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<FormControlLabel
|
||||||
|
control={
|
||||||
|
<MuiCheckbox
|
||||||
|
checked={checked}
|
||||||
|
onChange={(e) => onChange(e.target.checked)}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label={label}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
42
src/admin/ui/Select.tsx
Normal file
42
src/admin/ui/Select.tsx
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import MuiTextField, { type TextFieldProps } from "@mui/material/TextField";
|
||||||
|
import MenuItem from "@mui/material/MenuItem";
|
||||||
|
|
||||||
|
export interface SelectOption {
|
||||||
|
value: string | number;
|
||||||
|
label: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type SelectProps = Omit<TextFieldProps, "onChange" | "select" | "value"> & {
|
||||||
|
value: string | number;
|
||||||
|
onChange: (value: string) => void;
|
||||||
|
options?: SelectOption[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Dropdown styled like the kit TextField; composes inside <Field>. */
|
||||||
|
export default function Select({
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
options,
|
||||||
|
children,
|
||||||
|
...props
|
||||||
|
}: SelectProps) {
|
||||||
|
return (
|
||||||
|
<MuiTextField
|
||||||
|
select
|
||||||
|
size="small"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
value={value}
|
||||||
|
onChange={(e) => onChange(e.target.value)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{options
|
||||||
|
? options.map((o) => (
|
||||||
|
<MenuItem key={o.value} value={o.value}>
|
||||||
|
{o.label}
|
||||||
|
</MenuItem>
|
||||||
|
))
|
||||||
|
: children}
|
||||||
|
</MuiTextField>
|
||||||
|
);
|
||||||
|
}
|
||||||
27
src/admin/ui/StatusChip.tsx
Normal file
27
src/admin/ui/StatusChip.tsx
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import Chip, { type ChipProps } from "@mui/material/Chip";
|
||||||
|
|
||||||
|
type StatusChipProps = Omit<ChipProps, "color"> & {
|
||||||
|
color?: "default" | "success" | "error" | "warning" | "info";
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Semantic status chip. Pass onClick to make it a clickable toggle. */
|
||||||
|
export default function StatusChip({
|
||||||
|
color = "default",
|
||||||
|
size = "small",
|
||||||
|
onClick,
|
||||||
|
sx,
|
||||||
|
...props
|
||||||
|
}: StatusChipProps) {
|
||||||
|
return (
|
||||||
|
<Chip
|
||||||
|
color={color}
|
||||||
|
size={size}
|
||||||
|
onClick={onClick}
|
||||||
|
sx={[
|
||||||
|
{ fontWeight: 600, ...(onClick ? { cursor: "pointer" } : {}) },
|
||||||
|
...(Array.isArray(sx) ? sx : [sx]),
|
||||||
|
]}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -7,3 +7,8 @@ export { default as ConfirmDialog } from "./ConfirmDialog";
|
|||||||
export { default as DataTable } from "./DataTable";
|
export { default as DataTable } from "./DataTable";
|
||||||
export type { DataColumn } from "./DataTable";
|
export type { DataColumn } from "./DataTable";
|
||||||
export { Field, SwitchField } from "./Field";
|
export { Field, SwitchField } from "./Field";
|
||||||
|
export { default as Select } from "./Select";
|
||||||
|
export type { SelectOption } from "./Select";
|
||||||
|
export { default as StatusChip } from "./StatusChip";
|
||||||
|
export { CheckboxField } from "./Checkbox";
|
||||||
|
export { default as Alert } from "./Alert";
|
||||||
|
|||||||
Reference in New Issue
Block a user