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