@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.
- package/dist/a11y.d.ts +52 -0
- package/dist/a11y.d.ts.map +1 -0
- package/dist/accessibility.d.ts +152 -0
- package/dist/accessibility.d.ts.map +1 -0
- package/dist/action-integration.d.ts +104 -0
- package/dist/action-integration.d.ts.map +1 -0
- package/dist/action.d.ts +33 -0
- package/dist/action.d.ts.map +1 -0
- package/dist/adapters.d.ts +25 -0
- package/dist/adapters.d.ts.map +1 -0
- package/dist/array-field.d.ts +49 -0
- package/dist/array-field.d.ts.map +1 -0
- package/dist/components.d.ts +8 -0
- package/dist/components.d.ts.map +1 -0
- package/dist/composition.d.ts +4 -0
- package/dist/composition.d.ts.map +1 -0
- package/dist/context.d.ts +9 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/field.d.ts +88 -0
- package/dist/field.d.ts.map +1 -0
- package/dist/form.d.ts +59 -0
- package/dist/form.d.ts.map +1 -0
- package/dist/hooks.d.ts +13 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2945 -0
- package/dist/proxy.d.ts +3 -0
- package/dist/proxy.d.ts.map +1 -0
- package/dist/schema.d.ts +31 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/store.d.ts +69 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/types.d.ts +243 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils.d.ts +8 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/validation-engine.d.ts +33 -0
- package/dist/validation-engine.d.ts.map +1 -0
- package/dist/validation.d.ts +241 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validators.d.ts +51 -0
- package/dist/validators.d.ts.map +1 -0
- package/dist/wizard.d.ts +52 -0
- package/dist/wizard.d.ts.map +1 -0
- 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"}
|
package/dist/action.d.ts
ADDED
|
@@ -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"}
|
package/dist/field.d.ts
ADDED
|
@@ -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"}
|