@reformer/ui-kit 8.0.0 → 9.0.0-beta.1

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.
package/llms.txt CHANGED
@@ -2398,7 +2398,7 @@ Props компонента {@link Checkbox}.
2398
2398
  ```typescript
2399
2399
  export interface CheckboxProps extends Omit<
2400
2400
  React.InputHTMLAttributes<HTMLInputElement>,
2401
- 'value' | 'onChange' | 'type'
2401
+ 'value' | 'onChange' | 'type' | 'checked' | 'defaultChecked'
2402
2402
  > {
2403
2403
  /** Дополнительный CSS-класс для самого input. */
2404
2404
  className?: string;
@@ -2583,6 +2583,28 @@ return <ErrorState error={error} onRetry={() => window.location.reload()} />;
2583
2583
 
2584
2584
  _Source: src/components/state/error-state.tsx_
2585
2585
 
2586
+ ### ErrorStateProps
2587
+
2588
+ **Kind:** `interface`
2589
+
2590
+ **Signature:**
2591
+ ```typescript
2592
+ export interface ErrorStateProps {
2593
+ /** Текст ошибки, показывается под заголовком. */
2594
+ error: string;
2595
+ /** Заголовок блока ошибки. По умолчанию `'Ошибка загрузки'`. */
2596
+ title?: string;
2597
+ /** Колбэк повторной попытки. Если задан — рендерится кнопка «Повторить». */
2598
+ onRetry?: () => void;
2599
+ /** Подпись кнопки повтора. По умолчанию `'Повторить'`. */
2600
+ retryLabel?: string;
2601
+ /** Внешний CSS-класс контейнера. По умолчанию `'w-full'`. */
2602
+ className?: string;
2603
+ }
2604
+ ```
2605
+
2606
+ _Source: src/components/state/error-state.tsx_
2607
+
2586
2608
  ### ExampleCard
2587
2609
 
2588
2610
  **Kind:** `function`
@@ -3187,7 +3209,7 @@ import { Input } from '@reformer/ui-kit';
3187
3209
  <Input
3188
3210
  type="number"
3189
3211
  value={age}
3190
- onChange={(v) => setAge(v as number | null)}
3212
+ onChange={setAge}
3191
3213
  min={0}
3192
3214
  placeholder="Возраст"
3193
3215
  />
@@ -3205,7 +3227,7 @@ return (
3205
3227
  type="email"
3206
3228
  value={value}
3207
3229
  disabled={disabled}
3208
- onChange={(v) => control.setValue((v ?? '') as string)}
3230
+ onChange={(v) => control.setValue(v ?? '')}
3209
3231
  onBlur={() => control.markAsTouched()}
3210
3232
  aria-invalid={shouldShowError}
3211
3233
  placeholder={shouldShowError ? errors[0]?.message : 'you@example.com'}
@@ -3266,7 +3288,7 @@ Props компонента {@link InputMask}.
3266
3288
  ```typescript
3267
3289
  export interface InputMaskProps extends Omit<
3268
3290
  React.InputHTMLAttributes<HTMLInputElement>,
