UNPKG

@geist-ui/react

Version:

Modern and minimalist React UI library.

224 lines (197 loc) 8.54 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties"; var _excluded = ["options", "initialValue", "onSelect", "onSearch", "onChange", "searching", "children", "type", "value", "clearable", "disabled", "dropdownClassName", "dropdownStyle", "disableMatchWidth", "disableFreeSolo", "getPopupContainer"]; import _JSXStyle from "../styled-jsx.es.js"; import React, { useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'; import Input from '../input'; import AutoCompleteItem from './auto-complete-item'; import AutoCompleteDropdown from './auto-complete-dropdown'; import AutoCompleteSearching from './auto-complete-searching'; import AutoCompleteEmpty from './auto-complete-empty'; import { AutoCompleteContext } from './auto-complete-context'; import Loading from '../loading'; import { pickChild } from '../utils/collections'; import useCurrentState from '../utils/use-current-state'; import useScaleable, { withPureProps, withScaleable } from '../use-scaleable'; var defaultProps = { options: [], initialValue: '', disabled: false, clearable: false, type: 'default', disableMatchWidth: false, disableFreeSolo: false, className: '' }; var childrenToOptionsNode = function childrenToOptionsNode(options) { return options.map(function (item, index) { var key = "auto-complete-item-".concat(index); if ( /*#__PURE__*/React.isValidElement(item)) return /*#__PURE__*/React.cloneElement(item, { key: key }); var validItem = item; return /*#__PURE__*/React.createElement(AutoCompleteItem, { key: key, value: validItem.value, isLabelOnly: true }, validItem.label); }); }; // When the search is not set, the "clearable" icon can be displayed in the original location. // When the search is seted, at least one element should exist to avoid re-render. var getSearchIcon = function getSearchIcon(searching) { var scale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; if (searching === undefined) return null; return searching ? /*#__PURE__*/React.createElement(Loading, { scale: +scale / 2 }) : /*#__PURE__*/React.createElement("span", null); }; var AutoCompleteComponent = /*#__PURE__*/React.forwardRef(function (_ref, userRef) { var options = _ref.options, customInitialValue = _ref.initialValue, onSelect = _ref.onSelect, onSearch = _ref.onSearch, onChange = _ref.onChange, searching = _ref.searching, children = _ref.children, type = _ref.type, value = _ref.value, clearable = _ref.clearable, disabled = _ref.disabled, dropdownClassName = _ref.dropdownClassName, dropdownStyle = _ref.dropdownStyle, disableMatchWidth = _ref.disableMatchWidth, disableFreeSolo = _ref.disableFreeSolo, getPopupContainer = _ref.getPopupContainer, props = _objectWithoutProperties(_ref, _excluded); var resetTimer = useRef(); var _useScaleable = useScaleable(), SCALES = _useScaleable.SCALES, getScaleableProps = _useScaleable.getScaleableProps; var ref = useRef(null); var inputRef = useRef(null); var _useCurrentState = useCurrentState(customInitialValue), _useCurrentState2 = _slicedToArray(_useCurrentState, 3), state = _useCurrentState2[0], setState = _useCurrentState2[1], stateRef = _useCurrentState2[2]; var _useState = useState(customInitialValue), _useState2 = _slicedToArray(_useState, 2), selectVal = _useState2[0], setSelectVal = _useState2[1]; var _useState3 = useState(false), _useState4 = _slicedToArray(_useState3, 2), visible = _useState4[0], setVisible = _useState4[1]; useImperativeHandle(userRef, function () { return inputRef.current; }); var _pickChild = pickChild(children, AutoCompleteSearching), _pickChild2 = _slicedToArray(_pickChild, 2), searchChild = _pickChild2[1]; var _pickChild3 = pickChild(children, AutoCompleteEmpty), _pickChild4 = _slicedToArray(_pickChild3, 2), emptyChild = _pickChild4[1]; var autoCompleteItems = useMemo(function () { var hasSearchChild = searchChild && React.Children.count(searchChild) > 0; var hasEmptyChild = emptyChild && React.Children.count(emptyChild) > 0; if (searching) { return hasSearchChild ? searchChild : /*#__PURE__*/React.createElement(AutoCompleteSearching, null, "Searching..."); } if (options.length === 0) { if (state === '') return null; return hasEmptyChild ? emptyChild : /*#__PURE__*/React.createElement(AutoCompleteEmpty, null, "No Options"); } return childrenToOptionsNode(options); }, [searching, options]); var showClearIcon = useMemo(function () { return clearable && searching === undefined; }, [clearable, searching]); var updateValue = function updateValue(val) { if (disabled) return; setSelectVal(val); onSelect && onSelect(val); setState(val); inputRef.current && inputRef.current.focus(); }; var updateVisible = function updateVisible(next) { return setVisible(next); }; var onInputChange = function onInputChange(event) { setVisible(true); onSearch && onSearch(event.target.value); setState(event.target.value); }; var resetInputValue = function resetInputValue() { if (!disableFreeSolo) return; if (!state || state === '') return; if (state !== selectVal) { setState(selectVal); } }; useEffect(function () { onChange && onChange(state); }, [state]); useEffect(function () { if (value === undefined) return; setState(value); }, [value]); var initialValue = useMemo(function () { return { ref: ref, value: state, updateValue: updateValue, visible: visible, updateVisible: updateVisible }; }, [state, visible]); var toggleFocusHandler = function toggleFocusHandler(next) { clearTimeout(resetTimer.current); setVisible(next); if (next) { onSearch && onSearch(stateRef.current); } else { resetTimer.current = window.setTimeout(function () { resetInputValue(); clearTimeout(resetTimer.current); }, 100); } }; var inputProps = _extends({}, withPureProps(props), { disabled: disabled, value: state }); return /*#__PURE__*/React.createElement(AutoCompleteContext.Provider, { value: initialValue }, /*#__PURE__*/React.createElement("div", { ref: ref, className: _JSXStyle.dynamic([["2878925540", [SCALES.width(1, 'max-content'), SCALES.height(1, 'auto'), SCALES.pt(0), SCALES.pr(0), SCALES.pb(0), SCALES.pl(0), SCALES.mt(0), SCALES.mr(0), SCALES.mb(0), SCALES.ml(0)]]]) + " " + "auto-complete" }, /*#__PURE__*/React.createElement(Input, _extends({ ref: inputRef, type: type, onChange: onInputChange, onFocus: function onFocus() { return toggleFocusHandler(true); }, onBlur: function onBlur() { return toggleFocusHandler(false); }, clearable: showClearIcon, width: SCALES.width(1, 'initial'), height: SCALES.height(2.25), iconRight: getSearchIcon(searching, getScaleableProps('scale')) }, inputProps)), /*#__PURE__*/React.createElement(AutoCompleteDropdown, { visible: visible, disableMatchWidth: disableMatchWidth, className: dropdownClassName, dropdownStyle: dropdownStyle, getPopupContainer: getPopupContainer }, autoCompleteItems), /*#__PURE__*/React.createElement(_JSXStyle, { id: "2878925540", dynamic: [SCALES.width(1, 'max-content'), SCALES.height(1, 'auto'), SCALES.pt(0), SCALES.pr(0), SCALES.pb(0), SCALES.pl(0), SCALES.mt(0), SCALES.mr(0), SCALES.mb(0), SCALES.ml(0)] }, ".auto-complete.__jsx-style-dynamic-selector{width:".concat(SCALES.width(1, 'max-content'), ";height:").concat(SCALES.height(1, 'auto'), ";padding:").concat(SCALES.pt(0), " ").concat(SCALES.pr(0), " ").concat(SCALES.pb(0), " ").concat(SCALES.pl(0), ";margin:").concat(SCALES.mt(0), " ").concat(SCALES.mr(0), " ").concat(SCALES.mb(0), " ").concat(SCALES.ml(0), ";}.auto-complete.__jsx-style-dynamic-selector .loading{width:-webkit-max-content;width:-moz-max-content;width:max-content;}")))); }); AutoCompleteComponent.defaultProps = defaultProps; AutoCompleteComponent.displayName = 'GeistAutoComplete'; var AutoComplete = withScaleable(AutoCompleteComponent); export default AutoComplete;