@etsoo/materialui
Version:
TypeScript Material-UI Implementation
133 lines (132 loc) • 7.54 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ButtonPopupRadio = ButtonPopupRadio;
const jsx_runtime_1 = require("react/jsx-runtime");
const Button_1 = __importDefault(require("@mui/material/Button"));
const Chip_1 = __importDefault(require("@mui/material/Chip"));
const react_1 = __importDefault(require("react"));
const shared_1 = require("@etsoo/shared");
const Grid_1 = __importDefault(require("@mui/material/Grid"));
const Typography_1 = __importDefault(require("@mui/material/Typography"));
const Add_1 = __importDefault(require("@mui/icons-material/Add"));
const FormControlLabel_1 = __importDefault(require("@mui/material/FormControlLabel"));
const Radio_1 = __importDefault(require("@mui/material/Radio"));
const TextField_1 = __importDefault(require("@mui/material/TextField"));
const FormLabel_1 = __importDefault(require("@mui/material/FormLabel"));
const RadioGroup_1 = __importDefault(require("@mui/material/RadioGroup"));
const FlexBox_1 = require("./FlexBox");
const ReactApp_1 = require("./app/ReactApp");
function ButtonPopupList(props) {
// Destruct
const { addSplitter = /\s*[,;]\s*/, value, items, labelFormatter, labels, onAdd, onValueChange } = props;
// Ref
const inputRef = react_1.default.useRef(null);
// State
const [currentValue, setCurrentValue] = react_1.default.useState();
react_1.default.useEffect(() => {
setCurrentValue(value);
}, [value]);
return ((0, jsx_runtime_1.jsxs)(FlexBox_1.VBox, { gap: 2, children: [(0, jsx_runtime_1.jsx)(RadioGroup_1.default, { value: currentValue ?? "", name: "radio-buttons-group", onChange: (e, v) => {
const checked = e.target.checked;
const value = checked
? typeof items[0].id === "number"
? shared_1.NumberUtils.parse(v)
: v
: undefined;
setCurrentValue(value);
onValueChange(value);
}, children: (0, jsx_runtime_1.jsx)(Grid_1.default, { container: true, spacing: 0, children: items.map((item) => ((0, jsx_runtime_1.jsx)(Grid_1.default, { size: { xs: 12, md: 6, lg: 4 }, display: "flex", justifyContent: "flex-start", alignItems: "center", gap: 1, children: (0, jsx_runtime_1.jsx)(FormControlLabel_1.default, { control: (0, jsx_runtime_1.jsx)(Radio_1.default, { value: item.id }), label: `${labelFormatter(item)}` }) }, item.id))) }) }), onAdd && ((0, jsx_runtime_1.jsxs)(FlexBox_1.HBox, { gap: 1, children: [(0, jsx_runtime_1.jsx)(TextField_1.default, { variant: "outlined", label: labels?.more, fullWidth: true, inputRef: inputRef }), (0, jsx_runtime_1.jsx)(Button_1.default, { sx: { width: "120px" }, variant: "contained", startIcon: (0, jsx_runtime_1.jsx)(Add_1.default, {}), 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 })] }))] }));
}
function ButtonPopupRadio(props) {
// App
const app = (0, ReactApp_1.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_1.default.useState([]);
const [currentValue, setCurrentValue] = react_1.default.useState();
const item = currentValue
? items.find((item) => item.id === currentValue)
: undefined;
react_1.default.useEffect(() => {
if (typeof loadData === "function") {
// Load data
loadData().then((data) => {
if (data != null) {
setItems(data);
}
});
}
else {
setItems(loadData);
}
}, [loadData]);
react_1.default.useEffect(() => {
setCurrentValue(value);
}, [value]);
// Selected id
const tempSelectedId = react_1.default.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: ((0, jsx_runtime_1.jsx)(ButtonPopupList, { addSplitter: addSplitter, value: currentValue, items: items, labelFormatter: labelFormatter, labels: labels, onAdd: onAdd, onValueChange: (id) => {
tempSelectedId.current = id;
} })),
fullScreen: app.smDown
});
};
return ((0, jsx_runtime_1.jsxs)(react_1.default.Fragment, { children: [(0, jsx_runtime_1.jsx)("input", { type: "text", style: { position: "absolute", opacity: 0, width: 0 }, name: inputName, required: required, defaultValue: currentValue }), (0, jsx_runtime_1.jsxs)(Button_1.default, { variant: variant, sx: sx, onClick: () => clickHandler(), ...rest, disabled: !items || items.length === 0, children: [label && ((0, jsx_runtime_1.jsx)(FormLabel_1.default, { required: required, sx: { fontSize: (theme) => theme.typography.body2.fontSize }, children: label })), item ? ((0, jsx_runtime_1.jsx)(Chip_1.default, { sx: {
height: "auto",
pointerEvents: "none",
"& .MuiChip-label": {
display: "block",
whiteSpace: "normal"
}
}, size: "small", label: labelFormatter(item) })) : undefined, labelEnd && (0, jsx_runtime_1.jsx)(Typography_1.default, { variant: "caption", children: labelEnd })] })] }));
}