UNPKG

@catho/quantum

Version:
389 lines (384 loc) 18.6 kB
"use strict"; function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _react = require("react"); var _propTypes = _interopRequireDefault(require("prop-types")); var _styledComponents = _interopRequireWildcard(require("styled-components")); var _shared = require("../shared"); var _theme = require("../shared/theme"); var _Icon = _interopRequireDefault(require("../Icon")); var _subComponents = require("../Input/sub-components"); var _UseKeyPress = _interopRequireDefault(require("./SubComponents/UseKeyPress")); var _jsxRuntime = require("react/jsx-runtime"); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } var ITEM_HEIGHT = '44px'; var MAX_ITEMS_VISIBILITY = 7; var DROPITEM_FONT_SIZE = _theme.baseFontSize * 0.875; var NON_FOCUSABLE_SUGGESTION_INDEX = -1; var ComponentWrapper = _styledComponents["default"].div.withConfig({ displayName: "AutoComplete__ComponentWrapper", componentId: "sc-1vy8gb0-0" })(["", ""], function (_ref) { var neutral = _ref.theme.colors.neutral, _ref$skin = _ref.skin, skin = _ref$skin === void 0 ? 'default' : _ref$skin; return (0, _styledComponents.css)(["position:relative;color:", ";"], skin === 'default' ? neutral[700] : neutral[0]); }); var InputWrapper = _styledComponents["default"].div.withConfig({ displayName: "AutoComplete__InputWrapper", componentId: "sc-1vy8gb0-1" })(["position:relative;"]); var InputText = (0, _styledComponents["default"])(_subComponents.TextInput).withConfig({ displayName: "AutoComplete__InputText", componentId: "sc-1vy8gb0-2" })(["", ""], function (_ref2) { var xsmall = _ref2.theme.spacing.xsmall; return (0, _styledComponents.css)(["margin-top:", "px;"], xsmall); }); var InputIcon = (0, _styledComponents["default"])(_Icon["default"]).withConfig({ displayName: "AutoComplete__InputIcon", componentId: "sc-1vy8gb0-3" })(["cursor:pointer;position:absolute;", ""], function (_ref3) { var _ref3$theme$spacing = _ref3.theme.spacing, xsmall = _ref3$theme$spacing.xsmall, medium = _ref3$theme$spacing.medium; return (0, _styledComponents.css)(["right:", "px;bottom:", "px;width:", "px;"], medium, xsmall * 1.25, _theme.baseFontSize * 1.5); }); var InputErrorIcon = (0, _styledComponents["default"])(InputIcon).attrs({ name: 'error' }).withConfig({ displayName: "AutoComplete__InputErrorIcon", componentId: "sc-1vy8gb0-4" })(["", ""], function (_ref4) { var error700 = _ref4.theme.colors.error[700], skin = _ref4.skin; return (0, _styledComponents.css)(["color:", ";"], skin === 'default' ? error700 : 'inherit'); }); var List = _styledComponents["default"].ul.withConfig({ displayName: "AutoComplete__List", componentId: "sc-1vy8gb0-5" })(["border-radius:4px;box-sizing:border-box;list-style:none;max-height:calc(", " * ", ");overflow:auto;padding:0;position:absolute;width:100%;z-index:1;", ""], ITEM_HEIGHT, MAX_ITEMS_VISIBILITY, function (_ref5) { var theme = _ref5.theme; var xxsmall = theme.spacing.xxsmall, _theme$colors$neutral = theme.colors.neutral, neutral0 = _theme$colors$neutral[0], neutral700 = _theme$colors$neutral[700]; return (0, _styledComponents.css)(["background-color:", ";margin-top:", "px;", ";"], neutral0, xxsmall, (0, _shared.shadow)(3, neutral700)({ theme: theme })); }); var ListItem = _styledComponents["default"].li.withConfig({ displayName: "AutoComplete__ListItem", componentId: "sc-1vy8gb0-6" })(["display:flex;align-items:center;justify-content:space-between;box-sizing:border-box;cursor:pointer;height:", ";", " &[aria-selected = 'true' ],&:hover{", "}"], ITEM_HEIGHT, function (_ref6) { var _ref6$theme = _ref6.theme, _ref6$theme$spacing = _ref6$theme.spacing, xsmall = _ref6$theme$spacing.xsmall, medium = _ref6$theme$spacing.medium, _ref6$theme$colors$ne = _ref6$theme.colors.neutral, neutral0 = _ref6$theme$colors$ne[0], neutral700 = _ref6$theme$colors$ne[700]; return (0, _styledComponents.css)(["color:", ";font-size:", "px;background-color:", ";padding:", "px ", "px;"], neutral700, DROPITEM_FONT_SIZE, neutral0, xsmall, medium); }, function (_ref7) { var neutral100 = _ref7.theme.colors.neutral[100]; return (0, _styledComponents.css)(["background-color:", ";"], neutral100); }); var PoliteStatus = _styledComponents["default"].div.withConfig({ displayName: "AutoComplete__PoliteStatus", componentId: "sc-1vy8gb0-7" })(["border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;"]); var AutoComplete = function AutoComplete(_ref8) { var _ref8$id = _ref8.id, id = _ref8$id === void 0 ? '' : _ref8$id, _ref8$name = _ref8.name, name = _ref8$name === void 0 ? '' : _ref8$name, _ref8$label = _ref8.label, label = _ref8$label === void 0 ? '' : _ref8$label, _ref8$value = _ref8.value, value = _ref8$value === void 0 ? '' : _ref8$value, _ref8$error = _ref8.error, error = _ref8$error === void 0 ? '' : _ref8$error, _ref8$disabled = _ref8.disabled, disabled = _ref8$disabled === void 0 ? false : _ref8$disabled, _ref8$helperText = _ref8.helperText, helperText = _ref8$helperText === void 0 ? '' : _ref8$helperText, _ref8$placeholder = _ref8.placeholder, placeholder = _ref8$placeholder === void 0 ? 'Select an option' : _ref8$placeholder, suggestions = _ref8.suggestions, _ref8$theme = _ref8.theme, theme = _ref8$theme === void 0 ? { spacing: _theme.spacing, colors: _theme.colors } : _ref8$theme, _ref8$onSelectedItem = _ref8.onSelectedItem, onSelectedItem = _ref8$onSelectedItem === void 0 ? function () {} : _ref8$onSelectedItem, _ref8$onChange = _ref8.onChange, onChange = _ref8$onChange === void 0 ? function () {} : _ref8$onChange, _ref8$required = _ref8.required, required = _ref8$required === void 0 ? false : _ref8$required, _ref8$skin = _ref8.skin, skin = _ref8$skin === void 0 ? 'default' : _ref8$skin; var _useState = (0, _react.useState)(value), _useState2 = _slicedToArray(_useState, 2), userTypedValue = _useState2[0], setUserTypedValue = _useState2[1]; var _useState3 = (0, _react.useState)(suggestions), _useState4 = _slicedToArray(_useState3, 2), filterSuggestions = _useState4[0], setFilterSuggestions = _useState4[1]; var _useState5 = (0, _react.useState)(filterSuggestions.length), _useState6 = _slicedToArray(_useState5, 2), filterSuggestionsLength = _useState6[0], setFilterSuggestionsLength = _useState6[1]; var _useState7 = (0, _react.useState)(false), _useState8 = _slicedToArray(_useState7, 2), showSuggestions = _useState8[0], setShowSuggestions = _useState8[1]; var _useState9 = (0, _react.useState)(NON_FOCUSABLE_SUGGESTION_INDEX), _useState10 = _slicedToArray(_useState9, 2), cursor = _useState10[0], setCursor = _useState10[1]; var wrapperRef = (0, _react.useRef)(); var listOptions = (0, _react.useRef)(); var autoInputRef = (0, _react.useRef)(null); var EscapeKeyPressValue = 'Escape'; var assistiveDescriptionDefault = "Digite uma ou mais letras para expandir os resultados. ".concat(filterSuggestionsLength, " est\xE3o disponiveis."); var assistiveDescriptionDropDownOpen = "".concat(assistiveDescriptionDefault, " ").concat(filterSuggestions[cursor], " \n ").concat(cursor + 1, " de ").concat(filterSuggestionsLength, " est\xE1 destacado"); var focusOnInput = function focusOnInput() { var _wrapperRef$current; var input = (_wrapperRef$current = wrapperRef.current) === null || _wrapperRef$current === void 0 ? void 0 : _wrapperRef$current.children[1]; if (input) { input.focus(); setCursor(NON_FOCUSABLE_SUGGESTION_INDEX); } }; var filterItems = function filterItems(currentValue) { return suggestions.filter(function (suggestion) { var option = (0, _shared.normalizeChars)(suggestion.toLowerCase()); option = (0, _shared.normalizeChars)(option); return option.indexOf((0, _shared.normalizeChars)(currentValue.toLowerCase())) > NON_FOCUSABLE_SUGGESTION_INDEX; }); }; var handleFilter = function handleFilter(currentValue) { var filteredValues = filterItems(currentValue); setShowSuggestions(!!filteredValues.length); setFilterSuggestions(filteredValues); }; var handleChange = function handleChange(currentValue) { setUserTypedValue(currentValue); onChange(currentValue); setCursor(NON_FOCUSABLE_SUGGESTION_INDEX); handleFilter(currentValue); }; var handleClickOutside = function handleClickOutside(event) { var _wrapperRef$current2; if (!((_wrapperRef$current2 = wrapperRef.current) !== null && _wrapperRef$current2 !== void 0 && _wrapperRef$current2.contains(event.target))) { setShowSuggestions(false); } }; var handleInputClick = function handleInputClick() { var filteredItem = filterItems(userTypedValue); setFilterSuggestions(filteredItem); setShowSuggestions(true); }; var handleItemClick = function handleItemClick(item) { setUserTypedValue(item); onSelectedItem(item); setShowSuggestions(false); }; var handleClearValue = function handleClearValue() { setUserTypedValue(''); onChange(''); setFilterSuggestions(suggestions); setCursor(NON_FOCUSABLE_SUGGESTION_INDEX); }; var handleEscPress = function handleEscPress(_ref9) { var key = _ref9.key; if (key === EscapeKeyPressValue) { setShowSuggestions(false); focusOnInput(); } }; var generateSuggestions = function generateSuggestions() { return showSuggestions && filterSuggestions ? /*#__PURE__*/(0, _jsxRuntime.jsx)(List, { theme: theme, role: "listbox", id: "autocompleteOptions", ref: listOptions, skin: skin, children: filterSuggestions.map(function (item, index) { return /*#__PURE__*/(0, _jsxRuntime.jsx)(ListItem, { "aria-posinset": index, onClick: function onClick() { return handleItemClick(item); }, theme: theme, "aria-selected": index === cursor, role: "option", tabIndex: "-1", children: item }, item); }) }) : null; }; var generateAssistiveDescript = function generateAssistiveDescript() { if (showSuggestions) { return assistiveDescriptionDropDownOpen; } return assistiveDescriptionDefault; }; var downPress = (0, _UseKeyPress["default"])('ArrowDown'); var upPress = (0, _UseKeyPress["default"])('ArrowUp'); var enterPress = (0, _UseKeyPress["default"])('Enter'); var tabPress = (0, _UseKeyPress["default"])('Tab'); (0, _react.useEffect)(function () { setFilterSuggestionsLength(filterSuggestions === null || filterSuggestions === void 0 ? void 0 : filterSuggestions.length); }, [filterSuggestions]); /* istanbul ignore next */ (0, _react.useEffect)(function () { if (showSuggestions && filterSuggestionsLength && downPress) { var selectedCursor = cursor < filterSuggestionsLength - 1 ? cursor + 1 : cursor; setCursor(selectedCursor); listOptions.current.children[selectedCursor].focus(); } }, [downPress]); /* istanbul ignore next */ (0, _react.useEffect)(function () { if (showSuggestions && filterSuggestionsLength && upPress && cursor > 0) { var selectedCursor = cursor > 0 ? cursor - 1 : cursor; setCursor(selectedCursor); listOptions.current.children[selectedCursor].focus(); } if (upPress && cursor === 0) { focusOnInput(); } }, [upPress]); /* istanbul ignore next */ (0, _react.useEffect)(function () { if (showSuggestions && filterSuggestionsLength && enterPress) { setUserTypedValue(filterSuggestions[cursor]); onSelectedItem(filterSuggestions[cursor]); setShowSuggestions(false); focusOnInput(); } }, [cursor, enterPress]); /* istanbul ignore next */ (0, _react.useEffect)(function () { if (tabPress) { if (showSuggestions && cursor !== NON_FOCUSABLE_SUGGESTION_INDEX) { setUserTypedValue(filterSuggestions[cursor]); onSelectedItem(filterSuggestions[cursor]); } setShowSuggestions(false); } }, [tabPress]); (0, _react.useEffect)(function () { window.addEventListener('click', handleClickOutside); window.addEventListener('keydown', handleEscPress); return function () { window.removeEventListener('click', handleClickOutside); window.removeEventListener('keydown', handleEscPress); }; }, []); (0, _react.useEffect)(function () { if (document.activeElement === autoInputRef.current) { handleFilter(userTypedValue); } }, [suggestions]); return /*#__PURE__*/(0, _jsxRuntime.jsxs)(ComponentWrapper, { theme: theme, skin: skin, children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(InputWrapper, { ref: wrapperRef, children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_subComponents.InputLabel, { htmlFor: id, error: error, children: [label, required && /*#__PURE__*/(0, _jsxRuntime.jsx)(_subComponents.RequiredMark, { skin: skin, children: "*" })] }), /*#__PURE__*/(0, _jsxRuntime.jsx)(InputText, { id: id, ref: autoInputRef, name: name, type: "text", error: error, disabled: disabled, placeholder: placeholder, autoComplete: "off", role: "combobox", "aria-owns": "autocompleteOptions", "aria-autocomplete": "both", "aria-expanded": showSuggestions, value: userTypedValue, onClick: function onClick() { return handleInputClick(); }, onChange: function onChange(e) { return handleChange(e.target.value); }, skin: skin, required: required }), userTypedValue && !error && !disabled && /*#__PURE__*/(0, _jsxRuntime.jsx)(InputIcon, { theme: theme, name: "clear", description: "limpar valor", onClick: function onClick() { return handleClearValue(); } }), generateSuggestions(), error && /*#__PURE__*/(0, _jsxRuntime.jsx)(InputErrorIcon, { description: error, theme: theme, skin: skin })] }), helperText && /*#__PURE__*/(0, _jsxRuntime.jsx)(_subComponents.HelperText, { children: helperText }), error && /*#__PURE__*/(0, _jsxRuntime.jsx)(_subComponents.InputErrorMessage, { theme: theme, skin: skin, children: error }), /*#__PURE__*/(0, _jsxRuntime.jsx)(PoliteStatus, { role: "status", "aria-atomic": "true", "aria-live": "polite", children: generateAssistiveDescript() })] }); }; AutoComplete.propTypes = { theme: _propTypes["default"].shape({ colors: _propTypes["default"].object, spacing: _propTypes["default"].object }), /** A list of string or objects with the values to show in component */ suggestions: _propTypes["default"].arrayOf(_propTypes["default"].string).isRequired, id: _propTypes["default"].string, /** Displays an error message and changes border color to error color */ error: _propTypes["default"].string, disabled: _propTypes["default"].bool, /** Displays a label text that describes the field */ label: _propTypes["default"].string, value: _propTypes["default"].string, name: _propTypes["default"].string, placeholder: _propTypes["default"].string, /** Callback function to receive what the user is typing */ onChange: _propTypes["default"].func, /** Callback function to receive user selected value */ onSelectedItem: _propTypes["default"].func, /** Displays a helper text below the component */ helperText: _propTypes["default"].string, required: _propTypes["default"].bool, skin: _propTypes["default"].oneOf(['default', 'dark']) }; var _default = exports["default"] = AutoComplete;