wix-style-react
Version:
197 lines (177 loc) • 7.06 kB
JavaScript
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;