UNPKG

@etsoo/materialui

Version:

TypeScript Material-UI Implementation

127 lines (126 loc) 6.5 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import Button from "@mui/material/Button"; import Chip from "@mui/material/Chip"; import React from "react"; import { NumberUtils } from "@etsoo/shared"; import Grid from "@mui/material/Grid"; import Typography from "@mui/material/Typography"; import AddIcon from "@mui/icons-material/Add"; import FormControlLabel from "@mui/material/FormControlLabel"; import Radio from "@mui/material/Radio"; import TextField from "@mui/material/TextField"; import FormLabel from "@mui/material/FormLabel"; import RadioGroup from "@mui/material/RadioGroup"; import { HBox, VBox } from "./FlexBox"; import { useRequiredAppContext } from "./app/ReactApp"; function ButtonPopupList(props) { // Destruct const { addSplitter = /\s*[,;]\s*/, value, items, labelFormatter, labels, onAdd, onValueChange } = props; // Ref const inputRef = React.useRef(null); // State const [currentValue, setCurrentValue] = React.useState(); React.useEffect(() => { setCurrentValue(value); }, [value]); return (_jsxs(VBox, { gap: 2, children: [_jsx(RadioGroup, { value: currentValue ?? "", name: "radio-buttons-group", onChange: (e, v) => { const checked = e.target.checked; const value = checked ? typeof items[0].id === "number" ? NumberUtils.parse(v) : v : undefined; setCurrentValue(value); onValueChange(value); }, children: _jsx(Grid, { container: true, spacing: 0, children: items.map((item) => (_jsx(Grid, { size: { xs: 12, md: 6, lg: 4 }, display: "flex", justifyContent: "flex-start", alignItems: "center", gap: 1, children: _jsx(FormControlLabel, { control: _jsx(Radio, { value: item.id }), label: `${labelFormatter(item)}` }) }, item.id))) }) }), onAdd && (_jsxs(HBox, { gap: 1, children: [_jsx(TextField, { variant: "outlined", label: labels?.more, fullWidth: true, inputRef: inputRef }), _jsx(Button, { sx: { width: "120px" }, variant: "contained", startIcon: _jsx(AddIcon, {}), size: "small", onClick: async () => { if (inputRef.current == null) return; const input = inputRef.current.value.trim(); if (input === "") { inputRef.current.focus(); return; } const inputIds = input .split(addSplitter) .filter((id) => !items.some((item) => item.id == id)); if (inputIds.length === 0) { inputRef.current.focus(); return; } const result = await onAdd(inputIds); if (result === false) { inputRef.current.focus(); return; } inputRef.current.value = ""; inputRef.current.focus(); }, children: labels?.add })] }))] })); } export function ButtonPopupRadio(props) { // App const app = useRequiredAppContext(); // Destruct const { addSplitter, inputName, label, labelEnd, labelFormatter = (data) => { if (labelField in data) { return data[labelField]; } return data.id.toString(); }, labelField, labels = {}, loadData, onAdd, onValueChange, popupTitle = label, popupMessage, required = false, sx = { gap: 1, justifyContent: "flex-start", minHeight: "56px" }, value, variant = "outlined", ...rest } = props; // Default labels if (!labels.add) labels.add = app.get("add"); if (!labels.dragIndicator) labels.dragIndicator = app.get("dragIndicator"); if (!labels.more) labels.more = app.get("more"); // State const [items, setItems] = React.useState([]); const [currentValue, setCurrentValue] = React.useState(); const item = currentValue ? items.find((item) => item.id === currentValue) : undefined; React.useEffect(() => { if (typeof loadData === "function") { // Load data loadData().then((data) => { if (data != null) { setItems(data); } }); } else { setItems(loadData); } }, [loadData]); React.useEffect(() => { setCurrentValue(value); }, [value]); // Selected id const tempSelectedId = React.useRef(); // Click handler const clickHandler = () => { app.showInputDialog({ title: popupTitle, message: popupMessage, callback: (form) => { if (form == null || tempSelectedId.current == null) return; const id = tempSelectedId.current; setCurrentValue(id); onValueChange?.(id); }, inputs: (_jsx(ButtonPopupList, { addSplitter: addSplitter, value: currentValue, items: items, labelFormatter: labelFormatter, labels: labels, onAdd: onAdd, onValueChange: (id) => { tempSelectedId.current = id; } })), fullScreen: app.smDown }); }; return (_jsxs(React.Fragment, { children: [_jsx("input", { type: "text", style: { position: "absolute", opacity: 0, width: 0 }, name: inputName, required: required, defaultValue: currentValue }), _jsxs(Button, { variant: variant, sx: sx, onClick: () => clickHandler(), ...rest, disabled: !items || items.length === 0, children: [label && (_jsx(FormLabel, { required: required, sx: { fontSize: (theme) => theme.typography.body2.fontSize }, children: label })), item ? (_jsx(Chip, { sx: { height: "auto", pointerEvents: "none", "& .MuiChip-label": { display: "block", whiteSpace: "normal" } }, size: "small", label: labelFormatter(item) })) : undefined, labelEnd && _jsx(Typography, { variant: "caption", children: labelEnd })] })] })); }