@etsoo/materialui
Version:
TypeScript Material-UI Implementation
70 lines (69 loc) • 4.08 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TagList = TagList;
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 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 TagList(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 { renderOption = ({ key, ...props }, option, { selected }) => ((0, jsx_runtime_1.jsxs)("li", { ...props, 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 }), option] }, key)), renderTags = (value, getTagProps) => value.map((option, index) => {
const { key, ...rest } = getTagProps({ index });
return (0, jsx_runtime_1.jsx)(Chip_1.default, { variant: "outlined", label: option, ...rest }, key);
}), noOptionsText = noOptions, loadingText = loadingLabel, openText = openDefault, loadData, 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 currentValue = react_1.default.useRef([]);
currentValue.current = value ?? [];
const loadDataLocal = async (keyword) => {
setLoading(true);
const result = (await loadData(keyword, maxItems)) ?? [];
const len = result.length;
currentValue.current.forEach((item) => {
if (!result.includes(item))
result.push(item);
});
if (len >= maxItems) {
result.push(moreLabel);
}
else if (len === 0) {
// When no result, hide the popup
setOpen(false);
}
setOptions(result);
setLoading(false);
};
return ((0, jsx_runtime_1.jsx)(Autocomplete_1.default, { multiple: true, freeSolo: true, filterOptions: (options, _state) => options, open: open, onOpen: () => {
setOpen(true);
if (options.length === 0) {
loadDataLocal();
}
}, onClose: () => {
setOpen(false);
}, options: options, loading: loading, disableCloseOnSelect: disableCloseOnSelect, clearOnBlur: true, openOnFocus: openOnFocus, renderOption: renderOption, renderTags: renderTags, renderInput: (params) => ((0, jsx_runtime_1.jsx)(InputField_1.InputField, { label: label, changeDelay: 480, onChange: async (event) => {
// Stop bubble
event.preventDefault();
event.stopPropagation();
await loadDataLocal(event.target.value);
}, ...inputProps, ...params })), getOptionDisabled: (item) => {
return item === moreLabel;
}, noOptionsText: noOptionsText, loadingText: loadingText, openText: openText, value: value, onChange: (event, value, reason, details) => {
currentValue.current = value;
if (onChange)
onChange(event, value, reason, details);
}, ...rest }));
}