@ereo/forms 0.1.23

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 (46) hide show
  1. package/dist/a11y.d.ts +52 -0
  2. package/dist/a11y.d.ts.map +1 -0
  3. package/dist/accessibility.d.ts +152 -0
  4. package/dist/accessibility.d.ts.map +1 -0
  5. package/dist/action-integration.d.ts +104 -0
  6. package/dist/action-integration.d.ts.map +1 -0
  7. package/dist/action.d.ts +33 -0
  8. package/dist/action.d.ts.map +1 -0
  9. package/dist/adapters.d.ts +25 -0
  10. package/dist/adapters.d.ts.map +1 -0
  11. package/dist/array-field.d.ts +49 -0
  12. package/dist/array-field.d.ts.map +1 -0
  13. package/dist/components.d.ts +8 -0
  14. package/dist/components.d.ts.map +1 -0
  15. package/dist/composition.d.ts +4 -0
  16. package/dist/composition.d.ts.map +1 -0
  17. package/dist/context.d.ts +9 -0
  18. package/dist/context.d.ts.map +1 -0
  19. package/dist/field.d.ts +88 -0
  20. package/dist/field.d.ts.map +1 -0
  21. package/dist/form.d.ts +59 -0
  22. package/dist/form.d.ts.map +1 -0
  23. package/dist/hooks.d.ts +13 -0
  24. package/dist/hooks.d.ts.map +1 -0
  25. package/dist/index.d.ts +16 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +2945 -0
  28. package/dist/proxy.d.ts +3 -0
  29. package/dist/proxy.d.ts.map +1 -0
  30. package/dist/schema.d.ts +31 -0
  31. package/dist/schema.d.ts.map +1 -0
  32. package/dist/store.d.ts +69 -0
  33. package/dist/store.d.ts.map +1 -0
  34. package/dist/types.d.ts +243 -0
  35. package/dist/types.d.ts.map +1 -0
  36. package/dist/utils.d.ts +8 -0
  37. package/dist/utils.d.ts.map +1 -0
  38. package/dist/validation-engine.d.ts +33 -0
  39. package/dist/validation-engine.d.ts.map +1 -0
  40. package/dist/validation.d.ts +241 -0
  41. package/dist/validation.d.ts.map +1 -0
  42. package/dist/validators.d.ts +51 -0
  43. package/dist/validators.d.ts.map +1 -0
  44. package/dist/wizard.d.ts +52 -0
  45. package/dist/wizard.d.ts.map +1 -0
  46. package/package.json +60 -0
