@neutro/form 0.0.5 → 0.1.0

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.
@@ -4,7 +4,7 @@
4
4
  */
5
5
  type Primitive = string | number | boolean | null | undefined | Date | File;
6
6
  type Prev = [never, 0, 1, 2, 3, 4, 5, ...any[]];
7
- type PathImpl<T, K extends keyof T, Depth extends number = 5> = [Depth] extends [never] ? never : K extends string ? T[K] extends Primitive ? K : T[K] extends Array<infer U> ? K | `${K}.${number}` | (U extends object ? `${K}.${number}.${PathImpl<U, keyof U, Prev[Depth]>}` : never) : T[K] extends object ? K | `${K}.${PathImpl<T[K], keyof T[K], Prev[Depth]>}` : K : never;
7
+ type PathImpl<T, K extends keyof T, Depth extends number = 5> = [Depth] extends [never] ? never : K extends string ? T[K] extends Primitive ? K : T[K] extends Array<infer U> ? K | `${K}.${number}` | (U extends object ? `${K}.${number}.${PathImpl<U, keyof U, Prev[Depth]>}` : never) : NonNullable<T[K]> extends object ? K | `${K}.${PathImpl<NonNullable<T[K]>, keyof NonNullable<T[K]>, Prev[Depth]>}` : K : never;
8
8
  type Path<T> = PathImpl<T, keyof T> & string;
9
9
  type _GetPathValue<T, P extends string> = P extends `${infer K}.${infer Rest}` ? K extends keyof T ? _GetPathValue<NonNullable<T[K]>, Rest> : T extends readonly any[] ? _GetPathValue<NonNullable<T[number]>, Rest> : unknown : P extends keyof T ? T[P] : T extends readonly any[] ? T[number] : unknown;
10
10
  type GetPathValue<T, P extends string> = _GetPathValue<T, P>;
@@ -17,19 +17,90 @@ interface FormState<T> {
17
17
  isValidating: boolean;
18
18
  }
19
19
  type FormSubscriber<T> = (state: FormState<T>) => void;
