UNPKG

@dccs/react-searchable-select-mui

Version:
133 lines (132 loc) 6.89 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; Object.defineProperty(exports, "__esModule", { value: true }); var React = require("react"); var Select_1 = require("@material-ui/core/Select"); var FormControl_1 = require("@material-ui/core/FormControl"); var InputLabel_1 = require("@material-ui/core/InputLabel"); var MenuItem_1 = require("@material-ui/core/MenuItem"); var TextField_1 = require("@material-ui/core/TextField"); var core_1 = require("@material-ui/core"); var ClickAwayListener_1 = require("@material-ui/core/ClickAwayListener"); var utils_1 = require("@dccs/utils"); // Needed because otherwise MUI-Select passes down props to the ClickAwayListeneder // This Component ignores those props // Additionally it has to be a React.Component instead of a functional component // Since functional components can't have a "ref" var SearchFieldWrapper = /** @class */ (function (_super) { __extends(SearchFieldWrapper, _super); function SearchFieldWrapper() { return _super !== null && _super.apply(this, arguments) || this; } SearchFieldWrapper.prototype.render = function () { var _a = this.props, searchFieldPlaceholder = _a.searchFieldPlaceholder, setQuery = _a.setQuery; return (React.createElement(ClickAwayListener_1.default, { onClickAway: function () { return null; } }, React.createElement(core_1.ListItem, null, React.createElement(TextField_1.default, { fullWidth: true, placeholder: searchFieldPlaceholder || "Search...", onChange: function (e) { setQuery(e.target.value); }, onKeyDown: function (e) { // Prevent MUI-Autoselect while typing e.stopPropagation(); } })))); }; return SearchFieldWrapper; }(React.Component)); function SearchableSelect(props) { var _a = React.useState(""), query = _a[0], setQuery = _a[1]; var label = props.label, error = props.error, searchFieldPlaceholder = props.searchFieldPlaceholder, removeSelectionText = props.removeSelectionText, value = props.value, onChange = props.onChange, helperText = props.helperText, options = props.options, formControlProps = props.formControlProps, formHelperTextProps = props.formHelperTextProps, showAll = props.showAll, maxVisibleOptions = props.maxVisibleOptions, others = __rest(props, ["label", "error", "searchFieldPlaceholder", "removeSelectionText", "value", "onChange", "helperText", "options", "formControlProps", "formHelperTextProps", "showAll", "maxVisibleOptions"]); // Customprops var _b = props, keyPropFn = _b.keyPropFn, valuePropFn = _b.valuePropFn; // Remove keyPropFn and valuePropFn to not get passed down to the select component delete others.keyPropFn; delete others.valuePropFn; // Customprops Undefined? Use defaults if (!keyPropFn && !valuePropFn) { keyPropFn = function (option) { return option.key; }; valuePropFn = function (option) { return option.value; }; } var defaultProps = { style: { minWidth: "240px" } }; function renderFilteredOptions() { var filteredOptions = options && options.filter && options.filter(function (option) { return (!valuePropFn(option) || (valuePropFn(option) && valuePropFn(option) .toString() .toLowerCase() .indexOf(query.toLowerCase()) !== -1)); }); if (!showAll) { filteredOptions = filteredOptions.slice(0, maxVisibleOptions || 20); var selectedOption = options.find(function (option) { return value === keyPropFn(option); }); if (selectedOption) { if (filteredOptions.indexOf(selectedOption) === -1) { filteredOptions.push(selectedOption); } } } return filteredOptions.map(function (option) { var searchVal = valuePropFn(option).toString(); return (React.createElement(MenuItem_1.default, { key: keyPropFn(option), value: keyPropFn(option) }, utils_1.HighlightQuery(searchVal, query))); }); } return (React.createElement(FormControl_1.default, __assign({ margin: "normal" }, formControlProps), label && React.createElement(InputLabel_1.default, null, label), React.createElement(Select_1.default, __assign({}, defaultProps, { // Material UI Bug: // => || "" is needed for the label to work properly. value: value || "", onChange: onChange, error: error, MenuProps: { onEnter: function () { setQuery(""); }, onExit: function () { setQuery(""); }, disableAutoFocusItem: true, MenuListProps: { disableListWrap: true } } }, others), React.createElement(SearchFieldWrapper, { searchFieldPlaceholder: searchFieldPlaceholder, setQuery: setQuery }), React.createElement(MenuItem_1.default, null, removeSelectionText || "Remove selection"), renderFilteredOptions()), React.createElement(core_1.FormHelperText, __assign({ error: error }, formHelperTextProps), helperText))); } exports.SearchableSelect = SearchableSelect;