package/dist/a11y.d.ts ADDED
@@ -0,0 +1,52 @@
1
+ import type { FieldState, FormSubmitState } from './types';
2
+ import type { FormStoreInterface } from './types';
3
+ export declare function generateA11yId(prefix?: string): string;
4
+ export declare function getFieldA11y(name: string, state: Pick<FieldState, 'errors' | 'touched'>): Record<string, string | boolean | undefined>;
5
+ export declare function getErrorA11y(name: string): {
6
+ id: string;
7
+ role: string;
8
+ 'aria-live': string;
9
+ };
10
+ export declare function getLabelA11y(name: string, opts?: {
11
+ id?: string;
12
+ }): {
13
+ htmlFor: string;
14
+ id: string;
15
+ };
16
+ export declare function getDescriptionA11y(name: string): {
17
+ id: string;
18
+ };
19
+ export declare function getFieldsetA11y(name: string, _legend?: string): {
20
+ role: string;
21
+ 'aria-labelledby': string;
22
+ };
23
+ export declare function getFieldWrapperA11y(name: string, state: Pick<FieldState, 'errors' | 'touched'>): Record<string, string | boolean | undefined>;
24
+ export declare function getFormA11y(id: string, opts?: {
25
+ isSubmitting?: boolean;
26
+ }): Record<string, string | boolean>;
27
+ export declare function getErrorSummaryA11y(formId: string): {
28
+ role: string;
29
+ 'aria-labelledby': string;
30
+ };
31
+ export declare function focusFirstError(form: FormStoreInterface<any>): void;
32
+ export declare function focusField(name: string): void;
33
+ export declare function trapFocus(container: HTMLElement): () => void;
34
+ export declare function announce(message: string, priority?: 'polite' | 'assertive'): void;
35
+ export declare function cleanupLiveRegion(): void;
36
+ export declare function announceErrors(errors: Record<string, string[]>, opts?: {
37
+ prefix?: string;
38
+ }): void;
39
+ export declare function announceSubmitStatus(status: FormSubmitState, opts?: {
40
+ successMessage?: string;
41
+ errorMessage?: string;
42
+ submittingMessage?: string;
43
+ }): void;
44
+ export declare function prefersReducedMotion(): boolean;
45
+ /**
46
+ * Heuristic detection — not reliable for all screen readers.
47
+ * Returns true if certain indicators are present, but many screen readers
48
+ * (VoiceOver, TalkBack, Orca) are undetectable from JavaScript.
49
+ * Prefer designing for accessibility by default rather than relying on detection.
50
+ */
51
+ export declare function isScreenReaderActive(): boolean;
52
+ //# sourceMappingURL=a11y.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a11y.d.ts","sourceRoot":"","sources":["../src/a11y.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAMlD,wBAAgB,cAAc,CAAC,MAAM,SAAS,GAAG,MAAM,CAEtD;AAID,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,GAAG,SAAS,CAAC,GAC5C,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAS9C;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB,CAMA;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GACrB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAKjC;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAI/D;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,GACf;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,CAK7C;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,GAAG,SAAS,CAAC,GAC5C,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAO9C;AAID,wBAAgB,WAAW,CACzB,EAAE,EAAE,MAAM,EACV,IAAI,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,GAChC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CASlC;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAKA;AAID,wBAAgB,eAAe,CAAC,IAAI,EAAE,kBAAkB,CAAC,GAAG,CAAC,GAAG,IAAI,CA0BnE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAS7C;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,WAAW,GAAG,MAAM,IAAI,CA8B5D;AA+BD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,QAAQ,GAAG,WAAsB,GAAG,IAAI,CAQ3F;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAKxC;AAED,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAChC,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACzB,IAAI,CAUN;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,eAAe,EACvB,IAAI,CAAC,EAAE;IAAE,cAAc,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAAE,GACpF,IAAI,CAYN;AAID,wBAAgB,oBAAoB,IAAI,OAAO,CAG9C;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAO9C"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * @ereo/forms - Accessibility Utilities
3
+ *
4
+ * Auto-generated ARIA attributes, focus management, and screen reader support.
5
+ */
6
+ import type { FieldState, FormStore } from './types';
7
+ /**
8
+ * Get ARIA attributes for a field.
9
+ *
10
+ * @example
11
+ * const a11y = getFieldA11y('email', fieldState);
12
+ * // Returns: { 'aria-invalid': true, 'aria-describedby': 'email-error', ... }
13
+ */
14
+ export declare function getFieldA11y(name: string, state: FieldState): Record<string, string | boolean | undefined>;
15
+ /**
16
+ * Get error container attributes.
17
+ *
18
+ * @example
19
+ * <div {...getErrorA11y('email')}>Error message</div>
20
+ */
21
+ export declare function getErrorA11y(name: string): Record<string, string>;
22
+ /**
23
+ * Get label attributes.
24
+ *
25
+ * @example
26
+ * <label {...getLabelA11y('email', { required: true })}>Email</label>
27
+ */
28
+ export declare function getLabelA11y(name: string, options?: {
29
+ required?: boolean;
30
+ }): Record<string, string | boolean | undefined>;
31
+ /**
32
+ * Get description/hint attributes.
33
+ *
34
+ * @example
35
+ * <span {...getDescriptionA11y('email')}>Enter your email address</span>
36
+ */
37
+ export declare function getDescriptionA11y(name: string): Record<string, string>;
38
+ /**
39
+ * Get fieldset attributes for grouped fields.
40
+ *
41
+ * @example
42
+ * <fieldset {...getFieldsetA11y('address', 'Your Address')}>...</fieldset>
43
+ */
44
+ export declare function getFieldsetA11y(name: string, legend: string): Record<string, string>;
45
+ /**
46
+ * Get complete field wrapper attributes.
47
+ *
48
+ * @example
49
+ * <div {...getFieldWrapperA11y('email', fieldState)}>
50
+ * <label>Email</label>
51
+ * <input />
52
+ * <span>Error</span>
53
+ * </div>
54
+ */
55
+ export declare function getFieldWrapperA11y(name: string, state: FieldState): Record<string, string | boolean>;
56
+ /**
57
+ * Focus the first field with an error.
58
+ *
59
+ * @example
60
+ * const handleSubmit = async () => {
61
+ * const result = await form.validate();
62
+ * if (!result.valid) {
63
+ * focusFirstError(form);
64
+ * return;
65
+ * }
66
+ * // Submit...
67
+ * };
68
+ */
69
+ export declare function focusFirstError<T extends Record<string, unknown>>(form: FormStore<T>): boolean;
70
+ /**
71
+ * Focus a specific field by name.
72
+ *
73
+ * @example
74
+ * focusField('email');
75
+ */
76
+ export declare function focusField(name: string): boolean;
77
+ /**
78
+ * Trap focus within a container (useful for modals/dialogs).
79
+ *
80
+ * @example
81
+ * const cleanup = trapFocus(dialogElement);
82
+ * // Later: cleanup();
83
+ */
84
+ export declare function trapFocus(container: HTMLElement): () => void;
85
+ /**
86
+ * Announce errors to screen readers.
87
+ *
88
+ * @example
89
+ * const errors = form.errors.get();
90
+ * if (Object.keys(errors).length > 0) {
91
+ * announceErrors(errors);
92
+ * }
93
+ */
94
+ export declare function announceErrors(errors: Record<string, string[]>, options?: {
95
+ prefix?: string;
96
+ joiner?: string;
97
+ }): void;
98
+ /**
99
+ * Announce a message to screen readers.
100
+ *
101
+ * @example
102
+ * announce('Form submitted successfully');
103
+ */
104
+ export declare function announce(message: string, priority?: 'polite' | 'assertive'): void;
105
+ /**
106
+ * Announce form submission status.
107
+ *
108
+ * @example
109
+ * announceSubmitStatus('submitting');
110
+ * // Later...
111
+ * announceSubmitStatus('success');
112
+ */
113
+ export declare function announceSubmitStatus(status: 'idle' | 'submitting' | 'success' | 'error', options?: {
114
+ submittingMessage?: string;
115
+ successMessage?: string;
116
+ errorMessage?: string;
117
+ }): void;
118
+ /**
119
+ * Generate a unique ID for accessibility purposes.
120
+ */
121
+ export declare function generateA11yId(prefix: string): string;
122
+ /**
123
+ * Check if reduced motion is preferred.
124
+ */
125
+ export declare function prefersReducedMotion(): boolean;
126
+ /**
127
+ * Check if screen reader is likely active.
128
+ * Note: This is not 100% reliable.
129
+ */
130
+ export declare function isScreenReaderActive(): boolean;
131
+ /**
132
+ * Get form element attributes.
133
+ *
134
+ * @example
135
+ * <form {...getFormA11y('contact-form', { submitting: true })}>
136
+ */
137
+ export declare function getFormA11y(id: string, options?: {
138
+ submitting?: boolean;
139
+ errorCount?: number;
140
+ }): Record<string, string | boolean | undefined>;
141
+ /**
142
+ * Get error summary container attributes.
143
+ *
144
+ * @example
145
+ * <div {...getErrorSummaryA11y('contact-form')}>
146
+ * <h2>Please fix the following errors:</h2>
147
+ * <ul>...</ul>
148
+ * </div>
149
+ */
150
+ export declare function getErrorSummaryA11y(formId: string): Record<string, string>;
151
+ export type { FieldState };
152
+ //# sourceMappingURL=accessibility.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessibility.d.ts","sourceRoot":"","sources":["../src/accessibility.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * @ereo/forms - Server Action Integration
3
+ *
4
+ * Direct integration with @ereo/data actions and server forms.
5
+ */
6
+ import { type ReactNode } from 'react';
7
+ import type { ActionFormProps, ActionResult, FormActionOptions, FormStore, ValidationSchema } from './types';
8
+ /**
9
+ * Create a form action handler for server-side processing.
10
+ *
11
+ * @example
12
+ * // In your server route (e.g., routes/contact.ts)
13
+ * import { createFormAction } from '@ereo/forms';
14
+ * import { z } from 'zod';
15
+ *
16
+ * const contactSchema = z.object({
17
+ * name: z.string().min(1),
18
+ * email: z.string().email(),
19
+ * message: z.string().min(10),
20
+ * });
21
+ *
22
+ * export const action = createFormAction({
23
+ * schema: contactSchema,
24
+ * handler: async ({ body }) => {
25
+ * await sendEmail(body);
26
+ * return { sent: true };
27
+ * },
28
+ * });
29
+ */
30
+ export declare function createFormAction<T, TResult = T>(options: FormActionOptions<T, TResult>): (args: {
31
+ request: Request;
32
+ }) => Promise<ActionResult<TResult>>;
33
+ /**
34
+ * Form component with automatic server action submission.
35
+ *
36
+ * @example
37
+ * <ActionForm
38
+ * form={form}
39
+ * action="/api/contact"
40
+ * onSuccess={(result) => {
41
+ * toast.success('Message sent!');
42
+ * router.push('/thank-you');
43
+ * }}
44
+ * onError={(result) => {
45
+ * toast.error('Failed to send message');
46
+ * }}
47
+ * >
48
+ * <Field form={form} name="name" label="Name" />
49
+ * <Field form={form} name="email" label="Email" />
50
+ * <Field form={form} name="message" label="Message" />
51
+ * <button type="submit">Send</button>
52
+ * </ActionForm>
53
+ */
54
+ export declare function ActionForm<T extends Record<string, unknown>>({ form, action, method, onSuccess, onError, resetOnSuccess, children, ...rest }: ActionFormProps<T>): ReactNode;
55
+ export interface UseFormActionOptions<T> {
56
+ /** Server action URL */
57
+ action: string;
58
+ /** HTTP method */
59
+ method?: 'post' | 'put' | 'patch' | 'delete';
60
+ /** Success callback */
61
+ onSuccess?: (result: ActionResult<T>) => void;
62
+ /** Error callback */
63
+ onError?: (result: ActionResult<T>) => void;
64
+ /** Validation schema for response */
65
+ responseSchema?: ValidationSchema<unknown, T>;
66
+ }
67
+ export interface UseFormActionReturn<T extends Record<string, unknown>, TResult = unknown> {
68
+ /** Submit the form */
69
+ submit: (form: FormStore<T>) => Promise<ActionResult<TResult>>;
70
+ /** Cancel pending submission */
71
+ cancel: () => void;
72
+ /** Current submission state */
73
+ isSubmitting: boolean;
74
+ /** Last submission result */
75
+ result: ActionResult<TResult> | null;
76
+ }
77
+ /**
78
+ * Hook for manual form action submission.
79
+ *
80
+ * @example
81
+ * function ContactForm() {
82
+ * const form = useForm({ initialValues: { email: '' } });
83
+ * const { submit, isSubmitting, result } = useFormAction({
84
+ * action: '/api/contact',
85
+ * onSuccess: (result) => console.log('Sent!', result),
86
+ * });
87
+ *
88
+ * return (
89
+ * <form onSubmit={(e) => { e.preventDefault(); submit(form); }}>
90
+ * <Field form={form} name="email" />
91
+ * <button disabled={isSubmitting}>
92
+ * {isSubmitting ? 'Sending...' : 'Send'}
93
+ * </button>
94
+ * </form>
95
+ * );
96
+ * }
97
+ */
98
+ export declare function useFormAction<T extends Record<string, unknown>, TResult = unknown>(options: UseFormActionOptions<TResult>): UseFormActionReturn<T, TResult>;
99
+ /**
100
+ * Parse action result from various response formats.
101
+ */
102
+ export declare function parseActionResult<T>(response: unknown): ActionResult<T>;
103
+ export type { ActionFormProps, ActionResult, FormActionOptions };
104
+ //# sourceMappingURL=action-integration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-integration.d.ts","sourceRoot":"","sources":["../src/action-integration.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,SAAS,EACT,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAQjB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,EAC7C,OAAO,EAAE,iBAAiB,CAAC,CAAC,EAAE,OAAO,CAAC,GACrC,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,KAAK,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAkDhE;AAMD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC5D,IAAI,EACJ,MAAM,EACN,MAAe,EACf,SAAS,EACT,OAAO,EACP,cAAc,EACd,QAAQ,EACR,GAAG,IAAI,EACR,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,SAAS,CAoGhC;AAMD,MAAM,WAAW,oBAAoB,CAAC,CAAC;IACrC,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB;IAClB,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IAC7C,uBAAuB;IACvB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IAC9C,qBAAqB;IACrB,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IAC5C,qCAAqC;IACrC,cAAc,CAAC,EAAE,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,mBAAmB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO;IACvF,sBAAsB;IACtB,MAAM,EAAE,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/D,gCAAgC;IAChC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,+BAA+B;IAC/B,YAAY,EAAE,OAAO,CAAC;IACtB,6BAA6B;IAC7B,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;CACtC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,EAChF,OAAO,EAAE,oBAAoB,CAAC,OAAO,CAAC,GACrC,mBAAmB,CAAC,CAAC,EAAE,OAAO,CAAC,CAoHjC;AAiDD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,CAkCvE;AAMD,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,iBAAiB,EAAE,CAAC"}
@@ -0,0 +1,33 @@
1
+ import type { ReactNode, ReactElement } from 'react';
2
+ import type { ActionResult, FormStoreInterface, ValidationSchema } from './types';
3
+ export interface CreateFormActionOptions<T, TResult = unknown> {
4
+ schema?: ValidationSchema<unknown, T>;
5
+ handler: (values: T) => Promise<TResult>;
6
+ onError?: (error: unknown) => ActionResult<TResult>;
7
+ }
8
+ export declare function createFormAction<T, TResult = unknown>(opts: CreateFormActionOptions<T, TResult>): (request: Request) => Promise<ActionResult<TResult>>;
9
+ export interface ActionFormProps<T extends Record<string, any>> {
10
+ form: FormStoreInterface<T>;
11
+ action: string | ((values: T) => Promise<ActionResult>);
12
+ method?: 'post' | 'put' | 'patch' | 'delete';
13
+ onSuccess?: (result: any) => void;
14
+ onError?: (errors: Record<string, string[]>) => void;
15
+ children: ReactNode;
16
+ className?: string;
17
+ id?: string;
18
+ encType?: 'application/json' | 'multipart/form-data';
19
+ }
20
+ export declare function ActionForm<T extends Record<string, any>>(props: ActionFormProps<T>): ReactElement;
21
+ export interface UseFormActionOptions<T, TResult = unknown> {
22
+ action: string | ((values: T) => Promise<ActionResult<TResult>>);
23
+ method?: string;
24
+ encType?: 'application/json' | 'multipart/form-data';
25
+ }
26
+ export declare function useFormAction<T, TResult = unknown>(opts: UseFormActionOptions<T, TResult>): {
27
+ submit: (values: T) => Promise<ActionResult<TResult>>;
28
+ cancel: () => void;
29
+ isSubmitting: boolean;
30
+ result: ActionResult<TResult> | null;
31
+ };
32
+ export declare function parseActionResult<T>(response: unknown): ActionResult<T>;
33
+ //# sourceMappingURL=action.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../src/action.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAa,YAAY,EAAE,MAAM,OAAO,CAAC;AAChE,OAAO,KAAK,EACV,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAEjB,MAAM,SAAS,CAAC;AAOjB,MAAM,WAAW,uBAAuB,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO;IAC3D,MAAM,CAAC,EAAE,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACtC,OAAO,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,YAAY,CAAC,OAAO,CAAC,CAAC;CACrD;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,EACnD,IAAI,EAAE,uBAAuB,CAAC,CAAC,EAAE,OAAO,CAAC,GACxC,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAsEtD;AAID,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAC5D,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC;IAC5B,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;IACxD,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IAC7C,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;IAClC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC;IACrD,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,kBAAkB,GAAG,qBAAqB,CAAC;CACtD;AAED,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACtD,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,GACxB,YAAY,CAqId;AAID,MAAM,WAAW,oBAAoB,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO;IACxD,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,kBAAkB,GAAG,qBAAqB,CAAC;CACtD;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,EAChD,IAAI,EAAE,oBAAoB,CAAC,CAAC,EAAE,OAAO,CAAC,GACrC;IACD,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;IACtD,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;CACtC,CA+DA;AAID,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,CAuCvE"}
@@ -0,0 +1,25 @@
1
+ import type { ReactElement } from 'react';
2
+ import type { UIAdapter, UIAdapterComponents, FieldState, FieldInputProps } from './types';
3
+ export declare function registerAdapter(adapter: UIAdapter): void;
4
+ export declare function getAdapter(name: string): UIAdapter | undefined;
5
+ export declare function setDefaultAdapter(name: string): void;
6
+ export declare function getDefaultAdapter(): UIAdapter | undefined;
7
+ export declare function listAdapters(): string[];
8
+ export declare function unregisterAdapter(name: string): void;
9
+ export declare function createAdapter(name: string, components: UIAdapterComponents, classNames?: Record<string, string>): UIAdapter;
10
+ export declare function useAdapter(name?: string): UIAdapter | undefined;
11
+ export interface AdaptedFieldProps {
12
+ inputProps: FieldInputProps;
13
+ state: Pick<FieldState, 'errors' | 'touched' | 'dirty'>;
14
+ adapter?: string;
15
+ type?: string;
16
+ label?: string;
17
+ placeholder?: string;
18
+ disabled?: boolean;
19
+ required?: boolean;
20
+ className?: string;
21
+ }
22
+ export declare function AdaptedField(props: AdaptedFieldProps): ReactElement;
23
+ export declare const htmlAdapter: UIAdapter;
24
+ export declare function clearAdapterRegistry(): void;
25
+ //# sourceMappingURL=adapters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapters.d.ts","sourceRoot":"","sources":["../src/adapters.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,KAAK,EAAE,SAAS,EAAE,mBAAmB,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAO3F,wBAAgB,eAAe,CAAC,OAAO,EAAE,SAAS,GAAG,IAAI,CAExD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAE9D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAKpD;AAED,wBAAgB,iBAAiB,IAAI,SAAS,GAAG,SAAS,CAGzD;AAED,wBAAgB,YAAY,IAAI,MAAM,EAAE,CAEvC;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAKpD;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,mBAAmB,EAC/B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAClC,SAAS,CAIX;AAID,wBAAgB,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAG/D;AAID,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,eAAe,CAAC;IAC5B,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,YAAY,CAuEnE;AAID,eAAO,MAAM,WAAW,EAAE,SAiEzB,CAAC;AAEF,wBAAgB,oBAAoB,IAAI,IAAI,CAG3C"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * @ereo/forms - Array Field Components
3
+ *
4
+ * First-class support for array fields with stable keys.
5
+ */
6
+ import { type ReactNode } from 'react';
7
+ import type { ArrayFieldHelpers, ArrayFieldItem, FieldArrayProps, FormStore, PathsOf, PathValue } from './types';
8
+ /**
9
+ * Hook for managing array fields.
10
+ *
11
+ * @example
12
+ * function TagsField() {
13
+ * const { fields, append, remove } = useFieldArray(form, 'tags');
14
+ *
15
+ * return (
16
+ * <div>
17
+ * {fields.map((field, index) => (
18
+ * <div key={field.id}>
19
+ * <Field form={form} name={`tags.${index}`} />
20
+ * <button onClick={() => remove(index)}>Remove</button>
21
+ * </div>
22
+ * ))}
23
+ * <button onClick={() => append('')}>Add Tag</button>
24
+ * </div>
25
+ * );
26
+ * }
27
+ */
28
+ export declare function useFieldArray<T extends Record<string, unknown>, K extends PathsOf<T>, Item = PathValue<T, K> extends Array<infer U> ? U : never>(form: FormStore<T>, name: K): ArrayFieldHelpers<Item>;
29
+ /**
30
+ * Component for rendering array fields.
31
+ *
32
+ * @example
33
+ * <FieldArray form={form} name="tags">
34
+ * {({ fields, append, remove }) => (
35
+ * <div>
36
+ * {fields.map((field, index) => (
37
+ * <div key={field.id}>
38
+ * <Field form={form} name={`tags.${index}`} />
39
+ * <button onClick={() => remove(index)}>×</button>
40
+ * </div>
41
+ * ))}
42
+ * <button onClick={() => append('')}>Add</button>
43
+ * </div>
44
+ * )}
45
+ * </FieldArray>
46
+ */
47
+ export declare function FieldArray<T extends Record<string, unknown>, K extends PathsOf<T>>({ form, name, children, }: FieldArrayProps<T, K>): ReactNode;
48
+ export type { ArrayFieldHelpers, ArrayFieldItem, FieldArrayProps };
49
+ //# sourceMappingURL=array-field.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"array-field.d.ts","sourceRoot":"","sources":["../src/array-field.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAkC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACvE,OAAO,KAAK,EACV,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,SAAS,EACT,OAAO,EACP,SAAS,EACV,MAAM,SAAS,CAAC;AAgFjB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,aAAa,CAC3B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,EACpB,IAAI,GAAG,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,EACzD,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAwPtD;AAMD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CACxB,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,EACpB,EACA,IAAI,EACJ,IAAI,EACJ,QAAQ,GACT,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAGnC;AAGD,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,eAAe,EAAE,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { ReactElement } from 'react';
2
+ import type { FieldComponentProps, TextareaFieldProps, SelectFieldProps, FieldArrayComponentProps } from './types';
3
+ export declare function Field<T extends Record<string, any>, K extends string = string>(props: FieldComponentProps<T, K>): ReactElement | null;
4
+ export declare function TextareaField<T extends Record<string, any>, K extends string = string>(props: TextareaFieldProps<T, K>): ReactElement | null;
5
+ export declare function SelectField<T extends Record<string, any>, K extends string = string>(props: SelectFieldProps<T, K>): ReactElement | null;
6
+ export declare function FieldArrayComponent<T extends Record<string, any>, K extends string = string>(props: FieldArrayComponentProps<T, K>): ReactElement | null;
7
+ export { FieldArrayComponent as FieldArray };
8
+ //# sourceMappingURL=components.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../src/components.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAa,YAAY,EAAE,MAAM,OAAO,CAAC;AAIrD,OAAO,KAAK,EAEV,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,wBAAwB,EAEzB,MAAM,SAAS,CAAC;AA+BjB,wBAAgB,KAAK,CACnB,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC7B,CAAC,SAAS,MAAM,GAAG,MAAM,EACzB,KAAK,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,YAAY,GAAG,IAAI,CAqDvD;AAID,wBAAgB,aAAa,CAC3B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC7B,CAAC,SAAS,MAAM,GAAG,MAAM,EACzB,KAAK,EAAE,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,YAAY,GAAG,IAAI,CA2CtD;AAID,wBAAgB,WAAW,CACzB,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC7B,CAAC,SAAS,MAAM,GAAG,MAAM,EACzB,KAAK,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,YAAY,GAAG,IAAI,CAoDpD;AAID,wBAAgB,mBAAmB,CACjC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC7B,CAAC,SAAS,MAAM,GAAG,MAAM,EACzB,KAAK,EAAE,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,YAAY,GAAG,IAAI,CAQ5D;AAGD,OAAO,EAAE,mBAAmB,IAAI,UAAU,EAAE,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { FormConfig, ValidationSchema } from './types';
2
+ export declare function mergeFormConfigs<A extends Record<string, any>, B extends Record<string, any>>(configA: FormConfig<A>, configB: FormConfig<B>): FormConfig<A & B>;
3
+ export declare function composeSchemas<A = unknown, B = unknown>(prefix1: string, schema1: ValidationSchema<unknown, A>, prefix2: string, schema2: ValidationSchema<unknown, B>): ValidationSchema<unknown, Record<string, unknown>>;
4
+ //# sourceMappingURL=composition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composition.d.ts","sourceRoot":"","sources":["../src/composition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAqB,MAAM,SAAS,CAAC;AA4B/E,wBAAgB,gBAAgB,CAC9B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC7B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC7B,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAkCnE;AAID,wBAAgB,cAAc,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EACrD,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,EACrC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,GACpC,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA+EpD"}
@@ -0,0 +1,9 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { FormStoreInterface } from './types';
3
+ export interface FormProviderProps<T extends Record<string, any>> {
4
+ form: FormStoreInterface<T>;
5
+ children: ReactNode;
6
+ }
7
+ export declare function FormProvider<T extends Record<string, any>>({ form, children, }: FormProviderProps<T>): import("react").FunctionComponentElement<import("react").ProviderProps<FormStoreInterface<any> | null>>;
8
+ export declare function useFormContext<T extends Record<string, any> = Record<string, any>>(): FormStoreInterface<T> | null;
9
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAIlD,MAAM,WAAW,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAC9D,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC;IAC5B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAC1D,IAAI,EACJ,QAAQ,GACT,EAAE,iBAAiB,CAAC,CAAC,CAAC,2GAEtB;AAED,wBAAgB,cAAc,CAC5B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAChD,kBAAkB,CAAC,CAAC,CAAC,GAAG,IAAI,CAEhC"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * @ereo/forms - Field Components
3
+ *
4
+ * Granular field components with signal-based subscriptions.
5
+ */
6
+ import { type ReactNode } from 'react';
7
+ import type { FieldProps, FieldRegistration, FieldState, FormStore, PathsOf, PathValue, ValidationRule } from './types';
8
+ /**
9
+ * Hook for granular field subscription.
10
+ * Only re-renders when THIS field's value or errors change.
11
+ *
12
+ * @example
13
+ * function EmailField() {
14
+ * const field = useField(form, 'email');
15
+ * return (
16
+ * <div>
17
+ * <input {...field.inputProps} />
18
+ * {field.state.errors.map(err => <span key={err}>{err}</span>)}
19
+ * </div>
20
+ * );
21
+ * }
22
+ */
23
+ export declare function useField<T extends Record<string, unknown>, K extends PathsOf<T>>(form: FormStore<T>, name: K, options?: {
24
+ validate?: ValidationRule | ValidationRule[];
25
+ }): FieldRegistration<PathValue<T, K>> & {
26
+ /** Reactive field value */
27
+ value: PathValue<T, K>;
28
+ /** Reactive field errors */
29
+ errors: string[];
30
+ /** Reactive touched state */
31
+ isTouched: boolean;
32
+ /** Reactive dirty state */
33
+ isDirty: boolean;
34
+ };
35
+ /**
36
+ * Field component with automatic input rendering.
37
+ *
38
+ * @example
39
+ * // Basic usage
40
+ * <Field form={form} name="email" type="email" label="Email" />
41
+ *
42
+ * // With render prop
43
+ * <Field form={form} name="bio">
44
+ * {(field) => <textarea {...field.inputProps} />}
45
+ * </Field>
46
+ *
47
+ * // With UI adapter
48
+ * <Field form={form} name="email" adapter="shadcn" />
49
+ */
50
+ export declare function Field<T extends Record<string, unknown>, K extends PathsOf<T>>({ form, name, type, label, placeholder, disabled, required, className, validate, adapter: adapterName, children, }: FieldProps<T, K>): ReactNode;
51
+ export interface TextareaFieldProps<T extends Record<string, unknown>, K extends PathsOf<T>> extends Omit<FieldProps<T, K>, 'type'> {
52
+ rows?: number;
53
+ cols?: number;
54
+ maxLength?: number;
55
+ minLength?: number;
56
+ }
57
+ /**
58
+ * Textarea field component.
59
+ *
60
+ * @example
61
+ * <TextareaField form={form} name="bio" label="Bio" rows={4} />
62
+ */
63
+ export declare function TextareaField<T extends Record<string, unknown>, K extends PathsOf<T>>({ form, name, label, placeholder, disabled, required, className, validate, rows, cols, maxLength, minLength, children, }: TextareaFieldProps<T, K>): ReactNode;
64
+ export interface SelectFieldProps<T extends Record<string, unknown>, K extends PathsOf<T>> extends Omit<FieldProps<T, K>, 'type'> {
65
+ options: Array<{
66
+ value: string;
67
+ label: string;
68
+ disabled?: boolean;
69
+ }>;
70
+ multiple?: boolean;
71
+ }
72
+ /**
73
+ * Select field component.
74
+ *
75
+ * @example
76
+ * <SelectField
77
+ * form={form}
78
+ * name="country"
79
+ * label="Country"
80
+ * options={[
81
+ * { value: 'us', label: 'United States' },
82
+ * { value: 'uk', label: 'United Kingdom' },
83
+ * ]}
84
+ * />
85
+ */
86
+ export declare function SelectField<T extends Record<string, unknown>, K extends PathsOf<T>>({ form, name, label, disabled, required, className, validate, options, multiple, placeholder, children, }: SelectFieldProps<T, K>): ReactNode;
87
+ export type { FieldProps, FieldRegistration, FieldState };
88
+ //# sourceMappingURL=field.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../src/field.ts"],"names":[],"mappings":"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"}
package/dist/form.d.ts ADDED
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @ereo/forms - Core Form Store
3
+ *
4
+ * Signal-based form state management for zero re-renders on field changes.
5
+ */
6
+ import { type ReactNode } from 'react';
7
+ import type { FormConfig, FormState, FormStore } from './types';
8
+ /**
9
+ * Create a new form store.
10
+ *
11
+ * @example
12
+ * const form = createForm({
13
+ * initialValues: { email: '', password: '' },
14
+ * schema: z.object({
15
+ * email: z.string().email(),
16
+ * password: z.string().min(8),
17
+ * }),
18
+ * validateOn: 'blur',
19
+ * onSubmit: async (values) => {
20
+ * await api.login(values);
21
+ * },
22
+ * });
23
+ */
24
+ export declare function createForm<T extends Record<string, unknown>>(config: FormConfig<T>): FormStore<T>;
25
+ /**
26
+ * Provide form store to child components.
27
+ */
28
+ export declare function FormProvider<T extends Record<string, unknown>>({ form, children, }: {
29
+ form: FormStore<T>;
30
+ children: ReactNode;
31
+ }): ReactNode;
32
+ /**
33
+ * Get form store from context.
34
+ */
35
+ export declare function useFormContext<T extends Record<string, unknown>>(): FormStore<T> | null;
36
+ /**
37
+ * React hook for using a form store.
38
+ * Creates a new form store or uses an existing one.
39
+ *
40
+ * @example
41
+ * const { register, handleSubmit, isValid } = useForm({
42
+ * initialValues: { email: '' },
43
+ * schema: z.object({ email: z.string().email() }),
44
+ * });
45
+ */
46
+ export declare function useForm<T extends Record<string, unknown>>(config: FormConfig<T>): FormStore<T> & {
47
+ /** Form values (reactive) */
48
+ formValues: T;
49
+ /** Field errors (reactive) */
50
+ fieldErrors: Record<string, string[]>;
51
+ /** Is form valid (reactive) */
52
+ isValid: boolean;
53
+ /** Is form submitting (reactive) */
54
+ isFormSubmitting: boolean;
55
+ /** Is form dirty (reactive) */
56
+ isDirty: boolean;
57
+ };
58
+ export type { FormStore, FormConfig, FormState };
59
+ //# sourceMappingURL=form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../src/form.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EACV,UAAU,EACV,SAAS,EACT,SAAS,EASV,MAAM,SAAS,CAAC;AA23BjB;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1D,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,GACpB,SAAS,CAAC,CAAC,CAAC,CAEd;AAQD;;GAEG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC9D,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB,GAAG,SAAS,CAMZ;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAEvF;AAMD;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvD,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,GACpB,SAAS,CAAC,CAAC,CAAC,GAAG;IAChB,6BAA6B;IAC7B,UAAU,EAAE,CAAC,CAAC;IACd,8BAA8B;IAC9B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACtC,+BAA+B;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,oCAAoC;IACpC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,+BAA+B;IAC/B,OAAO,EAAE,OAAO,CAAC;CAClB,CAiCA;AAGD,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC"}