UNPKG

wix-style-react

Version:
497 lines (378 loc) 21.2 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _InputWithOptions2 = _interopRequireDefault(require("../InputWithOptions/InputWithOptions")); var _Input = _interopRequireDefault(require("../Input")); var _MultiSelectCheckboxSt = require("./MultiSelectCheckbox.st.css"); var _ListItemSelect = require("../ListItemSelect"); var _ListItemSection = require("../ListItemSection"); var _DropdownLayout = require("../DropdownLayout/DropdownLayout"); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } var OPEN_DROPDOWN_CHARS = ['Enter', 'ArrowDown', 'Space', ' ']; var MultiSelectCheckbox = /*#__PURE__*/function (_InputWithOptions) { (0, _inherits2["default"])(MultiSelectCheckbox, _InputWithOptions); var _super = _createSuper(MultiSelectCheckbox); function MultiSelectCheckbox() { (0, _classCallCheck2["default"])(this, MultiSelectCheckbox); return _super.apply(this, arguments); } (0, _createClass2["default"])(MultiSelectCheckbox, [{ key: "createOptions", value: function createOptions(options) { var _this = this; return options.map(function (option) { if (_this._isUsingCustomRenderFunction(option)) { return _this._patchOptionWithSelectionMechanism(option); } else if (_this._isDivider(option)) { return (0, _ListItemSection.listItemSectionBuilder)(_objectSpread({ type: 'divider' }, option)); } else { var builder = (0, _ListItemSelect.listItemSelectBuilder)(_objectSpread(_objectSpread({}, option), {}, { checkbox: true, title: option.value, label: option.label })); return _this._patchOptionWithSelectionMechanism(builder); } }); } }, { key: "_patchOptionWithSelectionMechanism", value: function _patchOptionWithSelectionMechanism(option) { var _this2 = this; var _value = option.value; return _objectSpread(_objectSpread({}, option), {}, { value: function value(props) { return _value(_objectSpread(_objectSpread({}, props), {}, { selected: _this2.isSelectedId(option.id) })); } }); } }, { key: "_isUsingCustomRenderFunction", value: function _isUsingCustomRenderFunction(_ref) { var value = _ref.value; return typeof value === 'function'; } }, { key: "_isDivider", value: function _isDivider(_ref2) { var value = _ref2.value; return value === '-'; } }, { key: "isSelectedId", value: function isSelectedId(optionId) { return this.props.selectedOptions.indexOf(optionId) !== -1; } }, { key: "dropdownAdditionalProps", value: function dropdownAdditionalProps() { return { options: this.createOptions(this.props.options), closeOnSelect: false, selectedHighlight: false }; } }, { key: "selectedOptionsToText", value: function selectedOptionsToText() { var _this3 = this; return this.props.selectedOptions.map(function (selectedOption) { return _this3.props.options.find(function (option) { return option.id === selectedOption; }); }).filter(function (selectedOption) { return selectedOption; }).map(this.props.valueParser).join(this.props.delimiter); } }, { key: "inputAdditionalProps", value: function inputAdditionalProps() { var value = this.props.value !== undefined ? this.props.value : this.selectedOptionsToText(); return { readOnly: false, disableEditing: true, inputElement: /*#__PURE__*/_react["default"].createElement(_Input["default"], { textOverflow: "ellipsis", disableEditing: true }), value: value }; } }, { key: "inputClasses", value: function inputClasses() { return _MultiSelectCheckboxSt.classes.showPointer; } }, { key: "_onSelect", value: function _onSelect(option) { this.showOptions(); if (this.closeOnSelect()) { this.setState({ showOptions: false }); } // The option object is not the original since it was injected a checkbox var originalOption = this.props.options.find(function (op) { return option.id === op.id; }); if (this.isSelectedId(originalOption.id)) { this.props.onDeselect && this.props.onDeselect(originalOption.id, originalOption); } else { this.props.onSelect && this.props.onSelect(originalOption.id, originalOption); } } }, { key: "_onInputClicked", value: function _onInputClicked(event) { this.state.showOptions ? this.hideOptions() : this.showOptions(); if (this.props.onInputClicked) { this.props.onInputClicked(event); } } }, { key: "_onKeyDown", value: function _onKeyDown(event) { if (OPEN_DROPDOWN_CHARS.includes(event.key)) { event.preventDefault(); this.showOptions(); } this.dropdownLayout && this.dropdownLayout._onKeyDown(event); } }, { key: "_onFocus", value: function _onFocus(e) { if (this.props.disabled) { return; } this._focused = true; this.setState({ isEditing: false }); if (this.props.onFocus) { this.props.onFocus(e); } } }]); return MultiSelectCheckbox; }(_InputWithOptions2["default"]); MultiSelectCheckbox.displayName = 'MultiSelectCheckbox'; MultiSelectCheckbox.propTypes = { /** Associate a control with the regions that it controls */ ariaControls: _propTypes["default"].string, /** Associate a region with its descriptions. Similar to aria-controls but instead associating descriptions to the region and description identifiers are separated with a space. */ ariaDescribedby: _propTypes["default"].string, /** Define a string that labels the current element in case where a text label is not visible on the screen */ ariaLabel: _propTypes["default"].string, /** Focus the element on mount (standard React input autoFocus) */ autoFocus: _propTypes["default"].bool, /** Select the entire text of the element on focus (standard React input autoSelect) */ autoSelect: _propTypes["default"].bool, /** Control the border style of input */ border: _propTypes["default"].oneOf(['standard', 'round', 'bottomLine']), /** Specifies a CSS class name to be appended to the component’s root element */ className: _propTypes["default"].string, /** Displays clear button (X) on a non-empty input */ clearButton: _propTypes["default"].bool, /** Closes `DropdownLayout` when option is selected */ closeOnSelect: _propTypes["default"].bool, /** Render a custom input component instead of the default html input tag */ customInput: _propTypes["default"].node, /** Applies a data-hook HTML attribute that can be used in the tests */ dataHook: _propTypes["default"].string, /** Sets a default value for those who want to use this component un-controlled */ defaultValue: _propTypes["default"].string, /** Specifies the delimiter symbol to be displayed between the selected options in the input */ delimiter: _propTypes["default"].string, /** Specifies whether input should be disabled or not */ disabled: _propTypes["default"].bool, /** Restricts input editing */ disableEditing: _propTypes["default"].bool, /** Sets the offset of the dropdown from the left in pixels */ dropdownOffsetLeft: _propTypes["default"].string, /** Sets the width of the dropdown in pixels */ dropdownWidth: _propTypes["default"].string, /** Adds a fixed footer container at the bottom of options list in `<DropdownLayout/>` */ fixedFooter: _propTypes["default"].node, /** Adds a fixed header container at the top of options list in `<DropdownLayout/>` */ fixedHeader: _propTypes["default"].node, /** Highlights and scrolls view to the specified option when dropdown layout is opened. It does not select the specified option. */ focusOnOption: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]), /** Scrolls view to the selected option when dropdown layout is opened */ focusOnSelectedOption: _propTypes["default"].bool, /** USED FOR TESTING - forces focus state on the input */ forceFocus: _propTypes["default"].bool, /** USED FOR TESTING - forces hover state on the input */ forceHover: _propTypes["default"].bool, /** Specifies whether there are more items to be loaded */ hasMore: _propTypes["default"].bool, /** Specifies whether status suffix should be hidden */ hideStatusSuffix: _propTypes["default"].bool, /** Highlight word parts that match search criteria in bold */ highlight: _propTypes["default"].bool, /** Assigns an unique identifier for the root element */ id: _propTypes["default"].string, /** Specifies whether `<DropdownLayout/>` is in a container component. If true, some styles such as shadows, positioning and padding will be added to the component `contentContainer`. */ inContainer: _propTypes["default"].bool, /** Specifies whether lazy loading of the dropdown layout items is enabled */ infiniteScroll: _propTypes["default"].bool, /** Allows to render a custom input component instead of the default `<Input/>` */ inputElement: _propTypes["default"].element, /** Defines a callback function which is called on a request to render more list items */ loadMore: _propTypes["default"].func, /** Sets the default hover behavior: * - `false` - no initially hovered list item * - `true` - hover first selectable option * - any `number/string` specify the id of an option to be hovered */ markedOption: _propTypes["default"].oneOfType([_propTypes["default"].bool, _propTypes["default"].string, _propTypes["default"].number]), /** Sets a maximum value of an input. Similar to HTML5 max attribute. */ max: _propTypes["default"].number, /** Sets the maximum height of the `dropdownLayout` in pixels */ maxHeightPixels: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]), /** Sets the maximum number of characters that can be entered into a field */ maxLength: _propTypes["default"].number, /** Specifies whether input should have a dropdown menu arrow on the right side */ menuArrow: _propTypes["default"].bool, /** Sets a minimum value of an input. Similar to HTML5 min attribute. */ min: _propTypes["default"].number, /** Sets the minimum width of `dropdownLayout` in pixels */ minWidthPixels: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]), /** Reference element data when a form is submitted */ name: _propTypes["default"].string, /** Specifies whether input shouldn’t have rounded corners on its left */ noLeftBorderRadius: _propTypes["default"].bool, /** Specifies whether input shouldn’t have rounded corners on its right */ noRightBorderRadius: _propTypes["default"].bool, /** Defines a standard input `onBlur` callback */ onBlur: _propTypes["default"].func, /** Displays clear button (X) on a non-empty input and calls a callback function with no arguments */ onClear: _propTypes["default"].func, /** Defines a callback function which is called whenever the user presses the escape key */ onClose: _propTypes["default"].func, /** Defines a callback function called on `compositionstart`/`compositionend` events */ onCompositionChange: _propTypes["default"].func, /** Defines a callback function called on option deselect. Function receives the id of the unselected option as the first argument, and the actual option object as the second argument. */ onDeselect: _propTypes["default"].func, /** Defines a callback handler that is called when user presses -enter- */ onEnterPressed: _propTypes["default"].func, /** Defines a callback handler that is called when user presses -escape- */ onEscapePressed: _propTypes["default"].func, /** Defines a standard input `onFocus` callback */ onFocus: _propTypes["default"].func, /** Defines a standard input `onClick` callback. */ onInputClicked: _propTypes["default"].func, /** Defines a standard input `onKeyDown` callback */ onKeyDown: _propTypes["default"].func, /** Defines a standard input `onKeyUp` callback */ onKeyUp: _propTypes["default"].func, /** Defines a callback function which is called when user performs a submit action. Submit action triggers are: * "Enter", "Tab", [typing any defined delimiters], paste action. * `onManuallyInput(values: Array<string>): void` - the array of strings is the result of splitting the input value by the given delimiters. */ onManuallyInput: _propTypes["default"].func, /** Defines a callback function which is called whenever the user enters dropdown layout with the mouse cursor */ onMouseEnter: _propTypes["default"].func, /** Defines a callback function which is called whenever the user exits from dropdown layout with a mouse cursor */ onMouseLeave: _propTypes["default"].func, /** Defines a callback function which is called whenever an option becomes focused (hovered/active). Receives the relevant option object from the original `props.options` array. */ onOptionMarked: _propTypes["default"].func, /** Defines a callback function which is called when options dropdown is hidden */ onOptionsHide: _propTypes["default"].func, /** Defines a callback function which is called when options dropdown is shown */ onOptionsShow: _propTypes["default"].func, /** Defines a callback handler that is called when user pastes text from a clipboard (using mouse or keyboard shortcut) */ onPaste: _propTypes["default"].func, /** Defines a callback function which is called whenever user selects a different option in the list */ onSelect: _propTypes["default"].func, /** Array of objects: * - `id <string / number>` *required*: the id of the option, should be unique; * - value `<function / string / node>` *required*: can be a string, react element or a builder function; * - disabled `<bool>` *default value- false*: whether this option is disabled or not; * - linkTo `<string>`: when provided the option will be an anchor to the given value; * - title `<bool>` *default value- false* **deprecated**: please use `listItemSectionBuilder` for rendering a title; * - overrideStyle `<bool>` *default value- false* **deprecated**: please use `overrideOptionStyle` for override option styles; * - overrideOptionStyle `<bool>` *default value- false* - when set to `true`, the option will be responsible to its own styles. No styles will be applied from the DropdownLayout itself; * - label `<string>`: the string displayed within an input when the option is selected. This is used when using `<DropdownLayout/>` with an `<Input/>`. */ options: _propTypes["default"].arrayOf(_DropdownLayout.optionValidator), /** Handles container overflow */ overflow: _propTypes["default"].string, /** Sets a pattern that typed value must match to be valid (regex) */ pattern: _propTypes["default"].string, /** Sets a placeholder message to display */ placeholder: _propTypes["default"].string, /** Allows to pass all common popover props. Check `<Popover/>` API for a full list. */ popoverProps: _propTypes["default"].shape({ appendTo: _propTypes["default"].oneOf(['window', 'scrollParent', 'parent', 'viewport']), maxWidth: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]), minWidth: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]), flip: _propTypes["default"].bool, fixed: _propTypes["default"].bool, placement: _propTypes["default"].oneOf(['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start']), dynamicWidth: _propTypes["default"].bool }), /** Pass a component you want to show as the prefix of the input, e.g., text string, icon */ prefix: _propTypes["default"].node, /** Specifies whether input is read only */ readOnly: _propTypes["default"].bool, /** Specifies whether input is mandatory */ required: _propTypes["default"].bool, /** Flip component horizontally so it would be more suitable to RTL */ rtl: _propTypes["default"].bool, /** Specifies whether selected option will be highlighted when dropdown is reopened */ selectedHighlight: _propTypes["default"].bool, /** Specifies selected option by its id */ selectedId: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]), /** Specifies an array of selected options ids */ selectedOptions: _propTypes["default"].array, /** Controls whether to show options if input is empty */ showOptionsIfEmptyInput: _propTypes["default"].bool, /** Controls the size of the input */ size: _propTypes["default"].oneOf(['small', 'medium', 'large']), /** Specify the status of a field */ status: _propTypes["default"].oneOf(['error', 'warning', 'loading']), /** Defines the message to display on status icon hover. If not given or empty there will be no tooltip. */ statusMessage: _propTypes["default"].node, /** Pass a component you want to show as the suffix of the input, e.g., text string, icon */ suffix: _propTypes["default"].node, /** Indicates that element can be focused and where it participates in sequential keyboard navigation */ tabIndex: _propTypes["default"].number, /** Handles text overflow behavior. It can either `clip` (default) or display `ellipsis`. */ textOverflow: _propTypes["default"].string, /** Controls placement of a status tooltip */ tooltipPlacement: _propTypes["default"].string, /** Specifies the type of `<input>` element to display. Default type is text. */ type: _propTypes["default"].string, /** Specifies whether component should be shown or hidden */ visible: _propTypes["default"].bool, /** Specifies the current value of the element */ value: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]), valueParser: _propTypes["default"].func }; MultiSelectCheckbox.defaultProps = _objectSpread(_objectSpread({}, _InputWithOptions2["default"].defaultProps), {}, { delimiter: ', ', selectedOptions: [], closeOnSelect: false, valueParser: function valueParser(option) { return option.label || option.value; } }); var _default = MultiSelectCheckbox; exports["default"] = _default;