@central-design-system/components 4.0.0-alpha.2 → 4.0.0-alpha.3

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 (93) hide show
  1. package/CHANGELOG.md +5 -1
  2. package/MIGRATION.md +1 -1
  3. package/dist/cjs/entry.js +10 -10
  4. package/dist/es/entry.js +173 -163
  5. package/dist/es/entry.js.map +1 -1
  6. package/dist/es/src/components/CdsList/CdsList.vue_vue_type_script_setup_true_lang.js +1 -1
  7. package/dist/es/src/components/CdsList/CdsListGroup.vue_vue_type_script_setup_true_lang.js +1 -1
  8. package/dist/es/src/components/CdsList/CdsListItem.vue_vue_type_script_setup_true_lang.js +1 -1
  9. package/dist/es/src/components/CdsList/CdsListSubheader.vue_vue_type_script_setup_true_lang.js +1 -1
  10. package/dist/es/src/components/CdsList/api/CdsList.constants.js +4 -4
  11. package/dist/es/src/components/CdsList/api/CdsList.props.js +2 -2
  12. package/dist/es/src/components/CdsList/index.js +1 -1
  13. package/dist/es/src/components/CdsOtpInput/CdsOtpField.js +2 -0
  14. package/dist/es/src/components/CdsOtpInput/CdsOtpField.js.map +1 -0
  15. package/dist/es/src/components/CdsOtpInput/CdsOtpField.vue_vue_type_script_setup_true_lang.js +62 -0
  16. package/dist/es/src/components/CdsOtpInput/CdsOtpField.vue_vue_type_script_setup_true_lang.js.map +1 -0
  17. package/dist/es/src/components/CdsOtpInput/CdsOtpGroup.js +2 -0
  18. package/dist/es/src/components/CdsOtpInput/CdsOtpGroup.js.map +1 -0
  19. package/dist/es/src/components/CdsOtpInput/CdsOtpGroup.vue_vue_type_script_setup_true_lang.js +51 -0
  20. package/dist/es/src/components/CdsOtpInput/CdsOtpGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
  21. package/dist/es/src/components/CdsOtpInput/CdsOtpInput.css +204 -0
  22. package/dist/es/src/components/CdsOtpInput/CdsOtpInput.js +2 -0
  23. package/dist/es/src/components/CdsOtpInput/CdsOtpInput.js.map +1 -0
  24. package/dist/es/src/components/CdsOtpInput/CdsOtpInput.vue_vue_type_script_setup_true_lang.js +338 -0
  25. package/dist/es/src/components/CdsOtpInput/CdsOtpInput.vue_vue_type_script_setup_true_lang.js.map +1 -0
  26. package/dist/es/src/components/CdsOtpInput/CdsOtpSeparator.js +2 -0
  27. package/dist/es/src/components/CdsOtpInput/CdsOtpSeparator.js.map +1 -0
  28. package/dist/es/src/components/CdsOtpInput/CdsOtpSeparator.vue_vue_type_script_setup_true_lang.js +34 -0
  29. package/dist/es/src/components/CdsOtpInput/CdsOtpSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -0
  30. package/dist/es/src/components/CdsOtpInput/api/CdsOtpInput.constants.js +16 -0
  31. package/dist/es/src/components/CdsOtpInput/api/CdsOtpInput.constants.js.map +1 -0
  32. package/dist/es/src/components/CdsOtpInput/api/CdsOtpInput.props.js +97 -0
  33. package/dist/es/src/components/CdsOtpInput/api/CdsOtpInput.props.js.map +1 -0
  34. package/dist/es/src/components/CdsOtpInput/api/CdsOtpInput.types.js +2 -0
  35. package/dist/es/src/components/CdsOtpInput/api/CdsOtpInput.types.js.map +1 -0
  36. package/dist/es/src/components/CdsOtpInput/composables/useOtpInput.js +329 -0
  37. package/dist/es/src/components/CdsOtpInput/composables/useOtpInput.js.map +1 -0
  38. package/dist/es/src/components/CdsOtpInput/index.js +17 -0
  39. package/dist/es/src/components/CdsOtpInput/index.js.map +1 -0
  40. package/dist/es/src/components/index.js +10 -0
  41. package/dist/es/src/components/index.js.map +1 -1
  42. package/dist/es/src/composables/useDisabled/index.js +1 -1
  43. package/dist/es/src/composables/useDisabled/index.js.map +1 -1
  44. package/dist/es/src/composables/useLoader/index.js +1 -1
  45. package/dist/es/src/composables/useLoader/index.js.map +1 -1
  46. package/dist/es/src/composables/useLocation/index.js +1 -1
  47. package/dist/es/src/composables/useLocation/index.js.map +1 -1
  48. package/dist/es/src/composables/useRouter/index.js +1 -1
  49. package/dist/es/src/composables/useRouter/index.js.map +1 -1
  50. package/dist/es/src/locales/ru.js +1 -0
  51. package/dist/es/src/locales/ru.js.map +1 -1
  52. package/dist/esm-node/entry.mjs +173 -163
  53. package/dist/esm-node/src/components/CdsOtpInput/CdsOtpField.mjs +2 -0
  54. package/dist/esm-node/src/components/CdsOtpInput/CdsOtpField.vue_vue_type_script_setup_true_lang.mjs +62 -0
  55. package/dist/esm-node/src/components/CdsOtpInput/CdsOtpGroup.mjs +2 -0
  56. package/dist/esm-node/src/components/CdsOtpInput/CdsOtpGroup.vue_vue_type_script_setup_true_lang.mjs +51 -0
  57. package/dist/esm-node/src/components/CdsOtpInput/CdsOtpInput.css +204 -0
  58. package/dist/esm-node/src/components/CdsOtpInput/CdsOtpInput.mjs +2 -0
  59. package/dist/esm-node/src/components/CdsOtpInput/CdsOtpInput.vue_vue_type_script_setup_true_lang.mjs +336 -0
  60. package/dist/esm-node/src/components/CdsOtpInput/CdsOtpSeparator.mjs +2 -0
  61. package/dist/esm-node/src/components/CdsOtpInput/CdsOtpSeparator.vue_vue_type_script_setup_true_lang.mjs +34 -0
  62. package/dist/esm-node/src/components/CdsOtpInput/api/CdsOtpInput.constants.mjs +16 -0
  63. package/dist/esm-node/src/components/CdsOtpInput/api/CdsOtpInput.props.mjs +97 -0
  64. package/dist/esm-node/src/components/CdsOtpInput/api/CdsOtpInput.types.mjs +2 -0
  65. package/dist/esm-node/src/components/CdsOtpInput/composables/useOtpInput.mjs +329 -0
  66. package/dist/esm-node/src/components/CdsOtpInput/index.mjs +17 -0
  67. package/dist/esm-node/src/components/index.mjs +10 -0
  68. package/dist/esm-node/src/composables/useLoader/index.mjs +1 -1
  69. package/dist/esm-node/src/composables/useLocation/index.mjs +1 -1
  70. package/dist/esm-node/src/composables/useRouter/index.mjs +1 -1
  71. package/dist/esm-node/src/locales/ru.mjs +1 -0
  72. package/dist/iife/entry.js +10 -10
  73. package/dist/styles.css +1 -1
  74. package/dist/types/components/CdsOtpInput/CdsOtpField.vue.d.ts +25 -0
  75. package/dist/types/components/CdsOtpInput/CdsOtpGroup.vue.d.ts +34 -0
  76. package/dist/types/components/CdsOtpInput/CdsOtpInput.vue.d.ts +222 -0
  77. package/dist/types/components/CdsOtpInput/CdsOtpSeparator.vue.d.ts +25 -0
  78. package/dist/types/components/CdsOtpInput/api/CdsOtpInput.constants.d.ts +9 -0
  79. package/dist/types/components/CdsOtpInput/api/CdsOtpInput.props.d.ts +340 -0
  80. package/dist/types/components/CdsOtpInput/api/CdsOtpInput.types.d.ts +47 -0
  81. package/dist/types/components/CdsOtpInput/composables/useOtpInput.d.ts +76 -0
  82. package/dist/types/components/CdsOtpInput/index.d.ts +529 -0
  83. package/dist/types/components/index.d.ts +1 -0
  84. package/dist/types/entry.d.ts +5 -1
  85. package/dist/types/locales/en.d.ts +1 -0
  86. package/dist/types/locales/ru.d.ts +1 -0
  87. package/llms/llms-components.txt +512 -1
  88. package/llms/llms-full.txt +513 -2
  89. package/llms/llms-guides.txt +1 -1
  90. package/llms/llms-migration.txt +2 -2
  91. package/llms/llms-tokens.txt +1 -1
  92. package/llms/llms.txt +4 -3
  93. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  # Central Design System (CDS 4) — полная документация
