@reformer/cdk 1.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.
Files changed (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +96 -0
  3. package/dist/FormArray-CBT-1kKN.js +120 -0
  4. package/dist/FormWizard-DLDm4FJM.js +311 -0
  5. package/dist/Slot-YDt2BEtP.js +27 -0
  6. package/dist/components/form-array/FormArray.d.ts +223 -0
  7. package/dist/components/form-array/FormArrayAddButton.d.ts +6 -0
  8. package/dist/components/form-array/FormArrayContext.d.ts +137 -0
  9. package/dist/components/form-array/FormArrayCount.d.ts +17 -0
  10. package/dist/components/form-array/FormArrayEmpty.d.ts +22 -0
  11. package/dist/components/form-array/FormArrayItemIndex.d.ts +24 -0
  12. package/dist/components/form-array/FormArrayList.d.ts +26 -0
  13. package/dist/components/form-array/FormArrayRemoveButton.d.ts +26 -0
  14. package/dist/components/form-array/index.d.ts +13 -0
  15. package/dist/components/form-array/types.d.ts +77 -0
  16. package/dist/components/form-array/useFormArray.d.ts +95 -0
  17. package/dist/components/form-field/FormField.d.ts +107 -0
  18. package/dist/components/form-field/FormFieldContext.d.ts +56 -0
  19. package/dist/components/form-field/FormFieldControl.d.ts +35 -0
  20. package/dist/components/form-field/FormFieldDescription.d.ts +30 -0
  21. package/dist/components/form-field/FormFieldError.d.ts +36 -0
  22. package/dist/components/form-field/FormFieldLabel.d.ts +35 -0
  23. package/dist/components/form-field/FormFieldRoot.d.ts +32 -0
  24. package/dist/components/form-field/index.d.ts +10 -0
  25. package/dist/components/form-field/types.d.ts +114 -0
  26. package/dist/components/form-field/useFormField.d.ts +111 -0
  27. package/dist/components/form-wizard/FormWizard.d.ts +47 -0
  28. package/dist/components/form-wizard/FormWizardActions.d.ts +98 -0
  29. package/dist/components/form-wizard/FormWizardContext.d.ts +84 -0
  30. package/dist/components/form-wizard/FormWizardIndicator.d.ts +118 -0
  31. package/dist/components/form-wizard/FormWizardNext.d.ts +35 -0
  32. package/dist/components/form-wizard/FormWizardPrev.d.ts +35 -0
  33. package/dist/components/form-wizard/FormWizardProgress.d.ts +83 -0
  34. package/dist/components/form-wizard/FormWizardStep.d.ts +55 -0
  35. package/dist/components/form-wizard/FormWizardSubmit.d.ts +43 -0
  36. package/dist/components/form-wizard/Slot.d.ts +20 -0
  37. package/dist/components/form-wizard/Step.d.ts +24 -0
  38. package/dist/components/form-wizard/index.d.ts +21 -0
  39. package/dist/components/form-wizard/types.d.ts +108 -0
  40. package/dist/form-array.d.ts +2 -0
  41. package/dist/form-array.js +15 -0
  42. package/dist/form-field.d.ts +2 -0
  43. package/dist/form-field.js +12 -0
  44. package/dist/form-wizard.d.ts +2 -0
  45. package/dist/form-wizard.js +22 -0
  46. package/dist/index.d.ts +6 -0
  47. package/dist/index.js +33 -0
  48. package/dist/useFormField-DV396Bxa.js +232 -0
  49. package/llms.txt +3294 -0
  50. package/package.json +90 -0
@@ -0,0 +1,107 @@
1
+ import { FormFieldRoot } from './FormFieldRoot';
2
+ import { FormFieldLabel } from './FormFieldLabel';
3
+ import { FormFieldControl } from './FormFieldControl';
4
+ import { FormFieldError } from './FormFieldError';
5
+ import { FormFieldDescription } from './FormFieldDescription';
6
+ /**
7
+ * Compound component type with all sub-components attached
8
+ */
9
+ type FormFieldComponent = typeof FormFieldRoot & {
10
+ Root: typeof FormFieldRoot;
11
+ Label: typeof FormFieldLabel;
12
+ Control: typeof FormFieldControl;
13
+ Error: typeof FormFieldError;
14
+ Description: typeof FormFieldDescription;
15
+ };
16
+ /**
17
+ * FormField - Headless compound component for accessible form field anatomy.
18
+ *
19
+ * Provides complete freedom in building field UI while handling all accessible
20
+ * ID wiring (htmlFor, aria-labelledby, aria-describedby, aria-errormessage)
21
+ * and field state management internally.
22
+ *
23
+ * ## Features
24
+ * - **Headless** — complete freedom in building UI, no styles imposed
25
+ * - **Compound Components** — declarative API via nested components
26
+ * - **Accessible by default** — all ARIA relationships wired automatically
27
+ * - **Type Safe** — full TypeScript support with generics
28
+ *
29
+ * ## Sub-components
30
+ * - `FormField.Root` — context provider, accepts `control` and optional `id`
31
+ * - `FormField.Label` — `<label>` with automatic `htmlFor` and required indicator
32
+ * - `FormField.Control` — auto-renders `control.component` or wraps custom children
33
+ * - `FormField.Error` — error message with `role="alert"`, supports multi-error
34
+ * - `FormField.Description` — helper text with stable `id` for `aria-describedby`
35
+ *
36
+ * @example Minimal (auto-renders everything from field config)
37
+ * ```tsx
38
+ * <FormField.Root control={control.email}>
39
+ * <FormField.Label />
40
+ * <FormField.Control />
41
+ * <FormField.Error />
42
+ * </FormField.Root>
43
+ * ```
44
+ *
45
+ * @example Full control with custom styling
46
+ * ```tsx
47
+ * <FormField.Root control={control.email} hasDescription>
48
+ * <div className="space-y-1">
49
+ * <FormField.Label className="text-sm font-medium text-gray-700" />
50
+ *
51
+ * <FormField.Control asChild>
52
+ * <Input type="email" className="border rounded-md px-3 py-2 w-full" />
53
+ * </FormField.Control>
54
+ *
55
+ * <FormField.Description className="text-xs text-gray-500">
56
+ * We'll never share your email.
57
+ * </FormField.Description>
58
+ *
59
+ * <FormField.Error className="text-xs text-red-600" />
60
+ * </div>
61
+ * </FormField.Root>
62
+ * ```
63
+ *
64
+ * @example Multiple errors with custom rendering
65
+ * ```tsx
66
+ * <FormField.Root control={control.password}>
67
+ * <FormField.Label />
68
+ * <FormField.Control />
69
+ * <FormField.Error
70
+ * multi
71
+ * render={(err) => (
72
+ * <span className={err.severity === 'warning' ? 'text-yellow-600' : 'text-red-600'}>
73
+ * {err.message}
74
+ * </span>
75
+ * )}
76
+ * />
77
+ * </FormField.Root>
78
+ * ```
79
+ *
80
+ * @example Using useFormField hook for full customization
81
+ * ```tsx
82
+ * import { useFormField } from '@reformer/cdk/form-field';
83
+ *
84
+ * function EmailField({ control }: { control: FieldNode<string> }) {
85
+ * const { labelProps, controlProps, errorProps, state, ids } = useFormField(control);
86
+ *
87
+ * return (
88
+ * <div>
89
+ * <label {...labelProps}>{state.label}</label>
90
+ * <Input
91
+ * {...controlProps}
92
+ * aria-describedby={ids.descriptionId}
93
+ * type="email"
94
+ * />
95
+ * <p id={ids.descriptionId} className="text-xs text-gray-500">
96
+ * Helper text
97
+ * </p>
98
+ * {state.shouldShowError && (
99
+ * <p {...errorProps} className="text-xs text-red-600">{state.error}</p>
100
+ * )}
101
+ * </div>
102
+ * );
103
+ * }
104
+ * ```
105
+ */
106
+ export declare const FormField: FormFieldComponent;
107
+ export {};
@@ -0,0 +1,56 @@
1
+ import { FormValue } from '@reformer/core';
2
+ import { FormFieldContextValue } from './types';
3
+ /**
4
+ * React context, который снабжает дочерние компоненты `FormField` (Label, Error,
5
+ * Hint, Control) текущим контролом. Создаётся `FormField.Root`. Читать через
6
+ * {@link useFormFieldContext}.
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * import { FormFieldContext } from '@reformer/cdk/form-field';
11
+ *
12
+ * function CurrentValue() {
13
+ * const ctx = useContext(FormFieldContext);
14
+ * return <pre>{JSON.stringify(ctx?.control.value)}</pre>;
15
+ * }
16
+ * ```
17
+ */
18
+ export declare const FormFieldContext: import('react').Context<FormFieldContextValue<any> | null>;
19
+ /**
20
+ * Хук для доступа к контексту `FormField`. Бросает исключение, если вызван
21
+ * вне `FormField.Root`.
22
+ *
23
+ * @returns Текущий {@link FormFieldContextValue}.
24
+ * @throws Error если используется вне `<FormField.Root>`.
25
+ *
26
+ * @example Счётчик символов рядом с label
27
+ * ```tsx
28
+ * import { useFormFieldContext } from '@reformer/cdk/form-field';
29
+ *
30
+ * function CharCount() {
31
+ * const { control } = useFormFieldContext<string>();
32
+ * return <small>{control.value.length} chars</small>;
33
+ * }
34
+ * ```
35
+ *
36
+ * @example Async pending-индикатор и required-астериск
37
+ * ```tsx
38
+ * function PendingBadge() {
39
+ * const { pending, required, error } = useFormFieldContext();
40
+ * if (pending) return <Spinner size="xs" aria-label="Проверяем..." />;
41
+ * if (error) return <span className="text-red-600 text-xs">!</span>;
42
+ * if (required) return <span className="text-gray-400">*</span>;
43
+ * return null;
44
+ * }
45
+ *
46
+ * <FormField.Root control={form.username}>
47
+ * <div className="flex items-center gap-2">
48
+ * <FormField.Label />
49
+ * <PendingBadge />
50
+ * </div>
51
+ * <FormField.Control />
52
+ * <FormField.Error />
53
+ * </FormField.Root>
54
+ * ```
55
+ */
56
+ export declare function useFormFieldContext<T extends FormValue = FormValue>(): FormFieldContextValue<T>;
@@ -0,0 +1,35 @@
1
+ import { default as React } from 'react';
2
+ import { FormFieldControlProps } from './types';
3
+ /**
4
+ * FormField.Control - Renders the interactive form control.
5
+ *
6
+ * **Auto-render mode** (default): renders `control.component` with all necessary
7
+ * props pre-wired: `value`, `onChange`, `onBlur`, `disabled`, `aria-*` attributes,
8
+ * and all `componentProps` from the field config.
9
+ *
10
+ * **Custom children mode** (`asChild` or `children`): merges accessible props
11
+ * into the provided child element via Slot, letting you use any custom component.
12
+ *
13
+ * @example Auto-render (renders control.component)
14
+ * ```tsx
15
+ * <FormField.Root control={control.email}>
16
+ * <FormField.Label />
17
+ * <FormField.Control />
18
+ * </FormField.Root>
19
+ * ```
20
+ *
21
+ * @example Custom input with asChild (merges aria-* into your element)
22
+ * ```tsx
23
+ * <FormField.Control asChild>
24
+ * <MyInput type="email" className="custom-input" />
25
+ * </FormField.Control>
26
+ * ```
27
+ *
28
+ * @example Custom children (same as asChild)
29
+ * ```tsx
30
+ * <FormField.Control>
31
+ * <MyInput type="email" />
32
+ * </FormField.Control>
33
+ * ```
34
+ */
35
+ export declare const FormFieldControl: React.ForwardRefExoticComponent<FormFieldControlProps & React.RefAttributes<HTMLElement>>;
@@ -0,0 +1,30 @@
1
+ import { FormFieldDescriptionProps } from './types';
2
+ /**
3
+ * FormField.Description - Helper text for the form field.
4
+ *
5
+ * Renders with a stable `id` (descriptionId) that can be wired to
6
+ * `aria-describedby` on the control. To enable automatic wiring, pass
7
+ * `hasDescription` to the parent `FormField.Root`.
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * <FormField.Root control={control.email} hasDescription>
12
+ * <FormField.Label />
13
+ * <FormField.Control />
14
+ * <FormField.Description className="text-xs text-gray-500">
15
+ * We'll never share your email with anyone.
16
+ * </FormField.Description>
17
+ * <FormField.Error />
18
+ * </FormField.Root>
19
+ * ```
20
+ *
21
+ * @example With custom element (asChild)
22
+ * ```tsx
23
+ * <FormField.Description asChild>
24
+ * <Tooltip content="More info">
25
+ * <InfoIcon />
26
+ * </Tooltip>
27
+ * </FormField.Description>
28
+ * ```
29
+ */
30
+ export declare const FormFieldDescription: import('react').ForwardRefExoticComponent<FormFieldDescriptionProps & import('react').RefAttributes<HTMLParagraphElement>>;
@@ -0,0 +1,36 @@
1
+ import { FormFieldErrorProps } from './types';
2
+ /**
3
+ * FormField.Error - Displays validation error message(s).
4
+ *
5
+ * Renders nothing when `shouldShowError` is false (field not touched or no errors).
6
+ * The first error paragraph receives `id={ids.errorId}` for `aria-errormessage` wiring.
7
+ *
8
+ * @example Single error (default)
9
+ * ```tsx
10
+ * <FormField.Error className="text-xs text-red-600" />
11
+ * ```
12
+ *
13
+ * @example All errors
14
+ * ```tsx
15
+ * <FormField.Error multi className="text-xs text-red-600" />
16
+ * ```
17
+ *
18
+ * @example Custom render per error
19
+ * ```tsx
20
+ * <FormField.Error
21
+ * render={(err) => (
22
+ * <span className={err.severity === 'warning' ? 'text-yellow-600' : 'text-red-600'}>
23
+ * {err.message}
24
+ * </span>
25
+ * )}
26
+ * />
27
+ * ```
28
+ *
29
+ * @example Custom error content
30
+ * ```tsx
31
+ * <FormField.Error className="text-xs">
32
+ * This field is required
33
+ * </FormField.Error>
34
+ * ```
35
+ */
36
+ export declare const FormFieldError: import('react').ForwardRefExoticComponent<FormFieldErrorProps & import('react').RefAttributes<HTMLParagraphElement>>;
@@ -0,0 +1,35 @@
1
+ import { FormFieldLabelProps } from './types';
2
+ /**
3
+ * FormField.Label - Accessible label for the form field.
4
+ *
5
+ * Automatically wires `htmlFor` to the control ID and `id` to the label ID
6
+ * so that `aria-labelledby` on FormField.Control works correctly.
7
+ *
8
+ * The label text defaults to `componentProps.label` from the field config.
9
+ * Pass `children` to override or enrich the label content.
10
+ *
11
+ * A required indicator `*` is appended automatically when `componentProps.required` is set.
12
+ *
13
+ * @example Auto label from field config
14
+ * ```tsx
15
+ * <FormField.Root control={control.email}>
16
+ * <FormField.Label /> {/* renders componentProps.label *\/}
17
+ * <FormField.Control />
18
+ * </FormField.Root>
19
+ * ```
20
+ *
21
+ * @example Custom label content
22
+ * ```tsx
23
+ * <FormField.Label className="font-semibold">
24
+ * Email Address <span className="text-gray-400">(optional)</span>
25
+ * </FormField.Label>
26
+ * ```
27
+ *
28
+ * @example With custom element (asChild)
29
+ * ```tsx
30
+ * <FormField.Label asChild>
31
+ * <Typography variant="label">{label}</Typography>
32
+ * </FormField.Label>
33
+ * ```
34
+ */
35
+ export declare const FormFieldLabel: import('react').ForwardRefExoticComponent<FormFieldLabelProps & import('react').RefAttributes<HTMLLabelElement>>;
@@ -0,0 +1,32 @@
1
+ import { FormValue } from '@reformer/core';
2
+ import { FormFieldRootProps } from './types';
3
+ /**
4
+ * FormField.Root - Context provider for form field compound component.
5
+ *
6
+ * Computes stable accessible IDs (controlId, labelId, descriptionId, errorId)
7
+ * and provides all field state to child FormField.* components.
8
+ *
9
+ * @example Minimal usage
10
+ * ```tsx
11
+ * <FormField.Root control={control.email}>
12
+ * <FormField.Label />
13
+ * <FormField.Control />
14
+ * <FormField.Error />
15
+ * </FormField.Root>
16
+ * ```
17
+ *
18
+ * @example With description (pass hasDescription to auto-wire aria-describedby)
19
+ * ```tsx
20
+ * <FormField.Root control={control.email} hasDescription>
21
+ * <FormField.Label />
22
+ * <FormField.Control />
23
+ * <FormField.Description>Helper text</FormField.Description>
24
+ * <FormField.Error />
25
+ * </FormField.Root>
26
+ * ```
27
+ */
28
+ declare function FormFieldRoot<T extends FormValue>({ control, children, id, hasDescription, }: FormFieldRootProps<T>): import("react/jsx-runtime").JSX.Element;
29
+ declare namespace FormFieldRoot {
30
+ var displayName: string;
31
+ }
32
+ export { FormFieldRoot };
@@ -0,0 +1,10 @@
1
+ export { FormField } from './FormField';
2
+ export { FormFieldRoot } from './FormFieldRoot';
3
+ export { FormFieldLabel } from './FormFieldLabel';
4
+ export { FormFieldControl } from './FormFieldControl';
5
+ export { FormFieldError } from './FormFieldError';
6
+ export { FormFieldDescription } from './FormFieldDescription';
7
+ export { useFormField } from './useFormField';
8
+ export type { UseFormFieldReturn, UseFormFieldState, UseFormFieldLabelProps, UseFormFieldControlProps, UseFormFieldErrorProps, UseFormFieldDescriptionProps, } from './useFormField';
9
+ export { FormFieldContext, useFormFieldContext } from './FormFieldContext';
10
+ export type { FormFieldIds, FormFieldContextValue, FormFieldRootProps, FormFieldLabelProps, FormFieldControlProps, FormFieldErrorProps, FormFieldDescriptionProps, } from './types';
@@ -0,0 +1,114 @@
1
+ import { HTMLAttributes, LabelHTMLAttributes, ReactNode } from 'react';
2
+ import { FieldNode, FormValue, ValidationError } from '@reformer/core';
3
+ /**
4
+ * Stable IDs for all accessible elements of a form field
5
+ */
6
+ export interface FormFieldIds {
7
+ /** ID placed on the interactive control element (<input>, etc.) */
8
+ controlId: string;
9
+ /** ID placed on the <label> element */
10
+ labelId: string;
11
+ /** ID placed on the description paragraph */
12
+ descriptionId: string;
13
+ /** ID placed on the first error paragraph */
14
+ errorId: string;
15
+ }
16
+ /**
17
+ * Context value provided by FormField.Root
18
+ */
19
+ export interface FormFieldContextValue<T extends FormValue = FormValue> {
20
+ value: T;
21
+ errors: ValidationError[];
22
+ pending: boolean;
23
+ disabled: boolean;
24
+ valid: boolean;
25
+ invalid: boolean;
26
+ touched: boolean;
27
+ shouldShowError: boolean;
28
+ /** First error message, only set when shouldShowError is true */
29
+ error: string | undefined;
30
+ label: string | undefined;
31
+ required: boolean;
32
+ /** Full componentProps bag */
33
+ componentProps: Record<string, unknown>;
34
+ control: FieldNode<T>;
35
+ ids: FormFieldIds;
36
+ /** Whether a FormField.Description is present (drives aria-describedby on Control) */
37
+ hasDescription: boolean;
38
+ }
39
+ /**
40
+ * Props for FormField.Root
41
+ */
42
+ export interface FormFieldRootProps<T extends FormValue = FormValue> {
43
+ /** The FieldNode control from the form */
44
+ control: FieldNode<T>;
45
+ children: ReactNode;
46
+ /** Explicit id prefix; if omitted, useId() is used */
47
+ id?: string;
48
+ /**
49
+ * Set to true when the field has a description element so that
50
+ * FormField.Control automatically wires aria-describedby.
51
+ * Avoids the double-render caused by dynamic description registration.
52
+ * @default false
53
+ */
54
+ hasDescription?: boolean;
55
+ }
56
+ /**
57
+ * Props for FormField.Label
58
+ */
59
+ export interface FormFieldLabelProps extends Omit<LabelHTMLAttributes<HTMLLabelElement>, 'htmlFor'> {
60
+ /** Render as child element via Slot (merges accessible props into the child) */
61
+ asChild?: boolean;
62
+ /**
63
+ * Override label text. Defaults to componentProps.label.
64
+ * Pass children explicitly when you need custom content inside the label.
65
+ */
66
+ children?: ReactNode;
67
+ /**
68
+ * If true, always renders even when no label text is available.
69
+ * Useful when the consumer provides children.
70
+ * @default false
71
+ */
72
+ forceRender?: boolean;
73
+ }
74
+ /**
75
+ * Props for FormField.Control
76
+ */
77
+ export interface FormFieldControlProps extends Omit<HTMLAttributes<HTMLElement>, 'id' | 'onChange' | 'onBlur'> {
78
+ /**
79
+ * Merge accessible props into a custom child element instead of
80
+ * auto-rendering control.component.
81
+ */
82
+ asChild?: boolean;
83
+ /**
84
+ * Custom children. When provided, control.component is NOT auto-rendered.
85
+ * Accessible props are merged into the child via Slot.
86
+ */
87
+ children?: ReactNode;
88
+ }
89
+ /**
90
+ * Props for FormField.Error
91
+ */
92
+ export interface FormFieldErrorProps extends Omit<HTMLAttributes<HTMLParagraphElement>, 'id' | 'role'> {
93
+ asChild?: boolean;
94
+ /**
95
+ * When true, renders all errors instead of only the first.
96
+ * @default false
97
+ */
98
+ multi?: boolean;
99
+ /**
100
+ * Custom render function per error. When provided, multi is implied true.
101
+ */
102
+ render?: (error: ValidationError, index: number) => ReactNode;
103
+ /**
104
+ * Override error content. Defaults to errors[0].message.
105
+ */
106
+ children?: ReactNode;
107
+ }
108
+ /**
109
+ * Props for FormField.Description
110
+ */
111
+ export interface FormFieldDescriptionProps extends Omit<HTMLAttributes<HTMLParagraphElement>, 'id'> {
112
+ asChild?: boolean;
113
+ children: ReactNode;
114
+ }
@@ -0,0 +1,111 @@
1
+ import { FieldNode, FormValue, ValidationError } from '@reformer/core';
2
+ import { FormFieldIds } from './types';
3
+ /**
4
+ * Field state returned by useFormField
5
+ */
6
+ export interface UseFormFieldState<T extends FormValue = FormValue> {
7
+ value: T;
8
+ errors: ValidationError[];
9
+ /** First error message, only set when shouldShowError is true */
10
+ error: string | undefined;
11
+ isPending: boolean;
12
+ isDisabled: boolean;
13
+ isValid: boolean;
14
+ isInvalid: boolean;
15
+ isTouched: boolean;
16
+ shouldShowError: boolean;
17
+ label: string | undefined;
18
+ required: boolean;
19
+ /** Full componentProps bag from FieldNode config */
20
+ componentProps: Record<string, unknown>;
21
+ }
22
+ /** Props to spread onto a <label> element */
23
+ export interface UseFormFieldLabelProps {
24
+ id: string;
25
+ htmlFor: string;
26
+ }
27
+ /** Props to spread onto the interactive control element */
28
+ export interface UseFormFieldControlProps {
29
+ id: string;
30
+ disabled: boolean;
31
+ 'aria-labelledby': string;
32
+ 'aria-invalid': true | undefined;
33
+ 'aria-errormessage': string | undefined;
34
+ 'aria-required': true | undefined;
35
+ /** Direct-value onChange compatible with ReFormer field components */
36
+ onChange: (value: unknown) => void;
37
+ onBlur: () => void;
38
+ }
39
+ /** Props to spread onto an error paragraph */
40
+ export interface UseFormFieldErrorProps {
41
+ id: string;
42
+ role: 'alert';
43
+ }
44
+ /** Props to spread onto a description paragraph */
45
+ export interface UseFormFieldDescriptionProps {
46
+ id: string;
47
+ }
48
+ /**
49
+ * Return type of useFormField hook
50
+ */
51
+ export interface UseFormFieldReturn<T extends FormValue = FormValue> {
52
+ /** Spread onto <label> */
53
+ labelProps: UseFormFieldLabelProps;
54
+ /** Spread onto the interactive control; includes value */
55
+ controlProps: UseFormFieldControlProps & {
56
+ value: T;
57
+ };
58
+ /** Spread onto the first error paragraph */
59
+ errorProps: UseFormFieldErrorProps;
60
+ /** Spread onto the description paragraph */
61
+ descriptionProps: UseFormFieldDescriptionProps;
62
+ /** Structured field state */
63
+ state: UseFormFieldState<T>;
64
+ /** Field actions */
65
+ actions: {
66
+ setValue: (value: T) => void;
67
+ markAsTouched: () => void;
68
+ markAsUntouched: () => void;
69
+ reset: (value?: T) => void;
70
+ };
71
+ /** Raw IDs for manual wiring (e.g. aria-describedby) */
72
+ ids: FormFieldIds;
73
+ }
74
+ /**
75
+ * Primary hook for building accessible form fields.
76
+ *
77
+ * Returns partitioned prop collections and structured state that you can spread
78
+ * directly onto your own elements. No prescribed DOM structure.
79
+ *
80
+ * @example Basic usage
81
+ * ```tsx
82
+ * function EmailField({ control }: { control: FieldNode<string> }) {
83
+ * const { labelProps, controlProps, errorProps, state } = useFormField(control);
84
+ *
85
+ * return (
86
+ * <div>
87
+ * <label {...labelProps}>{state.label}</label>
88
+ * <input {...controlProps} type="email" />
89
+ * {state.shouldShowError && (
90
+ * <p {...errorProps}>{state.error}</p>
91
+ * )}
92
+ * </div>
93
+ * );
94
+ * }
95
+ * ```
96
+ *
97
+ * @example With description (manual aria-describedby wiring)
98
+ * ```tsx
99
+ * const { labelProps, controlProps, errorProps, descriptionProps, state, ids } =
100
+ * useFormField(control);
101
+ *
102
+ * const enrichedControlProps = {
103
+ * ...controlProps,
104
+ * 'aria-describedby': [
105
+ * ids.descriptionId,
106
+ * state.shouldShowError ? ids.errorId : null,
107
+ * ].filter(Boolean).join(' ') || undefined,
108
+ * };
109
+ * ```
110
+ */
111
+ export declare function useFormField<T extends FormValue>(control: FieldNode<T>, id?: string): UseFormFieldReturn<T>;
@@ -0,0 +1,47 @@
1
+ import { FormWizardStep } from './FormWizardStep';
2
+ import { FormWizardIndicator } from './FormWizardIndicator';
3
+ import { FormWizardActions } from './FormWizardActions';
4
+ import { FormWizardProgress } from './FormWizardProgress';
5
+ import { FormWizardPrev } from './FormWizardPrev';
6
+ import { FormWizardNext } from './FormWizardNext';
7
+ import { FormWizardSubmit } from './FormWizardSubmit';
8
+ import { FormWizardHandle, FormWizardProps } from './types';
9
+ declare const FormWizardBase: <T extends Record<string, any>>(props: FormWizardProps<T> & {
10
+ ref?: React.ForwardedRef<FormWizardHandle<T>>;
11
+ }) => React.ReactElement;
12
+ type FormWizardComponent = typeof FormWizardBase & {
13
+ Step: typeof FormWizardStep;
14
+ Indicator: typeof FormWizardIndicator;
15
+ Actions: typeof FormWizardActions;
16
+ Progress: typeof FormWizardProgress;
17
+ Prev: typeof FormWizardPrev;
18
+ Next: typeof FormWizardNext;
19
+ Submit: typeof FormWizardSubmit;
20
+ };
21
+ /**
22
+ * Headless multi-step wizard. Compound-компонент: `FormWizard` + `FormWizard.Step`,
23
+ * `FormWizard.Actions`, `FormWizard.Indicator`, `FormWizard.Progress`,
24
+ * `FormWizard.Prev`, `FormWizard.Next`, `FormWizard.Submit`.
25
+ *
26
+ * @example
27
+ * ```tsx
28
+ * import { FormWizard } from '@reformer/cdk/form-wizard';
29
+ *
30
+ * <FormWizard form={form} steps={[{ name: 'profile' }, { name: 'review' }]}>
31
+ * <FormWizard.Step name="profile"><ProfileFields /></FormWizard.Step>
32
+ * <FormWizard.Step name="review"><Review /></FormWizard.Step>
33
+ * <FormWizard.Actions>
34
+ * {({ prev, next, submit, isLastStep }) => (
35
+ * <div>
36
+ * <button {...prev}>Prev</button>
37
+ * {isLastStep ? <button {...submit}>Submit</button> : <button {...next}>Next</button>}
38
+ * </div>
39
+ * )}
40
+ * </FormWizard.Actions>
41
+ * </FormWizard>
42
+ * ```
43
+ *
44
+ * @see [docs/llms/03-form-navigation.md](../../../docs/llms/03-form-navigation.md)
45
+ */
46
+ export declare const FormWizard: FormWizardComponent;
47
+ export {};