@mapbox/mr-ui
Version:
UI components for Mapbox projects
127 lines (126 loc) • 5.82 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = ControlSelect;
var _react = _interopRequireDefault(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _omit = _interopRequireDefault(require("../utils/omit"));
var _controlLabel = _interopRequireDefault(require("../control-label"));
var _controlWrapper = _interopRequireDefault(require("../control-wrapper"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _extends() { _extends = Object.assign ? Object.assign.bind() : 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); }
const propNames = ['id', 'options', 'value', 'onChange', 'optional', 'label', 'aside', 'disabled', 'validationError', 'themeControlSelect', 'themeControlSelectContainer', 'themeControlWrapper', 'themeLabel',
// Passed when used with the Form component
'initialValue', 'validator'];
function ControlSelect(_ref) {
let {
id,
onChange,
options,
value = '',
label,
optional = false,
aside,
disabled = false,
validationError,
themeControlSelectContainer = '',
themeControlSelect = '',
themeControlWrapper,
themeLabel,
...props
} = _ref;
const extraProps = (0, _omit.default)(props, propNames);
const selectProps = {
id,
disabled,
value,
className: `select ${themeControlSelect}`,
onChange: e => onChange(e.target.value, id),
'aria-required': optional ? false : true,
'data-testid': `${id}-select`
};
if (validationError) {
selectProps['aria-invalid'] = true;
}
const renderOptions = _ref2 => {
let {
label,
value,
disabled,
options
} = _ref2;
if (options) {
return /*#__PURE__*/_react.default.createElement("optgroup", {
key: label,
label: label
}, options.map(renderOptions));
} else {
return /*#__PURE__*/_react.default.createElement("option", {
disabled: disabled,
key: value,
value: value
}, label);
}
};
return /*#__PURE__*/_react.default.createElement(_controlWrapper.default, {
id: id,
themeControlWrapper: themeControlWrapper,
validationError: validationError
}, label && /*#__PURE__*/_react.default.createElement(_controlLabel.default, {
text: label,
id: id,
aside: aside,
optional: optional,
themeLabel: themeLabel
}), /*#__PURE__*/_react.default.createElement("div", {
className: `select-container ${themeControlSelectContainer}`
}, /*#__PURE__*/_react.default.createElement("select", _extends({}, selectProps, extraProps), options.map(renderOptions)), /*#__PURE__*/_react.default.createElement("div", {
className: "select-arrow"
})));
}
ControlSelect.propTypes = {
/** Identifying value for input element. */
id: _propTypes.default.string.isRequired,
/** An array of objects containing `label` `value` key value pairings to represent each option. An optional `disable` key can be provided to disable the selection of an indiviual `<option>`. If `value` is not present but an `options` array is provided containing the same `label` `value` key value pairings, options will be grouped within a `<optgroup>` element as defined by `label` child key. Note that each `label` value must be unique. */
options: _propTypes.default.arrayOf(_propTypes.default.shape({
label: _propTypes.default.string.isRequired,
value: (props, propName, componentName) => {
if (!props.value && typeof props.value !== 'string' && props.options === undefined) {
return new Error(`The prop "${propName}" is required in ${componentName} if a options array is not provided for select groups.`);
} else if (props.value && typeof props.value !== 'number' && typeof props.value !== 'string') {
return new Error(`${props.value} of type ${typeof props.value} supplied to ${componentName}, expected a number or string.`);
} else if (props.value !== undefined && props.options !== undefined) {
return new Error(`You've provided both an 'options' & 'value' key to one of your options object groups. Only 'options' will be used.`);
}
},
disabled: _propTypes.default.bool,
options: _propTypes.default.arrayOf(_propTypes.default.shape({
label: _propTypes.default.string.isRequired,
value: _propTypes.default.string,
disabled: _propTypes.default.bool
}))
})).isRequired,
/** Called during changes to the input element. */
onChange: _propTypes.default.func.isRequired,
/** Input value */
value: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]),
/** Value passed to the label element. */
label: _propTypes.default.string,
/** If provided the text, "(optional)" is appended to the value of the label element. */
optional: _propTypes.default.bool,
/** Additional content inserted alongside the label element. */
aside: _propTypes.default.node,
/** Pass disabled attribute */
disabled: _propTypes.default.bool,
/** If provided, the value of this propery displays as an error message. */
validationError: _propTypes.default.node,
/** Assembly classes to apply to the select element */
themeControlSelect: _propTypes.default.string,
/** Assembly classes to apply to the select container */
themeControlSelectContainer: _propTypes.default.string,
/** Assembly classes to apply to the control wrapper */
themeControlWrapper: _propTypes.default.string,
/** Assembly classes to apply to the label element */
themeLabel: _propTypes.default.string
};