2
2
 
3
- > Версия: 4.0.0-alpha.2
3
+ > Версия: 4.0.0-alpha.3
4
4
  > Всё сразу: гайды, токены и темы, компоненты с примерами и контрактом API, миграция с CDS 3.
5
5
  > Сгенерировано автоматически (`bun run generate:meta` → `bun run generate:llms`). Не редактировать вручную.
6
6
 
@@ -22304,6 +22304,517 @@ function onUpdateModelValue(value: boolean, id: number) {
22304
22304
 
22305
22305
  ---
22306
22306
 
22307
+ # CdsOtpInput
22308
+
22309
+ _Категория: Controls · появился в 4.0.0 · статус: new_
22310
+
22311
+ Поле ввода одноразового кода — из SMS, письма или приложения-аутентификатора. Внешне это ряд отдельных ячеек, но ввод принимает один скрытый `input`: поэтому работают автозаполнение кода из SMS, вставка целой строкой из буфера, выделение и стрелки, а фокус не приходится перепрыгивать между ячейками вручную.
22312
+
22313
+ **Смотрите также:** Для обычного короткого текста или числа возьмите CdsTextInput: `CdsOtpInput` нужен там, где длина ввода известна заранее и каждый символ показывается отдельной ячейкой.
22314
+
22315
+ ## Анатомия
22316
+
22317
+ Ячейки (`CdsOtpField`) только рисуют код — введённый символ, заполнитель или
22318
+ мигающую каретку. Настоящий ввод принимает скрытый `input`: он прижат к нижнему
22319
+ краю компонента, поэтому подсказка автозаполнения из SMS появляется под ячейками
22320
+ и ничего не перекрывает. Между ячейками может стоять разделитель
22321
+ (`CdsOtpSeparator`), а в слитном виде ячейки собираются в группу (`CdsOtpGroup`).
22322
+
22323
+ **Пример — `Anatomy.vue`:**
22324
+
22325
+ ```vue
22326
+ <script setup lang="ts">
22327
+ import AnatomyDemo from '@cds/utils/docs/AnatomyDemo.vue';
22328
+ import { CdsOtpInput } from '@central-design-system/components';
22329
+
22330
+ // Схема 1: обычный ряд — ячейки и разделители между ними
22331
+ const fieldsMarkers = [
22332
+ { selector: '.cds-otp-input__content', label: 'Ряд ячеек', side: 'right' as const },
22333
+ { selector: '.cds-otp-field', label: 'Ячейка (CdsOtpField)', side: 'top' as const },
22334
+ { selector: '.cds-otp-separator', label: 'Разделитель (CdsOtpSeparator)', side: 'bottom' as const },
22335
+ { selector: '.cds-otp-field__placeholder', label: 'Символ-заполнитель', side: 'bottom' as const }
22336
+ ];
22337
+
22338
+ // Схема 2: слитный вид — ячейки собраны в общую группу
22339
+ const mergedMarkers = [
22340
+ { selector: '.cds-otp-field', label: 'Ячейка (CdsOtpField)', side: 'top' as const },
22341
+ { selector: '.cds-otp-group', label: 'Группа (CdsOtpGroup)', side: 'bottom' as const }
22342
+ ];
22343
+ </script>
22344
+
22345
+ <template>
22346
+ <div class="flex flex-col gap-600">
22347
+ <AnatomyDemo :markers="fieldsMarkers">
22348
+ <CdsOtpInput model-value="12" divider="-" placeholder="0" />
22349
+ </AnatomyDemo>
22350
+
22351
+ <AnatomyDemo :markers="mergedMarkers">
22352
+ <CdsOtpInput model-value="12" merged />
22353
+ </AnatomyDemo>
22354
+ </div>
22355
+ </template>
22356
+ ```
22357
+
22358
+ ## Вариации
22359
+
22360
+ ### Длина и тип кода
22361
+
22362
+ Свойство `length` задаёт число ячеек, `type` — что можно вводить: `number`
22363
+ (по умолчанию) принимает только цифры и открывает цифровую клавиатуру на
22364
+ мобильных, `text` — любые символы, `password` дополнительно скрывает введённое
22365
+ точками. Тот же эффект без смены типа даёт `masked`.
22366
+
22367
+ **Пример — `LengthAndType.vue`:**
22368
+
22369
+ ```vue
22370
+ <script setup lang="ts">
22371
+ import { CdsOtpInput } from '@central-design-system/components';
22372
+ </script>
22373
+
22374
+ <template>
22375
+ <div class="flex flex-col items-center gap-400">
22376
+ <CdsOtpInput :length="4" model-value="1234" />
22377
+ <CdsOtpInput type="text" model-value="AB12CD" />
22378
+ <CdsOtpInput type="password" model-value="123456" />
22379
+ </div>
22380
+ </template>
22381
+ ```
22382
+
22383
+ ### Допустимые символы
22384
+
22385
+ Свойство `pattern` сужает набор символов: имя готового набора (`numeric`,
22386
+ `alpha`, `alphanumeric`, `unicode-alpha`, `unicode-alphanumeric`) или своё
22387
+ регулярное выражение. Проверка идёт посимвольно — лишние символы не попадут в
22388
+ поле ни с клавиатуры, ни из буфера обмена.
22389
+
22390
+ **Пример — `Pattern.vue`:**
22391
+
22392
+ ```vue
22393
+ <script setup lang="ts">
22394
+ import { CdsOtpInput } from '@central-design-system/components';
22395
+ </script>
22396
+
22397
+ <template>
22398
+ <div class="flex flex-col items-center gap-400">
22399
+ <CdsOtpInput type="text" pattern="alpha" :length="4" placeholder="A" />
22400
+ <CdsOtpInput type="text" pattern="alphanumeric" placeholder="X" />
22401
+ <CdsOtpInput type="text" :pattern="/[0-9A-F]/" placeholder="F" />
22402
+ </div>
22403
+ </template>
22404
+ ```
22405
+
22406
+ ### Разделитель
22407
+
22408
+ Свойство `divider` ставит символ между ячейками — например, дефис в коде вида
22409
+ `123-456`. Слот `divider` даёт полную свободу разметки и получает `index` —
22410
+ номер ячейки слева от разделителя, так что разделитель можно поставить только
22411
+ в нужном месте.
22412
+
22413
+ **Пример — `Divider.vue`:**
22414
+
22415
+ ```vue
22416
+ <script setup lang="ts">
22417
+ import { CdsIcon, CdsOtpInput } from '@central-design-system/components';
22418
+ </script>
22419
+
22420
+ <template>
22421
+ <div class="flex flex-col items-center gap-400">
22422
+ <CdsOtpInput divider="-" model-value="123456" />
22423
+
22424
+ <CdsOtpInput model-value="123456">
22425
+ <template #divider="{ index }">
22426
+ <CdsIcon v-if="index === 2" name="minus" size="sm" />
22427
+ </template>
22428
+ </CdsOtpInput>
22429
+ </div>
22430
+ </template>
22431
+ ```
22432
+
22433
+ ### Слитный вид
22434
+
22435
+ Свойство `merged` убирает промежутки: ячейки становятся одним полем с общей
22436
+ рамкой. Такой вид компактнее и меньше дробит форму.
22437
+
22438
+ **Пример — `Merged.vue`:**
22439
+
22440
+ ```vue
22441
+ <script setup lang="ts">
22442
+ import { CdsOtpInput } from '@central-design-system/components';
22443
+ </script>
22444
+
22445
+ <template>
22446
+ <div class="flex justify-center">
22447
+ <CdsOtpInput merged model-value="1234" />
22448
+ </div>
22449
+ </template>
22450
+ ```
22451
+
22452
+ ### Заполнитель
22453
+
22454
+ Свойство `placeholder` показывает символ в пустых ячейках — подсказку формата
22455
+ или просто точку, чтобы ряд не выглядел пустым.
22456
+
22457
+ **Пример — `Placeholder.vue`:**
22458
+
22459
+ ```vue
22460
+ <script setup lang="ts">
22461
+ import { CdsOtpInput } from '@central-design-system/components';
22462
+ </script>
22463
+
22464
+ <template>
22465
+ <div class="flex flex-col items-center gap-400">
22466
+ <CdsOtpInput placeholder="0" />
22467
+ <CdsOtpInput placeholder="•" />
22468
+ </div>
22469
+ </template>
22470
+ ```
22471
+
22472
+ ### Размеры
22473
+
22474
+ Свойство `size` меняет высоту ячеек и размер шрифта. Размер по умолчанию — `md`.
22475
+
22476
+ **Пример — `Sizes.vue`:**
22477
+
22478
+ ```vue
22479
+ <script setup lang="ts">
22480
+ import { CdsOtpInput } from '@central-design-system/components';
22481
+
22482
+ const sizes = ['xs', 'sm', 'md', 'lg', 'xl'] as const;
22483
+ </script>
22484
+
22485
+ <template>
22486
+ <div class="flex flex-col items-center gap-400">
22487
+ <CdsOtpInput v-for="size of sizes" :key="size" :size="size" :length="4" model-value="1234" />
22488
+ </div>
22489
+ </template>
22490
+ ```
22491
+
22492
+ ### Состояния
22493
+
22494
+ `disabled` блокирует ввод, `error` подсвечивает весь ряд ошибкой, `loading`
22495
+ показывает индикатор поверх ячеек и не стирает набранный код. `focus-all`
22496
+ подсвечивает весь ряд, пока поле в фокусе, а не только активную ячейку.
22497
+
22498
+ **Пример — `States.vue`:**
22499
+
22500
+ ```vue
22501
+ <script setup lang="ts">
22502
+ import { CdsOtpInput } from '@central-design-system/components';
22503
+ </script>
22504
+
22505
+ <template>
22506
+ <div class="flex flex-col items-center gap-400">
22507
+ <CdsOtpInput :length="4" model-value="12" disabled />
22508
+ <CdsOtpInput :length="4" model-value="1234" error />
22509
+ <CdsOtpInput :length="4" model-value="1234" loading />
22510
+ <CdsOtpInput :length="4" model-value="12" focus-all />
22511
+ </div>
22512
+ </template>
22513
+ ```
22514
+
22515
+ ### Слоты
22516
+
22517
+ | Слот | Описание |
22518
+ | :-------- | :---------------------------------------------------------------------------- |
22519
+ | `fields` | Ряд ячеек целиком — своя разметка из `CdsOtpGroup`, `CdsOtpField` и `CdsOtpSeparator` |
22520
+ | `divider` | Разделитель между ячейками, `index` — номер ячейки слева от него |
22521
+ | `loader` | Свой индикатор загрузки (при `loading`) |
22522
+ | `default` | Произвольный контент поверх ячеек |
22523
+
22524
+ Слот `fields` нужен, когда ячейки собираются в группы: каждая `CdsOtpField`
22525
+ получает свой `index`, а `CdsOtpGroup` объединяет соседние ячейки в общую рамку.
22526
+
22527
+ **Пример — `CustomFields.vue`:**
22528
+
22529
+ ```vue
22530
+ <script setup lang="ts">
22531
+ import { CdsOtpField, CdsOtpGroup, CdsOtpInput, CdsOtpSeparator } from '@central-design-system/components';
22532
+ </script>
22533
+
22534
+ <template>
22535
+ <div class="flex justify-center">
22536
+ <CdsOtpInput model-value="123456">
22537
+ <template #fields>
22538
+ <CdsOtpGroup merged>
22539
+ <CdsOtpField v-for="index of [0, 1, 2]" :key="index" :index="index" />
22540
+ </CdsOtpGroup>
22541
+
22542
+ <CdsOtpSeparator>—</CdsOtpSeparator>
22543
+
22544
+ <CdsOtpGroup merged>
22545
+ <CdsOtpField v-for="index of [3, 4, 5]" :key="index" :index="index" />
22546
+ </CdsOtpGroup>
22547
+ </template>
22548
+ </CdsOtpInput>
22549
+ </div>
22550
+ </template>
22551
+ ```
22552
+
22553
+ ## Рекомендации
22554
+
22555
+ | ✅ Хорошо | ❌ Плохо |
22556
+ | --- | --- |
22557
+ | Число ячеек равно длине кода — пользователь сразу видит, сколько символов вводить. | Лишние ячейки заставляют гадать, весь ли код набран. |
22558
+ | Код целиком набирается в одном поле: вставка из буфера и автозаполнение из SMS работают. | Отдельные текстовые поля ломают вставку кода и заставляют вручную перепрыгивать фокус. |
22559
+ | При ошибке поле остаётся доступным, а текст рядом говорит, что делать дальше. | Заблокированное поле без объяснения не даёт исправить код. |
22560
+
22561
+ ## Сценарии использования
22562
+
22563
+ ### Подтверждение по SMS
22564
+
22565
+ Событие `finish` срабатывает, как только код набран целиком, — отправляйте
22566
+ запрос по нему, отдельная кнопка не нужна. На время проверки включите `loading`:
22567
+ код остаётся на экране, а поле не выглядит сломанным. Если сервер не принял код,
22568
+ `error` подсвечивает ряд, а методы `reset()` и `focus()` через ref очищают поле
22569
+ и возвращают в него курсор.
22570
+
22571
+ **Пример — `SmsConfirmation.vue`:**
22572
+
22573
+ ```vue
22574
+ <script setup lang="ts">
22575
+ import { CdsOtpInput } from '@central-design-system/components';
22576
+ import { ref } from 'vue';
22577
+
22578
+ const otpRef = ref<InstanceType<typeof CdsOtpInput>>();
22579
+
22580
+ const code = ref('');
22581
+ const loading = ref(false);
22582
+ const status = ref<'idle' | 'success' | 'error'>('idle');
22583
+
22584
+ // Имитация проверки кода на сервере: верный код — 123456
22585
+ function onFinish(value: string) {
22586
+ loading.value = true;
22587
+ status.value = 'idle';
22588
+
22589
+ setTimeout(() => {
22590
+ loading.value = false;
22591
+ status.value = value === '123456' ? 'success' : 'error';
22592
+
22593
+ if (status.value === 'error') {
22594
+ otpRef.value?.reset();
22595
+ otpRef.value?.focus();
22596
+ }
22597
+ }, 1000);
22598
+ }
22599
+ </script>
22600
+
22601
+ <template>
22602
+ <div class="flex flex-col items-center gap-300">
22603
+ <p class="text-200 text-content-secondary">Код отправлен на +7 999 000-00-00</p>
22604
+
22605
+ <CdsOtpInput
22606
+ ref="otpRef"
22607
+ v-model="code"
22608
+ :loading="loading"
22609
+ :error="status === 'error'"
22610
+ @finish="onFinish"
22611
+ @update:model-value="status = 'idle'"
22612
+ />
22613
+
22614
+ <p v-if="status === 'success'" class="text-200 text-status-success-content">Код подтверждён</p>
22615
+ <p v-else-if="status === 'error'" class="text-200 text-status-danger-content">
22616
+ Код неверный — введите последние цифры из SMS ещё раз
22617
+ </p>
22618
+ <p v-else class="text-200 text-content-tertiary">Введите 123456, чтобы увидеть подтверждение</p>
22619
+ </div>
22620
+ </template>
22621
+ ```
22622
+
22623
+ ### Повторная отправка кода
22624
+
22625
+ Кнопка «Отправить снова» открывается по таймеру — так пользователь не завалит
22626
+ запросами шлюз. Вместе с новым кодом сбрасывайте поле: `reset()` очищает ячейки,
22627
+ `focus()` ставит курсор в первую, и старый код не смешивается с новым.
22628
+
22629
+ **Пример — `ResendCode.vue`:**
22630
+
22631
+ ```vue
22632
+ <script setup lang="ts">
22633
+ import { CdsButton, CdsOtpInput } from '@central-design-system/components';
22634
+ import { onScopeDispose, ref } from 'vue';
22635
+
22636
+ const otpRef = ref<InstanceType<typeof CdsOtpInput>>();
22637
+
22638
+ const code = ref('');
22639
+ const seconds = ref(15);
22640
+
22641
+ let timer: ReturnType<typeof setInterval> | undefined;
22642
+
22643
+ function countdown() {
22644
+ clearInterval(timer);
22645
+
22646
+ timer = setInterval(() => {
22647
+ seconds.value -= 1;
22648
+
22649
+ if (seconds.value <= 0) clearInterval(timer);
22650
+ }, 1000);
22651
+ }
22652
+
22653
+ function resend() {
22654
+ seconds.value = 15;
22655
+ countdown();
22656
+
22657
+ otpRef.value?.reset();
22658
+ otpRef.value?.focus();
22659
+ }
22660
+
22661
+ countdown();
22662
+ onScopeDispose(() => clearInterval(timer));
22663
+ </script>
22664
+
22665
+ <template>
22666
+ <div class="flex flex-col items-center gap-300">
22667
+ <CdsOtpInput ref="otpRef" v-model="code" placeholder="•" />
22668
+
22669
+ <CdsButton
22670
+ appearance="tertiary"
22671
+ size="sm"
22672
+ :disabled="seconds > 0"
22673
+ :text="seconds > 0 ? `Отправить снова через ${seconds} с` : 'Отправить код снова'"
22674
+ @click="resend"
22675
+ />
22676
+ </div>
22677
+ </template>
22678
+ ```
22679
+
22680
+ ### Код в форме
22681
+
22682
+ Когда код — часть формы входа, оставьте кнопку подтверждения: она даёт явный
22683
+ момент отправки. Кнопка ждёт, пока набраны все символы, — длину кода видно из
22684
+ `v-model`, а `disabled` на поле фиксирует уже подтверждённый код.
22685
+
22686
+ **Пример — `TwoFactorForm.vue`:**
22687
+
22688
+ ```vue
22689
+ <script setup lang="ts">
22690
+ import { CdsButton, CdsForm, CdsOtpInput } from '@central-design-system/components';
22691
+ import { computed, ref } from 'vue';
22692
+
22693
+ const code = ref('');
22694
+ const loading = ref(false);
22695
+ const confirmed = ref(false);
22696
+
22697
+ const isComplete = computed(() => code.value.length === 6);
22698
+
22699
+ function submit() {
22700
+ loading.value = true;
22701
+
22702
+ setTimeout(() => {
22703
+ loading.value = false;
22704
+ confirmed.value = true;
22705
+ }, 1000);
22706
+ }
22707
+ </script>
22708
+
22709
+ <template>
22710
+ <CdsForm class="flex flex-col items-center gap-300 w-[350px] m-auto" @submit.prevent="submit">
22711
+ <p class="text-200 text-content-secondary">Введите код из приложения-аутентификатора</p>
22712
+
22713
+ <CdsOtpInput v-model="code" :disabled="confirmed" divider="-" />
22714
+
22715
+ <CdsButton type="submit" text="Подтвердить вход" :disabled="!isComplete || confirmed" :loading="loading" block />
22716
+
22717
+ <p v-if="confirmed" class="text-200 text-status-success-content">Вход подтверждён</p>
22718
+ </CdsForm>
22719
+ </template>
22720
+ ```
22721
+
22722
+ ## API
22723
+
22724
+ ### CdsOtpInput
22725
+
22726
+ **Props**
22727
+
22728
+ | Prop | Type | Default | Required | Description |
22729
+ | --- | --- | --- | --- | --- |
22730
+ | `activeColor` | `string \| undefined` | — | no | Цвет компонента, когда он находится в активном состоянии |
22731
+ | `autofocus` | `boolean \| undefined` | — | no | Включает автофокус |
22732
+ | `baseColor` | `string \| undefined` | — | no | Цвет неактивного компонента |
22733
+ | `bgColor` | `string \| undefined` | — | no | Цвет фона компонента |
22734
+ | `color` | `string \| undefined` | — | no | Цвет компонента |
22735
+ | `disabled` | `boolean \| null \| undefined` | `null` | no | Заблокированное состояние |
22736
+ | `divider` | `string \| undefined` | — | no | Символ-разделитель, который ставится между ячейками кода |
22737
+ | `error` | `boolean \| undefined` | — | no | Состояние ошибки |
22738
+ | `focusAll` | `boolean \| undefined` | — | no | Подсвечивать все ячейки, пока поле находится в фокусе, а не только активную |
22739
+ | `focused` | `boolean \| undefined` | — | no | Управляет состоянием фокуса компонента. Когда `true`, компонент считается сфокусированным и может применять соответствующие стили или поведение. |
22740
+ | `height` | `string \| number \| undefined` | — | no | Высота компонента |
22741
+ | `label` | `string \| undefined` | `'$cds.input.otp'` | no | Доступное имя поля (`aria-label`). Принимает ключ локализации вида `$cds.input.otp` |
22742
+ | `length` | `string \| number \| undefined` | `6` | no | Количество ячеек кода |
22743
+ | `loading` | `string \| boolean \| undefined` | — | no | Индикатор загрузки для компонента |
22744
+ | `masked` | `boolean \| undefined` | — | no | Скрывать введённые символы точками |
22745
+ | `maxHeight` | `string \| number \| undefined` | — | no | Максимальная высота компонента |
22746
+ | `maxWidth` | `string \| number \| undefined` | — | no | Максимальная ширина компонента |
22747
+ | `merged` | `boolean \| undefined` | — | no | Слитный вид: ячейки объединяются в одно поле без промежутков между ними |
22748
+ | `minHeight` | `string \| number \| undefined` | — | no | Минимальная высота компонента |
22749
+ | `minWidth` | `string \| number \| undefined` | — | no | Минимальная ширина компонента |
22750
+ | `modelValue` | `string \| number \| undefined` | — | no | Значение компонента v-model |
22751
+ | `pattern` | `RegExp \| "numeric" \| "alpha" \| "alphanumeric" \| "unicode-alpha" \| "unicode-alphanumeric" \| undefined` | — | no | Допустимые символы: имя готового паттерна (`numeric`, `alpha`, `alphanumeric`, `unicode-alpha`, `unicode-alphanumeric`) или собственное регулярное выражение |
22752
+ | `placeholder` | `string \| undefined` | — | no | Символ-заполнитель, который показывается в пустой ячейке |
22753
+ | `size` | `number \| "xs" \| "sm" \| "md" \| "lg" \| "xl" \| undefined` | `'md'` | no | Размер компонента |
22754
+ | `textColor` | `string \| undefined` | — | no | Цвет текста компонента |
22755
+ | `theme` | `string \| undefined` | — | no | Тема компонента |
22756
+ | `type` | `CdsOtpInputType \| undefined` | `'number'` | no | Тип вводимого кода. `number` ограничивает ввод цифрами, `password` скрывает символы |
22757
+ | `width` | `string \| number \| undefined` | — | no | Ширина компонента |
22758
+
22759
+ **Events**
22760
+
22761
+ | Name | Type | Description |
22762
+ | --- | --- | --- |
22763
+ | `finish` | `[value: string]` | Срабатывает, когда код набран полностью |
22764
+ | `update:focused` | `[focused: boolean]` | Срабатывает при получении или потере фокуса |
22765
+ | `update:modelValue` | `[value: string]` | Срабатывает при изменении значения компонента |
22766
+
22767
+ **Slots**
22768
+
22769
+ | Name | Type | Description |
22770
+ | --- | --- | --- |
22771
+ | `default` | `any` | Произвольный контент поверх ячеек кода |
22772
+ | `divider` | `{ index: number; }` | Разделитель между ячейками. `index` — номер ячейки слева от разделителя |
22773
+ | `fields` | `any` | Полностью заменяет ряд ячеек собственной разметкой из `CdsOtpGroup`, `CdsOtpField` и `CdsOtpSeparator` |
22774
+ | `loader` | `any` | Пользовательский индикатор загрузки |
22775
+
22776
+ **Exposed**
22777
+
22778
+ | Name | Type | Description |
22779
+ | --- | --- | --- |
22780
+ | `blur` | `() => void` | Снять фокус с поля |
22781
+ | `focus` | `() => void` | Установить фокус на поле |
22782
+ | `inputRef` | `HTMLInputElement \| undefined` | Ref-ссылка на скрытый input, который принимает ввод кода |
22783
+ | `isFocused` | `boolean \| undefined` | Состояние фокуса поля |
22784
+ | `reset` | `() => void` | Очистить введённый код |
22785
+
22786
+ ### CdsOtpField
22787
+
22788
+ **Props**
22789
+
22790
+ | Prop | Type | Default | Required | Description |
22791
+ | --- | --- | --- | --- | --- |
22792
+ | `index` | `number` | — | yes | Порядковый номер ячейки, начиная с нуля |
22793
+
22794
+ ### CdsOtpGroup
22795
+
22796
+ **Props**
22797
+
22798
+ | Prop | Type | Default | Required | Description |
22799
+ | --- | --- | --- | --- | --- |
22800
+ | `merged` | `boolean \| null \| undefined` | — | no | Слитный вид группы. По умолчанию наследуется от родительского `CdsOtpInput` |
22801
+
22802
+ **Slots**
22803
+
22804
+ | Name | Type | Description |
22805
+ | --- | --- | --- |
22806
+ | `default` | `any` | Ячейки кода группы |
22807
+
22808
+ ### CdsOtpSeparator
22809
+
22810
+ **Slots**
22811
+
22812
+ | Name | Type | Description |
22813
+ | --- | --- | --- |
22814
+ | `default` | `any` | Содержимое разделителя |
22815
+
22816
+ ---
22817
+
22307
22818
  # CdsOverlay
22308
22819
 
22309
22820
  _Категория: Content · появился в 4.0.0_
@@ -41092,7 +41603,7 @@ function toggle(id: number) {
41092
41603
  Этот документ — **живой** migration guide: записи добавляются по мере появления
41093
41604
  breaking-изменений в alpha/beta релизах CDS 4.
41094
41605
 
41095
- > Версии: CDS 3 — `3.10.1` (стабильная), CDS 4 — `4.0.0-alpha.2` (в разработке).
41606
+ > Версии: CDS 3 — `3.10.1` (стабильная), CDS 4 — `4.0.0-alpha.3` (в разработке).
41096
41607
 
41097
41608
  ## Как читать этот документ
41098
41609
 
@@ -1,6 +1,6 @@
1
1
  # Central Design System (CDS 4) — гайды
2
2
 
3
- > Версия: 4.0.0-alpha.2
3
+ > Версия: 4.0.0-alpha.3
4
4
  > Подключение, конвенции, формы, тематизация, Tailwind CSS, tree-shaking и адаптив.
5
5
  > Сгенерировано автоматически (`bun run generate:meta` → `bun run generate:llms`). Не редактировать вручную.
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Central Design System — миграция CDS 3 → CDS 4
2
2
 
3
- > Версия: 4.0.0-alpha.2
3
+ > Версия: 4.0.0-alpha.3
4
4
  > Полный гайд перехода: breaking-изменения, переименования, deprecations и шаги миграции.
5
5
  > Сгенерировано автоматически (`bun run generate:meta` → `bun run generate:llms`). Не редактировать вручную.
6
6
 
@@ -12,7 +12,7 @@
12
12
  Этот документ — **живой** migration guide: записи добавляются по мере появления
13
13
  breaking-изменений в alpha/beta релизах CDS 4.
14
14
 
15
- > Версии: CDS 3 — `3.10.1` (стабильная), CDS 4 — `4.0.0-alpha.2` (в разработке).
15
+ > Версии: CDS 3 — `3.10.1` (стабильная), CDS 4 — `4.0.0-alpha.3` (в разработке).
16
16
 
17
17
  ## Как читать этот документ
18
18
 
@@ -1,6 +1,6 @@
1
1
  # Central Design System (CDS 4) — токены и темы
2
2
 
3
- > Версия: 4.0.0-alpha.2
3
+ > Версия: 4.0.0-alpha.3
4
4
  > Три уровня токенов: палитра-примитивы, цветовые токены тем (`--cds-color-*`) и локальные переменные компонентов.
5
5
  > Сгенерировано автоматически (`bun run generate:meta` → `bun run generate:llms`). Не редактировать вручную.
6
6
 
package/llms/llms.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  # Central Design System (CDS 4)
2
2
 
3
- > Версия: 4.0.0-alpha.2. Модульная библиотека Vue 3 UI-компонентов `@central-design-system/components`.
3
+ > Версия: 4.0.0-alpha.3. Модульная библиотека Vue 3 UI-компонентов `@central-design-system/components`.
4
4
  > Этот файл — индекс для AI-агентов, собирающих продуктовый UI на CDS.
5
5
  > Сгенерировано автоматически (`bun run generate:meta` → `bun run generate:llms`). Не редактировать вручную.
6
6
 
@@ -47,7 +47,7 @@ createApp(App).use(cds).mount('#app');
47
47
  `CdsField` + `CdsLabel` + `CdsDescription` + `CdsMessages` + `CdsInput`).
48
48
  - Полный гайд миграции CDS 3 → CDS 4 — в `MIGRATION.md`.
49
49
 
50
- ## Компоненты (78)
50
+ ## Компоненты (79)
51
51
 
52
52
  Ниже — назначение каждого компонента. Полный контракт (props / events / slots /
53
53
  exposed) и примеры — в llms-components.txt.
@@ -92,7 +92,7 @@ exposed) и примеры — в llms-components.txt.
92
92
  - **CdsTree** — Дерево показывает иерархию: разделы каталога, файлы проекта, структуру организации.