3269
- 'value' | 'onChange'
3291
+ 'value' | 'onChange' | 'defaultValue'
3270
3292
  > {
3271
3293
  /** Дополнительный CSS-класс. */
3272
3294
  className?: string;
@@ -3341,7 +3363,7 @@ Props компонента {@link InputPassword}.
3341
3363
  ```typescript
3342
3364
  export interface InputPasswordProps extends Omit<
3343
3365
  React.InputHTMLAttributes<HTMLInputElement>,
3344
- 'value' | 'onChange' | 'type'
3366
+ 'value' | 'onChange' | 'type' | 'defaultValue'
3345
3367
  > {
3346
3368
  /** Дополнительный CSS-класс. */
3347
3369
  className?: string;
@@ -3367,39 +3389,14 @@ _Source: src/components/ui/input-password.tsx_
3367
3389
 
3368
3390
  ### InputProps
3369
3391
 
3370
- **Kind:** `interface`
3392
+ **Kind:** `type`
3371
3393
 
3372
- Props компонента {@link Input}.
3394
+ Props компонента {@link Input} — дискриминированный union по `type`:
3395
+ `type="number"` даёт `number | null` для `value`/`onChange`, любой другой `type` — `string | null`.
3373
3396
 
3374
3397
  **Signature:**
3375
3398
  ```typescript
3376
- export interface InputProps extends Omit<
3377
- React.InputHTMLAttributes<HTMLInputElement>,
3378
- 'value' | 'onChange'
3379
- > {
3380
- /** Дополнительный CSS-класс (мерджится с дефолтными Tailwind-классами через `tailwind-merge`). */
3381
- className?: string;
3382
- /**
3383
- * Текущее значение поля. Для `type='number'` ожидается `number | null`,
3384
- * для остальных — `string | null`. `null`/`undefined` рендерится как пустое поле.
3385
- */
3386
- value?: string | number | null;
3387
- /**
3388
- * Обработчик изменений. Получает уже распарсенное значение:
3389
- * - для `type='number'` — `number` или `null` (для пустой строки),
3390
- * - иначе — `string` или `null`.
3391
- * `NaN` не прокидывается. При `min >= 0` отрицательные значения превращаются в `0`.
3392
- */
3393
- onChange?: (value: string | number | null) => void;
3394
- /** Срабатывает при потере фокуса. Используется `FormField` для пометки `touched`. */
3395
- onBlur?: () => void;
3396
- /** HTML-тип input. Для `'number'` включается специальный парсинг значения. */
3397
- type?: 'text' | 'email' | 'number' | 'tel' | 'url' | 'password';
3398
- /** Подсказка внутри поля. */
3399
- placeholder?: string;
3400
- /** Блокирует ввод и редактирование. */
3401
- disabled?: boolean;
3402
- }
3399
+ export type InputProps = NumberInputProps | TextInputProps;
3403
3400
  ```
3404
3401
 
3405
3402
  _Source: src/components/ui/input.tsx_
@@ -3437,6 +3434,24 @@ return <LoadingState />;
3437
3434
 
3438
3435
  _Source: src/components/state/loading-state.tsx_
3439
3436
 
3437
+ ### LoadingStateProps
3438
+
3439
+ **Kind:** `interface`
3440
+
3441
+ **Signature:**
3442
+ ```typescript
3443
+ export interface LoadingStateProps {
3444
+ /** Основной текст. По умолчанию `'Загрузка данных...'`. */
3445
+ title?: string;
3446
+ /** Вспомогательный текст под спиннером. По умолчанию `'Пожалуйста, подождите'`. */
3447
+ subtitle?: string;
3448
+ /** Внешний CSS-класс контейнера. По умолчанию центрирует спиннер с отступами. */
3449
+ className?: string;
3450
+ }
3451
+ ```
3452
+
3453
+ _Source: src/components/state/loading-state.tsx_
3454
+
3440
3455
  ### RadioGroup
3441
3456
 
3442
3457
  **Kind:** `const`
@@ -3503,6 +3518,12 @@ export interface RadioGroupProps extends Omit<React.HTMLAttributes<HTMLDivElemen
3503
3518
  options: RadioOption[];
3504
3519
  /** Блокирует все варианты. */
3505
3520
  disabled?: boolean;
3521
+ /**
3522
+ * Общий `name` для всех radio группы — обеспечивает нативный одиночный выбор и
3523
+ * навигацию стрелками между вариантами. Если не задан, выводится из `id` /
3524
+ * `data-testid`, а в крайнем случае генерируется автоматически.
3525
+ */
3526
+ name?: string;
3506
3527
  /** Test-id (используется как для контейнера, так и как префикс для каждого radio). */
3507
3528
  'data-testid'?: string;
3508
3529
  }
@@ -3887,7 +3908,7 @@ Props компонента {@link Select}.
3887
3908
 
3888
3909
  **Signature:**
3889
3910
  ```typescript
3890
- export interface SelectProps<T> extends Omit<
3911
+ export interface SelectProps extends Omit<
3891
3912
  React.ComponentProps<typeof SelectPrimitive.Root>,
3892
3913
  'value' | 'onValueChange'
3893
3914
  > {
@@ -3900,7 +3921,7 @@ export interface SelectProps<T> extends Omit<
3900
3921
  /** Срабатывает при закрытии дропдауна (через `onOpenChange(false)`). */
3901
3922
  onBlur?: () => void;
3902
3923
  /** Асинхронный источник опций. Если задан вместе с `options`, приоритет у `options`. */
3903
- resource?: ResourceConfig<T>;
3924
+ resource?: ResourceConfig<unknown>;
3904
3925
  /**
3905
3926
  * Inline-варианты. `value` приводится к строке. Опции с одинаковым `group`
3906
3927
  * объединяются в `SelectGroup` с `SelectLabel` (см. рецепт grouped options).
@@ -4004,6 +4025,7 @@ function SelectTrigger({
4004
4025
  size = 'default',
4005
4026
  children,
4006
4027
  'aria-label': ariaLabel,
4028
+ 'aria-labelledby': ariaLabelledBy,
4007
4029
  ...props
4008
4030
  }: React.ComponentProps<typeof SelectPrimitive.Trigger> & {
4009
4031
  size?: 'sm' | 'default';
@@ -4151,7 +4173,7 @@ Props компонента {@link Textarea}.
4151
4173
  ```typescript
4152
4174
  export interface TextareaProps extends Omit<
4153
4175
  React.TextareaHTMLAttributes<HTMLTextAreaElement>,
4154
- 'value' | 'onChange'
4176
+ 'value' | 'onChange' | 'defaultValue'
4155
4177
  > {
4156
4178
  /** Дополнительный CSS-класс. */
4157
4179
  className?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reformer/ui-kit",
3
- "version": "8.0.0",
3
+ "version": "9.0.0-beta.1",
4
4
  "description": "Styled form components with Tailwind CSS and Radix UI for @reformer ecosystem",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -20,8 +20,8 @@
20
20
  "import": "./dist/form-wizard.js"
21
21
  },
22
22
  "./form-field": {
23
- "types": "./dist/form-field.d.ts",
24
- "import": "./dist/form-field.js"
23
+ "types": "./dist/ui/form-field.d.ts",
24
+ "import": "./dist/ui/form-field.js"
25
25
  },
26
26
  "./input": {
27
27
  "types": "./dist/ui/input.d.ts",
@@ -121,23 +121,22 @@
121
121
  "llms.txt"
122
122
  ],
123
123
  "peerDependencies": {
124
- "@radix-ui/react-select": "^2.0.0",
125
- "@radix-ui/react-slot": "^1.0.0",
126
124
  "@reformer/cdk": ">=1.0.0",
127
125
  "@reformer/core": ">=1.1.0",
128
126
  "@reformer/renderer-react": ">=1.0.0",
129
- "lucide-react": ">=0.400.0 <1.0.0",
130
127
  "react": "^18.0.0 || ^19.0.0",
131
128
  "react-dom": "^18.0.0 || ^19.0.0"
132
129
  },
133
130
  "dependencies": {
131
+ "@radix-ui/react-select": "^2.2.6",
132
+ "@radix-ui/react-slot": "^1.2.4",
134
133
  "class-variance-authority": "^0.7.0",
135
134
  "clsx": "^2.0.0",
136
- "tailwind-merge": "^2.0.0 || ^3.0.0"
135
+ "lucide-react": "^0.553.0",
136
+ "tailwind-merge": "^2.0.0 || ^3.0.0",
137
+ "tslib": "^2.6.0"
137
138
  },
138
139
  "devDependencies": {
139
- "@radix-ui/react-select": "^2.2.6",
140
- "@radix-ui/react-slot": "^1.2.4",
141
140
  "@reformer/cdk": "*",
142
141
  "@reformer/core": "*",
143
142
  "@reformer/renderer-react": "*",
@@ -148,7 +147,6 @@
148
147
  "@vitest/utils": "^4.0.8",
149
148
  "class-variance-authority": "^0.7.1",
150
149
  "clsx": "^2.1.1",
151
- "lucide-react": "^0.553.0",
152
150
  "react": "^19.2.1",
153
151
  "react-dom": "^19.2.1",
154
152
  "tailwind-merge": "^3.4.0",
@@ -1,38 +0,0 @@
1
- import { jsx as e, jsxs as a } from "react/jsx-runtime";
2
- import { Button as i } from "./ui/button.js";
3
- function o({
4
- error: r,
5
- title: d = "Ошибка загрузки",
6
- onRetry: t,
7
- retryLabel: l = "Повторить",
8
- className: s
9
- }) {
10
- return /* @__PURE__ */ e("div", { "data-testid": "error-state", className: s ?? "w-full", children: /* @__PURE__ */ a("div", { className: "bg-red-50 border border-red-200 rounded-lg p-6 text-center space-y-4", children: [
11
- /* @__PURE__ */ e("div", { className: "text-red-600 text-5xl", children: "!" }),
12
- /* @__PURE__ */ e("div", { className: "text-xl font-semibold text-red-800", children: d }),
13
- /* @__PURE__ */ e("div", { className: "text-red-700", children: r }),
14
- t && /* @__PURE__ */ e(i, { onClick: t, children: l })
15
- ] }) });
16
- }
17
- function m({
18
- title: r = "Загрузка данных...",
19
- subtitle: d = "Пожалуйста, подождите",
20
- className: t
21
- }) {
22
- return /* @__PURE__ */ e(
23
- "div",
24
- {
25
- "data-testid": "loading-state",
26
- className: t ?? "w-full flex items-center justify-center p-12",
27
- children: /* @__PURE__ */ a("div", { className: "text-center space-y-4", children: [
28
- /* @__PURE__ */ e("div", { className: "inline-block h-12 w-12 animate-spin rounded-full border-4 border-solid border-blue-600 border-r-transparent" }),
29
- /* @__PURE__ */ e("div", { className: "text-lg text-gray-600", children: r }),
30
- /* @__PURE__ */ e("div", { className: "text-sm text-gray-500", children: d })
31
- ] })
32
- }
33
- );
34
- }
35
- export {
36
- o as E,
37
- m as L
38
- };