wix-style-react
Version:
wix-style-react
108 lines • 6.66 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';
const DEFAULT_EMPTY = (React.createElement("div", { className: classes.defaultEmptyStateWrapper },
React.createElement(Text, null, "You don't have any items")));
const ListItems = ({ items, checkIsSelected, checkIndeterminate, onToggle, size, imageSize, imageShape, multiple, showDivider, }) => {
if (!items.length) {
return null;
}
return (React.createElement("ul", { "data-hook": dataHooks.list, className: classes.list }, items.map((item, index) => (React.createElement(Selector, { id: item.id, key: item.id, dataHook: dataHooks.selector, size: size, imageSize: imageSize, imageShape: imageShape, hasDivider: showDivider && index + 1 < items.length, toggleType: multiple ? 'checkbox' : 'radio', image: item.image, title: item.title, subtitle: item.subtitle, extraNode: item.extraNode
? item.extraNode
: item.extraText && React.createElement(Text, { secondary: true }, item.extraText), subtitleNode: item.subtitleNode, belowNode: item.belowNode, showBelowNodeOnSelect: item.showBelowNodeOnSelect, isSelected: checkIsSelected(item), indeterminate: checkIndeterminate?.(item), isDisabled: item.disabled, onToggle: () => {
!item.disabled && onToggle(item);
} })))));
};
const SelectorListContent = ({ dataHook = dataHooks.content, items, topScrollableContent, onToggle, emptyState = DEFAULT_EMPTY, renderNoResults = searchValue => (React.createElement("div", { className: classes.defaultNoResultsFoundStateWrapper },
React.createElement(Text, null,
"No items matched your search ",
`"${searchValue}"`))), isLoading, checkIsSelected, checkIndeterminate, isEmpty, noResultsFound, size, imageSize, imageShape, multiple, showDivider, searchValue, loadMore, hasMore, infiniteScrollRef, }) => {
return (React.createElement("div", { className: classes.content, "data-hook": dataHook },
isLoading && (React.createElement("div", { className: classes.mainLoaderWrapper },
React.createElement(Loader, { size: "medium", dataHook: dataHooks.mainLoader }))),
isEmpty && (React.createElement("div", { "data-hook": dataHooks.emptyState, className: classes.emptyStateWrapper, children: emptyState })),
items.length > 0 && (React.createElement(InfiniteScroll, { key: searchValue, ref: infiniteScrollRef, data: items, loadMore: loadMore, hasMore: hasMore, useWindow: false, initialLoad: false, loader: React.createElement("div", { className: classes.nextPageLoaderWrapper },
React.createElement(Loader, { size: "small", dataHook: dataHooks.nextPageLoader })) },
topScrollableContent,
React.createElement(ListItems, { items,
checkIsSelected,
checkIndeterminate,
onToggle,
size,
imageSize,
imageShape,
showDivider,
multiple }))),
noResultsFound && (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,
/** a function that receives an item and checks if it is in indeterminate mode */
checkIndeterminate: PropTypes.func,
/** whether list is empty */
isEmpty: PropTypes.bool,
/** whether list search found no matching items */
noResultsFound: PropTypes.bool,
/** Controls the size of the selector list. Mostly has an effect on padding of the list and its items. */
size: PropTypes.oneOf(['small', 'medium']),
/** 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: (props, propName, componentName) => {
if (['portrait', 'cinema'].includes(props.imageSize) &&
props[propName] === 'circle') {
return new Error(`${componentName}: prop "imageSize" with value of "${props.imageSize}" is incompatible with prop imageShape with value of "circle" — 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,
};
export default SelectorListContent;
//# sourceMappingURL=Content.js.map