@etsoo/materialui
Version:
TypeScript Material-UI Implementation
83 lines (82 loc) • 4.89 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TagListPro = TagListPro;
const jsx_runtime_1 = require("react/jsx-runtime");
const CheckBoxOutlineBlank_1 = __importDefault(require("@mui/icons-material/CheckBoxOutlineBlank"));
const CheckBox_1 = __importDefault(require("@mui/icons-material/CheckBox"));
const react_1 = __importDefault(require("react"));
const InputField_1 = require("./InputField");
const shared_1 = require("@etsoo/shared");
const ReactApp_1 = require("./app/ReactApp");
const Autocomplete_1 = __importDefault(require("@mui/material/Autocomplete"));
const Checkbox_1 = __importDefault(require("@mui/material/Checkbox"));
const Chip_1 = __importDefault(require("@mui/material/Chip"));
function TagListPro(props) {
// Global app
const app = (0, ReactApp_1.useAppContext)();
// Labels
const { noOptions, loading: loadingLabel, more = "More", open: openDefault } = app?.getLabels("noOptions", "loading", "more", "open") ?? {};
const moreLabel = more + "...";
// Destruct
const { getOptionKey = (option) => typeof option === "string" ? option : option.id, getOptionLabel = (option) => shared_1.DataTypes.getListItemLabel(option), renderOption = ({ key, ...props }, option, { selected }) => ((0, jsx_runtime_1.jsx)("li", { ...props, children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Checkbox_1.default, { icon: (0, jsx_runtime_1.jsx)(CheckBoxOutlineBlank_1.default, { fontSize: "small" }), checkedIcon: (0, jsx_runtime_1.jsx)(CheckBox_1.default, { fontSize: "small" }), style: { marginRight: 8 }, checked: selected }), getOptionLabel(option)] }) }, key)), renderValue = (value, getTagProps) => value.map((option, index) => {
const { key, ...rest } = getTagProps({ index });
return ((0, jsx_runtime_1.jsx)(Chip_1.default, { variant: "outlined", label: getOptionLabel(option), ...rest }, key));
}), noOptionsText = noOptions, loadingText = loadingLabel, openText = openDefault, loadData, loadIdValue, maxItems = 16, disableCloseOnSelect = true, openOnFocus = true, label, inputProps, onChange, value, ...rest } = props;
const [open, setOpen] = react_1.default.useState(false);
const [options, setOptions] = react_1.default.useState([]);
const [loading, setLoading] = react_1.default.useState(false);
const [valueState, setValueState] = react_1.default.useState(value ?? []);
const loadDataLocal = async (keyword) => {
setLoading(true);
const result = (await loadData(keyword, maxItems)) ?? [];
const len = result.length;
valueState.forEach((item) => {
if (!result.some((r) => r.id === item.id))
result.push(item);
});
if (len >= maxItems) {
result.push({ id: -1, name: moreLabel });
}
else if (len === 0) {
// When no result, hide the popup
setOpen(false);
}
setOptions(result);
setLoading(false);
};
react_1.default.useEffect(() => {
if (loadIdValue) {
loadIdValue().then((result) => {
if (result == null)
return;
setValueState(result);
});
}
}, [loadIdValue]);
return ((0, jsx_runtime_1.jsx)(Autocomplete_1.default, { multiple: true, filterOptions: (options, _state) => options, open: open, onOpen: () => {
setOpen(true);
if (options.length === 0) {
loadDataLocal();
}
}, onClose: () => {
setOptions([]);
setOpen(false);
}, options: options, loading: loading, disableCloseOnSelect: disableCloseOnSelect, openOnFocus: openOnFocus, renderOption: renderOption, renderValue: renderValue, renderInput: (params) => ((0, jsx_runtime_1.jsx)(InputField_1.InputField, { label: label, onChangeDelay: async (event) => {
// Stop bubble
event.preventDefault();
event.stopPropagation();
await loadDataLocal(event.target.value);
}, ...inputProps, ...params })), getOptionDisabled: (item) => {
return (typeof item.id === "number" &&
item.id < 0 &&
"name" in item &&
item["name"] === moreLabel);
}, getOptionKey: getOptionKey, getOptionLabel: getOptionLabel, isOptionEqualToValue: (option, value) => option.id === value.id, noOptionsText: noOptionsText, loadingText: loadingText, openText: openText, value: valueState, onChange: (event, value, reason, details) => {
setValueState(value);
if (onChange)
onChange(event, value, reason, details);
}, ...rest }));
}