wix-style-react
Version:
486 lines (401 loc) • 20.6 kB
JavaScript
"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;