@etsoo/materialui
Version:
TypeScript Material-UI Implementation
111 lines (110 loc) • 5 kB
JavaScript
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 }))] }));
}