20
- type PathSubscriber = (value: any, fieldState: {
20
+ type PathSubscriber<V = any> = (value: V, fieldState: {
21
21
  error?: string;
22
22
  touched?: boolean;
23
23
  dirty?: boolean;
24
24
  }) => void;
25
+ type ValidationMode = 'onChange' | 'onBlur' | 'onTouched' | 'onSubmitOnly';
26
+ type FormAction = {
27
+ type: 'SET';
28
+ path: string;
29
+ value: unknown;
30
+ options?: {
31
+ touch?: boolean;
32
+ validate?: boolean;
33
+ };
34
+ } | {
35
+ type: 'VALIDATE';
36
+ paths?: string[];
37
+ } | {
38
+ type: 'SUBMIT';
39
+ } | {
40
+ type: 'RESET';
41
+ newValues?: unknown;
42
+ } | {
43
+ type: 'SET_ERRORS';
44
+ errors: Record<string, string>;
45
+ } | {
46
+ type: 'CONNECT';
47
+ path: string;
48
+ } | {
49
+ type: 'DISCONNECT';
50
+ path: string;
51
+ } | {
52
+ type: 'BLUR';
53
+ path: string;
54
+ } | {
55
+ type: 'BATCH_START';
56
+ } | {
57
+ type: 'BATCH_END';
58
+ } | {
59
+ type: 'ARRAY_APPEND';
60
+ path: string;
61
+ item: unknown;
62
+ } | {
63
+ type: 'ARRAY_INSERT';
64
+ path: string;
65
+ index: number;
66
+ item: unknown;
67
+ } | {
68
+ type: 'ARRAY_REMOVE';
69
+ path: string;
70
+ index: number;
71
+ } | {
72
+ type: 'ARRAY_MOVE';
73
+ path: string;
74
+ from: number;
75
+ to: number;
76
+ } | {
77
+ type: 'ARRAY_SWAP';
78
+ path: string;
79
+ i: number;
80
+ j: number;
81
+ } | {
82
+ type: 'CLEAR_ERRORS';
83
+ };
84
+ interface AriaPropsOptions {
85
+ required?: boolean;
86
+ errorId?: string;
87
+ }
88
+ interface AriaProps {
89
+ 'aria-invalid': 'true' | 'false';
90
+ 'aria-describedby': string | undefined;
91
+ 'aria-required': true | undefined;
92
+ }
25
93
  interface ConnectOptions {
26
94
  persist?: boolean;
27
95
  format?: (val: string) => string;
96
+ validateOn?: ValidationMode;
28
97
  }
29
98
  interface FormInstance<T extends object> {
30
99
  subscribe: (fn: FormSubscriber<T>) => () => void;
31
- subscribeToPath: (path: Path<T> | string, fn: PathSubscriber) => () => void;
32
- get: (path: Path<T> | string | string[]) => any;
100
+ subscribeToPath<P extends Path<T>>(path: P, fn: PathSubscriber<GetPathValue<T, P>>): () => void;
101
+ subscribeToPath(path: string, fn: PathSubscriber): () => void;
102
+ get<P extends Path<T>>(path: P): GetPathValue<T, P>;
103
+ get(path: string | string[]): any;
33
104
  set: (path: Path<T> | string | string[], val: any, options?: {
34
105
  touch?: boolean;
35
106
  validate?: boolean;
@@ -40,6 +111,7 @@ interface FormInstance<T extends object> {
40
111
  handleSubmit: (onValid: (payload: Partial<T>) => void | Promise<void>, onInvalid?: (errors: Record<string, string>) => void) => (e?: Event) => void;
41
112
  getState: () => FormState<T>;
42
113
  getPayload: () => Partial<T>;
114
+ getAriaProps: (path: Path<T> | string, options?: AriaPropsOptions) => AriaProps;
43
115
  batch: (fn: () => void) => void;
44
116
  arrayAppend: (path: Path<T> | string | string[], item: any) => void;
45
117
  arrayInsert: (path: Path<T> | string | string[], index: number, item: any) => void;
@@ -49,9 +121,18 @@ interface FormInstance<T extends object> {
49
121
  reset: (newValues?: T) => void;
50
122
  getConnectedCount: () => number;
51
123
  destroy: () => void;
124
+ setErrors: (errors: Record<Path<T> | (string & {}), string>) => void;
125
+ clearErrors: () => void;
126
+ /**
127
+ * Returns the effective ValidationMode for a field. Useful for debugging
128
+ * validation timing; framework adapters should rely on this only in custom
129
+ * event handlers, not in render logic.
130
+ */
131
+ getFieldMode: (path: string) => ValidationMode;
132
+ _subscribeToActions: (fn: (action: FormAction, state: FormState<T>) => void) => () => void;
52
133
  }
53
134
 
54
- declare function useForm<T extends object>(form: FormInstance<T>): FormState<T> & Omit<FormInstance<T>, 'subscribe' | 'getState'>;
135
+ declare function useForm<T extends object>(form: FormInstance<T>): FormState<T> & Omit<FormInstance<T>, 'subscribe' | 'getState' | '_subscribeToActions'>;
55
136
  declare function useFormPath<T extends object, P extends Path<T>>(form: FormInstance<T>, path: P): GetPathValue<T, P>;
56
137
  declare function useFormConnect(form: any): (path: string, options?: any) => (el: HTMLElement | null) => void;
57
138
 
@@ -1,5 +1,5 @@
1
1
  // ../adapters/react/dist/index.js
2
- import { useSyncExternalStore, useCallback, useRef } from "react";
2
+ import { useCallback, useRef, useSyncExternalStore } from "react";
3
3
  function useForm(form) {
4
4
  const state = useSyncExternalStore(form.subscribe, form.getState, form.getState);
5
5
  return {
@@ -14,13 +14,17 @@ function useForm(form) {
14
14
  subscribeToPath: form.subscribeToPath,
15
15
  validate: form.validate,
16
16
  getPayload: form.getPayload,
17
+ getAriaProps: form.getAriaProps,
18
+ getFieldMode: form.getFieldMode,
17
19
  getConnectedCount: form.getConnectedCount,
18
20
  destroy: form.destroy,
19
21
  arrayAppend: form.arrayAppend,
20
22
  arrayInsert: form.arrayInsert,
21
23
  arrayRemove: form.arrayRemove,
22
24
  arrayMove: form.arrayMove,
23
- arraySwap: form.arraySwap
25
+ arraySwap: form.arraySwap,
26
+ setErrors: form.setErrors,
27
+ clearErrors: form.clearErrors
24
28
  };
25
29
  }
26
30
  function useFormPath(form, path) {
@@ -44,18 +44,27 @@ function useSolidForm(form) {
44
44
  handleSubmit: form.handleSubmit,
45
45
  reset: form.reset,
46
46
  batch: form.batch,
47
+ validate: form.validate,
48
+ subscribeToPath: form.subscribeToPath,
49
+ getPayload: form.getPayload,
50
+ getAriaProps: form.getAriaProps,
51
+ getFieldMode: form.getFieldMode,
52
+ getConnectedCount: form.getConnectedCount,
53
+ destroy: form.destroy,
47
54
  arrayAppend: form.arrayAppend,
48
55
  arrayInsert: form.arrayInsert,
49
56
  arrayRemove: form.arrayRemove,
50
57
  arrayMove: form.arrayMove,
51
- arraySwap: form.arraySwap
58
+ arraySwap: form.arraySwap,
59
+ setErrors: form.setErrors,
60
+ clearErrors: form.clearErrors
52
61
  }
53
62
  ];
54
63
  }
55
64
  function useSolidFormPath(form, path) {
56
- const [value, setValue] = (0, import_solid_js.createSignal)(form.get(path()));
65
+ const [value, setValue] = (0, import_solid_js.createSignal)(form.get(path));
57
66
  const [fieldState, setFieldState] = (0, import_solid_js.createSignal)(null);
58
- const unsubscribe = form.subscribeToPath(path(), (v, fs) => {
67
+ const unsubscribe = form.subscribeToPath(path, (v, fs) => {
59
68
  setValue(() => v);
60
69
  setFieldState(() => fs);
61
70
  });
@@ -1,20 +1,165 @@
1
1
  import * as solid_js from 'solid-js';
2
+ import { Store } from 'solid-js/store';
2
3
 
3
- declare function useSolidForm<T extends object>(form: any): readonly [any, {
4
- readonly get: any;
5
- readonly set: any;
6
- readonly connect: any;
7
- readonly submit: any;
8
- readonly handleSubmit: any;
9
- readonly reset: any;
10
- readonly batch: any;
11
- readonly arrayAppend: any;
12
- readonly arrayInsert: any;
13
- readonly arrayRemove: any;
14
- readonly arrayMove: any;
15
- readonly arraySwap: any;
16
- }];
17
- declare function useSolidFormPath(form: any, path: () => string): {
4
+ /**
5
+ * @neutro/form-core
6
+ * High-Performance, Zero-Dependency, Framework-Agnostic Reactive Form Engine.
7
+ */
8
+ type Primitive = string | number | boolean | null | undefined | Date | File;
9
+ type Prev = [never, 0, 1, 2, 3, 4, 5, ...any[]];
10
+ type PathImpl<T, K extends keyof T, Depth extends number = 5> = [Depth] extends [never] ? never : K extends string ? T[K] extends Primitive ? K : T[K] extends Array<infer U> ? K | `${K}.${number}` | (U extends object ? `${K}.${number}.${PathImpl<U, keyof U, Prev[Depth]>}` : never) : NonNullable<T[K]> extends object ? K | `${K}.${PathImpl<NonNullable<T[K]>, keyof NonNullable<T[K]>, Prev[Depth]>}` : K : never;
11
+ type Path<T> = PathImpl<T, keyof T> & string;
12
+ type _GetPathValue<T, P extends string> = P extends `${infer K}.${infer Rest}` ? K extends keyof T ? _GetPathValue<NonNullable<T[K]>, Rest> : T extends readonly any[] ? _GetPathValue<NonNullable<T[number]>, Rest> : unknown : P extends keyof T ? T[P] : T extends readonly any[] ? T[number] : unknown;
13
+ type GetPathValue<T, P extends string> = _GetPathValue<T, P>;
14
+ interface FormState<T> {
15
+ values: T;
16
+ errors: Record<string, string>;
17
+ touched: Record<string, boolean>;
18
+ dirty: Record<string, boolean>;
19
+ isSubmitting: boolean;
20
+ isValidating: boolean;
21
+ }
22
+ type FormSubscriber<T> = (state: FormState<T>) => void;
23
+ type PathSubscriber<V = any> = (value: V, fieldState: {
24
+ error?: string;
25
+ touched?: boolean;
26
+ dirty?: boolean;
27
+ }) => void;
28
+ type ValidationMode = 'onChange' | 'onBlur' | 'onTouched' | 'onSubmitOnly';
29
+ type FormAction = {
30
+ type: 'SET';
31
+ path: string;
32
+ value: unknown;
33
+ options?: {
34
+ touch?: boolean;
35
+ validate?: boolean;
36
+ };
37
+ } | {
38
+ type: 'VALIDATE';
39
+ paths?: string[];
40
+ } | {
41
+ type: 'SUBMIT';
42
+ } | {
43
+ type: 'RESET';
44
+ newValues?: unknown;
45
+ } | {
46
+ type: 'SET_ERRORS';
47
+ errors: Record<string, string>;
48
+ } | {
49
+ type: 'CONNECT';
50
+ path: string;
51
+ } | {
52
+ type: 'DISCONNECT';
53
+ path: string;
54
+ } | {
55
+ type: 'BLUR';
56
+ path: string;
57
+ } | {
58
+ type: 'BATCH_START';
59
+ } | {
60
+ type: 'BATCH_END';
61
+ } | {
62
+ type: 'ARRAY_APPEND';
63
+ path: string;
64
+ item: unknown;
65
+ } | {
66
+ type: 'ARRAY_INSERT';
67
+ path: string;
68
+ index: number;
69
+ item: unknown;
70
+ } | {
71
+ type: 'ARRAY_REMOVE';
72
+ path: string;
73
+ index: number;
74
+ } | {
75
+ type: 'ARRAY_MOVE';
76
+ path: string;
77
+ from: number;
78
+ to: number;
79
+ } | {
80
+ type: 'ARRAY_SWAP';
81
+ path: string;
82
+ i: number;
83
+ j: number;
84
+ } | {
85
+ type: 'CLEAR_ERRORS';
86
+ };
87
+ interface AriaPropsOptions {
88
+ required?: boolean;
89
+ errorId?: string;
90
+ }
91
+ interface AriaProps {
92
+ 'aria-invalid': 'true' | 'false';
93
+ 'aria-describedby': string | undefined;
94
+ 'aria-required': true | undefined;
95
+ }
96
+ interface ConnectOptions {
97
+ persist?: boolean;
98
+ format?: (val: string) => string;
99
+ validateOn?: ValidationMode;
100
+ }
101
+ interface FormInstance<T extends object> {
102
+ subscribe: (fn: FormSubscriber<T>) => () => void;
103
+ subscribeToPath<P extends Path<T>>(path: P, fn: PathSubscriber<GetPathValue<T, P>>): () => void;
104
+ subscribeToPath(path: string, fn: PathSubscriber): () => void;
105
+ get<P extends Path<T>>(path: P): GetPathValue<T, P>;
106
+ get(path: string | string[]): any;
107
+ set: (path: Path<T> | string | string[], val: any, options?: {
108
+ touch?: boolean;
109
+ validate?: boolean;
110
+ }) => void;
111
+ validate: (scopePaths?: Path<T>[] | string[] | string[][]) => Promise<boolean>;
112
+ connect: (path: Path<T> | string, el: HTMLElement, options?: ConnectOptions) => () => void;
113
+ submit: (onValid: (payload: Partial<T>) => void | Promise<void>) => Promise<boolean>;
114
+ handleSubmit: (onValid: (payload: Partial<T>) => void | Promise<void>, onInvalid?: (errors: Record<string, string>) => void) => (e?: Event) => void;
115
+ getState: () => FormState<T>;
116
+ getPayload: () => Partial<T>;
117
+ getAriaProps: (path: Path<T> | string, options?: AriaPropsOptions) => AriaProps;
118
+ batch: (fn: () => void) => void;
119
+ arrayAppend: (path: Path<T> | string | string[], item: any) => void;
120
+ arrayInsert: (path: Path<T> | string | string[], index: number, item: any) => void;
121
+ arrayRemove: (path: Path<T> | string | string[], index: number) => void;
122
+ arrayMove: (path: Path<T> | string | string[], fromIndex: number, toIndex: number) => void;
123
+ arraySwap: (path: Path<T> | string | string[], indexA: number, indexB: number) => void;
124
+ reset: (newValues?: T) => void;
125
+ getConnectedCount: () => number;
126
+ destroy: () => void;
127
+ setErrors: (errors: Record<Path<T> | (string & {}), string>) => void;
128
+ clearErrors: () => void;
129
+ /**
130
+ * Returns the effective ValidationMode for a field. Useful for debugging
131
+ * validation timing; framework adapters should rely on this only in custom
132
+ * event handlers, not in render logic.
133
+ */
134
+ getFieldMode: (path: string) => ValidationMode;
135
+ _subscribeToActions: (fn: (action: FormAction, state: FormState<T>) => void) => () => void;
136
+ }
137
+
138
+ interface SolidFormActions<T extends object> {
139
+ get: FormInstance<T>['get'];
140
+ set: FormInstance<T>['set'];
141
+ connect: FormInstance<T>['connect'];
142
+ submit: FormInstance<T>['submit'];
143
+ handleSubmit: FormInstance<T>['handleSubmit'];
144
+ reset: FormInstance<T>['reset'];
145
+ batch: FormInstance<T>['batch'];
146
+ validate: FormInstance<T>['validate'];
147
+ subscribeToPath: FormInstance<T>['subscribeToPath'];
148
+ getPayload: FormInstance<T>['getPayload'];
149
+ getAriaProps: FormInstance<T>['getAriaProps'];
150
+ getFieldMode: FormInstance<T>['getFieldMode'];
151
+ getConnectedCount: FormInstance<T>['getConnectedCount'];
152
+ destroy: FormInstance<T>['destroy'];
153
+ arrayAppend: FormInstance<T>['arrayAppend'];
154
+ arrayInsert: FormInstance<T>['arrayInsert'];
155
+ arrayRemove: FormInstance<T>['arrayRemove'];
156
+ arrayMove: FormInstance<T>['arrayMove'];
157
+ arraySwap: FormInstance<T>['arraySwap'];
158
+ setErrors: FormInstance<T>['setErrors'];
159
+ clearErrors: FormInstance<T>['clearErrors'];
160
+ }
161
+ declare function useSolidForm<T extends object>(form: FormInstance<T>): [Store<FormState<T>>, SolidFormActions<T>];
162
+ declare function useSolidFormPath<T extends object>(form: FormInstance<T>, path: string): {
18
163
  value: solid_js.Accessor<unknown>;
19
164
  fieldState: solid_js.Accessor<{
20
165
  error?: string;
@@ -23,4 +168,4 @@ declare function useSolidFormPath(form: any, path: () => string): {
23
168
  } | null>;
24
169
  };
25
170
 
26
- export { useSolidForm, useSolidFormPath };
171
+ export { type SolidFormActions, useSolidForm, useSolidFormPath };
@@ -1,20 +1,165 @@
1
1
  import * as solid_js from 'solid-js';
2
+ import { Store } from 'solid-js/store';
2
3
 
3
- declare function useSolidForm<T extends object>(form: any): readonly [any, {
4
- readonly get: any;
5
- readonly set: any;
6
- readonly connect: any;
7
- readonly submit: any;
8
- readonly handleSubmit: any;
9
- readonly reset: any;
10
- readonly batch: any;
11
- readonly arrayAppend: any;
12
- readonly arrayInsert: any;
13
- readonly arrayRemove: any;
14
- readonly arrayMove: any;
15
- readonly arraySwap: any;
16
- }];
17
- declare function useSolidFormPath(form: any, path: () => string): {
4
+ /**
5
+ * @neutro/form-core
6
+ * High-Performance, Zero-Dependency, Framework-Agnostic Reactive Form Engine.
7
+ */
8
+ type Primitive = string | number | boolean | null | undefined | Date | File;
9
+ type Prev = [never, 0, 1, 2, 3, 4, 5, ...any[]];
10
+ type PathImpl<T, K extends keyof T, Depth extends number = 5> = [Depth] extends [never] ? never : K extends string ? T[K] extends Primitive ? K : T[K] extends Array<infer U> ? K | `${K}.${number}` | (U extends object ? `${K}.${number}.${PathImpl<U, keyof U, Prev[Depth]>}` : never) : NonNullable<T[K]> extends object ? K | `${K}.${PathImpl<NonNullable<T[K]>, keyof NonNullable<T[K]>, Prev[Depth]>}` : K : never;
11
+ type Path<T> = PathImpl<T, keyof T> & string;
12
+ type _GetPathValue<T, P extends string> = P extends `${infer K}.${infer Rest}` ? K extends keyof T ? _GetPathValue<NonNullable<T[K]>, Rest> : T extends readonly any[] ? _GetPathValue<NonNullable<T[number]>, Rest> : unknown : P extends keyof T ? T[P] : T extends readonly any[] ? T[number] : unknown;
13
+ type GetPathValue<T, P extends string> = _GetPathValue<T, P>;
14
+ interface FormState<T> {
15
+ values: T;
16
+ errors: Record<string, string>;
17
+ touched: Record<string, boolean>;
18
+ dirty: Record<string, boolean>;
19
+ isSubmitting: boolean;
20
+ isValidating: boolean;
21
+ }
22
+ type FormSubscriber<T> = (state: FormState<T>) => void;
23
+ type PathSubscriber<V = any> = (value: V, fieldState: {
24
+ error?: string;
25
+ touched?: boolean;
26
+ dirty?: boolean;
27
+ }) => void;
28
+ type ValidationMode = 'onChange' | 'onBlur' | 'onTouched' | 'onSubmitOnly';
29
+ type FormAction = {
30
+ type: 'SET';
31
+ path: string;
32
+ value: unknown;
33
+ options?: {
34
+ touch?: boolean;
35
+ validate?: boolean;
36
+ };
37
+ } | {
38
+ type: 'VALIDATE';
39
+ paths?: string[];
40
+ } | {
41
+ type: 'SUBMIT';
42
+ } | {
43
+ type: 'RESET';
44
+ newValues?: unknown;
45
+ } | {
46
+ type: 'SET_ERRORS';
47
+ errors: Record<string, string>;
48
+ } | {
49
+ type: 'CONNECT';
50
+ path: string;
51
+ } | {
52
+ type: 'DISCONNECT';
53
+ path: string;
54
+ } | {
55
+ type: 'BLUR';
56
+ path: string;
57
+ } | {
58
+ type: 'BATCH_START';
59
+ } | {
60
+ type: 'BATCH_END';
61
+ } | {
62
+ type: 'ARRAY_APPEND';
63
+ path: string;
64
+ item: unknown;
65
+ } | {
66
+ type: 'ARRAY_INSERT';
67
+ path: string;
68
+ index: number;
69
+ item: unknown;
70
+ } | {
71
+ type: 'ARRAY_REMOVE';
72
+ path: string;
73
+ index: number;
74
+ } | {
75
+ type: 'ARRAY_MOVE';
76
+ path: string;
77
+ from: number;
78
+ to: number;
79
+ } | {
80
+ type: 'ARRAY_SWAP';
81
+ path: string;
82
+ i: number;
83
+ j: number;
84
+ } | {
85
+ type: 'CLEAR_ERRORS';
86
+ };
87
+ interface AriaPropsOptions {
88
+ required?: boolean;
89
+ errorId?: string;
90
+ }
91
+ interface AriaProps {
92
+ 'aria-invalid': 'true' | 'false';
93
+ 'aria-describedby': string | undefined;
94
+ 'aria-required': true | undefined;
95
+ }
96
+ interface ConnectOptions {
97
+ persist?: boolean;
98
+ format?: (val: string) => string;
99
+ validateOn?: ValidationMode;
100
+ }
101
+ interface FormInstance<T extends object> {
102
+ subscribe: (fn: FormSubscriber<T>) => () => void;
103
+ subscribeToPath<P extends Path<T>>(path: P, fn: PathSubscriber<GetPathValue<T, P>>): () => void;
104
+ subscribeToPath(path: string, fn: PathSubscriber): () => void;
105
+ get<P extends Path<T>>(path: P): GetPathValue<T, P>;
106
+ get(path: string | string[]): any;
107
+ set: (path: Path<T> | string | string[], val: any, options?: {
108
+ touch?: boolean;
109
+ validate?: boolean;
110
+ }) => void;
111
+ validate: (scopePaths?: Path<T>[] | string[] | string[][]) => Promise<boolean>;
112
+ connect: (path: Path<T> | string, el: HTMLElement, options?: ConnectOptions) => () => void;
113
+ submit: (onValid: (payload: Partial<T>) => void | Promise<void>) => Promise<boolean>;
114
+ handleSubmit: (onValid: (payload: Partial<T>) => void | Promise<void>, onInvalid?: (errors: Record<string, string>) => void) => (e?: Event) => void;
115
+ getState: () => FormState<T>;
116
+ getPayload: () => Partial<T>;
117
+ getAriaProps: (path: Path<T> | string, options?: AriaPropsOptions) => AriaProps;
118
+ batch: (fn: () => void) => void;
119
+ arrayAppend: (path: Path<T> | string | string[], item: any) => void;
120
+ arrayInsert: (path: Path<T> | string | string[], index: number, item: any) => void;
121
+ arrayRemove: (path: Path<T> | string | string[], index: number) => void;
122
+ arrayMove: (path: Path<T> | string | string[], fromIndex: number, toIndex: number) => void;
123
+ arraySwap: (path: Path<T> | string | string[], indexA: number, indexB: number) => void;
124
+ reset: (newValues?: T) => void;
125
+ getConnectedCount: () => number;
126
+ destroy: () => void;
127
+ setErrors: (errors: Record<Path<T> | (string & {}), string>) => void;
128
+ clearErrors: () => void;
129
+ /**
130
+ * Returns the effective ValidationMode for a field. Useful for debugging
131
+ * validation timing; framework adapters should rely on this only in custom
132
+ * event handlers, not in render logic.
133
+ */
134
+ getFieldMode: (path: string) => ValidationMode;
135
+ _subscribeToActions: (fn: (action: FormAction, state: FormState<T>) => void) => () => void;
136
+ }
137
+
138
+ interface SolidFormActions<T extends object> {
139
+ get: FormInstance<T>['get'];
140
+ set: FormInstance<T>['set'];
141
+ connect: FormInstance<T>['connect'];
142
+ submit: FormInstance<T>['submit'];
143
+ handleSubmit: FormInstance<T>['handleSubmit'];
144
+ reset: FormInstance<T>['reset'];
145
+ batch: FormInstance<T>['batch'];
146
+ validate: FormInstance<T>['validate'];
147
+ subscribeToPath: FormInstance<T>['subscribeToPath'];
148
+ getPayload: FormInstance<T>['getPayload'];
149
+ getAriaProps: FormInstance<T>['getAriaProps'];
150
+ getFieldMode: FormInstance<T>['getFieldMode'];
151
+ getConnectedCount: FormInstance<T>['getConnectedCount'];
152
+ destroy: FormInstance<T>['destroy'];
153
+ arrayAppend: FormInstance<T>['arrayAppend'];
154
+ arrayInsert: FormInstance<T>['arrayInsert'];
155
+ arrayRemove: FormInstance<T>['arrayRemove'];
156
+ arrayMove: FormInstance<T>['arrayMove'];
157
+ arraySwap: FormInstance<T>['arraySwap'];
158
+ setErrors: FormInstance<T>['setErrors'];
159
+ clearErrors: FormInstance<T>['clearErrors'];
160
+ }
161
+ declare function useSolidForm<T extends object>(form: FormInstance<T>): [Store<FormState<T>>, SolidFormActions<T>];
162
+ declare function useSolidFormPath<T extends object>(form: FormInstance<T>, path: string): {
18
163
  value: solid_js.Accessor<unknown>;
19
164
  fieldState: solid_js.Accessor<{
20
165
  error?: string;
@@ -23,4 +168,4 @@ declare function useSolidFormPath(form: any, path: () => string): {
23
168
  } | null>;
24
169
  };
25
170
 
26
- export { useSolidForm, useSolidFormPath };
171
+ export { type SolidFormActions, useSolidForm, useSolidFormPath };
@@ -17,18 +17,27 @@ function useSolidForm(form) {
17
17
  handleSubmit: form.handleSubmit,
18
18
  reset: form.reset,
19
19
  batch: form.batch,
20
+ validate: form.validate,
21
+ subscribeToPath: form.subscribeToPath,
22
+ getPayload: form.getPayload,
23
+ getAriaProps: form.getAriaProps,
24
+ getFieldMode: form.getFieldMode,
25
+ getConnectedCount: form.getConnectedCount,
26
+ destroy: form.destroy,
20
27
  arrayAppend: form.arrayAppend,
21
28
  arrayInsert: form.arrayInsert,
22
29
  arrayRemove: form.arrayRemove,
23
30
  arrayMove: form.arrayMove,
24
- arraySwap: form.arraySwap
31
+ arraySwap: form.arraySwap,
32
+ setErrors: form.setErrors,
33
+ clearErrors: form.clearErrors
25
34
  }
26
35
  ];
27
36
  }
28
37
  function useSolidFormPath(form, path) {
29
- const [value, setValue] = createSignal(form.get(path()));
38
+ const [value, setValue] = createSignal(form.get(path));
30
39
  const [fieldState, setFieldState] = createSignal(null);
31
- const unsubscribe = form.subscribeToPath(path(), (v, fs) => {
40
+ const unsubscribe = form.subscribeToPath(path, (v, fs) => {
32
41
  setValue(() => v);
33
42
  setFieldState(() => fs);
34
43
  });
@@ -28,10 +28,10 @@ module.exports = __toCommonJS(svelte_exports);
28
28
  // ../adapters/svelte/dist/index.js
29
29
  var import_store = require("svelte/store");
30
30
  function useSvelteForm(form) {
31
- const state = (0, import_store.readable)(
32
- form.getState(),
33
- (set) => form.subscribe((s) => set(s))
34
- );
31
+ const state = (0, import_store.readable)(form.getState(), (set) => {
32
+ set(form.getState());
33
+ return form.subscribe((s) => set(s));
34
+ });
35
35
  return {
36
36
  state,
37
37
  get: form.get,
@@ -41,18 +41,27 @@ function useSvelteForm(form) {
41
41
  handleSubmit: form.handleSubmit,
42
42
  reset: form.reset,
43
43
  batch: form.batch,
44
+ validate: form.validate,
45
+ subscribeToPath: form.subscribeToPath,
46
+ getPayload: form.getPayload,
47
+ getAriaProps: form.getAriaProps,
48
+ getFieldMode: form.getFieldMode,
49
+ getConnectedCount: form.getConnectedCount,
50
+ destroy: form.destroy,
44
51
  arrayAppend: form.arrayAppend,
45
52
  arrayInsert: form.arrayInsert,
46
53
  arrayRemove: form.arrayRemove,
47
54
  arrayMove: form.arrayMove,
48
- arraySwap: form.arraySwap
55
+ arraySwap: form.arraySwap,
56
+ setErrors: form.setErrors,
57
+ clearErrors: form.clearErrors
49
58
  };
50
59
  }
51
60
  function useSvelteFormPath(form, path) {
52
- const field = (0, import_store.readable)(
53
- { value: form.get(path), fieldState: null },
54
- (set) => form.subscribeToPath(path, (v, fs) => set({ value: v, fieldState: fs }))
55
- );
61
+ const field = (0, import_store.readable)({ value: form.get(path), fieldState: null }, (set) => {
62
+ set({ value: form.get(path), fieldState: null });
63
+ return form.subscribeToPath(path, (v, fs) => set({ value: v, fieldState: fs }));
64
+ });
56
65
  return field;
57
66
  }
58
67
  // Annotate the CommonJS export names for ESM import in node: