UNPKG

@react-awesome-query-builder/mui

Version:
285 lines (279 loc) 12.3 kB
import _extends from "@babel/runtime/helpers/extends"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; var _excluded = ["width"]; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } import React, { useCallback } from "react"; import omit from "lodash/omit"; import TextField from "@mui/material/TextField"; import FormControl from "@mui/material/FormControl"; import Autocomplete, { createFilterOptions } from "@mui/material/Autocomplete"; import CircularProgress from "@mui/material/CircularProgress"; import Chip from "@mui/material/Chip"; import MenuItem from "@mui/material/MenuItem"; import Check from "@mui/icons-material/Check"; import ListItemIcon from "@mui/material/ListItemIcon"; import ListItemText from "@mui/material/ListItemText"; import Tooltip from "@mui/material/Tooltip"; import { Hooks } from "@react-awesome-query-builder/ui"; import { useTheme } from "@mui/material/styles"; var useListValuesAutocomplete = Hooks.useListValuesAutocomplete; var emptyArray = []; // tip: option can contain `group: {label, title}` intead of `groupTitle` // but it's internal format, made for field autocomplete // see `JSON.stringify(option.group)` and `JSON.parse(groupMaybeJson)` export default (function (props) { var allowCustomValues = props.allowCustomValues, multiple = props.multiple, disableClearable = props.disableClearable, selectedValue = props.value, customProps = props.customProps, readonly = props.readonly, config = props.config, filterOptionsConfig = props.filterOptionsConfig, errorText = props.errorText, tooltipText = props.tooltipText, isFieldAutocomplete = props.isFieldAutocomplete, dontFixOptionsOrder = props.dontFixOptionsOrder; var stringifyOption = useCallback(function (option) { var keysForFilter = config.settings.listKeysForSearch; var valueForFilter = keysForFilter.map(function (k) { return typeof option[k] == "string" ? option[k] : ""; }).join("\0"); return valueForFilter; }, [config]); var defaultFilterOptionsConfig = { stringify: stringifyOption }; var filterOptionsFn = createFilterOptions(filterOptionsConfig || defaultFilterOptionsConfig); // hook var _useListValuesAutocom = useListValuesAutocomplete(props, { debounceTimeout: 100, multiple: multiple, uif: "mui", isFieldAutocomplete: isFieldAutocomplete, dontFixOptionsOrder: dontFixOptionsOrder }), open = _useListValuesAutocom.open, onOpen = _useListValuesAutocom.onOpen, onClose = _useListValuesAutocom.onClose, onChange = _useListValuesAutocom.onChange, onInputChange = _useListValuesAutocom.onInputChange, inputValue = _useListValuesAutocom.inputValue, options = _useListValuesAutocom.options, isInitialLoading = _useListValuesAutocom.isInitialLoading, isLoading = _useListValuesAutocom.isLoading, aPlaceholder = _useListValuesAutocom.aPlaceholder, extendOptions = _useListValuesAutocom.extendOptions, getOptionSelected = _useListValuesAutocom.getOptionSelected, getOptionDisabled = _useListValuesAutocom.getOptionDisabled, getOptionIsCustom = _useListValuesAutocom.getOptionIsCustom, getOptionLabel = _useListValuesAutocom.getOptionLabel, selectedListValue = _useListValuesAutocom.selectedListValue; // settings var _config$settings = config.settings, defaultSelectWidth = _config$settings.defaultSelectWidth, defaultSearchWidth = _config$settings.defaultSearchWidth, renderSize = _config$settings.renderSize; var _ref = customProps || {}, width = _ref.width, rest = _objectWithoutProperties(_ref, _excluded); var customInputProps = rest.input || {}; var inputWidth = customInputProps.width || defaultSearchWidth; // todo: use as min-width for Autocomplete comp customInputProps = omit(customInputProps, ["width"]); var customAutocompleteProps = omit(rest, ["showSearch", "showCheckboxes"]); var fullWidth = false; var minWidth = width || defaultSelectWidth; var style = { width: multiple ? undefined : minWidth, minWidth: minWidth }; var placeholder = !readonly ? aPlaceholder : ""; // For accessibility, always give the input field an aria-label var ariaLabel = placeholder || config.settings.fieldPlaceholder; var hasValue = selectedValue != null; // should be simple value to prevent re-render!s var value = hasValue ? selectedValue : multiple ? emptyArray : null; var filterOptions = function filterOptions(options, params) { var filtered = filterOptionsFn(options, params); var extended = extendOptions(filtered); return extended; }; var groupBy = function groupBy(option) { return option !== null && option !== void 0 && option.group ? JSON.stringify(option.group) : option === null || option === void 0 ? void 0 : option.groupTitle; }; var theme = useTheme(); // render var renderInput = function renderInput(params) { var _ref2, _selectedListValue$ti, _ref3; // parity with Antd var shouldRenderSelected = !multiple && !open; var selectedTitle = (_ref2 = (_selectedListValue$ti = selectedListValue === null || selectedListValue === void 0 ? void 0 : selectedListValue.title) !== null && _selectedListValue$ti !== void 0 ? _selectedListValue$ti : value === null || value === void 0 ? void 0 : value.toString()) !== null && _ref2 !== void 0 ? _ref2 : ""; var shouldHide = multiple && !open; var renderValue = shouldRenderSelected ? selectedTitle : shouldHide ? "" : (_ref3 = inputValue !== null && inputValue !== void 0 ? inputValue : value === null || value === void 0 ? void 0 : value.toString()) !== null && _ref3 !== void 0 ? _ref3 : ""; return /*#__PURE__*/React.createElement(TextField, _extends({ variant: "standard" }, params, { inputProps: _objectSpread(_objectSpread({ "aria-label": ariaLabel }, params.inputProps), {}, { value: renderValue }), InputProps: _objectSpread(_objectSpread({}, params.InputProps), {}, { readOnly: readonly, endAdornment: /*#__PURE__*/React.createElement(React.Fragment, null, isLoading ? /*#__PURE__*/React.createElement(CircularProgress, { color: "inherit", size: 20 }) : null, params.InputProps.endAdornment) }), size: renderSize, disabled: readonly, placeholder: placeholder, error: !!errorText //onChange={onInputChange} }, customInputProps)); }; var GroupHeader = function GroupHeader(_ref4) { var group = _ref4.group; var groupLabel = group.label; if (groupLabel && group.tooltip) { groupLabel = /*#__PURE__*/React.createElement(Tooltip, { title: group.tooltip, placement: "left-start" }, /*#__PURE__*/React.createElement("span", null, groupLabel)); } var res = /*#__PURE__*/React.createElement("div", { style: { position: "sticky", top: "-8px", padding: "4px 10px", color: theme.palette.primary.main, backgroundColor: theme.palette.background["default"] } }, groupLabel); return res; }; var GroupItems = function GroupItems(_ref5) { var children = _ref5.children; return /*#__PURE__*/React.createElement(React.Fragment, null, children); }; var renderGroup = function renderGroup(params) { var _group$parentGroups; var groupMaybeJson = params.group; var group; if (typeof groupMaybeJson === "string" && groupMaybeJson[0] === "{") { try { group = JSON.parse(groupMaybeJson); } catch (_) { // ignore } } else if (groupMaybeJson) { group = { label: groupMaybeJson }; } var groups = group ? (_group$parentGroups = group.parentGroups) !== null && _group$parentGroups !== void 0 ? _group$parentGroups : [group] : []; var res = /*#__PURE__*/React.createElement("div", { key: params.key }, groups.map(function (gr) { return /*#__PURE__*/React.createElement(GroupHeader, { key: gr === null || gr === void 0 ? void 0 : gr.path, group: gr }); }), /*#__PURE__*/React.createElement(GroupItems, null, params.children)); return res; }; var renderTags = function renderTags(value, getTagProps) { return value.map(function (option, index) { return /*#__PURE__*/React.createElement(Chip, _extends({ key: option.value, label: getOptionLabel(option), size: "small", variant: getOptionIsCustom(option) ? "outlined" : "filled" }, getTagProps({ index: index }))); }); }; var isOptionEqualToValue = function isOptionEqualToValue(option, value) { return (option === null || option === void 0 ? void 0 : option.value) == value; }; var renderOption = function renderOption(props, option) { var title = option.title, renderTitle = option.renderTitle, value = option.value, isHidden = option.isHidden, tooltip = option.tooltip, group = option.group, groupTitle = option.groupTitle; var isGrouped = groupTitle || group; var isSelected = multiple ? (selectedValue || []).includes(value) : selectedValue == value; var className = getOptionIsCustom(option) ? "customSelectOption" : undefined; var prefix = !isFieldAutocomplete && isGrouped ? "\xA0\xA0" : ""; var finalTitle = renderTitle || prefix + title; var titleSpan = /*#__PURE__*/React.createElement("span", { className: className }, finalTitle); if (tooltip) { titleSpan = /*#__PURE__*/React.createElement(Tooltip, { title: tooltip, placement: "left-start" }, titleSpan); } if (isHidden) return null; if (option.specialValue) { return /*#__PURE__*/React.createElement("div", props, finalTitle); } else if (multiple) { var itemContent = isSelected ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ListItemIcon, null, /*#__PURE__*/React.createElement(Check, null)), titleSpan) : /*#__PURE__*/React.createElement(ListItemText, { inset: true }, titleSpan); return /*#__PURE__*/React.createElement(MenuItem, _extends({}, props, { size: "small", selected: isSelected }), itemContent); } else { return /*#__PURE__*/React.createElement("div", props, titleSpan); } }; var res = /*#__PURE__*/React.createElement(Autocomplete, _extends({ disableClearable: disableClearable, disableCloseOnSelect: multiple, fullWidth: fullWidth, multiple: multiple, style: style, freeSolo: allowCustomValues, loading: isInitialLoading, open: open, onOpen: onOpen, onClose: onClose, inputValue: inputValue, onInputChange: onInputChange, label: placeholder, onChange: onChange, value: value, disabled: readonly, readOnly: readonly, options: options, groupBy: groupBy, getOptionLabel: getOptionLabel, getOptionDisabled: getOptionDisabled, renderInput: renderInput, renderGroup: renderGroup, renderTags: renderTags, renderOption: renderOption, filterOptions: filterOptions, isOptionEqualToValue: isOptionEqualToValue, size: renderSize }, customAutocompleteProps)); if (tooltipText) { res = /*#__PURE__*/React.createElement(Tooltip, { title: !open ? tooltipText : null, placement: "top-start" }, res); } res = /*#__PURE__*/React.createElement(FormControl, { fullWidth: fullWidth }, res); return res; });