UNPKG

wix-style-react

Version:
439 lines (332 loc) 19.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 _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get")); 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 _defaultTo = _interopRequireDefault(require("lodash/defaultTo")); var _isEqual = _interopRequireDefault(require("lodash/isEqual")); var _sortBy = _interopRequireDefault(require("lodash/sortBy")); var _propTypes = require("../utils/propTypes"); var _InputWithOptions2 = _interopRequireDefault(require("../InputWithOptions")); var _DropdownSt = require("./Dropdown.st.css"); var _propTypes2 = _interopRequireDefault(require("prop-types")); 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 NO_SELECTED_ID = null; var Dropdown = /*#__PURE__*/function (_InputWithOptions) { (0, _inherits2["default"])(Dropdown, _InputWithOptions); var _super = _createSuper(Dropdown); function Dropdown(props) { var _this; (0, _classCallCheck2["default"])(this, Dropdown); _this = _super.call(this, props); _this.state = _objectSpread({ value: '', selectedId: NO_SELECTED_ID }, Dropdown.getNextState(props, (0, _defaultTo["default"])(props.selectedId, props.initialSelectedId))); return _this; } (0, _createClass2["default"])(Dropdown, [{ key: "isSelectedIdControlled", value: function isSelectedIdControlled() { return typeof this.props.selectedId !== 'undefined'; } }, { key: "getSelectedId", value: function getSelectedId() { return this.isSelectedIdControlled() ? this.props.selectedId : this.state.selectedId; } }, { key: "_onInputClicked", value: function _onInputClicked(event) { if (this.props.onInputClicked) { this.props.onInputClicked(event); } if (this.props.readOnly) { return; } if (this.state.showOptions && Date.now() - this.state.lastOptionsShow > 200) { this.hideOptions(); } else { this.showOptions(); } } /** * Updates the value by the selectedId. * If selectedId is not found in options, then value is NOT changed. */ }, { key: "UNSAFE_componentWillReceiveProps", value: function UNSAFE_componentWillReceiveProps(nextProps) { if (nextProps.selectedId !== this.props.selectedId || !Dropdown.isOptionsEqual(this.props.options, nextProps.options)) { this.setState(Dropdown.getNextState(nextProps, nextProps.selectedId, this.state.selectedId)); } } }, { key: "inputClasses", value: function inputClasses() { var noBorder = this.props.noBorder; return (0, _DropdownSt.st)(_DropdownSt.classes.showPointer, { noBorder: noBorder }); } }, { key: "dropdownAdditionalProps", value: function dropdownAdditionalProps() { return { selectedId: this.getSelectedId(), value: this.state.value, tabIndex: -1, withArrow: false }; } }, { key: "inputAdditionalProps", value: function inputAdditionalProps() { return { disableEditing: true, value: this.state.value }; } }, { key: "_onSelect", value: function _onSelect(option) { if (!this.isSelectedIdControlled()) { this.setState({ value: this.props.valueParser(option), selectedId: option.id }); } (0, _get2["default"])((0, _getPrototypeOf2["default"])(Dropdown.prototype), "_onSelect", this).call(this, option); } }, { key: "_onChange", value: function _onChange(event) { this.setState({ value: event.target.value }); (0, _get2["default"])((0, _getPrototypeOf2["default"])(Dropdown.prototype), "_onChange", this).call(this, event); } }], [{ key: "isOptionsEqual", value: function isOptionsEqual(optionsA, optionsB) { return (0, _isEqual["default"])((0, _sortBy["default"])(optionsA, 'id'), (0, _sortBy["default"])(optionsB, 'id')); } }, { key: "getNextState", value: function getNextState(props, selectedId) { if (typeof selectedId !== 'undefined') { var option = props.options.find(function (_option) { return _option.id === selectedId; }); if (option) { var value = props.valueParser(option) || ''; return { value: value, selectedId: selectedId }; } } return { value: '', selectedId: NO_SELECTED_ID }; } }]); return Dropdown; }(_InputWithOptions2["default"]); Dropdown.propTypes = { /** An initial selected option id. (Implies Uncontrolled mode) */ initialSelectedId: _propTypes2["default"].oneOfType([_propTypes2["default"].string, _propTypes2["default"].number]), /** Associate a control with the regions that it controls. */ ariaControls: _propTypes2["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: _propTypes2["default"].string, /** Define a string that labels the current element in case where a text label is not visible on the screen. */ ariaLabel: _propTypes2["default"].string, /** Focus the element on mount (standard React input autoFocus). */ autoFocus: _propTypes2["default"].bool, /** Select the entire text of the element on focus (standard React input autoSelect). */ autoSelect: _propTypes2["default"].bool, /** Control the border style of input. */ border: _propTypes2["default"].oneOf(['standard', 'round', 'bottomLine']), /** Specifies a CSS class name to be appended to the component’s root element. */ className: _propTypes2["default"].string, /** Displays clear button (X) on a non-empty input. */ clearButton: _propTypes2["default"].bool, /** Closes DropdownLayout when option is selected. */ closeOnSelect: _propTypes2["default"].bool, /** Render a custom input component instead of the default html input tag. */ customInput: _propTypes2["default"].node, /** Applies a data-hook HTML attribute that can be used in the tests. */ dataHook: _propTypes2["default"].string, /** Specifies whether input should be disabled or not. */ disabled: _propTypes2["default"].bool, /** Restricts input editing. */ disableEditing: _propTypes2["default"].bool, /** Sets the offset of the dropdown from the left in pixels. */ dropdownOffsetLeft: _propTypes2["default"].string, /** Sets the width of the dropdown in pixels. */ dropdownWidth: _propTypes2["default"].string, /** Adds a fixed footer container at the bottom of options list in `<DropdownLayout/>`. */ fixedFooter: _propTypes2["default"].node, /** Adds a fixed header container at the top of options list in `<DropdownLayout/>`. */ fixedHeader: _propTypes2["default"].node, /** Highlights and scrolls view to the specified option when dropdown layout is opened. It does not select the specified option. */ focusOnOption: _propTypes2["default"].oneOfType([_propTypes2["default"].string, _propTypes2["default"].number]), /** Scrolls view to the selected option when dropdown layout is opened. */ focusOnSelectedOption: _propTypes2["default"].bool, /** USED FOR TESTING. Forces focus state on the input. */ forceFocus: _propTypes2["default"].bool, /** USED FOR TESTING. Forces hover state on the input. */ forceHover: _propTypes2["default"].bool, /** Specifies whether there are more items to be loaded. */ hasMore: _propTypes2["default"].bool, /** Specifies whether status suffix should be hidden. */ hideStatusSuffix: _propTypes2["default"].bool, /** Assigns an unique identifier for the root element. */ id: _propTypes2["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: _propTypes2["default"].bool, /** Specifies whether lazy loading of the dropdown layout items is enabled. */ infiniteScroll: _propTypes2["default"].bool, /** Allows to render a custom input component instead of the default `<Input/>`. */ inputElement: _propTypes2["default"].element, /** Defines a callback function which is called on a request to render more list items. */ loadMore: _propTypes2["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: _propTypes2["default"].oneOfType([_propTypes2["default"].bool, _propTypes2["default"].string, _propTypes2["default"].number]), /** Sets the maximum height of the dropdownLayout in pixels. */ maxHeightPixels: _propTypes2["default"].oneOfType([_propTypes2["default"].string, _propTypes2["default"].number]), /** Specifies whether input should have a dropdown menu arrow on the right side. */ menuArrow: _propTypes2["default"].bool, /** Sets a minimum value of an input. Similar to HTML5 min attribute. */ min: _propTypes2["default"].number, /** Sets the minimum width of dropdownLayout in pixels. */ minWidthPixels: _propTypes2["default"].oneOfType([_propTypes2["default"].string, _propTypes2["default"].number]), /** Reference element data when a form is submitted. */ name: _propTypes2["default"].string, /** Render options list via native select element. */ "native": _propTypes2["default"].bool, /** Specifies whether input shouldn’t have rounded corners on its left. */ noLeftBorderRadius: _propTypes2["default"].bool, /** Specifies whether input shouldn’t have rounded corners on its right. */ noRightBorderRadius: _propTypes2["default"].bool, /** Defines a standard input onBlur callback */ onBlur: _propTypes2["default"].func, /** Displays clear button (X) on a non-empty input and calls a callback function with no arguments. */ onClear: _propTypes2["default"].func, /** Defines a callback function which is called whenever the user presses the escape key. */ onClose: _propTypes2["default"].func, /** Defines a standard input onChange callback. */ onChange: _propTypes2["default"].func, /** Defines a callback function called on compositionstart/compositionend events. */ onCompositionChange: _propTypes2["default"].func, /** Defines a callback handler that is called when user presses -enter-. */ onEnterPressed: _propTypes2["default"].func, /** Defines a callback handler that is called when user presses -escape- */ onEscapePressed: _propTypes2["default"].func, /** Defines a standard input onFocus callback. */ onFocus: _propTypes2["default"].func, /** Defines a standard input onClick callback. */ onInputClicked: _propTypes2["default"].func, /** Defines a standard input onKeyDown callback. */ onKeyDown: _propTypes2["default"].func, /** Defines a standard input onKeyUp callback. */ onKeyUp: _propTypes2["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: _propTypes2["default"].func, /** Defines a callback function which is called whenever the user enters dropdown layout with the mouse cursor. */ onMouseEnter: _propTypes2["default"].func, /** Defines a callback function which is called whenever the user exits from dropdown layout with a mouse cursor. */ onMouseLeave: _propTypes2["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: _propTypes2["default"].func, /** Defines a callback function which is called when options dropdown is hidden. */ onOptionsHide: _propTypes2["default"].func, /** Defines a callback function which is called when options dropdown is shown. */ onOptionsShow: _propTypes2["default"].func, /** Defines a callback function which is called whenever user selects a different option in the list. */ onSelect: _propTypes2["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: _propTypes2["default"].arrayOf(_DropdownLayout.optionValidator), /** Handles container overflow. */ overflow: _propTypes2["default"].string, /** Sets a placeholder message to display. */ placeholder: _propTypes2["default"].string, /** Allows to pass all common popover props. */ popoverProps: _propTypes2["default"].shape({ appendTo: _propTypes2["default"].oneOf(['window', 'scrollParent', 'parent', 'viewport']), maxWidth: _propTypes2["default"].oneOfType([_propTypes2["default"].string, _propTypes2["default"].number]), minWidth: _propTypes2["default"].oneOfType([_propTypes2["default"].string, _propTypes2["default"].number]), flip: _propTypes2["default"].bool, fixed: _propTypes2["default"].bool, placement: _propTypes2["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: _propTypes2["default"].bool }), /** Pass a component you want to show as the prefix of the input, e.g., text string, icon. */ prefix: _propTypes2["default"].node, /** Specifies whether input is read only. */ readOnly: _propTypes2["default"].bool, /** Flip component horizontally so it would be more suitable to RTL. */ rtl: _propTypes2["default"].bool, /** Specifies whether selected option will be highlighted when dropdown is reopened. */ selectedHighlight: _propTypes2["default"].bool, /** Specifies selected option by its id. */ selectedId: _propTypes2["default"].oneOfType([_propTypes2["default"].string, _propTypes2["default"].number]), /** Controls whether to show options if input is empty. */ showOptionsIfEmptyInput: _propTypes2["default"].bool, /** Controls the size of the input */ size: _propTypes2["default"].oneOf(['small', 'medium', 'large']), /** Specify the status of a field. */ status: _propTypes2["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: _propTypes2["default"].node, /** Pass a component you want to show as the suffix of the input, e.g., text string, icon. */ suffix: _propTypes2["default"].node, /** Indicates that element can be focused and where it participates in sequential keyboard navigation. */ tabIndex: _propTypes2["default"].number, /** Handles text overflow behavior. It can either clip (default) or display ellipsis. */ textOverflow: _propTypes2["default"].string, /** Controls placement of a status tooltip. */ tooltipPlacement: _propTypes2["default"].string, /** Specifies whether component should be shown or hidden. */ visible: _propTypes2["default"].bool }; (0, _propTypes.extendPropTypes)(Dropdown, { selectedId: (0, _propTypes.allValidators)(_propTypes2["default"].oneOfType([_propTypes2["default"].string, _propTypes2["default"].number]), function (props, propName) { if (props[propName] !== undefined && props['initialSelectedId'] !== undefined) { return new Error("'selectedId' and 'initialSelectedId' cannot both be used at the same time."); } }) }); Dropdown.defaultProps = _InputWithOptions2["default"].defaultProps; Dropdown.displayName = 'Dropdown'; var _default = Dropdown; exports["default"] = _default;