UNPKG

@etsoo/materialui

Version:

TypeScript Material-UI Implementation

111 lines (110 loc) 5 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { DataTypes, Utils } from "@etsoo/shared"; import Box from "@mui/material/Box"; import Checkbox from "@mui/material/Checkbox"; import FormControl from "@mui/material/FormControl"; import FormControlLabel from "@mui/material/FormControlLabel"; import FormGroup from "@mui/material/FormGroup"; import FormHelperText from "@mui/material/FormHelperText"; import InputLabel from "@mui/material/InputLabel"; import NotchedOutline from "@mui/material/OutlinedInput"; import Radio from "@mui/material/Radio"; import RadioGroup from "@mui/material/RadioGroup"; import React from "react"; /** * OptionGroup * @param props Props * @returns Component */ export function OptionGroup(props) { // Destruct const { getOptionLabel, defaultValue, idField = "id", label, labelField = "label", multiple = false, mRef, name, onValueChange, options, readOnly, row, itemSize, helperText, variant, required, fullWidth, ...rest } = props; // Outlined const outlined = variant === "outlined"; // Get option value // D type should be the source id type const getOptionValue = (option) => { const value = DataTypes.getValue(option, idField); if (value == null) return null; return value; }; // Checkbox values const [values, setValues] = React.useState([]); // Values const dv = React.useMemo(() => defaultValue == null ? [] : Array.isArray(defaultValue) ? defaultValue : [defaultValue], [defaultValue]); React.useEffect(() => { setValues(dv); }, [dv]); // Disabled ids const [disabledIds, setDisabledIds] = React.useState(); // Item checked const itemChecked = (option) => { // Value const value = getOptionValue(option); if (value == null) return false; return values.includes(value); }; React.useImperativeHandle(mRef, () => ({ disable(ids) { setDisabledIds(ids); } })); // First item value const firstOptionValue = getOptionValue(options[0]); // Items const list = options.map((option) => { // Value const ov = getOptionValue(option); // Control const control = multiple ? (_jsx(Checkbox, { name: name, readOnly: readOnly, size: itemSize, checked: itemChecked(option), disabled: disabledIds?.includes(ov), onChange: (event) => { if (firstOptionValue == null) return; const typeValue = Utils.parseString(event.target.value, firstOptionValue); const changedValues = [...values]; if (event.target.checked) { if (changedValues.includes(typeValue)) return; changedValues.push(typeValue); } else { changedValues.remove(typeValue); } if (onValueChange) onValueChange(changedValues); setValues(changedValues); } })) : (_jsx(Radio, { disabled: disabledIds?.includes(ov), size: itemSize, readOnly: readOnly })); // Label const label = getOptionLabel == null ? `${option[labelField]}` : getOptionLabel(option); // Value, convert to string // Will fail when type is number const value = getOptionValue(option); return (_jsx(FormControlLabel, { control: control, value: value, label: label }, value)); }); // Group const group = multiple ? (_jsx(FormGroup, { row: row, children: list })) : (_jsx(RadioGroup, { row: row, name: name, value: values[0] ?? "", onChange: (_event, value) => { if (firstOptionValue == null) return; const typeValue = Utils.parseString(value, firstOptionValue); if (onValueChange) onValueChange(typeValue); setValues([typeValue]); }, children: list })); // Layout return (_jsxs(React.Fragment, { children: [_jsxs(FormControl, { fullWidth: fullWidth, ...rest, children: [label && (_jsx(InputLabel, { required: required, variant: variant, shrink: true, children: label })), outlined ? (_jsx(NotchedOutline, { label: label && required ? label + " *" : label, notched: true, endAdornment: group, sx: { cursor: "default", display: "flex", gap: 1, paddingX: 2, paddingY: "7px", width: fullWidth ? "100%" : "auto", "& input": { display: "none" } } })) : (_jsx(Box, { paddingLeft: 2, paddingY: "7px", children: group }))] }), helperText && (_jsx(FormHelperText, { sx: { marginLeft: 2, marginRight: 2 }, children: helperText }))] })); }