@salutejs/plasma-new-hope 0.120.0 → 0.121.0-canary.1347.10314776748.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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