@salutejs/plasma-new-hope 0.120.0 → 0.121.0-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,561 @@
1
+ ---
2
+ id: autocomplete
3
+ title: Autocomplete
4
+ ---
5
+
6
+ import { PropsTable, Description } from '@site/src/components';
7
+ import Tabs from '@theme/Tabs';
8
+ import TabItem from '@theme/TabItem';
9
+
10
+ # Autocomplete
11
+ Поле ввода с подсказками в выпадающем списке.
12
+
13
+ <Description name="Autocomplete" />
14
+ <PropsTable name="Autocomplete" />
15
+
16
+ ## Использование
17
+ Расширенная версия компонента `TextField`. Добавилась возможность использования выпадающего списка с подсказками.\
18
+ По умолчанию подсказки фильтруются вне зависимости от регистра. Но это можно изменить, прокинув свой коллбэк `filter`.\
19
+ Все пропсы, которые поддерживает компонент `TextField` также поддерживаются и здесь.
20
+ Формат подсказок `suggestions` следующий:
21
+
22
+ ```tsx
23
+ type SuggestionItem = {
24
+ /**
25
+ * Метка-подпись к подсказке
26
+ */
27
+ label: string;
28
+ /**
29
+ * Слот для контента слева
30
+ */
31
+ contentLeft?: ReactNode;
32
+ /**
33
+ * Слот для контента справа
34
+ */
35
+ contentRight?: ReactNode;
36
+ };
37
+ ```
38
+
39
+ ## Примеры
40
+
41
+ <Tabs>
42
+ <TabItem value="default" label="Default" default>
43
+ ```tsx live
44
+ import React from 'react';
45
+ import { Autocomplete } from '@salutejs/{{ package }}';
46
+
47
+ export function App() {
48
+ const mockData = [
49
+ { label: 'Алексей Смирнов' },
50
+ { label: 'Екатерина Иванова' },
51
+ { label: 'Дмитрий Петров' },
52
+ { label: 'Ольга Васильева' },
53
+ { label: 'Сергей Сидоров' },
54
+ { label: 'Мария Кузнецова' },
55
+ { label: 'Андрей Попов' },
56
+ { label: 'Анна Николаева' },
57
+ { label: 'Иван Федоров' },
58
+ { label: 'Наталья Морозова' },
59
+ { label: 'Михаил Павлов' },
60
+ { label: 'Елена Романова' },
61
+ { label: 'Владимир Киселев' },
62
+ { label: 'Татьяна Захарова' },
63
+ { label: 'Николай Семенов' },
64
+ { label: 'Юлия Белова' },
65
+ { label: 'Александр Гусев' },
66
+ { label: 'Оксана Яковлева' },
67
+ { label: 'Игорь Егорова' },
68
+ { label: 'Вера Тихомирова' },
69
+ { label: 'Артем Григорьев' },
70
+ { label: 'Евгения Козлова' },
71
+ { label: 'Максим Лебедев' },
72
+ { label: 'Виктория Калашникова' },
73
+ { label: 'Константин Абрамов' },
74
+ { label: 'Светлана Новикова' },
75
+ { label: 'Юрий Волков' },
76
+ { label: 'Валентина Воробьева' },
77
+ { label: 'Павел Сергеев' },
78
+ { label: 'Людмила Виноградова' },
79
+ { label: 'Антон Соловьев' },
80
+ { label: 'Маргарита Цветкова' },
81
+ { label: 'Роман Трофимов' },
82
+ { label: 'Лариса Зайцева' },
83
+ { label: 'Евгений Никитин' },
84
+ { label: 'Галина Михайлова' },
85
+ { label: 'Владислав Антонов' },
86
+ { label: 'Дарья Филатова' },
87
+ { label: 'Олег Буров' },
88
+ { label: 'Инна Медведева' },
89
+ { label: 'Вячеслав Крылов' },
90
+ { label: 'Тамара Беляева' },
91
+ { label: 'Кирилл Марков' },
92
+ { label: 'Марина Пономарева' },
93
+ { label: 'Борис Захаров' },
94
+ { label: 'Жанна Савельева' },
95
+ { label: 'Федор Жуков' },
96
+ { label: 'Елизавета Логинова' },
97
+ { label: 'Виктор Рыбаков' },
98
+ { label: 'Лилия Макарова' },
99
+ ];
100
+
101
+ return (
102
+ <div style=\{{ display: 'block', height:"400px" }}>
103
+ <Autocomplete suggestions={mockData} listMaxHeight="250px" label="Label" placeholder="Placeholder" leftHelper="Введите имя Алексей" />
104
+ </div>
105
+ );
106
+ }
107
+ ```
108
+ </TabItem>
109
+ <TabItem value="controlled" label="Controlled">
110
+ ```tsx live
111
+ import React from 'react';
112
+ import { Autocomplete } from '@salutejs/{{ package }}';
113
+
114
+ export function App() {
115
+ const mockData = [
116
+ { label: 'Алексей Смирнов' },
117
+ { label: 'Екатерина Иванова' },
118
+ { label: 'Дмитрий Петров' },
119
+ { label: 'Ольга Васильева' },
120
+ { label: 'Сергей Сидоров' },
121
+ { label: 'Мария Кузнецова' },
122
+ { label: 'Андрей Попов' },
123
+ { label: 'Анна Николаева' },
124
+ { label: 'Иван Федоров' },
125
+ { label: 'Наталья Морозова' },
126
+ { label: 'Михаил Павлов' },
127
+ { label: 'Елена Романова' },
128
+ { label: 'Владимир Киселев' },
129
+ { label: 'Татьяна Захарова' },
130
+ { label: 'Николай Семенов' },
131
+ { label: 'Юлия Белова' },
132
+ { label: 'Александр Гусев' },
133
+ { label: 'Оксана Яковлева' },
134
+ { label: 'Игорь Егорова' },
135
+ { label: 'Вера Тихомирова' },
136
+ { label: 'Артем Григорьев' },
137
+ { label: 'Евгения Козлова' },
138
+ { label: 'Максим Лебедев' },
139
+ { label: 'Виктория Калашникова' },
140
+ { label: 'Константин Абрамов' },
141
+ { label: 'Светлана Новикова' },
142
+ { label: 'Юрий Волков' },
143
+ { label: 'Валентина Воробьева' },
144
+ { label: 'Павел Сергеев' },
145
+ { label: 'Людмила Виноградова' },
146
+ { label: 'Антон Соловьев' },
147
+ { label: 'Маргарита Цветкова' },
148
+ { label: 'Роман Трофимов' },
149
+ { label: 'Лариса Зайцева' },
150
+ { label: 'Евгений Никитин' },
151
+ { label: 'Галина Михайлова' },
152
+ { label: 'Владислав Антонов' },
153
+ { label: 'Дарья Филатова' },
154
+ { label: 'Олег Буров' },
155
+ { label: 'Инна Медведева' },
156
+ { label: 'Вячеслав Крылов' },
157
+ { label: 'Тамара Беляева' },
158
+ { label: 'Кирилл Марков' },
159
+ { label: 'Марина Пономарева' },
160
+ { label: 'Борис Захаров' },
161
+ { label: 'Жанна Савельева' },
162
+ { label: 'Федор Жуков' },
163
+ { label: 'Елизавета Логинова' },
164
+ { label: 'Виктор Рыбаков' },
165
+ { label: 'Лилия Макарова' },
166
+ ];
167
+
168
+ const [value, setValue] = useState('')
169
+
170
+ return (
171
+ <div style=\{{ display: 'block', height:"400px" }}>
172
+ <Autocomplete value={value} onChange={(e) => setValue(e.target.value)} onSuggestionSelect={(e) => setValue(e.label)} suggestions={mockData} listMaxHeight="250px" label="Label" placeholder="Placeholder" leftHelper="Введите имя Алексей" />
173
+ </div>
174
+ );
175
+ }
176
+ ```
177
+ </TabItem>
178
+ <TabItem value="infinite" label="Infinite Loading">
179
+ Это пример с бесконечным лоадингом подсказок в списке. Для удобства порог для открытия списка подсказок понижен до 0 (открываться будет сразу при фокусе).
180
+
181
+ ```tsx live
182
+ import React from 'react';
183
+ import { Autocomplete, Cell, Spinner } from '@salutejs/{{ package }}';
184
+
185
+ export function App() {
186
+ const mockData = [
187
+ { label: 'Алексей Смирнов' },
188
+ { label: 'Екатерина Иванова' },
189
+ { label: 'Дмитрий Петров' },
190
+ { label: 'Ольга Васильева' },
191
+ { label: 'Сергей Сидоров' },
192
+ { label: 'Мария Кузнецова' },
193
+ { label: 'Андрей Попов' },
194
+ { label: 'Анна Николаева' },
195
+ { label: 'Иван Федоров' },
196
+ { label: 'Наталья Морозова' },
197
+ { label: 'Михаил Павлов' },
198
+ { label: 'Елена Романова' },
199
+ { label: 'Владимир Киселев' },
200
+ { label: 'Татьяна Захарова' },
201
+ { label: 'Николай Семенов' },
202
+ { label: 'Юлия Белова' },
203
+ { label: 'Александр Гусев' },
204
+ { label: 'Оксана Яковлева' },
205
+ { label: 'Игорь Егорова' },
206
+ { label: 'Вера Тихомирова' },
207
+ { label: 'Артем Григорьев' },
208
+ { label: 'Евгения Козлова' },
209
+ { label: 'Максим Лебедев' },
210
+ { label: 'Виктория Калашникова' },
211
+ { label: 'Константин Абрамов' },
212
+ { label: 'Светлана Новикова' },
213
+ { label: 'Юрий Волков' },
214
+ { label: 'Валентина Воробьева' },
215
+ { label: 'Павел Сергеев' },
216
+ { label: 'Людмила Виноградова' },
217
+ { label: 'Антон Соловьев' },
218
+ { label: 'Маргарита Цветкова' },
219
+ { label: 'Роман Трофимов' },
220
+ { label: 'Лариса Зайцева' },
221
+ { label: 'Евгений Никитин' },
222
+ { label: 'Галина Михайлова' },
223
+ { label: 'Владислав Антонов' },
224
+ { label: 'Дарья Филатова' },
225
+ { label: 'Олег Буров' },
226
+ { label: 'Инна Медведева' },
227
+ { label: 'Вячеслав Крылов' },
228
+ { label: 'Тамара Беляева' },
229
+ { label: 'Кирилл Марков' },
230
+ { label: 'Марина Пономарева' },
231
+ { label: 'Борис Захаров' },
232
+ { label: 'Жанна Савельева' },
233
+ { label: 'Федор Жуков' },
234
+ { label: 'Елизавета Логинова' },
235
+ { label: 'Виктор Рыбаков' },
236
+ { label: 'Лилия Макарова' },
237
+ ];
238
+
239
+ const getData = async (data, page, pageSize = 10) => {
240
+ return new Promise((resolve) => {
241
+ setTimeout(() => {
242
+ resolve({page, data: data.slice(page * pageSize - 1, page * pageSize - 1 + pageSize)})
243
+ }, 1500)
244
+ })
245
+ }
246
+
247
+ const [suggestions, setSuggestions] = useState({ page: 1, data: mockData.slice(0, 10) })
248
+ const [isInfiniteLoading, setIsInfiniteLoading] = useState(false)
249
+
250
+ const onScroll = async (e) => {
251
+ if (isInfiniteLoading) return
252
+
253
+ if (e.target.scrollTop + e.target.offsetHeight + 10 > e.target.scrollHeight) {
254
+ setIsInfiniteLoading(true)
255
+
256
+ const res = await getData(mockData, suggestions.page + 1, 10)
257
+ setSuggestions({page: res.page, data: [...suggestions.data, ...res.data]})
258
+
259
+ setIsInfiniteLoading(false)
260
+ }
261
+ };
262
+
263
+ return (
264
+ <div style=\{{ display: 'block', height:"400px" }}>
265
+ <Autocomplete
266
+ suggestions={suggestions.data}
267
+ listMaxHeight="250px"
268
+ onScroll={onScroll}
269
+ threshold={0}
270
+ renderListEnd={isInfiniteLoading ? () => <Cell contentLeft={<Spinner view="primary" />} title="Загрузка" stretching="auto" /> : undefined}
271
+ label="Label"
272
+ placeholder="Placeholder"
273
+ leftHelper="Введите имя Алексей"
274
+ />
275
+ </div>
276
+ );
277
+ }
278
+ ```
279
+ </TabItem>
280
+ <TabItem value="filter" label="Custom Filter">
281
+ Пример кастомной фильтрации на бекенде. Не забываем отключить дефолтную фильтрацию.
282
+
283
+ ```tsx live
284
+ import React from 'react';
285
+ import { Autocomplete } from '@salutejs/{{ package }}';
286
+
287
+ export function App() {
288
+ const mockData = [
289
+ { label: 'Алексей Смирнов' },
290
+ { label: 'Екатерина Иванова' },
291
+ { label: 'Дмитрий Петров' },
292
+ { label: 'Ольга Васильева' },
293
+ { label: 'Сергей Сидоров' },
294
+ { label: 'Мария Кузнецова' },
295
+ { label: 'Андрей Попов' },
296
+ { label: 'Анна Николаева' },
297
+ { label: 'Иван Федоров' },
298
+ { label: 'Наталья Морозова' },
299
+ { label: 'Михаил Павлов' },
300
+ { label: 'Елена Романова' },
301
+ { label: 'Владимир Киселев' },
302
+ { label: 'Татьяна Захарова' },
303
+ { label: 'Николай Семенов' },
304
+ { label: 'Юлия Белова' },
305
+ { label: 'Александр Гусев' },
306
+ { label: 'Оксана Яковлева' },
307
+ { label: 'Игорь Егорова' },
308
+ { label: 'Вера Тихомирова' },
309
+ { label: 'Артем Григорьев' },
310
+ { label: 'Евгения Козлова' },
311
+ { label: 'Максим Лебедев' },
312
+ { label: 'Виктория Калашникова' },
313
+ { label: 'Константин Абрамов' },
314
+ { label: 'Светлана Новикова' },
315
+ { label: 'Юрий Волков' },
316
+ { label: 'Валентина Воробьева' },
317
+ { label: 'Павел Сергеев' },
318
+ { label: 'Людмила Виноградова' },
319
+ { label: 'Антон Соловьев' },
320
+ { label: 'Маргарита Цветкова' },
321
+ { label: 'Роман Трофимов' },
322
+ { label: 'Лариса Зайцева' },
323
+ { label: 'Евгений Никитин' },
324
+ { label: 'Галина Михайлова' },
325
+ { label: 'Владислав Антонов' },
326
+ { label: 'Дарья Филатова' },
327
+ { label: 'Олег Буров' },
328
+ { label: 'Инна Медведева' },
329
+ { label: 'Вячеслав Крылов' },
330
+ { label: 'Тамара Беляева' },
331
+ { label: 'Кирилл Марков' },
332
+ { label: 'Марина Пономарева' },
333
+ { label: 'Борис Захаров' },
334
+ { label: 'Жанна Савельева' },
335
+ { label: 'Федор Жуков' },
336
+ { label: 'Елизавета Логинова' },
337
+ { label: 'Виктор Рыбаков' },
338
+ { label: 'Лилия Макарова' },
339
+ ];
340
+
341
+ const [value, setValue] = useState('')
342
+ const [suggestions, setSuggestions] = useState(mockData)
343
+
344
+
345
+ const getData = async (value) => {
346
+ return new Promise((resolve) => {
347
+ setTimeout(() => {
348
+ resolve(mockData.filter(({ label }) => label.toLowerCase().includes(value.toString().toLowerCase())))
349
+ }, 200)
350
+ })
351
+ }
352
+
353
+ useEffect(() => {
354
+ getData(value).then(setSuggestions)
355
+ }, [value])
356
+
357
+ return (
358
+ <div style=\{{ display: 'block', height:"400px" }}>
359
+ <Autocomplete
360
+ value={value}
361
+ onChange={(e) => setValue(e.target.value)}
362
+ onSuggestionSelect={(e) => setValue(e.label)}
363
+ suggestions={suggestions}
364
+ listMaxHeight="250px"
365
+ filter={() => true} // Отключаем дефолтную фильтрацию
366
+ label="Label"
367
+ placeholder="Placeholder"
368
+ leftHelper="Введите имя Алексей"
369
+ />
370
+ </div>
371
+ );
372
+ }
373
+ ```
374
+ </TabItem>
375
+ <TabItem value="emptyState" label="Empty State">
376
+ Если произошла ошибка, или же к примеру нужно показать некую информацию пользователю, то для этой цели можно использовать компонент `EmptyState`.
377
+
378
+ ```tsx live
379
+ import React from 'react';
380
+ import { Autocomplete, EmptyState, Spinner } from '@salutejs/{{ package }}';
381
+ import { IconRefresh } from '@salutejs/plasma-icons';
382
+
383
+ export function App() {
384
+ const mockData = [
385
+ { label: 'Алексей Смирнов' },
386
+ { label: 'Екатерина Иванова' },
387
+ { label: 'Дмитрий Петров' },
388
+ { label: 'Ольга Васильева' },
389
+ { label: 'Сергей Сидоров' },
390
+ { label: 'Мария Кузнецова' },
391
+ { label: 'Андрей Попов' },
392
+ { label: 'Анна Николаева' },
393
+ { label: 'Иван Федоров' },
394
+ { label: 'Наталья Морозова' },
395
+ { label: 'Михаил Павлов' },
396
+ { label: 'Елена Романова' },
397
+ { label: 'Владимир Киселев' },
398
+ { label: 'Татьяна Захарова' },
399
+ { label: 'Николай Семенов' },
400
+ { label: 'Юлия Белова' },
401
+ { label: 'Александр Гусев' },
402
+ { label: 'Оксана Яковлева' },
403
+ { label: 'Игорь Егорова' },
404
+ { label: 'Вера Тихомирова' },
405
+ { label: 'Артем Григорьев' },
406
+ { label: 'Евгения Козлова' },
407
+ { label: 'Максим Лебедев' },
408
+ { label: 'Виктория Калашникова' },
409
+ { label: 'Константин Абрамов' },
410
+ { label: 'Светлана Новикова' },
411
+ { label: 'Юрий Волков' },
412
+ { label: 'Валентина Воробьева' },
413
+ { label: 'Павел Сергеев' },
414
+ { label: 'Людмила Виноградова' },
415
+ { label: 'Антон Соловьев' },
416
+ { label: 'Маргарита Цветкова' },
417
+ { label: 'Роман Трофимов' },
418
+ { label: 'Лариса Зайцева' },
419
+ { label: 'Евгений Никитин' },
420
+ { label: 'Галина Михайлова' },
421
+ { label: 'Владислав Антонов' },
422
+ { label: 'Дарья Филатова' },
423
+ { label: 'Олег Буров' },
424
+ { label: 'Инна Медведева' },
425
+ { label: 'Вячеслав Крылов' },
426
+ { label: 'Тамара Беляева' },
427
+ { label: 'Кирилл Марков' },
428
+ { label: 'Марина Пономарева' },
429
+ { label: 'Борис Захаров' },
430
+ { label: 'Жанна Савельева' },
431
+ { label: 'Федор Жуков' },
432
+ { label: 'Елизавета Логинова' },
433
+ { label: 'Виктор Рыбаков' },
434
+ { label: 'Лилия Макарова' },
435
+ ];
436
+
437
+ const getData = async () => {
438
+ return new Promise((resolve) => {
439
+ setTimeout(() => {
440
+ resolve(mockData)
441
+ }, 1500)
442
+ })
443
+ }
444
+
445
+ const [isError, setIsError] = useState(true)
446
+ const [isLoading, setIsLoading] = useState(false)
447
+ const [value, setValue] = useState('')
448
+ const [suggestions, setSuggestions] = useState([])
449
+
450
+ const handleGetData = async () => {
451
+ setIsLoading(true)
452
+
453
+ const res = await getData()
454
+
455
+ setIsLoading(false)
456
+ setIsError(false)
457
+ setSuggestions(res)
458
+ }
459
+
460
+ return (
461
+ <div style=\{{ display: 'block', height:"400px" }}>
462
+ <Autocomplete
463
+ value={value}
464
+ onChange={(e) => setValue(e.target.value)}
465
+ onSuggestionSelect={(e) => setValue(e.label)}
466
+ suggestions={suggestions}
467
+ listMaxHeight="250px"
468
+ renderList={isError ? () => <EmptyState icon={<IconRefresh />} description="Произошла ошибка. Попробуйте обновить." buttonText="Обновить" buttonAction={handleGetData} /> : undefined}
469
+ contentRight={isLoading ? <Spinner view="primary" /> : undefined}
470
+ label="Label"
471
+ placeholder="Placeholder"
472
+ leftHelper="Введите имя Алексей"
473
+ />
474
+ </div>
475
+ );
476
+ }
477
+ ```
478
+ </TabItem>
479
+ <TabItem value="portal" label="Portal">
480
+ Иногда возникает необходимость вынесения выпадающего списка на уровни выше в DOM. К примеру, когда у родительского блока имеется скролл, и список будет обрезаться, чего хотелось бы избежать.\
481
+ Для такой реализации имеется пропс `portal`, который принимает либо `ref` либо `id` html-тега.
482
+ ```tsx live
483
+ import React from 'react';
484
+ import { Autocomplete } from '@salutejs/{{ package }}';
485
+
486
+ export function App() {
487
+ const mockData = [
488
+ { label: 'Алексей Смирнов' },
489
+ { label: 'Екатерина Иванова' },
490
+ { label: 'Дмитрий Петров' },
491
+ { label: 'Ольга Васильева' },
492
+ { label: 'Сергей Сидоров' },
493
+ { label: 'Мария Кузнецова' },
494
+ { label: 'Андрей Попов' },
495
+ { label: 'Анна Николаева' },
496
+ { label: 'Иван Федоров' },
497
+ { label: 'Наталья Морозова' },
498
+ { label: 'Михаил Павлов' },
499
+ { label: 'Елена Романова' },
500
+ { label: 'Владимир Киселев' },
501
+ { label: 'Татьяна Захарова' },
502
+ { label: 'Николай Семенов' },
503
+ { label: 'Юлия Белова' },
504
+ { label: 'Александр Гусев' },
505
+ { label: 'Оксана Яковлева' },
506
+ { label: 'Игорь Егорова' },
507
+ { label: 'Вера Тихомирова' },
508
+ { label: 'Артем Григорьев' },
509
+ { label: 'Евгения Козлова' },
510
+ { label: 'Максим Лебедев' },
511
+ { label: 'Виктория Калашникова' },
512
+ { label: 'Константин Абрамов' },
513
+ { label: 'Светлана Новикова' },
514
+ { label: 'Юрий Волков' },
515
+ { label: 'Валентина Воробьева' },
516
+ { label: 'Павел Сергеев' },
517
+ { label: 'Людмила Виноградова' },
518
+ { label: 'Антон Соловьев' },
519
+ { label: 'Маргарита Цветкова' },
520
+ { label: 'Роман Трофимов' },
521
+ { label: 'Лариса Зайцева' },
522
+ { label: 'Евгений Никитин' },
523
+ { label: 'Галина Михайлова' },
524
+ { label: 'Владислав Антонов' },
525
+ { label: 'Дарья Филатова' },
526
+ { label: 'Олег Буров' },
527
+ { label: 'Инна Медведева' },
528
+ { label: 'Вячеслав Крылов' },
529
+ { label: 'Тамара Беляева' },
530
+ { label: 'Кирилл Марков' },
531
+ { label: 'Марина Пономарева' },
532
+ { label: 'Борис Захаров' },
533
+ { label: 'Жанна Савельева' },
534
+ { label: 'Федор Жуков' },
535
+ { label: 'Елизавета Логинова' },
536
+ { label: 'Виктор Рыбаков' },
537
+ { label: 'Лилия Макарова' },
538
+ ];
539
+
540
+ const ref = useRef(null);
541
+
542
+ return (
543
+ <div style=\{{ position: 'relative', display: 'block', height: "400px" }} ref={ref}>
544
+ <Autocomplete suggestions={mockData} listMaxHeight="250px" label="Label" placeholder="Placeholder" leftHelper="Введите имя Алексей" portal={ref} />
545
+ </div>
546
+ );
547
+ }
548
+ ```
549
+ </TabItem>
550
+ </Tabs>
551
+
552
+ ## Клавиатурная навигация
553
+
554
+ Данный компонент соответствует требования W3C: [Combobox](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-autocomplete-list/).
555
+
556
+ - `Tab, Escape` - закрывает автокомплит. Перемещает фокус на следующий элемент на странице;
557
+ - `Enter` - выбираем подсказку из списка;
558
+ - `Home` - перемещает фокус на первый элемент;
559
+ - `End` - перемещает фокус на последний элемент;
560
+ - `ArrowUp` - перемещает фокус на один элемент выше;
561
+ - `ArrowDown` - перемещает фокус на один элемент ниже;
@@ -1,4 +1,4 @@
1
- var _excluded = ["value", "onChange", "suggestions", "view", "size", "labelPlacement", "disabled", "readOnly", "label", "leftHelper", "contentLeft", "contentRight", "textBefore", "textAfter", "onScroll", "listMaxHeight", "listWidth", "filter", "onSuggestionSelect", "threshold", "renderList", "renderListEnd", "onSearch"];
1
+ var _excluded = ["value", "onChange", "suggestions", "view", "size", "labelPlacement", "disabled", "readOnly", "label", "leftHelper", "contentLeft", "contentRight", "textBefore", "textAfter", "onScroll", "listMaxHeight", "listWidth", "portal", "filter", "onSuggestionSelect", "threshold", "renderList", "renderListEnd", "onSearch"];
2
2
  function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
