UNPKG

@massds/mayflower-react

Version:

React versions of Mayflower design system UI components

134 lines (133 loc) 5.07 kB
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } /** * TypeAheadDropdown module. * @module @massds/mayflower-react/TypeAheadDropdown * @requires module:@massds/mayflower-assets/scss/01-atoms/button-with-icon * @requires module:@massds/mayflower-assets/scss/01-atoms/button-search * @requires module:@massds/mayflower-assets/scss/01-atoms/input-typeahead * @requires module:@massds/mayflower-assets/scss/01-atoms/svg-icons * @requires module:@massds/mayflower-assets/scss/01-atoms/svg-loc-icons */ import React from "react"; import PropTypes from "prop-types"; import ButtonWithIcon from "../ButtonWithIcon/index.mjs"; import InputTextFuzzy from "../InputTextFuzzy/index.mjs"; // eslint-disable-next-line import/no-unresolved import IconCaretDown from "../Icon/IconCaretDown.mjs"; const TypeAheadDropdown = props => { const _React$useState = React.useState(false), buttonExpand = _React$useState[0], setButtonExpand = _React$useState[1]; const _React$useState2 = React.useState(props.dropdownButton.text), buttonText = _React$useState2[0], setButtonText = _React$useState2[1]; const _React$useState3 = React.useState(), buttonClicked = _React$useState3[0], setButtonClicked = _React$useState3[1]; const buttonRef = React.useRef(); const wrapperRef = React.useRef(); const handleRefMouseDown = () => { setButtonClicked(true); }; const handleClick = () => { setButtonExpand(!buttonExpand); }; const handleKeyDown = event => { // If the user pressed escape, or pressed enter with nothing selected close // the panel. if (event.key === 'Escape' || event.key === 'Enter' && event.target.value === '') { closeDropdown(); } if (event.key === 'Escape' && buttonRef) { buttonRef.focus(); } if (typeof props.onKeyDown === 'function') { props.onKeyDown(event); } }; const handleInputBlur = () => { if (buttonClicked) { closeDropdown(); } }; const handleSelect = (event, _ref) => { let suggestion = _ref.suggestion; // Stop the filters form submission if enter is pressed in the selector. event.preventDefault(); // Update this component state and pass the event out to the calling code. const text = suggestion.item.text; if (text.length > 0) { setButtonText(text); setButtonExpand(false); if (typeof props.inputText.onSuggestionClick === 'function') { props.inputText.onSuggestionClick(event, { suggestion: suggestion }); } } }; const handleClickOutside = event => { // Close the panel if the user clicks outside the component. const node = wrapperRef.current; if (node && !node.contains(event.target)) { if (buttonExpand) { setButtonExpand(false); } } }; const closeDropdown = () => { setButtonExpand(false); }; // update state from prop React.useEffect(() => { const defaultValue = props.defaultValue; if (defaultValue !== undefined) { setButtonText(defaultValue); setButtonExpand(false); } }, [props.defaultValue]); React.useEffect(() => { setButtonClicked(false); document.addEventListener('mousedown', handleClickOutside); buttonRef.current.addEventListener('mousedown', handleRefMouseDown); return () => { document.removeEventListener('mousedown', handleClickOutside); if (buttonRef && buttonRef.current) { buttonRef.current.removeEventListener('mousedown', handleRefMouseDown); } }; }); const dropdownButton = _extends({ onClick: handleClick, setButtonRef: buttonRef, expanded: buttonExpand, icon: /*#__PURE__*/React.createElement(IconCaretDown, { height: 20, width: 20 }), size: '' }, props.dropdownButton); dropdownButton.text = buttonText || dropdownButton.text; const inputTextFuzzyProps = _extends({}, props.inputText, { onKeyDown: handleKeyDown, onSuggestionClick: handleSelect, onBlur: handleInputBlur, autoFocusInput: true }); return /*#__PURE__*/React.createElement("div", { ref: wrapperRef }, /*#__PURE__*/React.createElement(ButtonWithIcon, dropdownButton), buttonExpand && /*#__PURE__*/React.createElement(InputTextFuzzy, inputTextFuzzyProps)); }; TypeAheadDropdown.propTypes = process.env.NODE_ENV !== "production" ? { /** The props to set up the dropdown button */ dropdownButton: PropTypes.shape(ButtonWithIcon.propTypes).isRequired, /** The props to set up the inputTextFuzzy */ inputText: PropTypes.shape(InputTextFuzzy.propTypes).isRequired, /** Default text value for the selection */ defaultValue: PropTypes.string, /** Custom keydown callback */ onKeyDown: PropTypes.func, /** Custom suggestion onClick callback */ onSuggestionClick: PropTypes.func } : {}; export default TypeAheadDropdown;