UNPKG

wix-style-react

Version:
197 lines (177 loc) • 7.06 kB
import React from 'react'; import PropTypes from 'prop-types'; import { classes } from './Content.st.css'; import { dataHooks } from '../SelectorList.helpers'; import Selector from '../../Selector'; import Loader from '../../Loader'; import InfiniteScroll from '../../utils/InfiniteScroll'; import Text from '../../Text'; var DEFAULT_EMPTY = /*#__PURE__*/React.createElement("div", { className: classes.defaultEmptyStateWrapper }, /*#__PURE__*/React.createElement(Text, null, "You don't have any items")); var ListItems = function ListItems(_ref) { var items = _ref.items, checkIsSelected = _ref.checkIsSelected, _onToggle = _ref.onToggle, imageSize = _ref.imageSize, imageShape = _ref.imageShape, multiple = _ref.multiple; if (!items.length) { return null; } return /*#__PURE__*/React.createElement("ul", { "data-hook": dataHooks.list, className: classes.list }, items.map(function (item) { return /*#__PURE__*/React.createElement(Selector, { id: item.id, key: item.id, dataHook: dataHooks.selector, imageSize: imageSize, imageShape: imageShape, toggleType: multiple ? 'checkbox' : 'radio', image: item.image, title: item.title, subtitle: item.subtitle, extraNode: item.extraNode ? item.extraNode : item.extraText && /*#__PURE__*/React.createElement(Text, { secondary: true }, item.extraText), subtitleNode: item.subtitleNode, belowNode: item.belowNode, showBelowNodeOnSelect: item.showBelowNodeOnSelect, isSelected: checkIsSelected(item), isDisabled: item.disabled, onToggle: function onToggle() { !item.disabled && _onToggle(item); } }); })); }; var SelectorListContent = function SelectorListContent(_ref2) { var dataHook = _ref2.dataHook, items = _ref2.items, topScrollableContent = _ref2.topScrollableContent, onToggle = _ref2.onToggle, emptyState = _ref2.emptyState, renderNoResults = _ref2.renderNoResults, isLoading = _ref2.isLoading, checkIsSelected = _ref2.checkIsSelected, isEmpty = _ref2.isEmpty, noResultsFound = _ref2.noResultsFound, imageSize = _ref2.imageSize, imageShape = _ref2.imageShape, multiple = _ref2.multiple, searchValue = _ref2.searchValue, loadMore = _ref2.loadMore, hasMore = _ref2.hasMore, infiniteScrollRef = _ref2.infiniteScrollRef; return /*#__PURE__*/React.createElement("div", { className: classes.content, "data-hook": dataHook }, isLoading && /*#__PURE__*/React.createElement("div", { className: classes.mainLoaderWrapper }, /*#__PURE__*/React.createElement(Loader, { size: "medium", dataHook: dataHooks.mainLoader })), isEmpty && /*#__PURE__*/React.createElement("div", { "data-hook": dataHooks.emptyState, className: classes.emptyStateWrapper, children: emptyState }), items.length > 0 && /*#__PURE__*/React.createElement(InfiniteScroll, { key: searchValue, ref: infiniteScrollRef, data: items, loadMore: loadMore, hasMore: hasMore, useWindow: false, initialLoad: false, loader: /*#__PURE__*/React.createElement("div", { className: classes.nextPageLoaderWrapper }, /*#__PURE__*/React.createElement(Loader, { size: "small", dataHook: dataHooks.nextPageLoader })) }, topScrollableContent, /*#__PURE__*/React.createElement(ListItems, { items: items, checkIsSelected: checkIsSelected, onToggle: onToggle, imageSize: imageSize, imageShape: imageShape, multiple: multiple })), noResultsFound && /*#__PURE__*/React.createElement("div", { "data-hook": dataHooks.noResultsFoundState, className: classes.noResultsFoundStateWrapper, children: renderNoResults(searchValue) })); }; SelectorListContent.propTypes = { /** applied as data-hook HTML attribute that can be used to create driver in testing */ dataHook: PropTypes.string, /** array of selector items to show */ items: PropTypes.arrayOf(PropTypes.shape({ id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, title: PropTypes.node.isRequired, subtitle: PropTypes.string, extraText: PropTypes.string, extraNode: PropTypes.node, disabled: PropTypes.bool, // show item as disabled, dont count it in "select all", exclude from `onOk` selected: PropTypes.bool, // force item as selected image: PropTypes.node, subtitleNode: PropTypes.node, belowNode: PropTypes.node, showBelowNodeOnSelect: PropTypes.bool })), /** Component/element that will be rendered above the list that will not be sticky, but scrollable */ topScrollableContent: PropTypes.node, /** callback to trigger when toggling a selector, receives SelectorList item */ onToggle: PropTypes.func, /** * Component/element that will be rendered when there is nothing to display, * i.e. empty `{items:[], totalCount: 0}` was returned on the first call to `dataSource` * */ emptyState: PropTypes.node, /** * Function that will get the current `searchQuery` and should return the component/element * that will be rendered when there are no items that suffice the entered search query * */ renderNoResults: PropTypes.func, /** whether list is loading */ isLoading: PropTypes.bool, /** a function that receives an item and checks if it is selected */ checkIsSelected: PropTypes.func.isRequired, /** whether list is empty */ isEmpty: PropTypes.bool, /** whether list search found no matching items */ noResultsFound: PropTypes.bool, /** Image icon size */ imageSize: PropTypes.oneOf(['tiny', 'small', 'portrait', 'large', 'cinema']), /** * Image icon shape, `rectangular` or `circle`.<br> * NOTE: `circle` is not compatible with `imageSize` of `portrait` or `cinema` * */ imageShape: function imageShape(props, propName, componentName) { if (['portrait', 'cinema'].includes(props.imageSize) && props[propName] === 'circle') { return new Error("".concat(componentName, ": prop \"imageSize\" with value of \"").concat(props.imageSize, "\" is incompatible with prop imageShape with value of \"circle\" \u2014 use \"rectangular\" instead.")); } }, /** display checkbox and allow multi selection */ multiple: PropTypes.bool, /** search input value */ searchValue: PropTypes.string.isRequired, /** A callback called when more items are requested to be rendered. */ loadMore: PropTypes.func.isRequired, /** Whether there are more items to be loaded. */ hasMore: PropTypes.bool }; SelectorListContent.defaultProps = { dataHook: dataHooks.content, emptyState: DEFAULT_EMPTY, renderNoResults: function renderNoResults(searchValue) { return /*#__PURE__*/React.createElement("div", { className: classes.defaultNoResultsFoundStateWrapper }, /*#__PURE__*/React.createElement(Text, null, "No items matched your search ", "\"".concat(searchValue, "\""))); } }; export default SelectorListContent;