@salutejs/plasma-new-hope 0.194.0-canary.1562.11857238836.0 → 0.194.0-canary.1565.11870784206.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.
Files changed (180) hide show
  1. package/cjs/components/Combobox/ComboboxNew/Combobox.js +1 -0
  2. package/cjs/components/Combobox/ComboboxNew/Combobox.js.map +1 -1
  3. package/cjs/components/Combobox/ComboboxNew/ui/Inner/ui/Item/Item.js +2 -1
  4. package/cjs/components/Combobox/ComboboxNew/ui/Inner/ui/Item/Item.js.map +1 -1
  5. package/cjs/components/Combobox/ComboboxOld/Combobox.css +4 -5
  6. package/cjs/components/Combobox/ComboboxOld/ui/ComboboxDivider/ComboboxDivider.css +4 -5
  7. package/cjs/components/Combobox/ComboboxOld/ui/ComboboxFooter/ComboboxFooter.css +4 -5
  8. package/cjs/components/Combobox/ComboboxOld/ui/ComboboxGroup/ComboboxGroup.css +4 -5
  9. package/cjs/components/Combobox/ComboboxOld/ui/ComboboxHeader/ComboboxHeader.css +4 -5
  10. package/cjs/components/Dropdown/Dropdown.css +4 -5
  11. package/cjs/components/Dropdown/Dropdown.js +2 -4
  12. package/cjs/components/Dropdown/Dropdown.js.map +1 -1
  13. package/cjs/components/Dropdown/ui/DropdownItem/DropdownItem.css +4 -5
  14. package/cjs/components/Dropdown/ui/DropdownItem/DropdownItem.js +2 -3
  15. package/cjs/components/Dropdown/ui/DropdownItem/DropdownItem.js.map +1 -1
  16. package/cjs/components/Dropdown/ui/DropdownItem/DropdownItem.styles.js +1 -7
  17. package/cjs/components/Dropdown/ui/DropdownItem/DropdownItem.styles.js.map +1 -1
  18. package/cjs/components/Dropdown/ui/DropdownItem/{DropdownItem.styles_14yih1y.css → DropdownItem.styles_1b439rx.css} +0 -1
  19. package/cjs/components/Select/Select.js +1 -0
  20. package/cjs/components/Select/Select.js.map +1 -1
  21. package/cjs/components/Select/ui/Inner/ui/Item/Item.js +2 -1
  22. package/cjs/components/Select/ui/Inner/ui/Item/Item.js.map +1 -1
  23. package/cjs/components/Select/ui/Target/ui/Textfield/Textfield.js +3 -18
  24. package/cjs/components/Select/ui/Target/ui/Textfield/Textfield.js.map +1 -1
  25. package/cjs/components/TextField/TextField.js +27 -3
  26. package/cjs/components/TextField/TextField.js.map +1 -1
  27. package/cjs/components/TextField/hooks/useValidation.js +273 -0
  28. package/cjs/components/TextField/hooks/useValidation.js.map +1 -0
  29. package/cjs/index.css +4 -5
  30. package/cjs/utils/constants.js +4 -0
  31. package/cjs/utils/constants.js.map +1 -1
  32. package/emotion/cjs/components/Combobox/ComboboxNew/Combobox.js +1 -0
  33. package/emotion/cjs/components/Combobox/ComboboxNew/ui/Inner/ui/Item/Item.js +2 -1
  34. package/emotion/cjs/components/Dropdown/Dropdown.js +2 -4
  35. package/emotion/cjs/components/Dropdown/ui/DropdownItem/DropdownItem.js +2 -3
  36. package/emotion/cjs/components/Dropdown/ui/DropdownItem/DropdownItem.styles.js +11 -15
  37. package/emotion/cjs/components/Select/Select.js +1 -0
  38. package/emotion/cjs/components/Select/ui/Inner/ui/Item/Item.js +2 -1
  39. package/emotion/cjs/components/Select/ui/Target/ui/Textfield/Textfield.js +3 -24
  40. package/emotion/cjs/components/TextField/TextField.js +27 -4
  41. package/emotion/cjs/components/TextField/TextField.template-doc.mdx +330 -0
  42. package/emotion/cjs/components/TextField/hooks/index.js +8 -1
  43. package/emotion/cjs/components/TextField/hooks/useValidation.js +276 -0
  44. package/emotion/cjs/examples/plasma_b2c/components/TextField/TextField.stories.tsx +253 -1
  45. package/emotion/cjs/examples/plasma_web/components/TextField/TextField.stories.tsx +252 -0
  46. package/emotion/cjs/utils/constants.js +4 -2
  47. package/emotion/es/components/Combobox/ComboboxNew/Combobox.js +1 -0
  48. package/emotion/es/components/Combobox/ComboboxNew/ui/Inner/ui/Item/Item.js +2 -1
  49. package/emotion/es/components/Dropdown/Dropdown.js +2 -4
  50. package/emotion/es/components/Dropdown/ui/DropdownItem/DropdownItem.js +3 -4
  51. package/emotion/es/components/Dropdown/ui/DropdownItem/DropdownItem.styles.js +11 -15
  52. package/emotion/es/components/Select/Select.js +1 -0
  53. package/emotion/es/components/Select/ui/Inner/ui/Item/Item.js +2 -1
  54. package/emotion/es/components/Select/ui/Target/ui/Textfield/Textfield.js +3 -24
  55. package/emotion/es/components/TextField/TextField.js +28 -5
  56. package/emotion/es/components/TextField/TextField.template-doc.mdx +330 -0
  57. package/emotion/es/components/TextField/hooks/index.js +2 -1
  58. package/emotion/es/components/TextField/hooks/useValidation.js +270 -0
  59. package/emotion/es/examples/plasma_b2c/components/TextField/TextField.stories.tsx +253 -1
  60. package/emotion/es/examples/plasma_web/components/TextField/TextField.stories.tsx +252 -0
  61. package/emotion/es/utils/constants.js +3 -1
  62. package/es/components/Combobox/ComboboxNew/Combobox.js +1 -0
  63. package/es/components/Combobox/ComboboxNew/Combobox.js.map +1 -1
  64. package/es/components/Combobox/ComboboxNew/ui/Inner/ui/Item/Item.js +2 -1
  65. package/es/components/Combobox/ComboboxNew/ui/Inner/ui/Item/Item.js.map +1 -1
  66. package/es/components/Combobox/ComboboxOld/Combobox.css +4 -5
  67. package/es/components/Combobox/ComboboxOld/ui/ComboboxDivider/ComboboxDivider.css +4 -5
  68. package/es/components/Combobox/ComboboxOld/ui/ComboboxFooter/ComboboxFooter.css +4 -5
  69. package/es/components/Combobox/ComboboxOld/ui/ComboboxGroup/ComboboxGroup.css +4 -5
  70. package/es/components/Combobox/ComboboxOld/ui/ComboboxHeader/ComboboxHeader.css +4 -5
  71. package/es/components/Dropdown/Dropdown.css +4 -5
  72. package/es/components/Dropdown/Dropdown.js +2 -4
  73. package/es/components/Dropdown/Dropdown.js.map +1 -1
  74. package/es/components/Dropdown/ui/DropdownItem/DropdownItem.css +4 -5
  75. package/es/components/Dropdown/ui/DropdownItem/DropdownItem.js +3 -4
  76. package/es/components/Dropdown/ui/DropdownItem/DropdownItem.js.map +1 -1
  77. package/es/components/Dropdown/ui/DropdownItem/DropdownItem.styles.js +2 -7
  78. package/es/components/Dropdown/ui/DropdownItem/DropdownItem.styles.js.map +1 -1
  79. package/es/components/Dropdown/ui/DropdownItem/{DropdownItem.styles_14yih1y.css → DropdownItem.styles_1b439rx.css} +0 -1
  80. package/es/components/Select/Select.js +1 -0
  81. package/es/components/Select/Select.js.map +1 -1
  82. package/es/components/Select/ui/Inner/ui/Item/Item.js +2 -1
  83. package/es/components/Select/ui/Inner/ui/Item/Item.js.map +1 -1
  84. package/es/components/Select/ui/Target/ui/Textfield/Textfield.js +4 -19
  85. package/es/components/Select/ui/Target/ui/Textfield/Textfield.js.map +1 -1
  86. package/es/components/TextField/TextField.js +27 -3
  87. package/es/components/TextField/TextField.js.map +1 -1
  88. package/es/components/TextField/hooks/useValidation.js +269 -0
  89. package/es/components/TextField/hooks/useValidation.js.map +1 -0
  90. package/es/index.css +4 -5
  91. package/es/utils/constants.js +3 -1
  92. package/es/utils/constants.js.map +1 -1
  93. package/package.json +2 -3
  94. package/styled-components/cjs/components/Combobox/ComboboxNew/Combobox.js +1 -0
  95. package/styled-components/cjs/components/Combobox/ComboboxNew/ui/Inner/ui/Item/Item.js +2 -1
  96. package/styled-components/cjs/components/Dropdown/Dropdown.js +2 -4
  97. package/styled-components/cjs/components/Dropdown/ui/DropdownItem/DropdownItem.js +2 -3
  98. package/styled-components/cjs/components/Dropdown/ui/DropdownItem/DropdownItem.styles.js +2 -5
  99. package/styled-components/cjs/components/Select/Select.js +1 -0
  100. package/styled-components/cjs/components/Select/ui/Inner/ui/Item/Item.js +2 -1
  101. package/styled-components/cjs/components/Select/ui/Target/ui/Textfield/Textfield.js +3 -24
  102. package/styled-components/cjs/components/TextField/TextField.js +26 -3
  103. package/styled-components/cjs/components/TextField/TextField.template-doc.mdx +330 -0
  104. package/styled-components/cjs/components/TextField/hooks/index.js +8 -1
  105. package/styled-components/cjs/components/TextField/hooks/useValidation.js +276 -0
  106. package/styled-components/cjs/examples/plasma_b2c/components/TextField/TextField.stories.tsx +253 -1
  107. package/styled-components/cjs/examples/plasma_web/components/TextField/TextField.stories.tsx +252 -0
  108. package/styled-components/cjs/utils/constants.js +4 -2
  109. package/styled-components/es/components/Combobox/ComboboxNew/Combobox.js +1 -0
  110. package/styled-components/es/components/Combobox/ComboboxNew/ui/Inner/ui/Item/Item.js +2 -1
  111. package/styled-components/es/components/Dropdown/Dropdown.js +2 -4
  112. package/styled-components/es/components/Dropdown/ui/DropdownItem/DropdownItem.js +3 -4
  113. package/styled-components/es/components/Dropdown/ui/DropdownItem/DropdownItem.styles.js +2 -5
  114. package/styled-components/es/components/Select/Select.js +1 -0
  115. package/styled-components/es/components/Select/ui/Inner/ui/Item/Item.js +2 -1
  116. package/styled-components/es/components/Select/ui/Target/ui/Textfield/Textfield.js +3 -24
  117. package/styled-components/es/components/TextField/TextField.js +27 -4
  118. package/styled-components/es/components/TextField/TextField.template-doc.mdx +330 -0
  119. package/styled-components/es/components/TextField/hooks/index.js +2 -1
  120. package/styled-components/es/components/TextField/hooks/useValidation.js +270 -0
  121. package/styled-components/es/examples/plasma_b2c/components/TextField/TextField.stories.tsx +253 -1
  122. package/styled-components/es/examples/plasma_web/components/TextField/TextField.stories.tsx +252 -0
  123. package/styled-components/es/utils/constants.js +3 -1
  124. package/types/components/Autocomplete/Autocomplete.types.d.ts +2 -2
  125. package/types/components/Autocomplete/Autocomplete.types.d.ts.map +1 -1
  126. package/types/components/Autocomplete/ui/TextField/TextField.styles.d.ts +1676 -92
  127. package/types/components/Autocomplete/ui/TextField/TextField.styles.d.ts.map +1 -1
  128. package/types/components/Combobox/ComboboxNew/Combobox.d.ts.map +1 -1
  129. package/types/components/Combobox/ComboboxNew/Combobox.types.d.ts +2 -1
  130. package/types/components/Combobox/ComboboxNew/Combobox.types.d.ts.map +1 -1
  131. package/types/components/Combobox/ComboboxNew/ui/Inner/ui/Item/Item.d.ts.map +1 -1
  132. package/types/components/Combobox/ComboboxNew/ui/Target/Target.styles.d.ts +1676 -92
  133. package/types/components/Combobox/ComboboxNew/ui/Target/Target.styles.d.ts.map +1 -1
  134. package/types/components/DatePicker/SingleDate/SingleDate.styles.d.ts +1676 -92
  135. package/types/components/DatePicker/SingleDate/SingleDate.styles.d.ts.map +1 -1
  136. package/types/components/Dropdown/Dropdown.d.ts +2 -50
  137. package/types/components/Dropdown/Dropdown.d.ts.map +1 -1
  138. package/types/components/Dropdown/Dropdown.types.d.ts +6 -11
  139. package/types/components/Dropdown/Dropdown.types.d.ts.map +1 -1
  140. package/types/components/Dropdown/index.d.ts +0 -1
  141. package/types/components/Dropdown/index.d.ts.map +1 -1
  142. package/types/components/Dropdown/ui/DropdownItem/DropdownItem.d.ts.map +1 -1
  143. package/types/components/Dropdown/ui/DropdownItem/DropdownItem.styles.d.ts +0 -1
  144. package/types/components/Dropdown/ui/DropdownItem/DropdownItem.styles.d.ts.map +1 -1
  145. package/types/components/Range/Range.styles.d.ts +1676 -92
  146. package/types/components/Range/Range.styles.d.ts.map +1 -1
  147. package/types/components/Select/Select.d.ts.map +1 -1
  148. package/types/components/Select/Select.types.d.ts +2 -1
  149. package/types/components/Select/Select.types.d.ts.map +1 -1
  150. package/types/components/Select/ui/Inner/ui/Item/Item.d.ts.map +1 -1
  151. package/types/components/Select/ui/Target/ui/Textfield/Textfield.d.ts.map +1 -1
  152. package/types/components/Select/ui/Target/ui/Textfield/Textfield.styles.d.ts +1676 -92
  153. package/types/components/Select/ui/Target/ui/Textfield/Textfield.styles.d.ts.map +1 -1
  154. package/types/components/Slider/components/Double/Double.styles.d.ts +1676 -92
  155. package/types/components/Slider/components/Double/Double.styles.d.ts.map +1 -1
  156. package/types/components/TextField/TextField.d.ts.map +1 -1
  157. package/types/components/TextField/TextField.types.d.ts +51 -1
  158. package/types/components/TextField/TextField.types.d.ts.map +1 -1
  159. package/types/components/TextField/hooks/index.d.ts +1 -0
  160. package/types/components/TextField/hooks/index.d.ts.map +1 -1
  161. package/types/components/TextField/hooks/useValidation.d.ts +7 -0
  162. package/types/components/TextField/hooks/useValidation.d.ts.map +1 -0
  163. package/types/examples/plasma_b2c/components/Autocomplete/Autocomplete.d.ts +64 -2
  164. package/types/examples/plasma_b2c/components/Autocomplete/Autocomplete.d.ts.map +1 -1
  165. package/types/examples/plasma_b2c/components/Dropdown/Dropdown.d.ts +1 -25
  166. package/types/examples/plasma_b2c/components/Dropdown/Dropdown.d.ts.map +1 -1
  167. package/types/examples/plasma_b2c/components/Mask/Mask.d.ts +2732 -92
  168. package/types/examples/plasma_b2c/components/Mask/Mask.d.ts.map +1 -1
  169. package/types/examples/plasma_b2c/components/TextField/TextField.d.ts +1676 -92
  170. package/types/examples/plasma_b2c/components/TextField/TextField.d.ts.map +1 -1
  171. package/types/examples/plasma_web/components/Autocomplete/Autocomplete.d.ts +64 -2
  172. package/types/examples/plasma_web/components/Autocomplete/Autocomplete.d.ts.map +1 -1
  173. package/types/examples/plasma_web/components/Dropdown/Dropdown.d.ts +1 -25
  174. package/types/examples/plasma_web/components/Dropdown/Dropdown.d.ts.map +1 -1
  175. package/types/examples/plasma_web/components/Mask/Mask.d.ts +2732 -92
  176. package/types/examples/plasma_web/components/Mask/Mask.d.ts.map +1 -1
  177. package/types/examples/plasma_web/components/TextField/TextField.d.ts +1676 -92
  178. package/types/examples/plasma_web/components/TextField/TextField.d.ts.map +1 -1
  179. package/types/utils/constants.d.ts +2 -0
  180. package/types/utils/constants.d.ts.map +1 -1
