1 | import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
2 | import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
|
3 | import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
4 | import * as React from 'react';
|
5 | import KeyCode from "rc-util/es/KeyCode";
|
6 | import pickAttrs from "rc-util/es/pickAttrs";
|
7 | import useMemo from "rc-util/es/hooks/useMemo";
|
8 | import classNames from 'classnames';
|
9 | import List from 'rc-virtual-list';
|
10 | import TransBtn from './TransBtn';
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 | var OptionList = function OptionList(_ref, ref) {
|
17 | var prefixCls = _ref.prefixCls,
|
18 | id = _ref.id,
|
19 | flattenOptions = _ref.flattenOptions,
|
20 | childrenAsData = _ref.childrenAsData,
|
21 | values = _ref.values,
|
22 | searchValue = _ref.searchValue,
|
23 | multiple = _ref.multiple,
|
24 | defaultActiveFirstOption = _ref.defaultActiveFirstOption,
|
25 | height = _ref.height,
|
26 | itemHeight = _ref.itemHeight,
|
27 | notFoundContent = _ref.notFoundContent,
|
28 | open = _ref.open,
|
29 | menuItemSelectedIcon = _ref.menuItemSelectedIcon,
|
30 | virtual = _ref.virtual,
|
31 | onSelect = _ref.onSelect,
|
32 | onToggleOpen = _ref.onToggleOpen,
|
33 | onActiveValue = _ref.onActiveValue,
|
34 | onScroll = _ref.onScroll,
|
35 | onMouseEnter = _ref.onMouseEnter;
|
36 | var itemPrefixCls = "".concat(prefixCls, "-item");
|
37 | var memoFlattenOptions = useMemo(function () {
|
38 | return flattenOptions;
|
39 | }, [open, flattenOptions], function (prev, next) {
|
40 | return next[0] && prev[1] !== next[1];
|
41 | });
|
42 |
|
43 | var listRef = React.useRef(null);
|
44 |
|
45 | var onListMouseDown = function onListMouseDown(event) {
|
46 | event.preventDefault();
|
47 | };
|
48 |
|
49 | var scrollIntoView = function scrollIntoView(index) {
|
50 | if (listRef.current) {
|
51 | listRef.current.scrollTo({
|
52 | index: index
|
53 | });
|
54 | }
|
55 | };
|
56 |
|
57 |
|
58 | var getEnabledActiveIndex = function getEnabledActiveIndex(index) {
|
59 | var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
60 | var len = memoFlattenOptions.length;
|
61 |
|
62 | for (var i = 0; i < len; i += 1) {
|
63 | var current = (index + i * offset + len) % len;
|
64 | var _memoFlattenOptions$c = memoFlattenOptions[current],
|
65 | group = _memoFlattenOptions$c.group,
|
66 | data = _memoFlattenOptions$c.data;
|
67 |
|
68 | if (!group && !data.disabled) {
|
69 | return current;
|
70 | }
|
71 | }
|
72 |
|
73 | return -1;
|
74 | };
|
75 |
|
76 | var _React$useState = React.useState(function () {
|
77 | return getEnabledActiveIndex(0);
|
78 | }),
|
79 | _React$useState2 = _slicedToArray(_React$useState, 2),
|
80 | activeIndex = _React$useState2[0],
|
81 | setActiveIndex = _React$useState2[1];
|
82 |
|
83 | var setActive = function setActive(index) {
|
84 | setActiveIndex(index);
|
85 |
|
86 | var flattenItem = memoFlattenOptions[index];
|
87 |
|
88 | if (!flattenItem) {
|
89 | onActiveValue(null, -1);
|
90 | return;
|
91 | }
|
92 |
|
93 | onActiveValue(flattenItem.data.value, index);
|
94 | };
|
95 |
|
96 |
|
97 | React.useEffect(function () {
|
98 | setActive(defaultActiveFirstOption !== false ? getEnabledActiveIndex(0) : -1);
|
99 | }, [memoFlattenOptions.length, searchValue]);
|
100 |
|
101 | React.useEffect(function () {
|
102 | |
103 |
|
104 |
|
105 |
|
106 |
|
107 | var timeoutId = setTimeout(function () {
|
108 | if (!multiple && open && values.size === 1) {
|
109 | var value = Array.from(values)[0];
|
110 | var index = memoFlattenOptions.findIndex(function (_ref2) {
|
111 | var data = _ref2.data;
|
112 | return data.value === value;
|
113 | });
|
114 | setActive(index);
|
115 | scrollIntoView(index);
|
116 | }
|
117 | });
|
118 | return function () {
|
119 | return clearTimeout(timeoutId);
|
120 | };
|
121 | }, [open]);
|
122 |
|
123 | var onSelectValue = function onSelectValue(value) {
|
124 | if (value !== undefined) {
|
125 | onSelect(value, {
|
126 | selected: !values.has(value)
|
127 | });
|
128 | }
|
129 |
|
130 |
|
131 | if (!multiple) {
|
132 | onToggleOpen(false);
|
133 | }
|
134 | };
|
135 |
|
136 |
|
137 | React.useImperativeHandle(ref, function () {
|
138 | return {
|
139 | onKeyDown: function onKeyDown(event) {
|
140 | var which = event.which;
|
141 |
|
142 | switch (which) {
|
143 |
|
144 | case KeyCode.UP:
|
145 | case KeyCode.DOWN:
|
146 | {
|
147 | var offset = 0;
|
148 |
|
149 | if (which === KeyCode.UP) {
|
150 | offset = -1;
|
151 | } else if (which === KeyCode.DOWN) {
|
152 | offset = 1;
|
153 | }
|
154 |
|
155 | if (offset !== 0) {
|
156 | var nextActiveIndex = getEnabledActiveIndex(activeIndex + offset, offset);
|
157 | scrollIntoView(nextActiveIndex);
|
158 | setActive(nextActiveIndex);
|
159 | }
|
160 |
|
161 | break;
|
162 | }
|
163 |
|
164 |
|
165 | case KeyCode.ENTER:
|
166 | {
|
167 |
|
168 | var item = memoFlattenOptions[activeIndex];
|
169 |
|
170 | if (item && !item.data.disabled) {
|
171 | onSelectValue(item.data.value);
|
172 | } else {
|
173 | onSelectValue(undefined);
|
174 | }
|
175 |
|
176 | if (open) {
|
177 | event.preventDefault();
|
178 | }
|
179 |
|
180 | break;
|
181 | }
|
182 |
|
183 |
|
184 | case KeyCode.ESC:
|
185 | {
|
186 | onToggleOpen(false);
|
187 | }
|
188 | }
|
189 | },
|
190 | onKeyUp: function onKeyUp() {},
|
191 | scrollTo: function scrollTo(index) {
|
192 | scrollIntoView(index);
|
193 | }
|
194 | };
|
195 | });
|
196 |
|
197 | if (memoFlattenOptions.length === 0) {
|
198 | return React.createElement("div", {
|
199 | role: "listbox",
|
200 | id: "".concat(id, "_list"),
|
201 | className: "".concat(itemPrefixCls, "-empty"),
|
202 | onMouseDown: onListMouseDown
|
203 | }, notFoundContent);
|
204 | }
|
205 |
|
206 | function renderItem(index) {
|
207 | var item = memoFlattenOptions[index];
|
208 | if (!item) return null;
|
209 | var itemData = item.data || {};
|
210 | var value = itemData.value,
|
211 | label = itemData.label,
|
212 | children = itemData.children;
|
213 | var attrs = pickAttrs(itemData, true);
|
214 | var mergedLabel = childrenAsData ? children : label;
|
215 | return item ? React.createElement("div", Object.assign({
|
216 | "aria-label": typeof mergedLabel === 'string' ? mergedLabel : null
|
217 | }, attrs, {
|
218 | key: index,
|
219 | role: "option",
|
220 | id: "".concat(id, "_list_").concat(index),
|
221 | "aria-selected": values.has(value)
|
222 | }), value) : null;
|
223 | }
|
224 |
|
225 | return React.createElement(React.Fragment, null, React.createElement("div", {
|
226 | role: "listbox",
|
227 | id: "".concat(id, "_list"),
|
228 | style: {
|
229 | height: 0,
|
230 | width: 0,
|
231 | overflow: 'hidden'
|
232 | }
|
233 | }, renderItem(activeIndex - 1), renderItem(activeIndex), renderItem(activeIndex + 1)), React.createElement(List, {
|
234 | itemKey: "key",
|
235 | ref: listRef,
|
236 | data: memoFlattenOptions,
|
237 | height: height,
|
238 | itemHeight: itemHeight,
|
239 | fullHeight: false,
|
240 | onMouseDown: onListMouseDown,
|
241 | onScroll: onScroll,
|
242 | virtual: virtual,
|
243 | onMouseEnter: onMouseEnter
|
244 | }, function (_ref3, itemIndex) {
|
245 | var _classNames;
|
246 |
|
247 | var group = _ref3.group,
|
248 | groupOption = _ref3.groupOption,
|
249 | data = _ref3.data;
|
250 | var label = data.label,
|
251 | key = data.key;
|
252 |
|
253 | if (group) {
|
254 | return React.createElement("div", {
|
255 | className: classNames(itemPrefixCls, "".concat(itemPrefixCls, "-group"))
|
256 | }, label !== undefined ? label : key);
|
257 | }
|
258 |
|
259 | var disabled = data.disabled,
|
260 | value = data.value,
|
261 | title = data.title,
|
262 | children = data.children,
|
263 | style = data.style,
|
264 | className = data.className,
|
265 | otherProps = _objectWithoutProperties(data, ["disabled", "value", "title", "children", "style", "className"]);
|
266 |
|
267 |
|
268 | var selected = values.has(value);
|
269 | var optionPrefixCls = "".concat(itemPrefixCls, "-option");
|
270 | var optionClassName = classNames(itemPrefixCls, optionPrefixCls, className, (_classNames = {}, _defineProperty(_classNames, "".concat(optionPrefixCls, "-grouped"), groupOption), _defineProperty(_classNames, "".concat(optionPrefixCls, "-active"), activeIndex === itemIndex && !disabled), _defineProperty(_classNames, "".concat(optionPrefixCls, "-disabled"), disabled), _defineProperty(_classNames, "".concat(optionPrefixCls, "-selected"), selected), _classNames));
|
271 | var mergedLabel = childrenAsData ? children : label;
|
272 | var iconVisible = !menuItemSelectedIcon || typeof menuItemSelectedIcon === 'function' || selected;
|
273 | return React.createElement("div", Object.assign({}, otherProps, {
|
274 | "aria-selected": selected,
|
275 | className: optionClassName,
|
276 | title: title,
|
277 | onMouseMove: function onMouseMove() {
|
278 | if (activeIndex === itemIndex || disabled) {
|
279 | return;
|
280 | }
|
281 |
|
282 | setActive(itemIndex);
|
283 | },
|
284 | onClick: function onClick() {
|
285 | if (!disabled) {
|
286 | onSelectValue(value);
|
287 | }
|
288 | },
|
289 | style: style
|
290 | }), React.createElement("div", {
|
291 | className: "".concat(optionPrefixCls, "-content")
|
292 | }, mergedLabel || value), React.isValidElement(menuItemSelectedIcon) || selected, iconVisible && React.createElement(TransBtn, {
|
293 | className: "".concat(itemPrefixCls, "-option-state"),
|
294 | customizeIcon: menuItemSelectedIcon,
|
295 | customizeIconProps: {
|
296 | isSelected: selected
|
297 | }
|
298 | }, selected ? '✓' : null));
|
299 | }));
|
300 | };
|
301 |
|
302 | var RefOptionList = React.forwardRef(OptionList);
|
303 | RefOptionList.displayName = 'OptionList';
|
304 | export default RefOptionList; |
\ | No newline at end of file |