93
93
  - **CdsVirtualScroll** — Виртуальный скролл держит длинные списки быстрыми: в DOM попадают только видимые строки, а не весь массив.
94
94
 
95
- ### Controls (17)
95
+ ### Controls (18)
96
96
 
97
97
  - **CdsAutocomplete** — Автокомплит — поле выбора из длинного списка: пользователь вводит запрос, список фильтруется на лету, совпадения подсвечиваются.
98
98
  - **CdsCheckbox** — Чекбокс включает и выключает независимую опцию: согласие с условиями, пункт в списке фильтров, настройку профиля.
@@ -103,6 +103,7 @@ exposed) и примеры — в llms-components.txt.
103
103
  - **CdsFileInput** — Поле выбора файлов: пользователь прикладывает документы кликом, перетаскиванием или вставкой из буфера обмена.
104
104
  - **CdsFileUpload** — Зона загрузки файлов: принимает файлы перетаскиванием, вставкой из буфера обмена и через системный диалог, а выбранное показывает списком с превью изображений.
105
105
  - **CdsForm** — Форма объединяет поля в одну группу: собирает их валидацию в общий статус, перехватывает отправку и умеет сбрасывать значения.
106
+ - **CdsOtpInput** — Поле ввода одноразового кода — из SMS, письма или приложения-аутентификатора.
106
107
  - **CdsRadio** — Радиокнопка — один вариант взаимоисключающего выбора.
107
108
  - **CdsRadioGroup** — Группа радиокнопок — выбор одного варианта из короткого взаимоисключающего набора: способ оплаты, тариф, период отчёта.
108
109
  - **CdsSelect** — Селект открывает выпадающий список и позволяет выбрать одно или несколько значений из заранее известного набора: страну, статус, категорию.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@central-design-system/components",
3
- "version": "4.0.0-alpha.2",
3
+ "version": "4.0.0-alpha.3",
4
4
  "author": "magersoft",
5
5
  "description": "Luma Design System - Vue 3 UI Framework",
6
6
  "homepage": "https://cds.b2b-center.ru/",