@etsoo/materialui
Version:
TypeScript Material-UI Implementation
146 lines (145 loc) • 8.65 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ButtonPopupCheckbox = ButtonPopupCheckbox;
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 Grid_1 = __importDefault(require("@mui/material/Grid"));
const Typography_1 = __importDefault(require("@mui/material/Typography"));
const DragIndicator_1 = __importDefault(require("@mui/icons-material/DragIndicator"));
const Add_1 = __importDefault(require("@mui/icons-material/Add"));
const IconButton_1 = __importDefault(require("@mui/material/IconButton"));
const FormControlLabel_1 = __importDefault(require("@mui/material/FormControlLabel"));
const Checkbox_1 = __importDefault(require("@mui/material/Checkbox"));
const TextField_1 = __importDefault(require("@mui/material/TextField"));
const FlexBox_1 = require("./FlexBox");
const ReactApp_1 = require("./app/ReactApp");
const FormLabel_1 = __importDefault(require("@mui/material/FormLabel"));
const DnDList_1 = require("./DnDList");
function ButtonPopupList(props) {
// Destruct
const { addSplitter = /\s*[,;]\s*/, value = [], items, labelField, labelFormatter, labels, onAdd, onValueChange } = props;
// Methods
const dndRef = react_1.default.createRef();
// Refs
const inputRef = react_1.default.useRef(null);
const tempSelectedIds = react_1.default.useRef([]);
// State
const [selectedIds, setSelectedIds] = react_1.default.useState([]);
const setSelectedIdsHandler = (ids) => {
tempSelectedIds.current = ids;
setSelectedIds(ids);
};
react_1.default.useEffect(() => {
// Sort items by ids for first load
items.sortByProperty("id", value);
// Set selected ids
setSelectedIdsHandler([...value]);
}, [value]);
return ((0, jsx_runtime_1.jsxs)(FlexBox_1.VBox, { gap: 2, children: [(0, jsx_runtime_1.jsx)(DnDList_1.DnDList, { component: Grid_1.default, componentProps: { container: true, spacing: 0 }, items: items, labelField: labelField, onFormChange: (items) => {
const ids = items
.filter((item) => tempSelectedIds.current.includes(item.id))
.map((item) => item.id);
onValueChange(ids);
}, itemRenderer: (item, index, nodeRef, actionNodeRef) => ((0, jsx_runtime_1.jsxs)(Grid_1.default, { size: { xs: 12, md: 6, lg: 4 }, display: "flex", justifyContent: "flex-start", alignItems: "center", gap: 1, ...nodeRef, children: [(0, jsx_runtime_1.jsx)(IconButton_1.default, { style: { cursor: "move" }, size: "small", title: labels?.dragIndicator, ...actionNodeRef, children: (0, jsx_runtime_1.jsx)(DragIndicator_1.default, {}) }), (0, jsx_runtime_1.jsx)(FormControlLabel_1.default, { control: (0, jsx_runtime_1.jsx)(Checkbox_1.default, { name: "item", value: item.id, checked: selectedIds.includes(item.id), onChange: (e) => {
const checked = e.target.checked;
const newIds = [
...selectedIds.toggleItem(item.id, checked)
];
setSelectedIdsHandler(newIds);
} }), label: `${index + 1}. ${labelFormatter(item)}` })] })), height: 200, mRef: dndRef }), 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 items = dndRef.current?.getItems() ?? [];
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;
}
dndRef.current?.addItems(result);
inputRef.current.value = "";
inputRef.current.focus();
}, children: labels?.add })] }))] }));
}
function ButtonPopupCheckbox(props) {
// App
const app = (0, ReactApp_1.useRequiredAppContext)();
// Destruct
const { addSplitter, value = [], 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" }, 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 [selectedIds, setSelectedIds] = react_1.default.useState();
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(() => {
// Set selected ids
setSelectedIds(value);
}, [value]);
// Selected ids
const tempSelectedIds = react_1.default.useRef();
// Click handler
const clickHandler = () => {
app.showInputDialog({
title: popupTitle,
message: popupMessage,
callback: (form) => {
if (form == null || tempSelectedIds.current == null)
return;
const ids = tempSelectedIds.current;
setSelectedIds(ids);
onValueChange?.(ids);
},
inputs: ((0, jsx_runtime_1.jsx)(ButtonPopupList, { addSplitter: addSplitter, value: selectedIds, items: items, labelFormatter: labelFormatter, labelField: labelField, labels: labels, onAdd: onAdd, onValueChange: (ids) => {
tempSelectedIds.current = ids;
} })),
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: selectedIds?.join(",") }), (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 })), selectedIds?.map((id) => {
const item = items.find((item) => item.id === id);
if (item == null)
return null;
return ((0, jsx_runtime_1.jsx)(Chip_1.default, { sx: {
pointerEvents: "none"
}, size: "small", label: labelFormatter(item) }, id));
}), labelEnd && (0, jsx_runtime_1.jsx)(Typography_1.default, { variant: "caption", children: labelEnd })] })] }));
}