@reformer/ui-kit 1.0.0-beta.2

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 (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +96 -0
  3. package/dist/components/form-array/form-array-section.d.ts +60 -0
  4. package/dist/components/form-array/index.d.ts +2 -0
  5. package/dist/components/form-wizard/form-wizard-actions.d.ts +11 -0
  6. package/dist/components/form-wizard/form-wizard-progress.d.ts +7 -0
  7. package/dist/components/form-wizard/form-wizard.d.ts +40 -0
  8. package/dist/components/form-wizard/index.d.ts +8 -0
  9. package/dist/components/form-wizard/step-indicator.d.ts +10 -0
  10. package/dist/components/state/error-state.d.ts +10 -0
  11. package/dist/components/state/index.d.ts +2 -0
  12. package/dist/components/state/loading-state.d.ts +8 -0
  13. package/dist/components/ui/async-boundary.d.ts +63 -0
  14. package/dist/components/ui/box.d.ts +41 -0
  15. package/dist/components/ui/button.d.ts +35 -0
  16. package/dist/components/ui/checkbox.d.ts +48 -0
  17. package/dist/components/ui/collapsible.d.ts +59 -0
  18. package/dist/components/ui/example-card.d.ts +57 -0
  19. package/dist/components/ui/form-field.d.ts +72 -0
  20. package/dist/components/ui/input-mask.d.ts +52 -0
  21. package/dist/components/ui/input-password.d.ts +51 -0
  22. package/dist/components/ui/input.d.ts +54 -0
  23. package/dist/components/ui/radio-group.d.ts +60 -0
  24. package/dist/components/ui/section.d.ts +52 -0
  25. package/dist/components/ui/select.d.ts +316 -0
  26. package/dist/components/ui/textarea.d.ts +53 -0
  27. package/dist/form-array-section-CItAR061.js +92 -0
  28. package/dist/form-array.d.ts +2 -0
  29. package/dist/form-array.js +4 -0
  30. package/dist/form-wizard-C-yRYqTI.js +118 -0
  31. package/dist/form-wizard.d.ts +2 -0
  32. package/dist/form-wizard.js +7 -0
  33. package/dist/index.d.ts +37 -0
  34. package/dist/index.js +170 -0
  35. package/dist/lib/utils.d.ts +29 -0
  36. package/dist/loading-state-4VeOE6iN.js +38 -0
  37. package/dist/state.d.ts +2 -0
  38. package/dist/state.js +5 -0
  39. package/dist/ui/async-boundary.d.ts +2 -0
  40. package/dist/ui/async-boundary.js +12 -0
  41. package/dist/ui/box.d.ts +2 -0
  42. package/dist/ui/box.js +7 -0
  43. package/dist/ui/button.d.ts +2 -0
  44. package/dist/ui/button.js +78 -0
  45. package/dist/ui/checkbox.d.ts +2 -0
  46. package/dist/ui/checkbox.js +35 -0
  47. package/dist/ui/collapsible.d.ts +2 -0
  48. package/dist/ui/collapsible.js +31 -0
  49. package/dist/ui/form-field.d.ts +2 -0
  50. package/dist/ui/form-field.js +217 -0
  51. package/dist/ui/input-mask.d.ts +2 -0
  52. package/dist/ui/input-mask.js +36 -0
  53. package/dist/ui/input-password.d.ts +2 -0
  54. package/dist/ui/input-password.js +72 -0
  55. package/dist/ui/input.d.ts +2 -0
  56. package/dist/ui/input.js +48 -0
  57. package/dist/ui/radio-group.d.ts +2 -0
  58. package/dist/ui/radio-group.js +53 -0
  59. package/dist/ui/section.d.ts +2 -0
  60. package/dist/ui/section.js +16 -0
  61. package/dist/ui/select.d.ts +2 -0
  62. package/dist/ui/select.js +241 -0
  63. package/dist/ui/textarea.d.ts +2 -0
  64. package/dist/ui/textarea.js +38 -0
  65. package/dist/utils-DtaLkIY8.js +2776 -0
  66. package/llms.txt +3461 -0
  67. package/package.json +161 -0
@@ -0,0 +1,53 @@
1
+ import * as React from 'react';
2
+ /** Props компонента {@link Textarea}. */
3
+ export interface TextareaProps extends Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, 'value' | 'onChange'> {
4
+ /** Дополнительный CSS-класс. */
5
+ className?: string;
6
+ /** Текущее значение. `null`/`undefined` рендерится как пустое поле. */
7
+ value?: string | null;
8
+ /** Обработчик изменений. Пустая строка приводится к `null`. */
9
+ onChange?: (value: string | null) => void;
10
+ /** Срабатывает при потере фокуса. */
11
+ onBlur?: () => void;
12
+ /** Подсказка внутри поля. */
13
+ placeholder?: string;
14
+ /** Блокирует ввод. */
15
+ disabled?: boolean;
16
+ /** Видимая высота в строках. По умолчанию `3`. */
17
+ rows?: number;
18
+ /**
19
+ * Hard-лимит длины (нативное HTML-поведение). Используется как soft-protection
20
+ * на уровне UI; для бизнес-валидации добавляй `maxLength` через `validations`.
21
+ */
22
+ maxLength?: number;
23
+ }
24
+ /**
25
+ * Многострочное поле ввода. Resize по вертикали разрешён (`resize-y`).
26
+ *
27
+ * @example Поле для комментария с лимитом длины
28
+ * ```tsx
29
+ * import { Textarea } from '@reformer/ui-kit';
30
+ *
31
+ * <Textarea
32
+ * value={comment}
33
+ * onChange={setComment}
34
+ * rows={5}
35
+ * maxLength={500}
36
+ * placeholder="Опишите проблему"
37
+ * />
38
+ * ```
39
+ *
40
+ * @example Поле адреса
41
+ * ```tsx
42
+ * import { Textarea } from '@reformer/ui-kit';
43
+ *
44
+ * <Textarea
45
+ * value={address}
46
+ * onChange={setAddress}
47
+ * rows={3}
48
+ * placeholder="Адрес доставки"
49
+ * />
50
+ * ```
51
+ */
52
+ declare const Textarea: React.ForwardRefExoticComponent<TextareaProps & React.RefAttributes<HTMLTextAreaElement>>;
53
+ export { Textarea };
@@ -0,0 +1,92 @@
1
+ import { jsx as e, jsxs as i } from "react/jsx-runtime";
2
+ import { useFormControl as S, extractPath as $, FieldPathNavigator as P } from "@reformer/core";
3
+ import { FormArray as s } from "@reformer/cdk/form-array";
4
+ const R = new P();
5
+ function B(t, a) {
6
+ if (!t) return null;
7
+ if (typeof t == "object" && typeof t.push == "function" && typeof t.removeAt == "function")
8
+ return t;
9
+ if (!a)
10
+ return typeof console < "u" && console.warn(
11
+ "[FormArraySection] control is a FieldPath but no `form` prop available. Ensure this component is rendered inside FormRenderer with form available, or pass form explicitly."
12
+ ), null;
13
+ try {
14
+ const r = $(t), n = R.getNodeByPath(a, r);
15
+ return n || (typeof console < "u" && console.warn(`[FormArraySection] No ArrayNode at path "${r}".`), null);
16
+ } catch (r) {
17
+ return typeof console < "u" && console.warn("[FormArraySection] Failed to resolve control:", r), null;
18
+ }
19
+ }
20
+ function E({
21
+ control: t,
22
+ itemComponent: a,
23
+ title: r,
24
+ itemLabel: n,
25
+ addButtonLabel: u = "+ Добавить",
26
+ removeButtonLabel: v = "Удалить",
27
+ emptyMessage: f,
28
+ emptyMessageHint: m,
29
+ hasItems: b,
30
+ initialValue: h,
31
+ showRemoveOnSingle: g = !1,
32
+ maxItems: p,
33
+ className: x = "space-y-3 mt-2",
34
+ cardClassName: N = "mb-4 p-4 bg-white rounded border",
35
+ form: w
36
+ }) {
37
+ const d = B(t, w), A = S(
38
+ d ?? void 0
39
+ );
40
+ if (b === !1 || !d) return null;
41
+ const c = A?.length ?? 0, y = p != null && c >= p, F = (l, o) => typeof n == "function" ? n(l, o) : `${n ?? r ?? "Элемент"} #${o + 1}`;
42
+ return /* @__PURE__ */ e(s.Root, { control: d, children: /* @__PURE__ */ i("section", { className: x, children: [
43
+ r ? /* @__PURE__ */ i("div", { className: "flex justify-between items-center mb-4", children: [
44
+ /* @__PURE__ */ e("h3", { className: "text-lg font-semibold", children: r }),
45
+ y ? null : /* @__PURE__ */ e(
46
+ s.AddButton,
47
+ {
48
+ initialValue: h,
49
+ "data-testid": "array-add",
50
+ className: "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground shadow hover:bg-primary/90 h-9 px-4 py-2",
51
+ children: u
52
+ }
53
+ )
54
+ ] }) : null,
55
+ /* @__PURE__ */ e(s.List, { className: "space-y-3", children: ({ control: l, index: o, remove: j }) => {
56
+ const C = g || c > 1;
57
+ return /* @__PURE__ */ i("div", { className: N, "data-testid": `array-item-${o}`, children: [
58
+ r || n ? /* @__PURE__ */ i("div", { className: "flex justify-between items-center mb-3", children: [
59
+ /* @__PURE__ */ e("h4", { className: "font-medium", children: F(l, o) }),
60
+ C ? /* @__PURE__ */ e(
61
+ "button",
62
+ {
63
+ type: "button",
64
+ onClick: j,
65
+ "data-testid": `array-item-${o}-remove`,
66
+ className: "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 bg-destructive text-destructive-foreground shadow hover:bg-destructive/90 h-9 px-4 py-2",
67
+ children: v
68
+ }
69
+ ) : null
70
+ ] }) : null,
71
+ /* @__PURE__ */ e(a, { control: l })
72
+ ] });
73
+ } }),
74
+ c === 0 && f ? /* @__PURE__ */ e(s.Empty, { children: /* @__PURE__ */ i("div", { className: "p-4 bg-gray-100 border border-gray-300 rounded text-center text-gray-600", children: [
75
+ f,
76
+ m && /* @__PURE__ */ e("div", { className: "mt-2 text-xs text-gray-500", children: m })
77
+ ] }) }) : null,
78
+ !r && !y ? /* @__PURE__ */ e("div", { children: /* @__PURE__ */ e(
79
+ s.AddButton,
80
+ {
81
+ initialValue: h,
82
+ "data-testid": "array-add",
83
+ className: "text-sm text-blue-600 hover:text-blue-700 hover:underline",
84
+ children: u
85
+ }
86
+ ) }) : null
87
+ ] }) });
88
+ }
89
+ E.__selfManagedChildren = !0;
90
+ export {
91
+ E as F
92
+ };
@@ -0,0 +1,2 @@
1
+ export * from './components/form-array/index'
2
+ export {}
@@ -0,0 +1,4 @@
1
+ import { F as a } from "./form-array-section-CItAR061.js";
2
+ export {
3
+ a as FormArraySection
4
+ };
@@ -0,0 +1,118 @@
1
+ import { jsxs as s, jsx as n } from "react/jsx-runtime";
2
+ import { forwardRef as N, useRef as x, useImperativeHandle as p, isValidElement as f } from "react";
3
+ import { FormWizard as o } from "@reformer/cdk/form-wizard";
4
+ import { RenderNodeComponent as $ } from "@reformer/renderer-react";
5
+ import { Button as u } from "./ui/button.js";
6
+ import { c as v } from "./utils-DtaLkIY8.js";
7
+ const y = ({
8
+ prev: e,
9
+ next: t,
10
+ submit: a,
11
+ isFirstStep: d,
12
+ isLastStep: i,
13
+ isValidating: c,
14
+ isSubmitting: r,
15
+ className: l,
16
+ prevLabel: m = "← Назад",
17
+ nextLabel: g = "Далее →",
18
+ submitLabel: b = "Отправить заявку",
19
+ validatingLabel: h = "Проверка...",
20
+ submittingLabel: C = "Отправка..."
21
+ }) => /* @__PURE__ */ s("div", { className: `flex gap-4 ${l || ""}`, children: [
22
+ !d && /* @__PURE__ */ n(u, { onClick: e.onClick, disabled: e.disabled, "data-testid": "btn-previous", children: m }),
23
+ /* @__PURE__ */ n("div", { className: "flex-1" }),
24
+ i ? /* @__PURE__ */ n(u, { onClick: a.onClick, disabled: a.disabled, "data-testid": "btn-submit", children: r ? C : b }) : /* @__PURE__ */ n(u, { onClick: t.onClick, disabled: t.disabled, "data-testid": "btn-next", children: c ? h : g })
25
+ ] }), F = ({ current: e, total: t, percent: a }) => `Шаг ${e} из ${t} • ${a}% завершено`, S = ({
26
+ className: e,
27
+ format: t = F,
28
+ ...a
29
+ }) => {
30
+ const d = v("text-center text-sm text-gray-600", e);
31
+ return /* @__PURE__ */ n("div", { className: d, children: t(a) });
32
+ }, k = (e) => `Шаг ${e.number}: ${e.title}` + (e.isCurrent ? " (текущий)" : "") + (e.isCompleted ? " (завершён)" : ""), w = ({
33
+ steps: e,
34
+ goToStep: t,
35
+ className: a,
36
+ navAriaLabel: d = "Шаги формы",
37
+ stepAriaLabel: i = k
38
+ }) => {
39
+ const c = (r) => r.isCurrent ? "bg-blue-500 text-white" : r.isCompleted ? "text-green-500 hover:bg-gray-200" : r.canNavigate ? "hover:bg-gray-200" : "opacity-50";
40
+ return /* @__PURE__ */ n(
41
+ "div",
42
+ {
43
+ className: `flex items-center justify-between p-4 bg-gray-100 rounded-lg ${a || ""}`,
44
+ "data-testid": "step-indicator",
45
+ role: "navigation",
46
+ "aria-label": d,
47
+ children: e.map((r, l) => /* @__PURE__ */ s("div", { className: "flex items-center flex-1", children: [
48
+ /* @__PURE__ */ s(
49
+ "div",
50
+ {
51
+ className: `flex items-center gap-2 p-3 rounded-lg transition-all ${c(r)} ${r.canNavigate ? "cursor-pointer" : "cursor-not-allowed"}`,
52
+ onClick: () => r.canNavigate && t(r.number),
53
+ onKeyDown: (m) => m.key === "Enter" && r.canNavigate && t(r.number),
54
+ "data-testid": `step-indicator-${r.number}`,
55
+ "data-step-number": r.number,
56
+ "data-step-current": r.isCurrent,
57
+ "data-step-completed": r.isCompleted,
58
+ "data-step-can-navigate": r.canNavigate,
59
+ role: "button",
60
+ "aria-label": i(r),
61
+ "aria-current": r.isCurrent ? "step" : void 0,
62
+ tabIndex: r.canNavigate ? 0 : -1,
63
+ children: [
64
+ /* @__PURE__ */ n("div", { className: "text-2xl", "aria-hidden": "true", children: r.isCompleted ? "✓" : r.icon }),
65
+ /* @__PURE__ */ n("div", { className: "text-sm font-semibold", children: r.title }),
66
+ /* @__PURE__ */ n("div", { className: "text-sm", children: r.number })
67
+ ]
68
+ }
69
+ ),
70
+ l < e.length - 1 && /* @__PURE__ */ n(
71
+ "div",
72
+ {
73
+ className: `flex-1 h-0.5 mx-2 ${r.isCompleted ? "bg-green-500" : "bg-gray-300"}`,
74
+ "aria-hidden": "true"
75
+ }
76
+ )
77
+ ] }, r.number))
78
+ }
79
+ );
80
+ };
81
+ function z(e) {
82
+ return e !== null && typeof e == "object" && !f(e) && "component" in e && // RenderNode-shape, НЕ React component reference (memo/forwardRef имеют $$typeof).
83
+ !("$$typeof" in e);
84
+ }
85
+ function W(e) {
86
+ return typeof e == "function" ? !0 : e !== null && typeof e == "object" && "$$typeof" in e ? !f(e) : !1;
87
+ }
88
+ function I(e, t) {
89
+ return f(e) ? e : W(e) ? /* @__PURE__ */ n(e, { control: t }) : z(e) ? /* @__PURE__ */ n($, { node: e, form: t }) : e;
90
+ }
91
+ function j(e, t) {
92
+ const a = x(null);
93
+ p(t, () => a.current);
94
+ const d = e.steps.map(({ number: i, title: c, icon: r }) => ({
95
+ number: i,
96
+ title: c,
97
+ icon: r
98
+ }));
99
+ return /* @__PURE__ */ s(o, { ref: a, form: e.form, config: e.config, children: [
100
+ /* @__PURE__ */ n(o.Indicator, { steps: d, children: (i) => /* @__PURE__ */ n(w, { ...i, className: "mb-8" }) }),
101
+ /* @__PURE__ */ n("div", { className: "bg-white p-8 rounded-lg shadow-md", children: e.steps.map((i) => /* @__PURE__ */ n(o.Step, { children: I(i.body, e.form) }, i.number)) }),
102
+ /* @__PURE__ */ n(o.Actions, { onSubmit: e.onSubmit, children: (i) => /* @__PURE__ */ n(y, { ...i, className: "mt-8" }) }),
103
+ /* @__PURE__ */ n(o.Progress, { children: (i) => /* @__PURE__ */ n(S, { ...i, className: "mt-4" }) })
104
+ ] });
105
+ }
106
+ const A = N(j), R = Object.assign(A, {
107
+ Indicator: o.Indicator,
108
+ Step: o.Step,
109
+ Actions: o.Actions,
110
+ Progress: o.Progress
111
+ });
112
+ R.__selfManagedChildren = !0;
113
+ export {
114
+ R as F,
115
+ w as S,
116
+ y as a,
117
+ S as b
118
+ };
@@ -0,0 +1,2 @@
1
+ export * from './components/form-wizard/index'
2
+ export {}
@@ -0,0 +1,7 @@
1
+ import { F as o, a as s, b as i, S as d } from "./form-wizard-C-yRYqTI.js";
2
+ export {
3
+ o as FormWizard,
4
+ s as FormWizardActions,
5
+ i as FormWizardProgress,
6
+ d as StepIndicator
7
+ };
@@ -0,0 +1,37 @@
1
+ export { AsyncBoundary } from './components/ui/async-boundary';
2
+ export type { AsyncBoundaryProps, AsyncStatus } from './components/ui/async-boundary';
3
+ export { Box } from './components/ui/box';
4
+ export type { BoxProps } from './components/ui/box';
5
+ export { Button } from './components/ui/button';
6
+ export { Checkbox } from './components/ui/checkbox';
7
+ export type { CheckboxProps } from './components/ui/checkbox';
8
+ export { Collapsible } from './components/ui/collapsible';
9
+ export type { CollapsibleProps } from './components/ui/collapsible';
10
+ export { ExampleCard } from './components/ui/example-card';
11
+ export type { ExampleCardProps } from './components/ui/example-card';
12
+ export { FormField } from './components/ui/form-field';
13
+ export type { FormFieldProps } from './components/ui/form-field';
14
+ export { Input } from './components/ui/input';
15
+ export type { InputProps } from './components/ui/input';
16
+ export { InputMask } from './components/ui/input-mask';
17
+ export type { InputMaskProps } from './components/ui/input-mask';
18
+ export { InputPassword } from './components/ui/input-password';
19
+ export type { InputPasswordProps } from './components/ui/input-password';
20
+ export { RadioGroup } from './components/ui/radio-group';
21
+ export type { RadioGroupProps, RadioOption } from './components/ui/radio-group';
22
+ export { Section } from './components/ui/section';
23
+ export type { SectionProps } from './components/ui/section';
24
+ export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectTrigger, SelectValue, } from './components/ui/select';
25
+ export type { SelectProps } from './components/ui/select';
26
+ export { Textarea } from './components/ui/textarea';
27
+ export type { TextareaProps } from './components/ui/textarea';
28
+ export { ErrorState } from './components/state/error-state';
29
+ export { LoadingState } from './components/state/loading-state';
30
+ export { FormArraySection } from './components/form-array/form-array-section';
31
+ export type { FormArraySectionProps } from './components/form-array/form-array-section';
32
+ export { FormWizard } from './components/form-wizard/form-wizard';
33
+ export type { FormWizardProps, FormWizardStep, FormWizardStepBody, } from './components/form-wizard/form-wizard';
34
+ export { StepIndicator } from './components/form-wizard/step-indicator';
35
+ export { FormWizardActions } from './components/form-wizard/form-wizard-actions';
36
+ export { FormWizardProgress } from './components/form-wizard/form-wizard-progress';
37
+ export { cn } from './lib/utils';
package/dist/index.js ADDED
@@ -0,0 +1,170 @@
1
+ import { AsyncBoundary as F } from "./ui/async-boundary.js";
2
+ import { Box as j } from "./ui/box.js";
3
+ import { Button as E } from "./ui/button.js";
4
+ import { Checkbox as z } from "./ui/checkbox.js";
5
+ import { Collapsible as M } from "./ui/collapsible.js";
6
+ import { jsxs as o, jsx as e } from "react/jsx-runtime";
7
+ import { useState as c, useCallback as d } from "react";
8
+ import { c as i } from "./utils-DtaLkIY8.js";
9
+ import { FormField as G } from "./ui/form-field.js";
10
+ import { Input as D } from "./ui/input.js";
11
+ import { InputMask as U } from "./ui/input-mask.js";
12
+ import { InputPassword as q } from "./ui/input-password.js";
13
+ import { RadioGroup as J } from "./ui/radio-group.js";
14
+ import { Section as O } from "./ui/section.js";
15
+ import { Select as X, SelectContent as Y, SelectGroup as _, SelectItem as $, SelectLabel as ee, SelectScrollDownButton as oe, SelectScrollUpButton as te, SelectTrigger as re, SelectValue as ne } from "./ui/select.js";
16
+ import { Textarea as ie } from "./ui/textarea.js";
17
+ import { E as ae, L as ce } from "./loading-state-4VeOE6iN.js";
18
+ import { F as pe } from "./form-array-section-CItAR061.js";
19
+ import { F as me, a as xe, b as ge, S as ue } from "./form-wizard-C-yRYqTI.js";
20
+ const f = () => /* @__PURE__ */ o(
21
+ "svg",
22
+ {
23
+ xmlns: "http://www.w3.org/2000/svg",
24
+ width: "16",
25
+ height: "16",
26
+ viewBox: "0 0 24 24",
27
+ fill: "none",
28
+ stroke: "currentColor",
29
+ strokeWidth: "2",
30
+ strokeLinecap: "round",
31
+ strokeLinejoin: "round",
32
+ children: [
33
+ /* @__PURE__ */ e("rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2" }),
34
+ /* @__PURE__ */ e("path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" })
35
+ ]
36
+ }
37
+ ), v = () => /* @__PURE__ */ e(
38
+ "svg",
39
+ {
40
+ xmlns: "http://www.w3.org/2000/svg",
41
+ width: "16",
42
+ height: "16",
43
+ viewBox: "0 0 24 24",
44
+ fill: "none",
45
+ stroke: "currentColor",
46
+ strokeWidth: "2",
47
+ strokeLinecap: "round",
48
+ strokeLinejoin: "round",
49
+ children: /* @__PURE__ */ e("polyline", { points: "20 6 9 17 4 12" })
50
+ }
51
+ ), y = () => /* @__PURE__ */ o(
52
+ "svg",
53
+ {
54
+ xmlns: "http://www.w3.org/2000/svg",
55
+ width: "16",
56
+ height: "16",
57
+ viewBox: "0 0 24 24",
58
+ fill: "none",
59
+ stroke: "currentColor",
60
+ strokeWidth: "2",
61
+ strokeLinecap: "round",
62
+ strokeLinejoin: "round",
63
+ children: [
64
+ /* @__PURE__ */ e("polyline", { points: "16 18 22 12 16 6" }),
65
+ /* @__PURE__ */ e("polyline", { points: "8 6 2 12 8 18" })
66
+ ]
67
+ }
68
+ ), k = () => /* @__PURE__ */ o(
69
+ "svg",
70
+ {
71
+ xmlns: "http://www.w3.org/2000/svg",
72
+ width: "16",
73
+ height: "16",
74
+ viewBox: "0 0 24 24",
75
+ fill: "none",
76
+ stroke: "currentColor",
77
+ strokeWidth: "2",
78
+ strokeLinecap: "round",
79
+ strokeLinejoin: "round",
80
+ children: [
81
+ /* @__PURE__ */ e("path", { d: "M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z" }),
82
+ /* @__PURE__ */ e("circle", { cx: "12", cy: "12", r: "3" })
83
+ ]
84
+ }
85
+ );
86
+ function L({
87
+ title: p,
88
+ description: l,
89
+ children: h,
90
+ code: r,
91
+ className: m,
92
+ bgColor: x = "bg-white"
93
+ }) {
94
+ const [t, g] = c(!1), [n, a] = c(!1), u = d(async () => {
95
+ try {
96
+ await navigator.clipboard.writeText(r), a(!0), setTimeout(() => a(!1), 2e3);
97
+ } catch (s) {
98
+ console.error("Failed to copy:", s);
99
+ }
100
+ }, [r]), w = d(() => {
101
+ g((s) => !s);
102
+ }, []);
103
+ return /* @__PURE__ */ o("div", { className: i("p-4 border rounded-lg", x, m), children: [
104
+ /* @__PURE__ */ o("div", { className: "flex items-start justify-between mb-2", children: [
105
+ /* @__PURE__ */ o("div", { className: "flex-1 min-w-0 pr-2", children: [
106
+ /* @__PURE__ */ e("h3", { className: "text-lg font-semibold", children: p }),
107
+ l && /* @__PURE__ */ e("p", { className: "text-sm text-gray-600 mt-1", children: l })
108
+ ] }),
109
+ /* @__PURE__ */ e("div", { className: "flex items-center gap-1 flex-shrink-0", children: /* @__PURE__ */ e(
110
+ "button",
111
+ {
112
+ onClick: w,
113
+ className: i(
114
+ "p-1.5 rounded transition-colors",
115
+ t ? "bg-blue-100 text-blue-600" : "hover:bg-gray-200 text-gray-600 hover:text-gray-800"
116
+ ),
117
+ title: t ? "Показать пример" : "Показать код",
118
+ children: t ? /* @__PURE__ */ e(k, {}) : /* @__PURE__ */ e(y, {})
119
+ }
120
+ ) })
121
+ ] }),
122
+ t ? /* @__PURE__ */ o("div", { className: "relative", children: [
123
+ /* @__PURE__ */ e("pre", { className: "text-xs bg-gray-800 text-green-400 p-3 pr-10 rounded overflow-x-auto whitespace-pre", children: r }),
124
+ /* @__PURE__ */ e(
125
+ "button",
126
+ {
127
+ onClick: u,
128
+ className: i(
129
+ "absolute top-2 right-2 p-1.5 rounded transition-colors",
130
+ n ? "bg-green-700 text-green-300" : "bg-gray-700 text-gray-400 hover:bg-gray-600 hover:text-gray-200"
131
+ ),
132
+ title: n ? "Скопировано!" : "Копировать код",
133
+ children: n ? /* @__PURE__ */ e(v, {}) : /* @__PURE__ */ e(f, {})
134
+ }
135
+ )
136
+ ] }) : /* @__PURE__ */ e("div", { className: "mt-4", children: h })
137
+ ] });
138
+ }
139
+ export {
140
+ F as AsyncBoundary,
141
+ j as Box,
142
+ E as Button,
143
+ z as Checkbox,
144
+ M as Collapsible,
145
+ ae as ErrorState,
146
+ L as ExampleCard,
147
+ pe as FormArraySection,
148
+ G as FormField,
149
+ me as FormWizard,
150
+ xe as FormWizardActions,
151
+ ge as FormWizardProgress,
152
+ D as Input,
153
+ U as InputMask,
154
+ q as InputPassword,
155
+ ce as LoadingState,
156
+ J as RadioGroup,
157
+ O as Section,
158
+ X as Select,
159
+ Y as SelectContent,
160
+ _ as SelectGroup,
161
+ $ as SelectItem,
162
+ ee as SelectLabel,
163
+ oe as SelectScrollDownButton,
164
+ te as SelectScrollUpButton,
165
+ re as SelectTrigger,
166
+ ne as SelectValue,
167
+ ue as StepIndicator,
168
+ ie as Textarea,
169
+ i as cn
170
+ };
@@ -0,0 +1,29 @@
1
+ import { ClassValue } from 'clsx';
2
+ /**
3
+ * Объединяет CSS-классы (`clsx` + `tailwind-merge`). Удобно для условных
4
+ * классов с разрешением конфликтов Tailwind: при конфликтующих классах из
5
+ * одной семьи (`px-2` и `px-4`) побеждает последний.
6
+ *
7
+ * @example Условные классы (последний `px-*` побеждает)
8
+ * ```typescript
9
+ * import { cn } from '@reformer/ui-kit';
10
+ *
11
+ * cn('px-2 py-1', isActive && 'bg-blue-500', 'px-4');
12
+ * // → 'py-1 bg-blue-500 px-4'
13
+ * ```
14
+ *
15
+ * @example Override дефолтных стилей в forwardRef-компоненте
16
+ * ```tsx
17
+ * import * as React from 'react';
18
+ * import { cn } from '@reformer/ui-kit';
19
+ *
20
+ * const Card = React.forwardRef<HTMLDivElement, { className?: string }>(
21
+ * ({ className, ...props }, ref) => (
22
+ * <div ref={ref} className={cn('rounded-lg border p-4', className)} {...props} />
23
+ * )
24
+ * );
25
+ *
26
+ * <Card className="p-8" /> // p-4 затёрт пользовательским p-8
27
+ * ```
28
+ */
29
+ export declare function cn(...inputs: ClassValue[]): string;
@@ -0,0 +1,38 @@
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
+ };
@@ -0,0 +1,2 @@
1
+ export * from './components/state/index'
2
+ export {}
package/dist/state.js ADDED
@@ -0,0 +1,5 @@
1
+ import { E as t, L as o } from "./loading-state-4VeOE6iN.js";
2
+ export {
3
+ t as ErrorState,
4
+ o as LoadingState
5
+ };
@@ -0,0 +1,2 @@
1
+ export * from '../components/ui/async-boundary'
2
+ export {}
@@ -0,0 +1,12 @@
1
+ import { jsx as r, Fragment as f } from "react/jsx-runtime";
2
+ function t({
3
+ status: n,
4
+ LoadingComponent: u,
5
+ ErrorComponent: l,
6
+ children: e
7
+ }) {
8
+ return n === "loading" ? u ? /* @__PURE__ */ r(u, {}) : null : n === "error" ? l ? /* @__PURE__ */ r(l, {}) : null : /* @__PURE__ */ r(f, { children: e });
9
+ }
10
+ export {
11
+ t as AsyncBoundary
12
+ };
@@ -0,0 +1,2 @@
1
+ export * from '../components/ui/box'
2
+ export {}
package/dist/ui/box.js ADDED
@@ -0,0 +1,7 @@
1
+ import { jsx as t } from "react/jsx-runtime";
2
+ function n({ className: o, children: r }) {
3
+ return /* @__PURE__ */ t("div", { className: o, children: r });
4
+ }
5
+ export {
6
+ n as Box
7
+ };
@@ -0,0 +1,2 @@
1
+ export * from '../components/ui/button'
2
+ export {}