diff --git a/src/admin/ui/Alert.tsx b/src/admin/ui/Alert.tsx new file mode 100644 index 0000000..1e09f9e --- /dev/null +++ b/src/admin/ui/Alert.tsx @@ -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 ( + + {children} + + ); +} diff --git a/src/admin/ui/Checkbox.tsx b/src/admin/ui/Checkbox.tsx new file mode 100644 index 0000000..37bf3d5 --- /dev/null +++ b/src/admin/ui/Checkbox.tsx @@ -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 ( + onChange(e.target.checked)} + /> + } + label={label} + /> + ); +} diff --git a/src/admin/ui/Select.tsx b/src/admin/ui/Select.tsx new file mode 100644 index 0000000..7b1f70b --- /dev/null +++ b/src/admin/ui/Select.tsx @@ -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 & { + value: string | number; + onChange: (value: string) => void; + options?: SelectOption[]; +}; + +/** Dropdown styled like the kit TextField; composes inside . */ +export default function Select({ + value, + onChange, + options, + children, + ...props +}: SelectProps) { + return ( + onChange(e.target.value)} + {...props} + > + {options + ? options.map((o) => ( + + {o.label} + + )) + : children} + + ); +} diff --git a/src/admin/ui/StatusChip.tsx b/src/admin/ui/StatusChip.tsx new file mode 100644 index 0000000..d048bbe --- /dev/null +++ b/src/admin/ui/StatusChip.tsx @@ -0,0 +1,27 @@ +import Chip, { type ChipProps } from "@mui/material/Chip"; + +type StatusChipProps = Omit & { + 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 ( + + ); +} diff --git a/src/admin/ui/index.ts b/src/admin/ui/index.ts index d904161..279df9c 100644 --- a/src/admin/ui/index.ts +++ b/src/admin/ui/index.ts @@ -7,3 +7,8 @@ export { default as ConfirmDialog } from "./ConfirmDialog"; export { default as DataTable } from "./DataTable"; export type { DataColumn } from "./DataTable"; 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";