@mskcc/carbon-react
Version:
Carbon react components for the MSKCC DSM
243 lines (235 loc) • 8.73 kB
JavaScript
/**
* MSKCC 2021, 2024
*/
;
Object.defineProperty(exports, '__esModule', { value: true });
var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
var PropTypes = require('prop-types');
var React = require('react');
var cx = require('classnames');
var deprecate = require('../../prop-types/deprecate.js');
var usePrefix = require('../../internal/usePrefix.js');
require('../FluidForm/FluidForm.js');
var FormContext = require('../FluidForm/FormContext.js');
var setupGetInstanceId = require('../../tools/setupGetInstanceId.js');
var MskIcon = require('../Icon/MskIcon.js');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
var cx__default = /*#__PURE__*/_interopDefaultLegacy(cx);
const getInstanceId = setupGetInstanceId["default"]();
const Select = /*#__PURE__*/React__default["default"].forwardRef(function Select(_ref, ref) {
let {
className,
id,
inline = false,
labelText,
disabled = false,
children,
noLabel = false,
hideLabel = false,
invalid = false,
invalidText = '',
helperText = '',
light = false,
readOnly,
size,
warn = false,
warnText,
value,
placeholder,
...other
} = _ref;
const prefix = usePrefix.usePrefix();
const {
isFluid
} = React.useContext(FormContext.FormContext);
const [isFocused, setIsFocused] = React.useState(false);
const {
current: selectInstanceId
} = React.useRef(getInstanceId());
const selectClasses = cx__default["default"]({
[`${prefix}--select`]: true,
[`${prefix}--select--inline`]: inline,
[`${prefix}--select--light`]: light,
[`${prefix}--select--invalid`]: invalid,
[`${prefix}--select--disabled`]: disabled,
[`${prefix}--select--readonly`]: readOnly,
[`${prefix}--select--warning`]: warn,
[`${prefix}--select--fluid--invalid`]: isFluid && invalid,
[`${prefix}--select--fluid--focus`]: isFluid && isFocused
});
const labelClasses = cx__default["default"](`${prefix}--label`, {
[`${prefix}--visually-hidden`]: hideLabel,
[`${prefix}--label--disabled`]: disabled
});
const inputClasses = cx__default["default"]({
[`${prefix}--select-input`]: true,
[`${prefix}--select-input--${size}`]: size
});
const errorId = `${id}-error-msg`;
const errorText = invalid ? invalidText : warn ? warnText : null;
const error = invalid || warn ? /*#__PURE__*/React__default["default"].createElement("div", {
className: `msk-validation-msg`
}, /*#__PURE__*/React__default["default"].createElement("span", {
className: `msk-validation-msg--icon msk-icon`
}, invalid ? 'error' : 'warning'), /*#__PURE__*/React__default["default"].createElement("div", {
id: errorId,
className: `${prefix}--form-requirement`
}, errorText)) : null;
const helperTextClasses = cx__default["default"](`${prefix}--form__helper-text`, {
[`${prefix}--form__helper-text--disabled`]: disabled
});
const helperId = helperText ? `select-helper-text-${selectInstanceId}` : undefined;
const helper = helperText ? /*#__PURE__*/React__default["default"].createElement("div", {
id: helperId,
className: helperTextClasses
}, helperText) : null;
const ariaProps = {
...(invalid ? {
'aria-describedby': errorId
} : {}),
...(!inline && !isFluid || invalid ? {} : {
'aria-describedby': helperId
})
};
const handleFocus = evt => {
setIsFocused(evt.type === 'focus');
};
const readOnlyEventHandlers = {
onMouseDown: evt => {
if (readOnly) {
evt.preventDefault();
evt.currentTarget.focus();
}
},
onKeyDown: evt => {
const selectAccessKeys = ['ArrowDown', 'ArrowUp', ' '];
if (readOnly && selectAccessKeys.includes(evt.key)) {
evt.preventDefault();
}
}
};
const input = /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement("select", _rollupPluginBabelHelpers["extends"]({}, other, ariaProps, {
id: id,
className: inputClasses,
disabled: disabled,
"aria-invalid": invalid,
"aria-readonly": readOnly,
value: value,
placeholder: placeholder
}, readOnlyEventHandlers, {
ref: ref
}), children), /*#__PURE__*/React__default["default"].createElement(MskIcon.Icon, {
icon: "expand_more",
className: `${prefix}--select__arrow`
}));
return /*#__PURE__*/React__default["default"].createElement("div", {
className: cx__default["default"](`${prefix}--form-item`, className)
}, /*#__PURE__*/React__default["default"].createElement("div", {
className: selectClasses
}, !noLabel && /*#__PURE__*/React__default["default"].createElement("label", {
htmlFor: id,
className: labelClasses
}, labelText), inline ? /*#__PURE__*/React__default["default"].createElement("div", {
className: `${prefix}--select-input--inline__wrapper`
}, /*#__PURE__*/React__default["default"].createElement("div", {
className: `${prefix}--select-input__wrapper`,
"data-invalid": invalid || null
}, input), error) : /*#__PURE__*/React__default["default"].createElement("div", {
className: `${prefix}--select-input__wrapper`,
"data-invalid": invalid || null,
onFocus: handleFocus,
onBlur: handleFocus
}, input, isFluid && /*#__PURE__*/React__default["default"].createElement("hr", {
className: `${prefix}--select__divider`
}), isFluid && error ? error : null), !inline && !isFluid && error ? error : helper));
});
Select.displayName = 'Select';
Select.propTypes = {
/**
* Provide the contents of your Select
*/
children: PropTypes__default["default"].node,
/**
* Specify an optional className to be applied to the node containing the label and the select box
*/
className: PropTypes__default["default"].string,
/**
* Optionally provide the default value of the `<select>`
*/
defaultValue: PropTypes__default["default"].any,
/**
* Specify whether the control is disabled
*/
disabled: PropTypes__default["default"].bool,
/**
* Provide text that is used alongside the control label for additional help
*/
helperText: PropTypes__default["default"].node,
/**
* Specify whether the label should be hidden, or not
*/
hideLabel: PropTypes__default["default"].bool,
/**
* Specify a custom `id` for the `<select>`
*/
id: PropTypes__default["default"].string.isRequired,
/**
* Specify whether you want the inline version of this control
*/
inline: PropTypes__default["default"].bool,
/**
* Specify if the currently value is invalid.
*/
invalid: PropTypes__default["default"].bool,
/**
* Message which is displayed if the value is invalid.
*/
invalidText: PropTypes__default["default"].node,
/**
* Provide label text to be read by screen readers when interacting with the
* control
*/
labelText: PropTypes__default["default"].node,
/**
* `true` to use the light version. For use on $ui-01 backgrounds only.
* Don't use this to make tile background color same as container background color.
*/
light: deprecate["default"](PropTypes__default["default"].bool, 'The `light` prop for `Select` is no longer needed and has ' + 'been deprecated in v11 in favor of the new `Layer` component. It will be moved in the next major release.'),
/**
* Reserved for use with <Pagination> component. Will not render a label for the
* select since Pagination renders one for us.
*/
noLabel: PropTypes__default["default"].bool,
/**
* Provide an optional `onChange` hook that is called each time the value of
* the underlying `<input>` changes
*/
onChange: PropTypes__default["default"].func,
/**
* Whether the select should be read-only
*/
readOnly: PropTypes__default["default"].bool,
/**
* Specify the size of the Select Input.
*/
size: PropTypes__default["default"].oneOf(['sm', 'md', 'lg']),
/**
* Specify whether the control is currently in warning state
*/
warn: PropTypes__default["default"].bool,
/**
* Provide the text that is displayed when the control is in warning state
*/
warnText: PropTypes__default["default"].node,
/**
* Specify the value of the select input.
*/
value: PropTypes__default["default"].oneOfType([PropTypes__default["default"].string, PropTypes__default["default"].number]),
/**
* Placeholder for the select input.
*/
placeholder: PropTypes__default["default"].string
};
exports["default"] = Select;