UNPKG

@helpscout/hsds-react

Version:

React component library for Help Scout's Design System

300 lines (233 loc) 10.1 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.default = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose")); var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _classnames = _interopRequireDefault(require("classnames")); var _lodash = _interopRequireDefault(require("lodash.isnil")); var _lodash2 = _interopRequireDefault(require("lodash.get")); var _getValidProps = _interopRequireDefault(require("@helpscout/react-utils/dist/getValidProps")); var _ChoiceGroup = _interopRequireDefault(require("./ChoiceGroup.Context")); var _FormGroup = _interopRequireDefault(require("../FormGroup")); var _Context = _interopRequireDefault(require("../FormLabel/Context")); var _id = require("../../utilities/id"); var _ChoiceGroup2 = require("./ChoiceGroup.css"); var _jsxRuntime = require("react/jsx-runtime"); function noop() {} var uniqueID = (0, _id.createUniqueIDFactory)('ChoiceGroup'); var ChoiceGroup = /*#__PURE__*/function (_React$Component) { (0, _inheritsLoose2.default)(ChoiceGroup, _React$Component); function ChoiceGroup(_props) { var _this; _this = _React$Component.call(this, _props) || this; _this.getMultiSelectValue = function (value, checked) { var selectedValue = _this.state.selectedValue; var valueIndex = selectedValue.indexOf(value); if (valueIndex < 0 && checked) { return selectedValue.concat(value); } return selectedValue.filter(function (v) { return v !== value; }); }; _this.getSingleSelectValue = function (value, checked) { return checked ? value : []; }; _this.getSelectLimitState = function (props, selectedValue) { var multiSelect = props.multiSelect, multiSelectLimit = props.multiSelectLimit; return multiSelect && !(0, _lodash.default)(multiSelectLimit) && multiSelectLimit > 0 && selectedValue.length === multiSelectLimit; }; _this.handleOnChange = function (value, checked) { var _this$props = _this.props, multiSelect = _this$props.multiSelect, onChange = _this$props.onChange; var selectedValue = multiSelect ? _this.getMultiSelectValue(value, checked) : _this.getSingleSelectValue(value, checked); var limitReached = _this.getSelectLimitState(_this.props, selectedValue); _this.setState({ selectedValue: selectedValue, limitReached: limitReached }); onChange(selectedValue); }; _this.handleOnEnter = function (value, checked) { var _this$props2 = _this.props, multiSelect = _this$props2.multiSelect, onEnter = _this$props2.onEnter, onChange = _this$props2.onChange; var selectedValue = multiSelect ? _this.getMultiSelectValue(value, checked) : _this.getSingleSelectValue(value, checked); var limitReached = _this.getSelectLimitState(_this.props, selectedValue); _this.setState({ selectedValue: selectedValue, limitReached: limitReached }); onEnter(selectedValue); onChange(selectedValue); }; _this.getContextProps = function () { var _this$props3 = _this.props, onBlur = _this$props3.onBlur, onFocus = _this$props3.onFocus, name = _this$props3.name; var selectedValue = _this.state.selectedValue; return { onBlur: onBlur, onChange: _this.handleOnChange, onEnter: _this.handleOnEnter, onFocus: onFocus, name: name, selectedValue: selectedValue }; }; _this.getChildrenMarkup = function () { var _this$props4 = _this.props, isResponsive = _this$props4.isResponsive, choiceMaxWidth = _this$props4.choiceMaxWidth, choiceHeight = _this$props4.choiceHeight, children = _this$props4.children; var _this$state = _this.state, id = _this$state.id, selectedValue = _this$state.selectedValue, limitReached = _this$state.limitReached; return children && _react.default.Children.map(children, function (child, index) { var key = (0, _lodash2.default)(child, 'props.id') || id + "-" + index; var isSelected = selectedValue.includes(child.props.value); var disabled = (0, _lodash2.default)(child, 'props.disabled') || limitReached && !isSelected; var clone = /*#__PURE__*/_react.default.isValidElement(child) ? /*#__PURE__*/_react.default.cloneElement(child, { checked: isSelected, disabled: disabled, maxWidth: choiceMaxWidth, height: choiceHeight }) : child; return /*#__PURE__*/(0, _jsxRuntime.jsx)(_FormGroup.default.Choice, { isResponsive: isResponsive, children: clone }, key); }); }; _this.getIdFromContextProps = function (props) { return props.id || _this.state.id; }; var _selectedValue = _this.getInitialSelectedValue(_props); _this.state = { id: uniqueID(), selectedValue: _selectedValue, limitReached: _this.getSelectLimitState(_props, _selectedValue) }; return _this; } var _proto = ChoiceGroup.prototype; _proto.UNSAFE_componentWillReceiveProps = function UNSAFE_componentWillReceiveProps(nextProps) { if (nextProps.value !== this.props.value) { this.setState({ selectedValue: this.getInitialSelectedValue(nextProps) }); } }; _proto.getInitialSelectedValue = function getInitialSelectedValue(props) { var value = props.value, multiSelect = props.multiSelect, multiSelectLimit = props.multiSelectLimit; var selectedValue = value ? [].concat(value) : []; /** When multiSelect is not enabled and we get a value prop with more * than one item, take the first and ignore the rest */ if (!multiSelect && selectedValue.length > 1) { selectedValue = selectedValue[0]; } /** When multiselec is enabled and we have a limit, make sure * we return a selectedValue array with no more items than said limit */ if (!(0, _lodash.default)(multiSelectLimit) && multiSelectLimit > 0) { selectedValue = selectedValue.slice(0, multiSelectLimit); } return selectedValue; }; _proto.render = function render() { var _this2 = this; var _this$props5 = this.props, align = _this$props5.align, className = _this$props5.className, children = _this$props5.children, isResponsive = _this$props5.isResponsive, onBlur = _this$props5.onBlur, onChange = _this$props5.onChange, onFocus = _this$props5.onFocus, onEnter = _this$props5.onEnter, multiSelect = _this$props5.multiSelect, name = _this$props5.name, rest = (0, _objectWithoutPropertiesLoose2.default)(_this$props5, ["align", "className", "children", "isResponsive", "onBlur", "onChange", "onFocus", "onEnter", "multiSelect", "name"]); var _this$state2 = this.state, limitReached = _this$state2.limitReached, selectedValue = _this$state2.selectedValue; var componentClassName = (0, _classnames.default)('c-ChoiceGroup', align && "is-align-" + align, multiSelect && 'is-multi-select', isResponsive && 'is-responsive', limitReached && 'limit-reached', hasSelectedValue(selectedValue) && 'has-selected-value', className); var childrenMarkup = this.getChildrenMarkup(); return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Context.default.Consumer, { children: function children(props) { return /*#__PURE__*/(0, _jsxRuntime.jsx)(_ChoiceGroup.default.Provider, { value: _this2.getContextProps(), children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ChoiceGroup2.ChoiceGroupUI, (0, _extends2.default)({}, (0, _getValidProps.default)(rest), { className: componentClassName, id: _this2.getIdFromContextProps(props), children: childrenMarkup })) }); } }); }; return ChoiceGroup; }(_react.default.Component); function hasSelectedValue(value) { if (Array.isArray(value)) { return value.length > 0; } if (!(0, _lodash.default)(value)) { return true; } return false; } ChoiceGroup.defaultProps = { align: 'vertical', 'data-cy': 'ChoiceGroup', isResponsive: false, onBlur: noop, onChange: noop, onFocus: noop, onEnter: noop, multiSelect: true }; ChoiceGroup.propTypes = { align: _propTypes.default.oneOf(['horizontal', 'vertical']), /** Custom class names to be added to the component. */ className: _propTypes.default.string, /** Set the max-width for the child `Choice` components. */ choiceMaxWidth: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]), /** Disable the input. */ disabled: _propTypes.default.bool, /** Enables responsive styling. */ isResponsive: _propTypes.default.bool, /** Allow multiple choice selection */ multiSelect: _propTypes.default.bool, /** Limit of selections allowed when multiSelect enabled */ multiSelectLimit: _propTypes.default.number, /** Name for the inputs. */ name: _propTypes.default.string, /** Callback when an input is blurred. */ onBlur: _propTypes.default.func, /** Callback when an input value is changed. */ onChange: _propTypes.default.func, /** Callback when an input is focused. */ onFocus: _propTypes.default.func, /** Callback when an enter or espace is pressed. */ onEnter: _propTypes.default.func, /** The default value of input group. */ value: _propTypes.default.any, /** Data attr for Cypress tests. */ 'data-cy': _propTypes.default.string }; var _default = ChoiceGroup; exports.default = _default;