@baaz/adapter
Version:
The core runtime of PWA
119 lines (109 loc) • 3.24 kB
JavaScript
import React, { useMemo, useCallback } from 'react';
import {
array,
func,
object,
oneOf,
oneOfType,
shape,
string
} from 'prop-types';
import fromRenderProp from '../util/fromRenderProp';
import iterable from '../validators/iterable';
import Items from './items';
/**
* The **List** component maps a collection of data objects into an array of elements.
* It also manages the selection and focus of those elements.
*
* @typedef List
* @kind functional component
*
* @param {props} props React Component props
*
* @returns{React.Element} A React component that displays list data.
*/
const List = props => {
const {
classes,
getItemKey,
initialSelection,
items,
render,
renderItem,
onSelectionChange,
selectionModel,
...restProps
} = props;
const customProps = {
classes,
getItemKey,
items,
onSelectionChange,
selectionModel
};
const handleSelectionChange = useCallback(
selection => {
if (onSelectionChange) {
onSelectionChange(selection);
}
},
[onSelectionChange]
);
const Root = useMemo(
() => fromRenderProp(render, Object.keys(customProps)),
[render, customProps]
);
return (
<Root className={classes.root} {...customProps} {...restProps}>
<Items
getItemKey={getItemKey}
initialSelection={initialSelection}
items={items}
renderItem={renderItem}
selectionModel={selectionModel}
onSelectionChange={handleSelectionChange}
/>
</Root>
);
};
/**
* props for {@link List}
*
* @typedef props
*
* @property {Object} classes css classes prop for List
* @property {string} classes.root css classes for List root container
* @property {func} getItemKey item key value getter
* @property {array | object} initialSelection A single or list of objects that should start off selected
* @property {iterable} items An iterable that yields `[key, item]` pairs such as an ES2015 Map
* @property {func | string} render A render prop for the list element. A tagname string, such as `"div"`, is also valid.
* @property {func | string} renderItem A render prop for the list item elements. A tagname string, such as `"div"`, is also valid
* @property {func} onSelectionChange A callback that fires when the selection state changes
* @property {checkbox | radio} selectionModel A string corresponding to a selection model
*/
List.propTypes = {
classes: shape({
root: string
}),
getItemKey: func.isRequired,
initialSelection: oneOfType([array, object]),
items: iterable.isRequired,
render: oneOfType([func, string]).isRequired,
renderItem: oneOfType([func, string]),
onSelectionChange: func,
selectionModel: oneOf(['checkbox', 'radio'])
};
/**
* default props for {@link List}
*
* @typedef defaultProps
*/
List.defaultProps = {
classes: {},
getItemKey: ({ id }) => id,
items: [],
render: 'div',
renderItem: 'div',
selectionModel: 'radio'
};
export default List;