UNPKG

@shopify/polaris

Version:

Shopify’s product component library

208 lines (182 loc) • 5.42 kB
import { objectWithoutProperties as _objectWithoutProperties } from '../../_virtual/_rollupPluginBabelHelpers.js'; import React$1 from 'react'; import { useFeatures } from '../../utilities/features/hooks.js'; import { useUniqueId } from '../../utilities/unique-id/hooks.js'; import { classNames } from '../../utilities/css.js'; import { SelectMinor } from '@shopify/polaris-icons'; import { Icon as Icon$1 } from '../Icon/Icon.js'; import { Labelled as Labelled$1, helpTextID } from '../Labelled/Labelled.js'; import styles from './Select.scss.js'; var PLACEHOLDER_VALUE = ''; var _ref = /*#__PURE__*/React$1.createElement(Icon$1, { source: SelectMinor }); function Select({ options: optionsProp, label, labelAction, labelHidden: labelHiddenProp, labelInline, disabled, helpText, placeholder, id: idProp, name, value = PLACEHOLDER_VALUE, error, onChange, onFocus, onBlur }) { var id = useUniqueId('Select', idProp); var labelHidden = labelInline ? true : labelHiddenProp; var { newDesignLanguage } = useFeatures(); var className = classNames(styles.Select, error && styles.error, disabled && styles.disabled, newDesignLanguage && styles.newDesignLanguage); var handleChange = onChange ? event => onChange(event.currentTarget.value, id) : undefined; var describedBy = []; if (helpText) { describedBy.push(helpTextID(id)); } if (error) { describedBy.push("".concat(id, "Error")); } var options = optionsProp || []; var normalizedOptions = options.map(normalizeOption); if (placeholder) { normalizedOptions = [{ label: placeholder, value: PLACEHOLDER_VALUE, disabled: true }, ...normalizedOptions]; } var inlineLabelMarkup = labelInline && /*#__PURE__*/React$1.createElement("span", { className: styles.InlineLabel }, label); var selectedOption = getSelectedOption(normalizedOptions, value); var prefixMarkup = selectedOption.prefix && /*#__PURE__*/React$1.createElement("div", { className: styles.Prefix }, selectedOption.prefix); var contentMarkup = /*#__PURE__*/React$1.createElement("div", { className: styles.Content, "aria-hidden": true, "aria-disabled": disabled }, inlineLabelMarkup, prefixMarkup, /*#__PURE__*/React$1.createElement("span", { className: styles.SelectedOption }, selectedOption.label), /*#__PURE__*/React$1.createElement("span", { className: styles.Icon }, _ref)); var optionsMarkup = normalizedOptions.map(renderOption); return /*#__PURE__*/React$1.createElement(Labelled$1, { id: id, label: label, error: error, action: labelAction, labelHidden: labelHidden, helpText: helpText }, /*#__PURE__*/React$1.createElement("div", { className: className }, /*#__PURE__*/React$1.createElement("select", { id: id, name: name, value: value, className: styles.Input, disabled: disabled, onFocus: onFocus, onBlur: onBlur, onChange: handleChange, "aria-invalid": Boolean(error), "aria-describedby": describedBy.length ? describedBy.join(' ') : undefined }, optionsMarkup), contentMarkup, /*#__PURE__*/React$1.createElement("div", { className: styles.Backdrop }))); } function isString(option) { return typeof option === 'string'; } function isGroup(option) { return typeof option === 'object' && 'options' in option && option.options != null; } function normalizeStringOption(option) { return { label: option, value: option }; } /** * Converts a string option (and each string option in a Group) into * an Option object. */ function normalizeOption(option) { if (isString(option)) { return normalizeStringOption(option); } else if (isGroup(option)) { var { title, options } = option; return { title, options: options.map(option => { return isString(option) ? normalizeStringOption(option) : option; }) }; } return option; } /** * Gets the text to display in the UI, for the currently selected option */ function getSelectedOption(options, value) { var flatOptions = flattenOptions(options); var selectedOption = flatOptions.find(option => value === option.value); if (selectedOption === undefined) { // Get the first visible option (not the hidden placeholder) selectedOption = flatOptions.find(option => !option.hidden); } return selectedOption || { value: '', label: '' }; } /** * Ungroups an options array */ function flattenOptions(options) { var flatOptions = []; options.forEach(optionOrGroup => { if (isGroup(optionOrGroup)) { flatOptions = flatOptions.concat(optionOrGroup.options); } else { flatOptions.push(optionOrGroup); } }); return flatOptions; } function renderSingleOption(option) { var { value, label, prefix: _prefix } = option, rest = _objectWithoutProperties(option, ["value", "label", "prefix"]); return /*#__PURE__*/React$1.createElement("option", Object.assign({ key: value, value: value }, rest), label); } function renderOption(optionOrGroup) { if (isGroup(optionOrGroup)) { var { title, options } = optionOrGroup; return /*#__PURE__*/React$1.createElement("optgroup", { label: title, key: title }, options.map(renderSingleOption)); } return renderSingleOption(optionOrGroup); } export { Select };