@salutejs/plasma-new-hope 0.119.2-canary.1333.10286827108.0 → 0.120.0-canary.1347.10286315854.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. package/cjs/components/Autocomplete/Autocomplete.js +12 -3
  2. package/cjs/components/Autocomplete/Autocomplete.js.map +1 -1
  3. package/cjs/components/Tabs/tokens.js +2 -5
  4. package/cjs/components/Tabs/tokens.js.map +1 -1
  5. package/cjs/components/Tabs/ui/TabItem/TabItem.css +1 -1
  6. package/cjs/components/Tabs/ui/TabItem/TabItem.js +2 -14
  7. package/cjs/components/Tabs/ui/TabItem/TabItem.js.map +1 -1
  8. package/cjs/components/Tabs/ui/TabItem/variations/_view/base.js +1 -1
  9. package/cjs/components/Tabs/ui/TabItem/variations/_view/base.js.map +1 -1
  10. package/cjs/components/Tabs/ui/TabItem/variations/_view/base_q8xs21.css +1 -0
  11. package/cjs/components/Tabs/ui/Tabs/Tabs.css +6 -6
  12. package/cjs/components/Tabs/ui/Tabs/Tabs.js +8 -57
  13. package/cjs/components/Tabs/ui/Tabs/Tabs.js.map +1 -1
  14. package/cjs/components/Tabs/ui/Tabs/Tabs.styles.js +7 -7
  15. package/cjs/components/Tabs/ui/Tabs/Tabs.styles.js.map +1 -1
  16. package/{es/components/Tabs/ui/Tabs/Tabs.styles_z4dnzh.css → cjs/components/Tabs/ui/Tabs/Tabs.styles_1b8qt33.css} +2 -2
  17. package/cjs/components/Tabs/ui/Tabs/variations/_stretch/base.js +1 -1
  18. package/cjs/components/Tabs/ui/Tabs/variations/_stretch/base.js.map +1 -1
  19. package/{es/components/Tabs/ui/Tabs/variations/_stretch/base_1c7lnrm.css → cjs/components/Tabs/ui/Tabs/variations/_stretch/base_176tz0n.css} +1 -1
  20. package/cjs/components/Tabs/ui/Tabs/variations/_view/base.js +1 -1
  21. package/{es/components/Tabs/ui/Tabs/variations/_view/base_aij3sf.css → cjs/components/Tabs/ui/Tabs/variations/_view/base_4xkt26.css} +1 -1
  22. package/cjs/index.css +7 -7
  23. package/emotion/cjs/components/Autocomplete/Autocomplete.js +12 -3
  24. package/emotion/cjs/components/Autocomplete/Autocomplete.template-doc.mdx +561 -0
  25. package/emotion/cjs/components/Tabs/Tabs.template-doc.mdx +3 -89
  26. package/emotion/cjs/components/Tabs/tokens.js +2 -5
  27. package/emotion/cjs/components/Tabs/ui/TabItem/TabItem.js +2 -14
  28. package/emotion/cjs/components/Tabs/ui/TabItem/variations/_view/base.js +1 -1
  29. package/emotion/cjs/components/Tabs/ui/Tabs/Tabs.js +8 -57
  30. package/emotion/cjs/components/Tabs/ui/Tabs/Tabs.styles.js +16 -8
  31. package/emotion/cjs/components/Tabs/ui/Tabs/variations/_stretch/base.js +1 -1
  32. package/emotion/cjs/components/Tabs/ui/Tabs/variations/_view/tokens.json +1 -1
  33. package/emotion/cjs/examples/plasma_b2c/components/Tabs/TabItem.config.js +15 -15
  34. package/emotion/cjs/examples/plasma_b2c/components/Tabs/Tabs.config.js +17 -16
  35. package/emotion/cjs/examples/plasma_b2c/components/Tabs/Tabs.stories.tsx +197 -238
  36. package/emotion/cjs/examples/plasma_web/components/Tabs/TabItem.config.js +15 -15
  37. package/emotion/cjs/examples/plasma_web/components/Tabs/Tabs.config.js +17 -16
  38. package/emotion/cjs/examples/plasma_web/components/Tabs/Tabs.stories.tsx +197 -238
  39. package/emotion/es/components/Autocomplete/Autocomplete.js +12 -3
  40. package/emotion/es/components/Autocomplete/Autocomplete.template-doc.mdx +561 -0
  41. package/emotion/es/components/Tabs/Tabs.template-doc.mdx +3 -89
  42. package/emotion/es/components/Tabs/tokens.js +2 -5
  43. package/emotion/es/components/Tabs/ui/TabItem/TabItem.js +2 -14
  44. package/emotion/es/components/Tabs/ui/TabItem/variations/_view/base.js +1 -1
  45. package/emotion/es/components/Tabs/ui/Tabs/Tabs.js +9 -58
  46. package/emotion/es/components/Tabs/ui/Tabs/Tabs.styles.js +17 -9
  47. package/emotion/es/components/Tabs/ui/Tabs/variations/_stretch/base.js +1 -1
  48. package/emotion/es/components/Tabs/ui/Tabs/variations/_view/tokens.json +1 -1
  49. package/emotion/es/examples/plasma_b2c/components/Tabs/TabItem.config.js +15 -15
  50. package/emotion/es/examples/plasma_b2c/components/Tabs/Tabs.config.js +17 -16
  51. package/emotion/es/examples/plasma_b2c/components/Tabs/Tabs.stories.tsx +197 -238
  52. package/emotion/es/examples/plasma_web/components/Tabs/TabItem.config.js +15 -15
  53. package/emotion/es/examples/plasma_web/components/Tabs/Tabs.config.js +17 -16
  54. package/emotion/es/examples/plasma_web/components/Tabs/Tabs.stories.tsx +197 -238
  55. package/es/components/Autocomplete/Autocomplete.js +12 -3
  56. package/es/components/Autocomplete/Autocomplete.js.map +1 -1
  57. package/es/components/Tabs/tokens.js +2 -5
  58. package/es/components/Tabs/tokens.js.map +1 -1
  59. package/es/components/Tabs/ui/TabItem/TabItem.css +1 -1
  60. package/es/components/Tabs/ui/TabItem/TabItem.js +2 -14
  61. package/es/components/Tabs/ui/TabItem/TabItem.js.map +1 -1
  62. package/es/components/Tabs/ui/TabItem/variations/_view/base.js +1 -1
  63. package/es/components/Tabs/ui/TabItem/variations/_view/base.js.map +1 -1
  64. package/es/components/Tabs/ui/TabItem/variations/_view/base_q8xs21.css +1 -0
  65. package/es/components/Tabs/ui/Tabs/Tabs.css +6 -6
  66. package/es/components/Tabs/ui/Tabs/Tabs.js +9 -58
  67. package/es/components/Tabs/ui/Tabs/Tabs.js.map +1 -1
  68. package/es/components/Tabs/ui/Tabs/Tabs.styles.js +7 -7
  69. package/es/components/Tabs/ui/Tabs/Tabs.styles.js.map +1 -1
  70. package/{cjs/components/Tabs/ui/Tabs/Tabs.styles_z4dnzh.css → es/components/Tabs/ui/Tabs/Tabs.styles_1b8qt33.css} +2 -2
  71. package/es/components/Tabs/ui/Tabs/variations/_stretch/base.js +1 -1
  72. package/es/components/Tabs/ui/Tabs/variations/_stretch/base.js.map +1 -1
  73. package/{cjs/components/Tabs/ui/Tabs/variations/_stretch/base_1c7lnrm.css → es/components/Tabs/ui/Tabs/variations/_stretch/base_176tz0n.css} +1 -1
  74. package/es/components/Tabs/ui/Tabs/variations/_view/base.js +1 -1
  75. package/{cjs/components/Tabs/ui/Tabs/variations/_view/base_aij3sf.css → es/components/Tabs/ui/Tabs/variations/_view/base_4xkt26.css} +1 -1
  76. package/es/index.css +7 -7
  77. package/package.json +2 -2
  78. package/styled-components/cjs/components/Autocomplete/Autocomplete.js +12 -3
  79. package/styled-components/cjs/components/Autocomplete/Autocomplete.template-doc.mdx +561 -0
  80. package/styled-components/cjs/components/Tabs/Tabs.template-doc.mdx +3 -89
  81. package/styled-components/cjs/components/Tabs/tokens.js +2 -5
  82. package/styled-components/cjs/components/Tabs/ui/TabItem/TabItem.js +2 -14
  83. package/styled-components/cjs/components/Tabs/ui/TabItem/variations/_view/base.js +1 -1
  84. package/styled-components/cjs/components/Tabs/ui/Tabs/Tabs.js +8 -57
  85. package/styled-components/cjs/components/Tabs/ui/Tabs/Tabs.styles.js +2 -2
  86. package/styled-components/cjs/components/Tabs/ui/Tabs/variations/_stretch/base.js +1 -1
  87. package/styled-components/cjs/components/Tabs/ui/Tabs/variations/_view/tokens.json +1 -1
  88. package/styled-components/cjs/examples/plasma_b2c/components/Tabs/TabItem.config.js +8 -8
  89. package/styled-components/cjs/examples/plasma_b2c/components/Tabs/Tabs.config.js +5 -4
  90. package/styled-components/cjs/examples/plasma_b2c/components/Tabs/Tabs.stories.tsx +197 -238
  91. package/styled-components/cjs/examples/plasma_web/components/Tabs/TabItem.config.js +8 -8
  92. package/styled-components/cjs/examples/plasma_web/components/Tabs/Tabs.config.js +5 -4
  93. package/styled-components/cjs/examples/plasma_web/components/Tabs/Tabs.stories.tsx +197 -238
  94. package/styled-components/es/components/Autocomplete/Autocomplete.js +12 -3
  95. package/styled-components/es/components/Autocomplete/Autocomplete.template-doc.mdx +561 -0
  96. package/styled-components/es/components/Tabs/Tabs.template-doc.mdx +3 -89
  97. package/styled-components/es/components/Tabs/tokens.js +2 -5
  98. package/styled-components/es/components/Tabs/ui/TabItem/TabItem.js +2 -14
  99. package/styled-components/es/components/Tabs/ui/TabItem/variations/_view/base.js +1 -1
  100. package/styled-components/es/components/Tabs/ui/Tabs/Tabs.js +9 -58
  101. package/styled-components/es/components/Tabs/ui/Tabs/Tabs.styles.js +3 -3
  102. package/styled-components/es/components/Tabs/ui/Tabs/variations/_stretch/base.js +1 -1
  103. package/styled-components/es/components/Tabs/ui/Tabs/variations/_view/tokens.json +1 -1
  104. package/styled-components/es/examples/plasma_b2c/components/Tabs/TabItem.config.js +8 -8
  105. package/styled-components/es/examples/plasma_b2c/components/Tabs/Tabs.config.js +5 -4
  106. package/styled-components/es/examples/plasma_b2c/components/Tabs/Tabs.stories.tsx +197 -238
  107. package/styled-components/es/examples/plasma_web/components/Tabs/TabItem.config.js +8 -8
  108. package/styled-components/es/examples/plasma_web/components/Tabs/Tabs.config.js +5 -4
  109. package/styled-components/es/examples/plasma_web/components/Tabs/Tabs.stories.tsx +197 -238
  110. package/types/components/Autocomplete/Autocomplete.d.ts.map +1 -1
  111. package/types/components/Autocomplete/Autocomplete.types.d.ts +4 -0
  112. package/types/components/Autocomplete/Autocomplete.types.d.ts.map +1 -1
  113. package/types/components/Tabs/tokens.d.ts +0 -3
  114. package/types/components/Tabs/tokens.d.ts.map +1 -1
  115. package/types/components/Tabs/ui/TabItem/TabItem.d.ts.map +1 -1
  116. package/types/components/Tabs/ui/TabItem/variations/_view/base.d.ts.map +1 -1
  117. package/types/components/Tabs/ui/Tabs/Tabs.d.ts +2 -4
  118. package/types/components/Tabs/ui/Tabs/Tabs.d.ts.map +1 -1
  119. package/types/components/Tabs/ui/Tabs/Tabs.styles.d.ts.map +1 -1
  120. package/types/components/Tabs/ui/Tabs/Tabs.types.d.ts +5 -12
  121. package/types/components/Tabs/ui/Tabs/Tabs.types.d.ts.map +1 -1
  122. package/types/components/Tabs/ui/Tabs/variations/_stretch/base.d.ts.map +1 -1
  123. package/types/examples/plasma_b2c/components/Tabs/TabItem.config.d.ts.map +1 -1
  124. package/types/examples/plasma_b2c/components/Tabs/Tabs.config.d.ts +1 -0
  125. package/types/examples/plasma_b2c/components/Tabs/Tabs.config.d.ts.map +1 -1
  126. package/types/examples/plasma_b2c/components/Tabs/Tabs.d.ts +1 -2
  127. package/types/examples/plasma_b2c/components/Tabs/Tabs.d.ts.map +1 -1
  128. package/types/examples/plasma_web/components/Tabs/TabItem.config.d.ts.map +1 -1
  129. package/types/examples/plasma_web/components/Tabs/Tabs.config.d.ts +1 -0
  130. package/types/examples/plasma_web/components/Tabs/Tabs.config.d.ts.map +1 -1
  131. package/types/examples/plasma_web/components/Tabs/Tabs.d.ts +1 -2
  132. package/types/examples/plasma_web/components/Tabs/Tabs.d.ts.map +1 -1
  133. package/types/examples/sds_engineer/components/Tabs/Tabs.d.ts +1 -2
  134. package/types/examples/sds_engineer/components/Tabs/Tabs.d.ts.map +1 -1
  135. package/cjs/components/Tabs/ui/TabItem/variations/_view/base_7pcxtm.css +0 -1
  136. package/es/components/Tabs/ui/TabItem/variations/_view/base_7pcxtm.css +0 -1
