UNPKG

@emsipl/react-select-search

Version:
327 lines (282 loc) 12.6 kB
"use strict"; exports.__esModule = true; exports["default"] = void 0; var _react = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _useSelect2 = _interopRequireDefault(require("./useSelect")); var _types = require("./types"); var _Option = _interopRequireDefault(require("./Components/Option")); var _isSelected = _interopRequireDefault(require("./lib/isSelected")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var SelectSearch = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, ref) { var defaultValue = _ref.value, disabled = _ref.disabled, placeholder = _ref.placeholder, multiple = _ref.multiple, search = _ref.search, autoFocus = _ref.autoFocus, autoComplete = _ref.autoComplete, defaultOptions = _ref.options, id = _ref.id, onChange = _ref.onChange, printOptions = _ref.printOptions, closeOnSelect = _ref.closeOnSelect, className = _ref.className, renderValue = _ref.renderValue, renderOption = _ref.renderOption, renderGroupHeader = _ref.renderGroupHeader, getOptions = _ref.getOptions, fuse = _ref.fuse, emptyMessage = _ref.emptyMessage, menuPlacement = _ref.menuPlacement; var selectRef = (0, _react.useRef)(null); var mainRef = (0, _react.useRef)(null); var _useState = (0, _react.useState)({}), optionsStyle = _useState[0], setOptionsStyle = _useState[1]; var _useSelect = (0, _useSelect2["default"])({ options: defaultOptions, value: defaultValue, multiple: multiple, disabled: disabled, fuse: fuse, search: search, onChange: onChange, getOptions: getOptions, closeOnSelect: closeOnSelect, closable: !multiple || printOptions === 'on-focus', allowEmpty: !!placeholder }), snapshot = _useSelect[0], valueProps = _useSelect[1], optionProps = _useSelect[2]; var focus = snapshot.focus, highlighted = snapshot.highlighted, value = snapshot.value, options = snapshot.options, searching = snapshot.searching, displayValue = snapshot.displayValue, searchValue = snapshot.search; var cls = (0, _react.useCallback)(function (key) { if (typeof className === 'function') { return className(key); } if (key.indexOf('container') === 0) { return key.replace('container', className); } if (key.indexOf('is-') === 0 || key.indexOf('has-') === 0) { return key; } return className.split(' ')[0] + "__" + key; }, [className]); var renderEmptyMessage = (0, _react.useCallback)(function () { if (emptyMessage === null) { return null; } var content = typeof emptyMessage === 'function' ? emptyMessage() : emptyMessage; return /*#__PURE__*/_react["default"].createElement("li", { className: cls('not-found') }, content); }, [emptyMessage, cls]); var wrapperClass = [cls('container'), disabled ? cls('is-disabled') : false, searching ? cls('is-loading') : false, focus ? cls('has-focus') : false].filter(function (single) { return !!single; }).join(' '); var inputValue = focus && search ? searchValue : displayValue; (0, _react.useEffect)(function () { var current = selectRef.current; if (!current || multiple || highlighted < 0 && !value) { return; } var query = highlighted > -1 ? "[data-index=\"" + highlighted + "\"]" : "[data-value=\"" + escape(value.value) + "\"]"; var selected = current.querySelector(query); if (selected) { var rect = current.getBoundingClientRect(); var selectedRect = selected.getBoundingClientRect(); current.scrollTop = selected.offsetTop - rect.height / 2 + selectedRect.height / 2; } }, [focus, value, highlighted, selectRef, multiple]); var shouldRenderOptions; switch (printOptions) { case 'never': shouldRenderOptions = false; break; case 'always': shouldRenderOptions = true; break; case 'on-focus': shouldRenderOptions = focus; break; default: shouldRenderOptions = !disabled && (focus || multiple); break; } var getMenuPlacement = function getMenuPlacement() { switch (menuPlacement) { case 'top': return 'top'; case 'auto': if (selectRef.current && mainRef.current) { var optionsRect = selectRef.current.getBoundingClientRect(); var mainRect = mainRef.current.getBoundingClientRect(); var spaceBelow = window.innerHeight - mainRect.bottom - optionsRect.height; var spaceAbove = mainRect.top - optionsRect.height; if (spaceBelow < 0 && spaceAbove > spaceBelow) { return 'top'; } } default: return 'bottom'; } }; var updateOptionsStyle = function updateOptionsStyle() { if (!selectRef.current || !mainRef.current) { return; } var placement = getMenuPlacement(); var rect = selectRef.current.getBoundingClientRect(); var newStyle = {}; if (placement === 'top') { newStyle.top = -rect.height - 10; } if (newStyle.top !== optionsStyle.top) { setOptionsStyle(newStyle); } }; var setSelectRef = function setSelectRef(r) { selectRef.current = r; updateOptionsStyle(); }; var setMainRef = function setMainRef(r) { mainRef.current = r; updateOptionsStyle(); if (ref) { if (typeof ref === 'function') { ref(mainRef.current); } else { ref.current = mainRef.current; } } }; return /*#__PURE__*/_react["default"].createElement("div", { ref: setMainRef, className: wrapperClass, id: id }, (!multiple || placeholder || search) && /*#__PURE__*/_react["default"].createElement("div", { className: cls('value') }, renderValue(_objectSpread(_objectSpread({}, valueProps), {}, { placeholder: placeholder, autoFocus: autoFocus, autoComplete: autoComplete, value: inputValue }), snapshot, cls('input'))), shouldRenderOptions && /*#__PURE__*/_react["default"].createElement("div", { className: cls('select'), ref: setSelectRef, style: optionsStyle, onMouseDown: function onMouseDown(e) { return e.preventDefault(); } }, /*#__PURE__*/_react["default"].createElement("ul", { className: cls('options') }, options.length > 0 ? options.map(function (option) { var isGroup = option.type === 'group'; var items = isGroup ? option.items : [option]; var base = { cls: cls, optionProps: optionProps, renderOption: renderOption }; var rendered = items.map(function (o) { return /*#__PURE__*/_react["default"].createElement(_Option["default"], _extends({ key: o.value, selected: (0, _isSelected["default"])(o, value), highlighted: highlighted === o.index }, base, o)); }); if (isGroup) { return /*#__PURE__*/_react["default"].createElement("li", { role: "none", className: cls('row'), key: option.groupId }, /*#__PURE__*/_react["default"].createElement("div", { className: cls('group') }, /*#__PURE__*/_react["default"].createElement("div", { className: cls('group-header') }, renderGroupHeader(option.name)), /*#__PURE__*/_react["default"].createElement("ul", { className: cls('options') }, rendered))); } return rendered; }) : renderEmptyMessage() || null))); }); SelectSearch.defaultProps = { className: 'select-search', disabled: false, search: false, multiple: false, placeholder: null, id: null, autoFocus: false, autoComplete: 'on', value: '', onChange: function onChange() {}, printOptions: 'auto', closeOnSelect: true, renderOption: function renderOption(domProps, option, snapshot, className) { return ( /*#__PURE__*/ // eslint-disable-next-line react/button-has-type _react["default"].createElement("button", _extends({ type: "button", className: className }, domProps), option.name) ); }, renderGroupHeader: function renderGroupHeader(name) { return name; }, renderValue: function renderValue(valueProps, snapshot, className) { return /*#__PURE__*/_react["default"].createElement("input", _extends({}, valueProps, { className: className })); }, fuse: { keys: ['name', 'groupName'], threshold: 0.3 }, getOptions: null, emptyMessage: null, menuPlacement: 'bottom' }; SelectSearch.propTypes = process.env.NODE_ENV !== "production" ? { options: _propTypes["default"].arrayOf(_types.optionType).isRequired, getOptions: _propTypes["default"].func, value: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number, _propTypes["default"].arrayOf(_propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]))]), className: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].func]), multiple: _propTypes["default"].bool, search: _propTypes["default"].bool, disabled: _propTypes["default"].bool, placeholder: _propTypes["default"].string, id: _propTypes["default"].string, autoComplete: _propTypes["default"].string, autoFocus: _propTypes["default"].bool, onChange: _propTypes["default"].func, printOptions: _propTypes["default"].oneOf(['auto', 'always', 'never', 'on-focus']), closeOnSelect: _propTypes["default"].bool, renderOption: _propTypes["default"].func, renderGroupHeader: _propTypes["default"].func, renderValue: _propTypes["default"].func, fuse: _propTypes["default"].oneOfType([_propTypes["default"].bool, _propTypes["default"].shape({ keys: _propTypes["default"].arrayOf(_propTypes["default"].string), threshold: _propTypes["default"].number })]), emptyMessage: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].func]), menuPlacement: _propTypes["default"].oneOf(['bottom', 'top', 'auto']) } : {}; var _default = /*#__PURE__*/(0, _react.memo)(SelectSearch); exports["default"] = _default;