mui-dynamic-field
Version:
A dynamic and customizable input field component for React, built with Material UI & TypeScript.
162 lines (159 loc) • 4.08 kB
JavaScript
import { useMemo, useCallback, createElement } from 'react';
import { extractValue } from '../../utils.js';
import { Autocomplete, MenuItem, Checkbox, Divider, TextField, Chip } from '@mui/material';
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
const MultiSelect = ({
_key,
value,
onChange,
disabled,
extraData,
color,
size,
error,
errorText,
placeholder,
ChipProps = {},
extraProps
}) => {
const selectedAll = useMemo(() => {
return value?.length === extraData?.length;
}, [value, extraData]);
const OPTIONS = useMemo(() => {
return [{
label: "Select All",
value: "__selectAll__",
isSelectAll: true
}, ...(extraData || [])];
}, [extraData]);
const {
textFieldProps = {},
...restProps
} = extraProps || {};
const {
slotProps = {},
...restTextFieldProps
} = textFieldProps;
const handleSelectAll = useCallback(() => {
if (!onChange) return;
if (selectedAll) {
onChange({
_key,
value: []
});
return;
}
onChange({
_key,
value: extraData
});
}, [_key, extraData, onChange, selectedAll]);
return /*#__PURE__*/jsx(Autocomplete, {
disablePortal: true,
multiple: true,
disabled: disabled,
readOnly: disabled,
options: OPTIONS,
onChange: (_, value, __, details) => {
if (details?.option?.isSelectAll) {
handleSelectAll();
return;
}
if (onChange) onChange({
_key,
value
});
},
value: Array.isArray(value) ? value : [value],
color: color,
size: size,
getOptionLabel: option => extractValue(option, "label"),
disableCloseOnSelect: true,
limitTags: 3,
isOptionEqualToValue: (option, value) => {
return extractValue(option, "value") === extractValue(value, "value");
},
renderTags: (tags, getTagProps) => {
return tags.map((tag, index) => {
const {
disabled,
onDelete,
...tagProps
} = getTagProps({
index
});
return /*#__PURE__*/jsx(Chip, {
onClick: e => {
e.stopPropagation();
if (ChipProps.onClick) ChipProps.onClick(tag);
},
onDelete: deleteProps => !disabled && onDelete(deleteProps),
label: extractValue(tag, "label"),
...tagProps
});
});
},
renderInput: params => {
const {
InputProps,
...restParams
} = params;
const {
startAdornment,
...restInputProps
} = InputProps;
return /*#__PURE__*/jsx(TextField, {
...restParams,
variant: "outlined",
size: size,
error: error,
helperText: errorText,
label: placeholder,
slotProps: {
inputLabel: slotProps.inputLabel,
input: {
startAdornment: /*#__PURE__*/jsx("div", {
style: {
maxHeight: 100,
overflowY: "auto"
},
className: "hide-scrollbar",
children: startAdornment
}),
...restInputProps,
...(slotProps?.input || {})
}
},
...restTextFieldProps
});
},
renderOption: ({
key,
...rest
}, option, {
selected
}) => {
if (option?.isSelectAll) {
return /*#__PURE__*/jsxs(Fragment, {
children: [/*#__PURE__*/createElement(MenuItem, {
...rest,
key: key
}, /*#__PURE__*/jsx(Checkbox, {
checked: selectedAll,
indeterminate: !!value?.length && !selectedAll,
tabIndex: -1
}), "Select All"), /*#__PURE__*/jsx(Divider, {})]
});
}
return /*#__PURE__*/jsxs(MenuItem, {
...rest,
children: [/*#__PURE__*/jsx(Checkbox, {
checked: selected
}), String(extractValue(option, "label"))]
}, key);
},
...restProps
});
};
export { MultiSelect as default };
//# sourceMappingURL=index.js.map