1 | import React, { Fragment, useMemo } from 'react';
|
2 | import { array, func, object, oneOf, oneOfType, string } from 'prop-types';
|
3 |
|
4 | import iterable from '../validators/iterable';
|
5 | import Item from './item';
|
6 | import { useListState } from './useListState';
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 | const Items = props => {
|
19 | const {
|
20 | getItemKey,
|
21 | initialSelection,
|
22 | items,
|
23 | onSelectionChange,
|
24 | renderItem,
|
25 | selectionModel
|
26 | } = props;
|
27 |
|
28 | const [state, api] = useListState({
|
29 | getItemKey,
|
30 | initialSelection,
|
31 | onSelectionChange,
|
32 | selectionModel
|
33 | });
|
34 | const { cursor, hasFocus, selectedKeys } = state;
|
35 | const { removeFocus, setFocus, updateSelectedKeys } = api;
|
36 |
|
37 | const children = useMemo(() => {
|
38 | return Array.from(items, (item, index) => {
|
39 | const key = getItemKey(item, index);
|
40 |
|
41 | return (
|
42 | <Item
|
43 | hasFocus={hasFocus && cursor === key}
|
44 | isSelected={selectedKeys.has(key)}
|
45 | item={item}
|
46 | itemIndex={index}
|
47 | key={key}
|
48 | onBlur={removeFocus}
|
49 | render={renderItem}
|
50 | setFocus={setFocus}
|
51 | uniqueId={key}
|
52 | updateSelectedKeys={updateSelectedKeys}
|
53 | />
|
54 | );
|
55 | });
|
56 | }, [
|
57 | cursor,
|
58 | getItemKey,
|
59 | hasFocus,
|
60 | items,
|
61 | removeFocus,
|
62 | renderItem,
|
63 | selectedKeys,
|
64 | setFocus,
|
65 | updateSelectedKeys
|
66 | ]);
|
67 |
|
68 | return <Fragment>{children}</Fragment>;
|
69 | };
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 |
|
79 |
|
80 |
|
81 |
|
82 |
|
83 | Items.propTypes = {
|
84 | getItemKey: func.isRequired,
|
85 | initialSelection: oneOfType([array, object]),
|
86 | items: iterable.isRequired,
|
87 | onSelectionChange: func,
|
88 | renderItem: oneOfType([func, string]),
|
89 | selectionModel: oneOf(['checkbox', 'radio'])
|
90 | };
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 | Items.defaultProps = {
|
98 | getItemKey: ({ id }) => id,
|
99 | selectionModel: 'radio'
|
100 | };
|
101 |
|
102 | export default Items;
|