@@ -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` - перемещает фокус на один элемент ниже;
@@ -51,7 +51,7 @@ export function App() {
51
51
  contentLeft={<IconClock size="xs" color="inherit" />}
52
52
  onClick={() => setIndex(i)}
53
53
  >
54
- {`Label${i + 1}`}
54
+ Label
55
55
  </TabItem>
56
56
  ))}
57
57
  </Tabs>
@@ -60,92 +60,6 @@ export function App() {
60
60
  }
61
61
  ```
62
62
 
63
- ### Пример с прокруткой
64
-
65
- ```tsx live
66
- import React, { useState } from 'react';
67
- import { Tabs, TabItem } from '@salutejs/{{ package }}';
68
- import { IconClock } from '@salutejs/plasma-icons';
69
-
70
- export function App() {
71
- const items = Array(8).fill(0);
72
- const [index, setIndex] = useState(0);
73
-
74
- return (
75
- <div>
76
- <Tabs view="divider" size="xs" style={{ width: '15rem' }}>
77
- {items.map((_, i) => (
78
- <TabItem
79
- view="divider"
80
- key={`item:${i}`}
81
- size="xs"
82
- selected={i === index}
83
- tabIndex={0}
84
- contentLeft={<IconClock size="xs" color="inherit" />}
85
- onClick={() => setIndex(i)}
86
- >
87
- {`Label${i + 1}`}
88
- </TabItem>
89
- ))}
90
- </Tabs>
91
- </div>
92
- );
93
- }
94
- ```
95
-
96
- ### Пример с Dropdown
97
-
98
- ```tsx live
99
- import React, { useState } from 'react';
100
- import { Tabs, TabItem, Dropdown } from '@salutejs/{{ package }}';
101
-
102
- export function App() {
103
- const items = Array(8).fill(0);
104
- const [index, setIndex] = useState(0);
105
-
106
- const maxItemQuantity = 3;
107
- const visibleItems = items.slice(0, maxItemQuantity);
108
- const otherItems = items.slice(maxItemQuantity);
109
-
110
- const dropdownItems = otherItems.map((_, i) => {
111
- const itemIndex = maxItemQuantity + i;
112
-
113
- return {
114
- label: `Label${itemIndex + 1}`,
115
- value: itemIndex,
116
- };
117
- });
118
-
119
- return (
120
- <div style={{ height: '15rem', alignItems: 'flex-start' }}>
121
- <Tabs clip="showAll" view="divider" size="xs">
122
- {visibleItems.map((_, i) => (
123
- <TabItem
124
- key={`item:${i}`}
125
- view="divider"
126
- selected={i === index}
127
- onClick={() => setIndex(i)}
128
- tabIndex={0}
129
- size="xs"
130
- >
131
- {`Label${i + 1}`}
132
- </TabItem>
133
- ))}
134
- {dropdownItems.length > 0 && (
135
- <div style={{ marginLeft: '1.75rem' }}>
136
- <Dropdown size="xs" items={dropdownItems} onItemSelect={(item) => setIndex(item.value)}>
137
- <TabItem key="item:ShowAll" view="divider" tabIndex={0} size="xs">
138
- ShowAll
139
- </TabItem>
140
- </Dropdown>
141
- </div>
142
- )}
143
- </Tabs>
144
- </div>
145
- );
146
- }
147
- ```
148
-
149
63
  ### Подключение клавиатурной навигации
150
64
  Для этого необходимо дополнительно прокинуть свойства `index, itemIndex, onIndexChange`.
151
65
  Клавиши ArrowLeft, ArrowRight, Home, End для навигации по вкладкам.
@@ -174,11 +88,11 @@ export function App() {
174
88
  contentLeft={<IconClock size="xs" color="inherit" />}
175
89
  onClick={() => setIndex(i)}
176
90
  >
177
- {`Label${i + 1}`}
91
+ Label
178
92
  </TabItem>
179
93
  ))}
180
94
  </Tabs>
181
95
  </div>
182
96
  );
183
97
  }
184
- ```
98
+ ```