wix-style-react
Version:
497 lines (378 loc) • 21.2 kB
JavaScript
"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;