UNPKG

@age/quantum

Version:
438 lines (379 loc) 19.7 kB
"use strict"; function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _styledComponents = _interopRequireDefault(require("styled-components")); var _downshift = _interopRequireDefault(require("downshift")); var _Icon = _interopRequireDefault(require("../Icon/Icon")); var _shared = require("../shared"); var _theme = require("../shared/theme"); var _subComponents = require("../Input/sub-components"); 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 _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } 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; } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } 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); } var ID_GENERATOR = (0, _shared.uniqId)('dropdown-'); var ITEM_HEIGHT = '44px'; var MAX_ITEMS_VISIBILITY = 7; var DROPITEM_FONT_SIZE = _theme.baseFontSize * 0.875; var DROPITEM_IMAGE_SIZE = '24px'; var DropInput = (0, _styledComponents.default)(_subComponents.TextInput).withConfig({ displayName: "Dropdown__DropInput", componentId: "sc-550qgk-0" })(["align-items:center;cursor:pointer;display:flex;justify-content:space-between;", ";"], function (_ref) { var text = _ref.text, autocomplete = _ref.autocomplete, theme = _ref.theme, _ref$theme = _ref.theme, _ref$theme$colors$neu = _ref$theme.colors.neutral, neutral900 = _ref$theme$colors$neu[900], neutral500 = _ref$theme$colors$neu[500], _ref$theme$spacing = _ref$theme.spacing, xsmall = _ref$theme$spacing.xsmall, medium = _ref$theme$spacing.medium, xxxlarge = _ref$theme$spacing.xxxlarge; return "\n ".concat(autocomplete ? "padding: ".concat(xsmall, "px ").concat(xxxlarge, "px ").concat(xsmall, "px ").concat(medium, "px;") : '', "\n ").concat(!text ? 'flex-direction: row-reverse;' : '', "\n color: ").concat(neutral900, ";\n ").concat((0, _shared.shadow)(5, neutral500)({ theme: theme }), ";\n "); }); var ArrowDown = (0, _styledComponents.default)(_Icon.default).attrs({ name: 'arrow_drop_down' }).withConfig({ displayName: "Dropdown__ArrowDown", componentId: "sc-550qgk-1" })(["pointer-events:none;", ""], function (_ref2) { var selectedItem = _ref2.selectedItem, neutral700 = _ref2.theme.colors.neutral[700]; return !selectedItem && "\n color: ".concat(neutral700, ";\n "); }); var ArrowUp = (0, _styledComponents.default)(_Icon.default).attrs({ name: 'arrow_drop_up' }).withConfig({ displayName: "Dropdown__ArrowUp", componentId: "sc-550qgk-2" })(["pointer-events:none;", ""], function (_ref3) { var selectedItem = _ref3.selectedItem, neutral700 = _ref3.theme.colors.neutral[700]; return !selectedItem && "\n color: ".concat(neutral700, ";\n "); }); var InputArrowDown = (0, _styledComponents.default)(ArrowDown).withConfig({ displayName: "Dropdown__InputArrowDown", componentId: "sc-550qgk-3" })(["position:absolute;", ""], function (_ref4) { var _ref4$theme$spacing = _ref4.theme.spacing, small = _ref4$theme$spacing.small, medium = _ref4$theme$spacing.medium; return "\n top: ".concat(small, "px;\n right: ").concat(medium * 0.875, "px;\n "); }); var InputArrowUp = (0, _styledComponents.default)(ArrowUp).withConfig({ displayName: "Dropdown__InputArrowUp", componentId: "sc-550qgk-4" })(["position:absolute;", ""], function (_ref5) { var _ref5$theme$spacing = _ref5.theme.spacing, small = _ref5$theme$spacing.small, medium = _ref5$theme$spacing.medium; return "\n top: ".concat(small, "px;\n right: ").concat(medium * 0.875, "px;\n "); }); var DropList = _styledComponents.default.ul.withConfig({ displayName: "Dropdown__DropList", componentId: "sc-550qgk-5" })(["border-radius:4px;box-sizing:border-box;list-style:none;max-height:calc(", " * ", ");overflow:auto;padding:0;position:absolute;width:100%;z-index:9999;", ""], ITEM_HEIGHT, MAX_ITEMS_VISIBILITY, function (_ref6) { var theme = _ref6.theme; var xxsmall = theme.spacing.xxsmall, _theme$colors$neutral = theme.colors.neutral, neutral0 = _theme$colors$neutral[0], neutral300 = _theme$colors$neutral[300]; return "\n background-color: ".concat(neutral0, ";\n margin-top: ").concat(xxsmall, "px;\n ").concat((0, _shared.shadow)(5, neutral300)({ theme: theme }), ";\n "); }); var CheckIcon = (0, _styledComponents.default)(_Icon.default).attrs({ name: 'check' }).withConfig({ displayName: "Dropdown__CheckIcon", componentId: "sc-550qgk-6" })(["", ""], function (_ref7) { var selectedItem = _ref7.selectedItem, primary700 = _ref7.theme.colors.primary[700]; return !selectedItem && "\n color: ".concat(primary700, ";\n "); }); var DropItem = _styledComponents.default.li.withConfig({ displayName: "Dropdown__DropItem", componentId: "sc-550qgk-7" })(["box-sizing:border-box;cursor:pointer;height:42px;", " &[aria-selected= 'true' ]{", "}", ""], function (_ref8) { var _ref8$theme = _ref8.theme, _ref8$theme$spacing = _ref8$theme.spacing, xsmall = _ref8$theme$spacing.xsmall, medium = _ref8$theme$spacing.medium, neutral0 = _ref8$theme.colors.neutral[0]; return "\n font-size: ".concat(DROPITEM_FONT_SIZE, "px;\n background-color: ").concat(neutral0, ";\n padding: ").concat(xsmall, "px ").concat(medium, "px;\n "); }, function (_ref9) { var neutral100 = _ref9.theme.colors.neutral[100]; return "\n background-color: ".concat(neutral100, ";\n "); }, function (_ref10) { var isSelected = _ref10.isSelected; return isSelected && "\n display: flex;\n justify-content: space-between;\n "; }); var DropContainer = _styledComponents.default.div.withConfig({ displayName: "Dropdown__DropContainer", componentId: "sc-550qgk-8" })(["position:relative;"]); var SelectedItemLabel = _styledComponents.default.span.withConfig({ displayName: "Dropdown__SelectedItemLabel", componentId: "sc-550qgk-9" })(["", ""], function (_ref11) { var primary700 = _ref11.theme.colors.primary[700]; return "\n color: ".concat(primary700, "\n "); }); var DropItemImage = _styledComponents.default.img.withConfig({ displayName: "Dropdown__DropItemImage", componentId: "sc-550qgk-10" })(["float:right;width:", ";height:", ";"], DROPITEM_IMAGE_SIZE, DROPITEM_IMAGE_SIZE); var DropItemLabel = _styledComponents.default.span.withConfig({ displayName: "Dropdown__DropItemLabel", componentId: "sc-550qgk-11" })(["vertical-align:middle;"]); DropInput.displayName = 'DropInput'; DropItem.displayName = 'DropItem'; SelectedItemLabel.displayName = 'SelectedItemLabel'; ArrowDown.displayName = 'ArrowDown'; ArrowUp.displayName = 'ArrowUp'; DropItemImage.displayName = 'DropItemImage'; DropContainer.displayName = 'DropContainer'; var _getValue = function _getValue(item) { return item ? item.value || item.label || item : ''; }; var _getLabel = function _getLabel(item) { return item ? item.label || item.value || item : ''; }; var _getImage = function _getImage(item) { return item ? item.img : null; }; var _getImageAlt = function _getImageAlt(item) { return item ? item.alt : null; }; var _isEqual = function _isEqual(selected, item) { return _getValue(selected) === _getValue(item); }; var itemPropType = _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.shape({ value: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]), label: _propTypes.default.string })]); var List = function List(_ref12) { var theme = _ref12.theme, items = _ref12.items, selectedItem = _ref12.selectedItem, getItemProps = _ref12.getItemProps; return _react.default.createElement(DropList, { theme: theme }, items.map(function (item) { return _react.default.createElement(DropItem, _extends({ theme: theme }, getItemProps({ item: item, isSelected: _isEqual(selectedItem, item), key: _getValue(item) })), _isEqual(selectedItem, item) ? _react.default.createElement(_react.default.Fragment, null, _react.default.createElement(SelectedItemLabel, { theme: theme }, _getLabel(item)), _getImage(item) ? _react.default.createElement(DropItemImage, { src: _getImage(item), alt: _getImageAlt(item) }) : _react.default.createElement(CheckIcon, { theme: theme })) : _react.default.createElement(_react.default.Fragment, null, _react.default.createElement(DropItemLabel, null, _getLabel(item)), _getImage(item) && _react.default.createElement(DropItemImage, { src: _getImage(item), alt: _getImageAlt(item) }))); })); }; List.defaultProps = { selectedItem: null }; List.propTypes = { selectedItem: itemPropType, theme: _propTypes.default.shape({ colors: _propTypes.default.object, spacing: _propTypes.default.object }).isRequired, items: _propTypes.default.arrayOf(itemPropType).isRequired, getItemProps: _propTypes.default.func.isRequired }; var Dropdown = function Dropdown(_ref13) { var label = _ref13.label, error = _ref13.error, helperText = _ref13.helperText, required = _ref13.required, disabled = _ref13.disabled, items = _ref13.items, placeholder = _ref13.placeholder, selectedItem = _ref13.selectedItem, onChange = _ref13.onChange, autocomplete = _ref13.autocomplete, theme = _ref13.theme, id = _ref13.id, name = _ref13.name, ignoreSpecialChars = _ref13.ignoreSpecialChars, rest = _objectWithoutProperties(_ref13, ["label", "error", "helperText", "required", "disabled", "items", "placeholder", "selectedItem", "onChange", "autocomplete", "theme", "id", "name", "ignoreSpecialChars"]); var _buttonLabel = selectedItem ? _getLabel(selectedItem) : placeholder; var _highlightedReducer = function _highlightedReducer(_ref14, changes) { var selected = _ref14.selectedItem; if (changes.isOpen !== undefined && changes.isOpen) { var selectedIndex = items.map(_getValue).indexOf(_getValue(selected)); var withRange = selectedIndex + Math.floor(MAX_ITEMS_VISIBILITY / 2); var length = items.length; return _objectSpread({}, changes, { highlightedIndex: withRange < length ? withRange : length - 1 }); } return changes; }; var hasLabel = !!label; var _useState = (0, _react.useState)(id || ID_GENERATOR.next().value), _useState2 = _slicedToArray(_useState, 1), _id = _useState2[0]; var inputFilter = function inputFilter(value) { return items.filter(function (item) { var itemValue = _getLabel(item).toLowerCase(); if (ignoreSpecialChars) { itemValue = (0, _shared.normalizeChars)(itemValue); return itemValue.indexOf((0, _shared.normalizeChars)(value.toLowerCase())) > -1; } return itemValue.indexOf(value.toLowerCase()) > -1; }); }; return _react.default.createElement(_shared.FieldGroup, null, _react.default.createElement(_downshift.default, _extends({}, rest, { selectedItem: selectedItem, onChange: onChange, itemToString: _getLabel, stateReducer: _highlightedReducer, autocomplete: autocomplete }), function (_ref15) { var getRootProps = _ref15.getRootProps, getLabelProps = _ref15.getLabelProps, getInputProps = _ref15.getInputProps, getToggleButtonProps = _ref15.getToggleButtonProps, getItemProps = _ref15.getItemProps, inputValue = _ref15.inputValue, openMenu = _ref15.openMenu, isOpen = _ref15.isOpen; var filteredInput = isOpen ? inputFilter(inputValue) : []; return _react.default.createElement(DropContainer, _extends({ theme: theme }, getRootProps()), label && _react.default.createElement(_subComponents.InputLabel, _extends({}, getLabelProps(), { error: error, disabled: disabled, htmlFor: _id }), label, required && _react.default.createElement(_subComponents.RequiredMark, null, "*")), _react.default.createElement("input", getInputProps({ name: name, type: 'hidden' })), autocomplete ? _react.default.createElement(_react.default.Fragment, null, _react.default.createElement(DropContainer, { theme: theme }, _react.default.createElement(DropInput, _extends({}, getInputProps({ isOpen: isOpen, placeholder: placeholder, onClick: openMenu }), { style: { cursor: 'inherit' }, error: error, disabled: disabled, text: _buttonLabel, theme: theme, hasLabel: hasLabel, id: _id, autocomplete: autocomplete })), isOpen ? _react.default.createElement(InputArrowUp, { theme: theme }) : _react.default.createElement(InputArrowDown, { theme: theme })), filteredInput.length > 0 && _react.default.createElement(List, { items: filteredInput, theme: theme, selectedItem: selectedItem, getItemProps: getItemProps })) : _react.default.createElement(_react.default.Fragment, null, _react.default.createElement(DropInput, _extends({}, getToggleButtonProps(), { as: "button", isOpen: isOpen, disabled: disabled, error: error, helperText: helperText, text: _buttonLabel, theme: theme, hasLabel: hasLabel, id: _id }), _buttonLabel, isOpen ? _react.default.createElement(ArrowUp, { theme: theme }) : _react.default.createElement(ArrowDown, { theme: theme })), isOpen && _react.default.createElement(List, { items: items, theme: theme, selectedItem: selectedItem, getItemProps: getItemProps }))); }), helperText && _react.default.createElement(_subComponents.HelperText, null, helperText), error && _react.default.createElement(_subComponents.InputErrorMessage, null, error)); }; Dropdown.defaultProps = { autocomplete: false, disabled: false, required: false, error: '', id: '', name: '', label: '', placeholder: 'Select an option', selectedItem: null, helperText: '', items: [], onChange: function onChange() {}, theme: { colors: _theme.colors, spacing: _theme.spacing, baseFontSize: _theme.baseFontSize }, ignoreSpecialChars: false }; Dropdown.propTypes = { /** Displays the list with start typing */ autocomplete: _propTypes.default.bool, /** Disables component */ disabled: _propTypes.default.bool, /** Displays a mark to shows thats component is required */ required: _propTypes.default.bool, /** Displays an error message and changes border color to error color */ error: _propTypes.default.string, id: _propTypes.default.string, name: _propTypes.default.string, /** Displays a label text that describes the field */ label: _propTypes.default.string, placeholder: _propTypes.default.string, /** Receives the item of the list to be selected */ selectedItem: itemPropType, /** Displays a helper text below the dropdown */ helperText: _propTypes.default.string, onChange: _propTypes.default.func, /** A list of string or objects with value and label keys */ items: _propTypes.default.arrayOf(itemPropType), theme: _propTypes.default.shape({ colors: _propTypes.default.object, spacing: _propTypes.default.object, baseFontSize: _propTypes.default.number }), ignoreSpecialChars: _propTypes.default.bool }; var _default = Dropdown; exports.default = _default;