@@ -5,6 +5,9 @@ title: TextField
5
5
 
6
6
  import { PropsTable, Description } from '@site/src/components';
7
7
 
8
+ import Tabs from '@theme/Tabs';
9
+ import TabItem from '@theme/TabItem';
10
+
8
11
  # TextField
9
12
  <Description name="TextField" />
10
13
  <PropsTable name="TextField" exclude={['$isFocused']} />
@@ -198,3 +201,330 @@ export function App() {
198
201
  );
199
202
  }
200
203
  ```
204
+
205
+ ### Валидация
206
+ Поддерживается валидация почты и пароля:
207
+
208
+ <Tabs>
209
+ <TabItem value="email" label="Email" default>
210
+ Свойства доступные при валидации почты:
211
+ ```tsx
212
+ type ValidationProps = {
213
+ /*
214
+ * Тип валидации
215
+ */
216
+ validationType: 'email';
217
+ /*
218
+ * Опции валидации
219
+ */
220
+ options?: EmailValidationOptions;
221
+ /*
222
+ * Функция, вызываемая при валидации значения.
223
+ * Вызывается при событии onBlur и по нажатию Enter, когда фокус на поле ввода
224
+ */
225
+ onValidate?: (args: OnValidateArgs) => void;
226
+ }
227
+ ```
228
+ Свойство `options` имеет следующий вид:
229
+ ```tsx
230
+ type EmailValidationOptions = {
231
+ /*
232
+ * Пользовательское регулярное выражение, для проверки почты на валидность
233
+ */
234
+ customEmailRegex?: {
235
+ value?: RegExp;
236
+ errorMessage?: string;
237
+ };
238
+ /*
239
+ * Минимальная длина почты
240
+ */
241
+ minLength?: {
242
+ value?: number;
243
+ errorMessage?: string;
244
+ };
245
+ /*
246
+ * Максимальная длина почты
247
+ */
248
+ maxLength?: {
249
+ value?: number;
250
+ errorMessage?: string;
251
+ };
252
+ /*
253
+ * Минимальная длина хоста (часть почты до `@`)
254
+ */
255
+ minHostLength?: {
256
+ value?: number;
257
+ errorMessage?: string;
258
+ };
259
+ /*
260
+ * Максимальная длина хоста (часть почты до `@`)
261
+ */
262
+ maxHostLength?: {
263
+ value?: number;
264
+ errorMessage?: string;
265
+ };
266
+ /*
267
+ * Минимальная длина домена (часть почты от `@` до `.` перед доменной зоной)
268
+ */
269
+ minDomainLength?: {
270
+ value?: number;
271
+ errorMessage?: string;
272
+ };
273
+ /*
274
+ * Максимальная длина домена (часть почты от `@` до `.` перед доменной зоной)
275
+ */
276
+ maxDomainLength?: {
277
+ value?: number;
278
+ errorMessage?: string;
279
+ };
280
+ /*
281
+ * Минимальная длина доменной зоны (часть почты от `.`; например `ru`, `com`...)
282
+ */
283
+ minZoneLength?: {
284
+ value?: number;
285
+ errorMessage?: string;
286
+ };
287
+ /*
288
+ * Максимальная длина доменной зоны (часть почты от `.`; например `ru`, `com`...)
289
+ */
290
+ maxZoneLength?: {
291
+ value?: number;
292
+ errorMessage?: string;
293
+ };
294
+ /*
295
+ * Список разрешенных доменов (например `['mail.ru', 'yahoo.ru', 'gmail.com']`)
296
+ */
297
+ whitelistDomains?: {
298
+ value?: string[];
299
+ errorMessage?: string;
300
+ };
301
+ /*
302
+ * Список запрещенных доменов (например `['org.biz', 'expressmail.com']`)
303
+ */
304
+ blacklistDomains?: {
305
+ value?: string[];
306
+ errorMessage?: string;
307
+ };
308
+ };
309
+ ```
310
+
311
+ ```tsx live
312
+ import React, { useState } from 'react';
313
+ import { TextField } from '@salutejs/{{ package }}';
314
+
315
+ export function App() {
316
+ const options = {
317
+ minLength: {
318
+ value: 7,
319
+ errorMessage: 'Почта слишком короткая',
320
+ },
321
+ maxLength: {
322
+ value: 30,
323
+ errorMessage: 'Почта слишком длинная',
324
+ },
325
+ minHostLength: {
326
+ value: 2,
327
+ errorMessage: 'Хост слишком короткий',
328
+ },
329
+ maxHostLength: {
330
+ value: 12,
331
+ errorMessage: 'Хост слишком длинный',
332
+ },
333
+ minDomainLength: {
334
+ value: 3,
335
+ errorMessage: 'Домен слишком короткий',
336
+ },
337
+ maxDomainLength: {
338
+ value: 6,
339
+ errorMessage: 'Домен слишком длинный',
340
+ },
341
+ minZoneLength: {
342
+ value: 2,
343
+ errorMessage: 'Доменная зона слишком короткая',
344
+ },
345
+ maxZoneLength: {
346
+ value: 5,
347
+ errorMessage: 'Доменная зона слишком длинная',
348
+ },
349
+ whitelistDomains: {
350
+ value: ['plasma.ru', 'gmail.com', 'mail.ru'],
351
+ errorMessage: 'Домен не разрешен',
352
+ },
353
+ blacklistDomains: {
354
+ value: ['hah.ah', 'heh.eh'],
355
+ errorMessage: 'Домен запрещен',
356
+ },
357
+ };
358
+
359
+ const [error, setError] = useState('');
360
+
361
+ const handleOnChange = () => {
362
+ setError('');
363
+ };
364
+
365
+ const handleOnValidate = ({ errorMessage }: { errorMessage?: string }) => {
366
+ setError(errorMessage || '');
367
+ };
368
+
369
+ return (
370
+ <div>
371
+ <TextField
372
+ label="Валидация почты"
373
+ placeholder="Заполните поле"
374
+ validationType="email"
375
+ options={options}
376
+ view={error ? 'negative' : 'default}
377
+ helperText={error || 'Валидация почты'}
378
+ onChange={handleOnChange}
379
+ onValidate={handleOnValidate}
380
+ />
381
+ </div>
382
+ );
383
+ }
384
+ ```
385
+ </TabItem>
386
+
387
+ <TabItem value="password" label="Password" default>
388
+ Свойства доступные при валидации пароля:
389
+ ```tsx
390
+ type ValidationProps = {
391
+ /*
392
+ * Тип валидации
393
+ */
394
+ validationType: 'password';
395
+ /*
396
+ * Опции валидации
397
+ */
398
+ options?: PasswordValidationOptions;
399
+ /*
400
+ * Состояние сокрытия оригинального пароля
401
+ */
402
+ passwordHidden?: boolean;
403
+ /*
404
+ * Функция, вызываемая при валидации значения.
405
+ * Вызывается при событии onBlur и по нажатию Enter, когда фокус на поле ввода
406
+ */
407
+ onValidate?: (args: OnValidateArgs) => void;
408
+ }
409
+ ```
410
+ Свойство `options` имеет следующий вид:
411
+ ```tsx
412
+ type PasswordValidationOptions = {
413
+ /*
414
+ * Минимальная длина пароля
415
+ */
416
+ minLength?: {
417
+ value?: number;
418
+ errorMessage?: string;
419
+ };
420
+ /*
421
+ * Максимальная длина пароля
422
+ */
423
+ maxLength?: {
424
+ value?: number;
425
+ errorMessage?: string;
426
+ };
427
+ /*
428
+ * Должны ли быть буквы верхнего регистра в пароле
429
+ */
430
+ includeUppercase?: {
431
+ value?: boolean;
432
+ errorMessage?: string;
433
+ };
434
+ /*
435
+ * Должны ли быть буквы нижнего регистра в пароле
436
+ */
437
+ includeLowercase?: {
438
+ value?: boolean;
439
+ errorMessage?: string;
440
+ };
441
+ /*
442
+ * Должны ли быть цифры в пароле
443
+ */
444
+ includeDigits?: {
445
+ value?: boolean;
446
+ errorMessage?: string;
447
+ };
448
+ /*
449
+ * Должны ли быть специальные символы в пароле
450
+ */
451
+ includeSpecialSymbols?: {
452
+ value?: boolean;
453
+ errorMessage?: string;
454
+ };
455
+ };
456
+ ```
457
+
458
+ ```tsx live
459
+ import React, { useState } from 'react';
460
+ import { TextField, IconButton } from '@salutejs/{{ package }}';
461
+ import { IconEyeFill, IconEyeClosedFill } from '@salutejs/plasma-icons';
462
+
463
+ export function App() {
464
+ const options = {
465
+ minLength: {
466
+ value: 5,
467
+ errorMessage: 'Пароль слишком короткий',
468
+ },
469
+ maxLength: {
470
+ value: 20,
471
+ errorMessage: 'Пароль слишком длинный',
472
+ },
473
+ includeUppercase: {
474
+ value: true,
475
+ errorMessage: 'Пароль должен содержать хотя бы одну заглавную букву',
476
+ },
477
+ includeLowercase: {
478
+ value: true,
479
+ errorMessage: 'Пароль должен содержать хотя бы одну строчную букву',
480
+ },
481
+ includeDigits: {
482
+ value: true,
483
+ errorMessage: 'Пароль должен содержать хотя бы одну цифру',
484
+ },
485
+ includeSpecialSymbols: {
486
+ value: true,
487
+ errorMessage: 'Пароль должен содержать хотя бы один специальный символ',
488
+ },
489
+ };
490
+
491
+ const [error, setError] = useState('');
492
+ const [hidden, setHidden] = useState(false);
493
+
494
+ const handleOnChange = () => {
495
+ setError('');
496
+ };
497
+
498
+ const handleOnValidate = ({ errorMessage }: { errorMessage?: string }) => {
499
+ setError(errorMessage || '');
500
+ };
501
+
502
+ const toggleShowPassword = () => setHidden(!hidden);
503
+
504
+ const HideButton = () => (
505
+ <IconButton size="s" view="clear" onClick={toggleShowPassword}>
506
+ {hidden ? <IconEyeClosedFill size="xs" color="inherit" /> : <IconEyeFill size="xs" color="inherit" />}
507
+ </IconButton>
508
+ )
509
+
510
+ return (
511
+ <div>
512
+ <TextField
513
+ label="Валидация пароля"
514
+ placeholder="Заполните поле"
515
+ validationType="password"
516
+ options={options}
517
+ view={error ? 'negative' : 'default'}
518
+ leftHelper={error || 'Валидация пароля'}
519
+ onChange={handleOnChange}
520
+ onValidate={handleOnValidate}
521
+ passwordHidden={hidden}
522
+ contentLeft={<HideButton />}
523
+ />
524
+ </div>
525
+ );
526
+ }
527
+ ```
528
+ </TabItem>
529
+ </Tabs>
530
+
@@ -1 +1,2 @@
1
- export { useKeyNavigation } from './useKeyNavigation';
1
+ export { useKeyNavigation } from './useKeyNavigation';
2
+ export { useValidation } from './useValidation';
@@ -0,0 +1,270 @@
1
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
2
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
4
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
5
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
6
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
7
+ import { useEffect } from 'react';
8
+ import { constants } from '../../../utils';
9
+ var getUniqueKeys = function getUniqueKeys(lengthOptions) {
10
+ return lengthOptions.map(function (option) {
11
+ return option.replace(/min|max|Length/g, '');
12
+ });
13
+ };
14
+ var validateLenghtOptions = function validateLenghtOptions(options) {
15
+ var _options$minLength, _options$maxLength;
16
+ if (!options) {
17
+ return;
18
+ }
19
+ var minHash = Object.keys(options).filter(function (key) {
20
+ return key.startsWith('min');
21
+ });
22
+ var maxHash = Object.keys(options).filter(function (key) {
23
+ return key.startsWith('max');
24
+ });
25
+ var minMaxUniqueKeys = (minHash === null || minHash === void 0 ? void 0 : minHash.length) >= (maxHash === null || maxHash === void 0 ? void 0 : maxHash.length) ? getUniqueKeys(minHash) : getUniqueKeys(maxHash);
26
+ var globalMinValue = Number(options === null || options === void 0 || (_options$minLength = options.minLength) === null || _options$minLength === void 0 ? void 0 : _options$minLength.value);
27
+ var globalMaxValue = Number(options === null || options === void 0 || (_options$maxLength = options.maxLength) === null || _options$maxLength === void 0 ? void 0 : _options$maxLength.value);
28
+ if (globalMinValue <= 0) {
29
+ console.error('minLength must be more than 0');
30
+ }
31
+ if (globalMaxValue <= 0) {
32
+ console.error('maxLength must be more than 0');
33
+ }
34
+ if (globalMaxValue <= globalMinValue) {
35
+ console.error('maxLength must be more than minLength');
36
+ }
37
+ minMaxUniqueKeys.forEach(function (key) {
38
+ var _options$optionMinKey, _options$optionMaxKey;
39
+ var optionMinKey = "min".concat(key, "Length");
40
+ var optionMaxKey = "max".concat(key, "Length");
41
+ var minValue = Number(options === null || options === void 0 || (_options$optionMinKey = options[optionMinKey]) === null || _options$optionMinKey === void 0 ? void 0 : _options$optionMinKey.value);
42
+ var maxValue = Number(options === null || options === void 0 || (_options$optionMaxKey = options[optionMaxKey]) === null || _options$optionMaxKey === void 0 ? void 0 : _options$optionMaxKey.value);
43
+ if (!minValue || minValue <= 0) {
44
+ console.error("".concat(optionMinKey, " must be more than 0"));
45
+ }
46
+ if (!maxValue || maxValue <= 0) {
47
+ console.error("".concat(optionMaxKey, " must be more than 0"));
48
+ }
49
+ if (maxValue <= minValue) {
50
+ console.error("".concat(optionMaxKey, " must be more than ").concat(optionMinKey));
51
+ }
52
+ });
53
+ };
54
+ var validateWithLengthOptions = function validateWithLengthOptions(value, options, optionKey) {
55
+ var _options$optionMinKey2, _options$optionMaxKey2;
56
+ var optionMinKey = "min".concat(optionKey, "Length");
57
+ var optionMaxKey = "max".concat(optionKey, "Length");
58
+ var minValue = Number((_options$optionMinKey2 = options[optionMinKey]) === null || _options$optionMinKey2 === void 0 ? void 0 : _options$optionMinKey2.value);
59
+ var maxValue = Number((_options$optionMaxKey2 = options[optionMaxKey]) === null || _options$optionMaxKey2 === void 0 ? void 0 : _options$optionMaxKey2.value);
60
+ if (minValue && value.length < minValue) {
61
+ var _options$optionMinKey3;
62
+ return {
63
+ isValid: false,
64
+ errorMessage: ((_options$optionMinKey3 = options[optionMinKey]) === null || _options$optionMinKey3 === void 0 ? void 0 : _options$optionMinKey3.errorMessage) || "".concat(optionMinKey, " is too short")
65
+ };
66
+ }
67
+ if (maxValue && value.length > maxValue) {
68
+ var _options$optionMaxKey3;
69
+ return {
70
+ isValid: false,
71
+ errorMessage: ((_options$optionMaxKey3 = options[optionMaxKey]) === null || _options$optionMaxKey3 === void 0 ? void 0 : _options$optionMaxKey3.errorMessage) || "".concat(optionMaxKey, " is too long")
72
+ };
73
+ }
74
+ return {
75
+ isValid: true
76
+ };
77
+ };
78
+ var validateEmailDomainsLists = function validateEmailDomainsLists(blacklistDomains, whitelistDomains) {
79
+ if (!(blacklistDomains !== null && blacklistDomains !== void 0 && blacklistDomains.length) || !(whitelistDomains !== null && whitelistDomains !== void 0 && whitelistDomains.length)) {
80
+ return;
81
+ }
82
+ var uniqueDomains = new Set([].concat(_toConsumableArray(blacklistDomains), _toConsumableArray(whitelistDomains)));
83
+ if (uniqueDomains.size !== blacklistDomains.length + whitelistDomains.length) {
84
+ console.error('Blacklisted domains must not overlap whitelisted domains');
85
+ }
86
+ };
87
+ var validateWithDomainsLists = function validateWithDomainsLists(domainWithZone, options) {
88
+ var _options$whitelistDom, _options$blacklistDom, _options$blacklistDom2, _options$whitelistDom2;
89
+ if (!((_options$whitelistDom = options.whitelistDomains) !== null && _options$whitelistDom !== void 0 && (_options$whitelistDom = _options$whitelistDom.value) !== null && _options$whitelistDom !== void 0 && _options$whitelistDom.length) && !((_options$blacklistDom = options.blacklistDomains) !== null && _options$blacklistDom !== void 0 && (_options$blacklistDom = _options$blacklistDom.value) !== null && _options$blacklistDom !== void 0 && _options$blacklistDom.length)) {
90
+ return {
91
+ isValid: true
92
+ };
93
+ }
94
+ if (options !== null && options !== void 0 && (_options$blacklistDom2 = options.blacklistDomains) !== null && _options$blacklistDom2 !== void 0 && (_options$blacklistDom2 = _options$blacklistDom2.value) !== null && _options$blacklistDom2 !== void 0 && _options$blacklistDom2.includes(domainWithZone)) {
95
+ var _options$blacklistDom3;
96
+ return {
97
+ isValid: false,
98
+ errorMessage: ((_options$blacklistDom3 = options.blacklistDomains) === null || _options$blacklistDom3 === void 0 ? void 0 : _options$blacklistDom3.errorMessage) || 'Domain is blacklisted'
99
+ };
100
+ }
101
+ if (!(options !== null && options !== void 0 && (_options$whitelistDom2 = options.whitelistDomains) !== null && _options$whitelistDom2 !== void 0 && (_options$whitelistDom2 = _options$whitelistDom2.value) !== null && _options$whitelistDom2 !== void 0 && _options$whitelistDom2.includes(domainWithZone))) {
102
+ var _options$whitelistDom3;
103
+ return {
104
+ isValid: false,
105
+ errorMessage: ((_options$whitelistDom3 = options.whitelistDomains) === null || _options$whitelistDom3 === void 0 ? void 0 : _options$whitelistDom3.errorMessage) || 'Domain is not whitelisted'
106
+ };
107
+ }
108
+ return {
109
+ isValid: true
110
+ };
111
+ };
112
+ var validateEmail = function validateEmail(email, options) {
113
+ var _options$customEmailR, _options$minLength2, _options$maxLength2;
114
+ if (!email) {
115
+ return {
116
+ isValid: true
117
+ };
118
+ }
119
+ var emailRegex = (options === null || options === void 0 || (_options$customEmailR = options.customEmailRegex) === null || _options$customEmailR === void 0 ? void 0 : _options$customEmailR.value) || constants.emailPattern;
120
+ if (!emailRegex.test(email)) {
121
+ var _options$customEmailR2;
122
+ return {
123
+ isValid: false,
124
+ errorMessage: (options === null || options === void 0 || (_options$customEmailR2 = options.customEmailRegex) === null || _options$customEmailR2 === void 0 ? void 0 : _options$customEmailR2.errorMessage) || 'Invalid email'
125
+ };
126
+ }
127
+ if (!options) {
128
+ return {
129
+ isValid: true
130
+ };
131
+ }
132
+ if ((_options$minLength2 = options.minLength) !== null && _options$minLength2 !== void 0 && _options$minLength2.value && email.length < options.minLength.value) {
133
+ var _options$minLength3;
134
+ return {
135
+ isValid: false,
136
+ errorMessage: ((_options$minLength3 = options.minLength) === null || _options$minLength3 === void 0 ? void 0 : _options$minLength3.errorMessage) || 'Email is too short'
137
+ };
138
+ }
139
+ if ((_options$maxLength2 = options.maxLength) !== null && _options$maxLength2 !== void 0 && _options$maxLength2.value && email.length > options.maxLength.value) {
140
+ var _options$maxLength3;
141
+ return {
142
+ isValid: false,
143
+ errorMessage: ((_options$maxLength3 = options.maxLength) === null || _options$maxLength3 === void 0 ? void 0 : _options$maxLength3.errorMessage) || 'Email is too long'
144
+ };
145
+ }
146
+ var emailHost = email.split('@')[0];
147
+ var emailDomainWithZone = email.split('@')[1];
148
+ var emailZone = emailDomainWithZone.split('.').pop();
149
+ if (!(emailZone !== null && emailZone !== void 0 && emailZone.length)) {
150
+ var _options$customEmailR3;
151
+ return {
152
+ isValid: false,
153
+ errorMessage: ((_options$customEmailR3 = options.customEmailRegex) === null || _options$customEmailR3 === void 0 ? void 0 : _options$customEmailR3.errorMessage) || 'Invalid email'
154
+ };
155
+ }
156
+ var emailDomain = emailDomainWithZone.substring(0, emailDomainWithZone.length - (emailZone.length + 1));
157
+ var hostValidation = validateWithLengthOptions(emailHost, options, 'Host');
158
+ if (!hostValidation.isValid) {
159
+ return hostValidation;
160
+ }
161
+ var domainValidation = validateWithLengthOptions(emailDomain, options, 'Domain');
162
+ if (!domainValidation.isValid) {
163
+ return domainValidation;
164
+ }
165
+ var zoneValidation = validateWithLengthOptions(emailZone, options, 'Zone');
166
+ if (!zoneValidation.isValid) {
167
+ return zoneValidation;
168
+ }
169
+ var domainWithZoneValidation = validateWithDomainsLists(emailDomainWithZone, options);
170
+ if (!domainWithZoneValidation.isValid) {
171
+ return domainWithZoneValidation;
172
+ }
173
+ return {
174
+ isValid: true
175
+ };
176
+ };
177
+ var validatePassword = function validatePassword(password, options) {
178
+ var _options$minLength4, _options$maxLength4, _options$includeUpper, _options$includeLower, _options$includeDigit, _options$includeSpeci;
179
+ if (!password || !options) {
180
+ return {
181
+ isValid: true
182
+ };
183
+ }
184
+ if ((_options$minLength4 = options.minLength) !== null && _options$minLength4 !== void 0 && _options$minLength4.value && password.length < options.minLength.value) {
185
+ var _options$minLength5;
186
+ return {
187
+ isValid: false,
188
+ errorMessage: ((_options$minLength5 = options.minLength) === null || _options$minLength5 === void 0 ? void 0 : _options$minLength5.errorMessage) || 'Password is too short'
189
+ };
190
+ }
191
+ if ((_options$maxLength4 = options.maxLength) !== null && _options$maxLength4 !== void 0 && _options$maxLength4.value && password.length > options.maxLength.value) {
192
+ var _options$maxLength5;
193
+ return {
194
+ isValid: false,
195
+ errorMessage: ((_options$maxLength5 = options.maxLength) === null || _options$maxLength5 === void 0 ? void 0 : _options$maxLength5.errorMessage) || 'Password is too long'
196
+ };
197
+ }
198
+ var lowercasedPassword = password.toLowerCase();
199
+ var uppercasedPassword = password.toUpperCase();
200
+ if ((_options$includeUpper = options.includeUppercase) !== null && _options$includeUpper !== void 0 && _options$includeUpper.value && password === lowercasedPassword) {
201
+ var _options$includeUpper2;
202
+ return {
203
+ isValid: false,
204
+ errorMessage: ((_options$includeUpper2 = options.includeUppercase) === null || _options$includeUpper2 === void 0 ? void 0 : _options$includeUpper2.errorMessage) || 'Password must contain at least one uppercase letter'
205
+ };
206
+ }
207
+ if ((_options$includeLower = options.includeLowercase) !== null && _options$includeLower !== void 0 && _options$includeLower.value && password === uppercasedPassword) {
208
+ var _options$includeLower2;
209
+ return {
210
+ isValid: false,
211
+ errorMessage: ((_options$includeLower2 = options.includeLowercase) === null || _options$includeLower2 === void 0 ? void 0 : _options$includeLower2.errorMessage) || 'Password must contain at least one lowercase letter'
212
+ };
213
+ }
214
+ if ((_options$includeDigit = options.includeDigits) !== null && _options$includeDigit !== void 0 && _options$includeDigit.value && !/\d/.test(password)) {
215
+ var _options$includeDigit2;
216
+ return {
217
+ isValid: false,
218
+ errorMessage: ((_options$includeDigit2 = options.includeDigits) === null || _options$includeDigit2 === void 0 ? void 0 : _options$includeDigit2.errorMessage) || 'Password must contain digits'
219
+ };
220
+ }
221
+ if ((_options$includeSpeci = options.includeSpecialSymbols) !== null && _options$includeSpeci !== void 0 && _options$includeSpeci.value && !constants.specialCharacters.test(password)) {
222
+ var _options$includeSpeci2;
223
+ return {
224
+ isValid: false,
225
+ errorMessage: ((_options$includeSpeci2 = options.includeSpecialSymbols) === null || _options$includeSpeci2 === void 0 ? void 0 : _options$includeSpeci2.errorMessage) || 'Password must contain special characters'
226
+ };
227
+ }
228
+ return {
229
+ isValid: true
230
+ };
231
+ };
232
+ var validationVariants = {
233
+ email: validateEmail,
234
+ password: validatePassword
235
+ };
236
+ export var useValidation = function useValidation(_ref) {
237
+ var validationType = _ref.validationType,
238
+ options = _ref.options,
239
+ onValidate = _ref.onValidate;
240
+ var handleValidationBlur = function handleValidationBlur(event) {
241
+ if (!validationType) {
242
+ return;
243
+ }
244
+ var validationResult = validationVariants[validationType](event.target.value, options);
245
+ onValidate === null || onValidate === void 0 || onValidate(validationResult);
246
+ };
247
+ var handleValidationKeyDown = function handleValidationKeyDown(event) {
248
+ if (!validationType) {
249
+ return;
250
+ }
251
+ if (event.keyCode === constants.keyCodes.Enter) {
252
+ event.preventDefault();
253
+ var _ref2 = event.target,
254
+ value = _ref2.value;
255
+ var validationResult = validationVariants[validationType](value, options);
256
+ onValidate === null || onValidate === void 0 || onValidate(validationResult);
257
+ }
258
+ };
259
+ useEffect(function () {
260
+ validateLenghtOptions(options);
261
+ if (validationType === 'email') {
262
+ var _whitelistDomains, _blacklistDomains;
263
+ validateEmailDomainsLists(options === null || options === void 0 || (_whitelistDomains = options.whitelistDomains) === null || _whitelistDomains === void 0 ? void 0 : _whitelistDomains.value, (_blacklistDomains = options.blacklistDomains) === null || _blacklistDomains === void 0 ? void 0 : _blacklistDomains.value);
264
+ }
265
+ }, []);
266
+ return {
267
+ handleValidationBlur: handleValidationBlur,
268
+ handleValidationKeyDown: handleValidationKeyDown
269
+ };
270
+ };