UNPKG

@etsoo/materialui

Version:

TypeScript Material-UI Implementation

100 lines (99 loc) 4.52 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ListChooser = ListChooser; const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("@etsoo/react"); const CheckBox_1 = __importDefault(require("@mui/icons-material/CheckBox")); const react_2 = __importDefault(require("react")); const FlexBox_1 = require("./FlexBox"); const ListItemButton_1 = __importDefault(require("@mui/material/ListItemButton")); const List_1 = __importDefault(require("@mui/material/List")); const TextField_1 = __importDefault(require("@mui/material/TextField")); const ListItem_1 = __importDefault(require("@mui/material/ListItem")); const ListItemText_1 = __importDefault(require("@mui/material/ListItemText")); /** * List chooser * @param props Props * @returns Component */ function ListChooser(props) { // Selected ids state const [selectedIds, setSelectedIds] = react_2.default.useState([]); const selectProps = (id) => ({ selected: selectedIds.includes(id), onClick: () => { if (multiple) { const index = selectedIds.indexOf(id); if (index === -1) selectedIds.push(id); else selectedIds.splice(index, 1); setSelectedIds([...selectedIds]); } else { setSelectedIds([id]); } } }); // Destruct const { conditionField = "title", conditionRenderer = (rq, delayed) => ((0, jsx_runtime_1.jsx)(TextField_1.default, { autoFocus: true, margin: "dense", name: conditionField, label: title, fullWidth: true, variant: "standard", slotProps: { htmlInput: { maxLength: 128 } }, onChange: (event) => { Reflect.set(rq, "title", event.target.value); delayed.call(); } })), itemRenderer = (item, selectProps) => { const id = item[idField]; const sp = selectProps(id); const label = typeof labelField === "function" ? labelField(item) : Reflect.get(item, labelField); return ((0, jsx_runtime_1.jsx)(ListItem_1.default, { disableGutters: true, secondaryAction: sp.selected ? (0, jsx_runtime_1.jsx)(CheckBox_1.default, { fontSize: "small" }) : undefined, children: (0, jsx_runtime_1.jsx)(ListItemButton_1.default, { ...sp, children: (0, jsx_runtime_1.jsx)(ListItemText_1.default, { primary: label }) }) }, `${id}`)); }, idField = "id", labelField = "label", loadData, multiple = false, onItemChange, title, doubleClickEnabled = false, onDoubleClick, ...rest } = props; // Default minimum height rest.sx ??= { minHeight: "220px" }; // State const [items, setItems] = react_2.default.useState([]); // Query request data const mounted = react_2.default.useRef(false); const rq = react_2.default.useRef({}); // Delayed execution const delayed = (0, react_1.useDelayedExecutor)(async () => { const result = await loadData(rq.current); if (result == null || !mounted.current) return; if (!multiple && selectedIds.length > 0 && !result.some((item) => selectedIds.includes(item[idField]))) { setSelectedIds([]); } setItems(result); }, 480); react_2.default.useEffect(() => { if (!mounted.current) return; onItemChange(items.filter((item) => selectedIds.includes(item[idField])), selectedIds); }, [selectedIds]); react_2.default.useEffect(() => { mounted.current = true; delayed.call(0); return () => { mounted.current = false; delayed.clear(); }; }, [delayed]); const onDoubleClickLocal = (event) => { if (onDoubleClick) onDoubleClick(event); if (doubleClickEnabled) { const button = event.currentTarget .closest("form") ?.elements.namedItem("okButton"); if (button) { button.click(); } } }; // Layout return ((0, jsx_runtime_1.jsxs)(FlexBox_1.VBox, { children: [conditionRenderer(rq.current, delayed), (0, jsx_runtime_1.jsx)(List_1.default, { onDoubleClick: onDoubleClickLocal, disablePadding: true, dense: true, ...rest, children: items.map((item) => itemRenderer(item, selectProps)) })] })); }