@shopify/polaris
Version:
Shopify’s product component library
208 lines (182 loc) • 5.42 kB
JavaScript
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 };