UNPKG

jobiqo-cl

Version:

[![CircleCI](https://circleci.com/gh/jobiqo/jobiqo-cl.svg?style=svg&circle-token=5a24efa5b8bbc4879276123e77d0d3f35ca7144c)](https://circleci.com/gh/jobiqo/jobiqo-cl)

126 lines (120 loc) 6.05 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var React = require('react'); var React__default = _interopDefault(React); var styled = require('styled-components'); var styled__default = _interopDefault(styled); var index = require('../11-form-item/index.js'); var downshift_esm = require('../../../../../node_modules/downshift/dist/downshift.esm.js'); var matchSorter_esm = require('../../../../../node_modules/match-sorter/dist/match-sorter.esm.js'); var subElements = require('./sub-elements/sub-elements.js'); /** * @file index.tsx * * @fileoverview Renders a searcheable select component using the downshift library. */ const DownshiftInput = styled__default.input ` width: calc(100% - 0.5rem); word-wrap: break-word; outline: 0; white-space: normal; display: inline-block; box-shadow: none; transition: box-shadow 0.1s ease, width 0.1s ease; font-size: ${props => props.theme.select.fontSize}; margin: ${props => props.theme.select.margin}; padding: ${props => props.theme.select.padding}; line-height: ${props => props.theme.select.height}; border-radius: ${props => props.theme.select.borderRadius}; border-width: ${props => props.theme.select.borderWidth}; border-top-width: ${props => props.theme.select.borderTopWidth}; border-left-width: ${props => props.theme.select.borderLeftWidth}; border-right-width: ${props => props.theme.select.borderRightWidth}; border-bottom-width: ${props => props.theme.select.borderBottomWidth}; border-style: ${props => props.theme.select.borderStyle}; border-color: ${props => props.theme.select.borderColor}; background: ${props => props.theme.select.background}; ${({ isOpen }) => isOpen && ` border-bottom-left-radius: 0; border-bottom-right-radius: 0; `}; &:focus, &:focus-within, &:active { outline: 0; border-color: ${props => props.theme.colors.focusRingColor}; box-shadow: ${props => props.theme.select.focus.boxShadowType}, ${props => `${props.theme.select.focus.boxShadowVals} ${props.theme.colors.focusRingColor}`}; } `; const ControlButton = styled__default.div ` background-color: transparent; border: none; position: absolute; cursor: pointer; -webkit-appearance: none; right: ${props => props.theme.select.controlButton.position.right}; top: ${props => props.theme.select.controlButton.position.top}; `; const parentStyle = { maxWidth: '250px', position: 'relative' }; const WrapDiv = styled__default.div ` position: relative; display: flex; width: 100%; `; const ArrowIcon = ({ isOpen }) => { return (React__default.createElement("svg", { viewBox: "0 0 20 20", preserveAspectRatio: "none", width: 16, fill: "transparent", stroke: "#979797", strokeWidth: "1.1px", transform: isOpen ? 'rotate(180)' : null }, React__default.createElement("path", { d: "M1,6 L10,15 L19,6" }))); }; const XIcon = () => { return (React__default.createElement("svg", { viewBox: "0 0 20 20", preserveAspectRatio: "none", width: 12, fill: "transparent", stroke: "#979797", strokeWidth: "1.1px" }, React__default.createElement("path", { d: "M1,1 L19,19" }), React__default.createElement("path", { d: "M19,1 L1,19" }))); }; function advancedFilter(theItems, value) { return matchSorter_esm.default(theItems, value, { keys: ['name', 'code'] }); } /** * Filters for the id that was selected. * * @param {SelectItem} items * The whole value list. * @param {string} value * The code that was passed as default value * * @return {string} * The value the pass to the input as default value. */ const getDefaultValue = (items, value) => { const filteredItem = items.filter(i => i.code === value); if (filteredItem.length > 0) { return filteredItem[0]; } return null; }; /** * A select widget that uses downshift internally. Renders a select where the user can search items. * Focuses on accessibility. */ const Select = ({ id, items = [], label, required, placeholder = 'Search an item', onChange, onBlur, selectedValue }) => (React__default.createElement(index.FormItem, null, label && React__default.createElement(index.FormLabel, { htmlFor: id }, label), React__default.createElement(downshift_esm.default, { itemToString: i => (i ? i.name : ''), onChange: selection => onChange(selection), initialSelectedItem: getDefaultValue(items, selectedValue) }, ({ highlightedIndex, isOpen, clearSelection, inputValue, selectedItem, getToggleButtonProps, getInputProps, getItemProps }) => (React__default.createElement("div", { style: parentStyle }, React__default.createElement(WrapDiv, null, React__default.createElement(DownshiftInput, Object.assign({}, getInputProps({ onBlur }), { isOpen, placeholder }, { id: id, "data-testid": "jobiqo-cl-select-input", required: required })), selectedItem ? (React__default.createElement(ControlButton, { onClick: clearSelection, "aria-label": "clear selection", "data-testid": "jobiqo-cl-select-clear-button" }, React__default.createElement(XIcon, null))) : (React__default.createElement(ControlButton, Object.assign({}, getToggleButtonProps({}), { "data-testid": "jobiqo-cl-select-toggle-button" }), React__default.createElement(ArrowIcon, { isOpen: isOpen })))), isOpen && (React__default.createElement(subElements.Menu, null, (inputValue ? advancedFilter(items, inputValue) : items).map((item, index) => (React__default.createElement(subElements.Item, Object.assign({ key: item.code }, getItemProps({ item, isSelected: selectedItem === item }), { isActive: highlightedIndex === index, "data-testid": `downshift-item-${index}` }), item.name)))))))))); exports.ControlButton = ControlButton; exports.DownshiftInput = DownshiftInput; exports.Select = Select;