1 | "use strict";
|
2 |
|
3 | exports.__esModule = true;
|
4 | exports.useHandleSelect = useHandleSelect;
|
5 | exports.default = exports.useScrollFocusedIntoView = void 0;
|
6 |
|
7 | var _classnames = _interopRequireDefault(require("classnames"));
|
8 |
|
9 | var _propTypes = _interopRequireDefault(require("prop-types"));
|
10 |
|
11 | var _react = _interopRequireWildcard(require("react"));
|
12 |
|
13 | var _ListOption = _interopRequireDefault(require("./ListOption"));
|
14 |
|
15 | var _ListOptionGroup = _interopRequireDefault(require("./ListOptionGroup"));
|
16 |
|
17 | var _messages = require("./messages");
|
18 |
|
19 | var CustomPropTypes = _interopRequireWildcard(require("./PropTypes"));
|
20 |
|
21 | var _ = require("./_");
|
22 |
|
23 | var _WidgetHelpers = require("./WidgetHelpers");
|
24 |
|
25 | var _useMutationObserver = _interopRequireDefault(require("@restart/hooks/useMutationObserver"));
|
26 |
|
27 | var _useCallbackRef = _interopRequireDefault(require("@restart/hooks/useCallbackRef"));
|
28 |
|
29 | var _useMergedRefs = _interopRequireDefault(require("@restart/hooks/useMergedRefs"));
|
30 |
|
31 | const _excluded = ["multiple", "data", "value", "onChange", "accessors", "className", "messages", "disabled", "renderItem", "renderGroup", "searchTerm", "groupBy", "elementRef", "optionComponent", "renderList"];
|
32 |
|
33 | function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
34 |
|
35 | function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
36 |
|
37 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
38 |
|
39 | function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
40 |
|
41 | const whitelist = ['style', 'className', 'role', 'id', 'autocomplete', 'size', 'tabIndex', 'maxLength', 'name'];
|
42 | const whitelistRegex = [/^aria-/, /^data-/, /^on[A-Z]\w+/];
|
43 |
|
44 | function pickElementProps(props) {
|
45 | const result = {};
|
46 | Object.keys(props).forEach(key => {
|
47 | if (whitelist.indexOf(key) !== -1 || whitelistRegex.some(r => !!key.match(r))) result[key] = props[key];
|
48 | });
|
49 | return result;
|
50 | }
|
51 |
|
52 | const propTypes = {
|
53 | data: _propTypes.default.array,
|
54 | dataKey: CustomPropTypes.accessor,
|
55 | textField: CustomPropTypes.accessor,
|
56 | onSelect: _propTypes.default.func,
|
57 | onMove: _propTypes.default.func,
|
58 | onHoverOption: _propTypes.default.func,
|
59 | optionComponent: _propTypes.default.elementType,
|
60 | renderItem: _propTypes.default.func,
|
61 | renderGroup: _propTypes.default.func,
|
62 | focusedItem: _propTypes.default.any,
|
63 | selectedItem: _propTypes.default.any,
|
64 | searchTerm: _propTypes.default.string,
|
65 | disabled: CustomPropTypes.disabled.acceptsArray,
|
66 | messages: _propTypes.default.shape({
|
67 | emptyList: _propTypes.default.func.isRequired
|
68 | })
|
69 | };
|
70 |
|
71 | const useScrollFocusedIntoView = (element, observeChanges = false) => {
|
72 | const scrollIntoView = (0, _react.useCallback)(() => {
|
73 | if (!element) return;
|
74 | let selectedItem = element.querySelector('[data-rw-focused]');
|
75 |
|
76 | if (selectedItem && selectedItem.scrollIntoView) {
|
77 | selectedItem.scrollIntoView({
|
78 | block: 'nearest',
|
79 | inline: 'nearest'
|
80 | });
|
81 | }
|
82 | }, [element]);
|
83 | (0, _useMutationObserver.default)(observeChanges ? element : null, {
|
84 | subtree: true,
|
85 | attributes: true,
|
86 | attributeFilter: ['data-rw-focused']
|
87 | }, scrollIntoView);
|
88 | return scrollIntoView;
|
89 | };
|
90 |
|
91 | exports.useScrollFocusedIntoView = useScrollFocusedIntoView;
|
92 |
|
93 | function useHandleSelect(multiple, dataItems, onChange) {
|
94 | return (dataItem, event) => {
|
95 | if (multiple === false) {
|
96 | onChange(dataItem, {
|
97 | dataItem,
|
98 | lastValue: dataItems[0],
|
99 | originalEvent: event
|
100 | });
|
101 | return;
|
102 | }
|
103 |
|
104 | const checked = dataItems.includes(dataItem);
|
105 | onChange(checked ? dataItems.filter(d => d !== dataItem) : [...dataItems, dataItem], {
|
106 | dataItem,
|
107 | lastValue: dataItems,
|
108 | action: checked ? 'remove' : 'insert',
|
109 | originalEvent: event
|
110 | });
|
111 | };
|
112 | }
|
113 |
|
114 | const List = _react.default.forwardRef(function List(_ref, outerRef) {
|
115 | var _elementProps$role;
|
116 |
|
117 | let {
|
118 | multiple = false,
|
119 | data = [],
|
120 | value,
|
121 | onChange,
|
122 | accessors,
|
123 | className,
|
124 | messages,
|
125 | disabled,
|
126 | renderItem,
|
127 | renderGroup,
|
128 | searchTerm,
|
129 | groupBy,
|
130 | elementRef,
|
131 | optionComponent: Option = _ListOption.default,
|
132 | renderList
|
133 | } = _ref,
|
134 | props = _objectWithoutPropertiesLoose(_ref, _excluded);
|
135 |
|
136 | const id = (0, _WidgetHelpers.useInstanceId)();
|
137 | const dataItems = (0, _.makeArray)(value, multiple);
|
138 | const groupedData = (0, _react.useMemo)(() => groupBy ? (0, _.groupBySortedKeys)(groupBy, data) : undefined, [data, groupBy]);
|
139 | const [element, ref] = (0, _useCallbackRef.default)();
|
140 | const disabledItems = (0, _.toItemArray)(disabled);
|
141 | const {
|
142 | emptyList
|
143 | } = (0, _messages.useMessagesWithDefaults)(messages);
|
144 | const divRef = (0, _useMergedRefs.default)(ref, elementRef);
|
145 | const handleSelect = useHandleSelect(multiple, dataItems, onChange);
|
146 | const scrollIntoView = useScrollFocusedIntoView(element, true);
|
147 | let elementProps = pickElementProps(props);
|
148 | (0, _react.useImperativeHandle)(outerRef, () => ({
|
149 | scrollIntoView
|
150 | }), [scrollIntoView]);
|
151 |
|
152 | function renderOption(item, idx) {
|
153 | const textValue = accessors.text(item);
|
154 | const itemIsDisabled = disabledItems.includes(item);
|
155 | const itemIsSelected = dataItems.includes(item);
|
156 | return _react.default.createElement(Option, {
|
157 | dataItem: item,
|
158 | key: `item_${idx}`,
|
159 | searchTerm: searchTerm,
|
160 | onSelect: handleSelect,
|
161 | disabled: itemIsDisabled,
|
162 | selected: itemIsSelected
|
163 | }, renderItem ? renderItem({
|
164 | item,
|
165 | searchTerm,
|
166 | index: idx,
|
167 | text: textValue,
|
168 |
|
169 | value: accessors.value(item),
|
170 | disabled: itemIsDisabled
|
171 | }) : textValue);
|
172 | }
|
173 |
|
174 | const items = groupedData ? groupedData.map(([group, items], idx) => _react.default.createElement("div", {
|
175 | role: "group",
|
176 | key: `group_${idx}`
|
177 | }, _react.default.createElement(_ListOptionGroup.default, null, renderGroup ? renderGroup({
|
178 | group
|
179 | }) : group), items.map(renderOption))) : data.map(renderOption);
|
180 | const rootProps = Object.assign({
|
181 | id,
|
182 | tabIndex: 0,
|
183 | ref: divRef
|
184 | }, elementProps, {
|
185 | 'aria-multiselectable': !!multiple,
|
186 | className: (0, _classnames.default)(className, 'rw-list'),
|
187 | role: (_elementProps$role = elementProps.role) != null ? _elementProps$role : 'listbox',
|
188 | children: _react.default.Children.count(items) ? items : _react.default.createElement("div", {
|
189 | className: "rw-list-empty"
|
190 | }, emptyList())
|
191 | });
|
192 | return renderList ? renderList(rootProps) : _react.default.createElement("div", rootProps);
|
193 | });
|
194 |
|
195 | List.displayName = 'List';
|
196 | List.propTypes = propTypes;
|
197 | var _default = List;
|
198 | exports.default = _default; |
\ | No newline at end of file |