3
3
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
4
4
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@@ -39,6 +39,7 @@ export var autocompleteRoot = function autocompleteRoot(Root) {
39
39
  onScroll = _ref.onScroll,
40
40
  listMaxHeight = _ref.listMaxHeight,
41
41
  listWidth = _ref.listWidth,
42
+ portal = _ref.portal,
42
43
  filter = _ref.filter,
43
44
  onSuggestionSelect = _ref.onSuggestionSelect,
44
45
  _ref$threshold = _ref.threshold,
@@ -119,6 +120,8 @@ export var autocompleteRoot = function autocompleteRoot(Root) {
119
120
  offset: [0, 0],
120
121
  placement: getPlacements('bottom'),
121
122
  isFocusTrapped: false,
123
+ usePortal: Boolean(portal),
124
+ frame: portal,
122
125
  target: /*#__PURE__*/React.createElement(StyledTextField, _extends({
123
126
  value: value,
124
127
  onChange: handleChange,
@@ -146,7 +149,13 @@ export var autocompleteRoot = function autocompleteRoot(Root) {
146
149
  preventOverflow: false,
147
150
  ref: targetRef,
148
151
  listWidth: listWidth
149
- }, renderList && renderList(finalResults) || Boolean(finalResults.length) && /*#__PURE__*/React.createElement(Ul, {
152
+ }, renderList && renderList(finalResults) || Boolean(finalResults.length) && /*#__PURE__*/React.createElement(Root, {
153
+ view: view,
154
+ size: size,
155
+ labelPlacement: labelPlacement,
156
+ disabled: disabled,
157
+ readOnly: readOnly
158
+ }, /*#__PURE__*/React.createElement(Ul, {
150
159
  id: listId,
151
160
  role: "listbox",
152
161
  "aria-label": label,
@@ -160,7 +169,7 @@ export var autocompleteRoot = function autocompleteRoot(Root) {
160
169
  id: "".concat(listId, "/").concat(index),
161
170
  focused: focused === index
162
171
  });
163
- }), renderListEnd && /*#__PURE__*/React.createElement(InfiniteLoaderWrapper, null, renderListEnd()))), leftHelper && /*#__PURE__*/React.createElement(LeftHelper, {
172
+ }), renderListEnd && /*#__PURE__*/React.createElement(InfiniteLoaderWrapper, null, renderListEnd())))), leftHelper && /*#__PURE__*/React.createElement(LeftHelper, {
164
173
  id: helperTextId,
165
174
  disabled: disabled,
166
175
  readOnly: readOnly