UNPKG

wix-style-react

Version:
486 lines (401 loc) • 20.6 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); 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 _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _DropdownBaseSt = require("./DropdownBase.st.css"); var _Popover = _interopRequireWildcard(require("../Popover")); var _DropdownLayout = _interopRequireDefault(require("../DropdownLayout")); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } 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 DropdownBase = /*#__PURE__*/function (_React$PureComponent) { (0, _inherits2["default"])(DropdownBase, _React$PureComponent); var _super = _createSuper(DropdownBase); function DropdownBase() { var _ref, _this$props$selectedI; var _this; (0, _classCallCheck2["default"])(this, DropdownBase); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _super.call.apply(_super, [this].concat(args)); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_dropdownLayoutRef", null); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_shouldCloseOnMouseLeave", false); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "state", { open: _this.props.open, selectedId: (_ref = (_this$props$selectedI = _this.props.selectedId) !== null && _this$props$selectedI !== void 0 ? _this$props$selectedI : _this.props.initialSelectedId) !== null && _ref !== void 0 ? _ref : -1 }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_isControllingOpen", function () { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this.props; return typeof props.open !== 'undefined'; }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_isControllingSelection", function () { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this.props; return typeof props.selectedId !== 'undefined' && typeof props.onSelect !== 'undefined'; }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_open", function () { if (!_this._isControllingOpen()) { _this.setState({ open: true }); _this.props.onShow(); } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_close", function (e) { if (_this._isControllingOpen()) { return; } // If called within a `mouseleave` event on the target element, we would like to close the // popover only on the popover's `mouseleave` event if (e && e.type === 'mouseleave') { // We're not using `setState` since we don't want to wait for the next render _this._shouldCloseOnMouseLeave = true; } else { _this.setState({ open: false }); } _this.props.onHide(); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_toggle", function () { !_this._isControllingOpen() && _this.setState(function (_ref2) { var open = _ref2.open; if (open) { _this.props.onHide(); } else { _this.props.onShow(); } return { open: !open }; }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_handleClickOutside", function () { var onClickOutside = _this.props.onClickOutside; _this._close(); onClickOutside && onClickOutside(); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_handlePopoverMouseEnter", function () { var onMouseEnter = _this.props.onMouseEnter; onMouseEnter && onMouseEnter(); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_handlePopoverMouseLeave", function () { var onMouseLeave = _this.props.onMouseLeave; if (_this._shouldCloseOnMouseLeave) { _this._shouldCloseOnMouseLeave = false; _this.setState({ open: false }); } onMouseLeave && onMouseLeave(); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_handleSelect", function (selectedOption) { var newState = {}; if (!_this._isControllingOpen()) { newState.open = false; _this.props.onHide(); } if (!_this._isControllingSelection()) { newState.selectedId = selectedOption.id; } _this.setState(newState, function () { var onSelect = _this.props.onSelect; onSelect && onSelect(selectedOption); }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_handleClose", function () { if (_this.state.open) { _this._close(); } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_getSelectedOption", function (selectedId) { return _this.props.options.find(function (_ref3) { var id = _ref3.id; return id === selectedId; }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_isOpenKey", function (key) { return ['Enter', 'Spacebar', ' ', 'ArrowDown'].includes(key); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_handleKeyDown", function (e) { if (_this._isControllingOpen()) { return; } var isHandledByDropdownLayout = _this._delegateKeyDown(e); if (!isHandledByDropdownLayout) { if (_this._isOpenKey(e.key)) { _this._open(); e.preventDefault(); } } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_delegateKeyDown", function (e) { if (!_this._dropdownLayoutRef) { return false; } return _this._dropdownLayoutRef._onKeyDown(e); }); return _this; } (0, _createClass2["default"])(DropdownBase, [{ key: "UNSAFE_componentWillReceiveProps", value: function UNSAFE_componentWillReceiveProps(nextProps) { // Keep internal state updated if needed if (this._isControllingOpen(nextProps) && this.props.open !== nextProps.open) { this.setState({ open: nextProps.open }); } if (this._isControllingSelection(nextProps) && this.props.selectedId !== nextProps.selectedId) { this.setState({ selectedId: nextProps.selectedId }); } } }, { key: "_renderChildren", value: function _renderChildren() { var children = this.props.children; var _this$state = this.state, selectedId = _this$state.selectedId, open = _this$state.open; if (!children) { return null; } return /*#__PURE__*/_react["default"].isValidElement(children) ? children // Returning the children as is when using in controlled mode : children({ open: this._open, close: this._close, toggle: this._toggle, isOpen: Boolean(open), delegateKeyDown: this._delegateKeyDown, selectedOption: this._getSelectedOption(selectedId) }); } }, { key: "render", value: function render() { var _this2 = this; var _this$props = this.props, dataHook = _this$props.dataHook, placement = _this$props.placement, appendTo = _this$props.appendTo, showArrow = _this$props.showArrow, zIndex = _this$props.zIndex, moveBy = _this$props.moveBy, options = _this$props.options, minWidth = _this$props.minWidth, maxWidth = _this$props.maxWidth, fixed = _this$props.fixed, flip = _this$props.flip, tabIndex = _this$props.tabIndex, overflow = _this$props.overflow, dynamicWidth = _this$props.dynamicWidth, maxHeight = _this$props.maxHeight, fluid = _this$props.fluid, animate = _this$props.animate, className = _this$props.className, focusOnSelectedOption = _this$props.focusOnSelectedOption, infiniteScroll = _this$props.infiniteScroll, loadMore = _this$props.loadMore, hasMore = _this$props.hasMore, focusOnOption = _this$props.focusOnOption, markedOption = _this$props.markedOption, onMouseDown = _this$props.onMouseDown; var _this$state2 = this.state, open = _this$state2.open, selectedId = _this$state2.selectedId; return /*#__PURE__*/_react["default"].createElement(_Popover["default"], (0, _extends2["default"])({}, this.props, { // backward compatible for migration stylable 1 to stylable 3 animate: animate, dataHook: dataHook, shown: open, placement: placement, dynamicWidth: dynamicWidth, appendTo: appendTo, showArrow: showArrow, zIndex: zIndex, moveBy: moveBy, onKeyDown: this._handleKeyDown, onMouseEnter: this._handlePopoverMouseEnter, onMouseLeave: this._handlePopoverMouseLeave, onClickOutside: this._handleClickOutside, fixed: fixed, flip: flip, fluid: fluid, className: (0, _DropdownBaseSt.st)(_DropdownBaseSt.classes.root, { withWidth: Boolean(minWidth || maxWidth), withArrow: showArrow }, className) }), /*#__PURE__*/_react["default"].createElement(_Popover["default"].Element, null, this._renderChildren()), /*#__PURE__*/_react["default"].createElement(_Popover["default"].Content, null, /*#__PURE__*/_react["default"].createElement("div", { style: { minWidth: minWidth, maxWidth: maxWidth } }, /*#__PURE__*/_react["default"].createElement(_DropdownLayout["default"], { dataHook: "dropdown-base-dropdownlayout", className: _DropdownBaseSt.classes.list, ref: function ref(r) { return _this2._dropdownLayoutRef = r; }, selectedId: selectedId, options: options, maxHeightPixels: maxHeight, onSelect: this._handleSelect, onClose: this._handleClose, tabIndex: tabIndex, inContainer: true, visible: true, overflow: overflow, focusOnSelectedOption: focusOnSelectedOption, infiniteScroll: infiniteScroll, loadMore: loadMore, hasMore: hasMore, focusOnOption: focusOnOption, markedOption: markedOption, onMouseDown: onMouseDown })))); } }]); return DropdownBase; }(_react["default"].PureComponent); (0, _defineProperty2["default"])(DropdownBase, "displayName", 'DropdownBase'); (0, _defineProperty2["default"])(DropdownBase, "propTypes", { /** Applies a data-hook HTML attribute that can be used in the tests */ dataHook: _propTypes["default"].string, /** Specifies a CSS class name to be appended to the component’s root element */ className: _propTypes["default"].string, /** Control whether the <Popover/> should be opened */ open: _propTypes["default"].bool, /** Control popover placement */ placement: _propTypes["default"].oneOf(_Popover.placements), /** Specifies where popover should be inserted as a last child - whether `parent` or `window` containers */ appendTo: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].node]), /** Specifies whether popover arrow should be shown */ showArrow: _propTypes["default"].bool, /** Defines a callback function which is called when user clicks outside of a dropdown */ onClickOutside: _propTypes["default"].func, /** Defines a callback function which is called on `onMouseEnter` event on the entire component */ onMouseEnter: _propTypes["default"].func, /** Defines a callback function which is called on `onMouseLeave` event on the entire component */ onMouseLeave: _propTypes["default"].func, /** Defines a callback function which is called when dropdown is opened */ onShow: _propTypes["default"].func, /** Defines a callback function which is called when dropdown is closed */ onHide: _propTypes["default"].func, /** Defines a callback function which is called whenever user selects a different option in the list */ onSelect: _propTypes["default"].func, /** * Set popover's content width to a minimum width of a trigger element, * but it can expand up to the defined value of `maxWidth` */ dynamicWidth: _propTypes["default"].bool, /** Controls the minimum width of dropdown layout */ minWidth: _propTypes["default"].oneOfType([_propTypes["default"].number, _propTypes["default"].string]), /** Controls the maximum width of dropdown layout */ maxWidth: _propTypes["default"].oneOfType([_propTypes["default"].number, _propTypes["default"].string]), /** Controls the maximum height of dropdown layout */ maxHeight: _propTypes["default"].oneOfType([_propTypes["default"].number, _propTypes["default"].string]), /** * Specifies a target component to be rendered. If a regular node is passed, it'll be rendered as-is. * If a function is passed, it's expected to return a React element. * The function accepts an object containing the following properties: * * * `open` - will open the Popover * * `close` - will close the Popover * * `toggle` - will toggle the Popover * * `isOpen` - indicates whether the items list is currently open * * `delegateKeyDown` - the underlying DropdownLayout's keydown handler. It can be called * inside another keyDown event in order to delegate it. * * `selectedOption` - the currently selected option * * Check inserted component documentation for more information on available properties. */ children: _propTypes["default"].oneOfType([_propTypes["default"].node, _propTypes["default"].func]), /** * Specifies an array of options for a dropdown list. Objects must have an id and can include string value or node. * If value is '-', a divider will be rendered instead (dividers do not require and id). */ options: _propTypes["default"].arrayOf(_propTypes["default"].oneOfType([_propTypes["default"].shape({ id: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]).isRequired, value: _propTypes["default"].oneOfType([_propTypes["default"].node, _propTypes["default"].string, _propTypes["default"].func]).isRequired, disabled: _propTypes["default"].bool, overrideStyle: _propTypes["default"].bool }), // A divider option without an id _propTypes["default"].shape({ value: _propTypes["default"].oneOf(['-']) })])), /** Sets the initial marking of an option in the list when opened: * - `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]), /** Define the selected option in the list */ selectedId: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]), /** Handles container overflow behaviour */ overflow: _propTypes["default"].string, /** Indicates that element can be focused and where it participates in sequential keyboard navigation */ tabIndex: _propTypes["default"].number, /** * Sets the initially selected option in the list. Used when selection * behaviour is being controlled. */ initialSelectedId: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]), /** Specifies the stack order (`z-index`) of a dropdown layout */ zIndex: _propTypes["default"].number, /** Moves dropdown content relative to the parent on X or Y axis by a defined amount of pixels */ moveBy: _propTypes["default"].shape({ x: _propTypes["default"].number, y: _propTypes["default"].number }), /** * Specifies whether to flip the <Popover/> placement * when it starts to overlap the target element (<Popover.Element/>) */ flip: _propTypes["default"].bool, /** * Specifies whether to enable the fixed behaviour. If enabled, <Popover/> keep its * original placement even when it's being positioned outside the boundary. */ fixed: _propTypes["default"].bool, /** Stretches trigger element to fill its parent container width */ fluid: _propTypes["default"].bool, /** Adds enter and exit animation */ animate: _propTypes["default"].bool, /** Scrolls to the selected option when dropdown is opened */ focusOnSelectedOption: _propTypes["default"].bool, /** Specifies whether lazy loading of the dropdown items is enabled */ infiniteScroll: _propTypes["default"].bool, /** Defines a callback function which is called on a request to render more list items */ loadMore: _propTypes["default"].func, /** Specifies whether there are more items to load */ hasMore: _propTypes["default"].bool, /** Scrolls to the specified option when dropdown is opened */ focusOnOption: _propTypes["default"].number }); (0, _defineProperty2["default"])(DropdownBase, "defaultProps", { placement: 'bottom', appendTo: 'parent', showArrow: false, maxHeight: '260px', fluid: false, animate: false, onShow: function onShow() {}, onHide: function onHide() {} }); var _default = DropdownBase; exports["default"] = _default;