@etsoo/materialui
Version:
TypeScript Material-UI Implementation
68 lines (67 loc) • 3.86 kB
JavaScript
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import CheckBoxOutlineBlankIcon from "@mui/icons-material/CheckBoxOutlineBlank";
import CheckBoxIcon from "@mui/icons-material/CheckBox";
import React from "react";
import { InputField } from "./InputField";
import { DataTypes } from "@etsoo/shared";
import { useAppContext } from "./app/ReactApp";
import Autocomplete from "@mui/material/Autocomplete";
import Checkbox from "@mui/material/Checkbox";
import Chip from "@mui/material/Chip";
export function TagListPro(props) {
// Global app
const app = useAppContext();
// Labels
const { noOptions, loading: loadingLabel, more = "More", open: openDefault } = app?.getLabels("noOptions", "loading", "more", "open") ?? {};
const moreLabel = more + "...";
const getLabel = (item) => DataTypes.getListItemLabel(item);
// Destruct
const { renderOption = ({ key, ...props }, option, { selected }) => (_jsx("li", { ...props, children: _jsxs(_Fragment, { children: [_jsx(Checkbox, { icon: _jsx(CheckBoxOutlineBlankIcon, { fontSize: "small" }), checkedIcon: _jsx(CheckBoxIcon, { fontSize: "small" }), style: { marginRight: 8 }, checked: selected }), getLabel(option)] }) }, key)), renderTags = (value, getTagProps) => value.map((option, index) => {
const { key, ...rest } = getTagProps({ index });
return (_jsx(Chip, { variant: "outlined", label: getLabel(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.useState(false);
const [options, setOptions] = React.useState([]);
const [loading, setLoading] = React.useState(false);
const currentValue = React.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.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);
};
return (_jsx(Autocomplete, { multiple: true, filterOptions: (options, _state) => options, open: open, onOpen: () => {
setOpen(true);
if (options.length === 0) {
loadDataLocal();
}
}, onClose: () => {
setOpen(false);
}, options: options, loading: loading, disableCloseOnSelect: disableCloseOnSelect, openOnFocus: openOnFocus, renderOption: renderOption, renderTags: renderTags, renderInput: (params) => (_jsx(InputField, { label: label, changeDelay: 480, onChange: 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 &&
getLabel(item) === moreLabel);
}, getOptionLabel: (item) => getLabel(item), isOptionEqualToValue: (option, value) => option.id === value.id, noOptionsText: noOptionsText, loadingText: loadingText, openText: openText, value: value, onChange: (event, value, reason, details) => {
currentValue.current = value;
if (onChange)
onChange(event, value, reason, details);
}, ...rest }));
}