UNPKG

@etsoo/materialui

Version:

TypeScript Material-UI Implementation

68 lines (67 loc) 3.86 kB
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 })); }