what-core 0.4.2 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -1,46 +1,46 @@
1
1
  // What Framework - TypeScript Definitions
2
2
 
3
+ export type Updater<T> = T | ((prev: T) => T);
4
+
3
5
  // --- Reactive Primitives ---
4
6
 
5
- /** A reactive value container */
6
7
  export interface Signal<T> {
7
- /** Read the current value (tracks dependency if inside effect) */
8
+ /** Read current value */
8
9
  (): T;
9
- /** Update the value */
10
- set(value: T | ((prev: T) => T)): void;
11
- /** Read without tracking */
10
+ /** Callable setter compatibility: sig(next) */
11
+ (value: Updater<T>): void;
12
+ /** Setter method compatibility: sig.set(next) */
13
+ set(value: Updater<T>): void;
14
+ /** Read without dependency tracking */
12
15
  peek(): T;
13
- /** Subscribe to changes */
16
+ /** Subscribe to value changes */
14
17
  subscribe(fn: (value: T) => void): () => void;
15
- /** Internal marker */
16
18
  _signal: true;
17
19
  }
18
20
 
19
- /** Create a reactive signal */
20
- export function signal<T>(initial: T): Signal<T>;
21
-
22
- /** A derived reactive value (lazy evaluation) */
23
21
  export interface Computed<T> {
24
22
  (): T;
25
23
  peek(): T;
26
24
  _signal: true;
27
25
  }
28
26
 
29
- /** Create a computed signal */
27
+ export function signal<T>(initial: T): Signal<T>;
30
28
  export function computed<T>(fn: () => T): Computed<T>;
31
-
32
- /** Create a side effect that re-runs when dependencies change */
33
- export function effect(fn: () => void | (() => void)): () => void;
34
-
35
- /** Batch multiple signal updates into one flush */
29
+ export function effect(fn: () => void | (() => void), opts?: { stable?: boolean }): () => void;
30
+ export function signalMemo<T>(fn: () => T): Computed<T>;
36
31
  export function batch<T>(fn: () => T): T;
37
-
38
- /** Read signals without subscribing */
39
32
  export function untrack<T>(fn: () => T): T;
33
+ export function flushSync(): void;
34
+ export function createRoot<T>(fn: (dispose: () => void) => T): T;
40
35
 
41
36
  // --- Virtual DOM ---
42
37
 
43
- export interface VNode<P = any> {
38
+ export type PrimitiveChild = string | number | boolean | null | undefined;
39
+ export type VNodeChild = PrimitiveChild | VNode | (() => VNodeChild) | VNodeChild[];
40
+
41
+ export type Component<P = {}> = (props: P & { children?: VNodeChild }) => VNodeChild;
42
+
43
+ export interface VNode<P = Record<string, any>> {
44
44
  tag: string | Component<P>;
45
45
  props: P;
46
46
  children: VNodeChild[];
@@ -48,115 +48,107 @@ export interface VNode<P = any> {
48
48
  _vnode: true;
49
49
  }
50
50
 
51
- export type VNodeChild = VNode | string | number | boolean | null | undefined | VNodeChild[];
52
-
53
- export type Component<P = {}> = (props: P & { children?: VNodeChild }) => VNode | VNodeChild;
54
-
55
- /** Create a virtual DOM node */
56
- export function h<P extends {}>(
51
+ export function h<P extends Record<string, any>>(
57
52
  tag: string | Component<P>,
58
53
  props?: P | null,
59
54
  ...children: VNodeChild[]
60
55
  ): VNode<P>;
61
56
 
62
- /** Fragment component */
63
57
  export function Fragment(props: { children?: VNodeChild }): VNodeChild;
64
-
65
- /** Tagged template for JSX-like syntax without build step */
66
58
  export function html(strings: TemplateStringsArray, ...values: any[]): VNode | VNode[];
67
59
 
68
- // --- DOM Mounting ---
60
+ // --- DOM ---
69
61
 
70
- /** Mount a VNode tree into a container */
71
- export function mount(vnode: VNode, container: string | Element): () => void;
62
+ export function mount(vnode: VNodeChild, container: string | Element): () => void;
72
63
 
73
- // --- Hooks ---
64
+ // Fine-grained rendering primitives
65
+ export function template(html: string): () => Element;
66
+ export function insert(parent: Node, child: any, marker?: Node | null): any;
67
+ export function mapArray<T>(
68
+ source: () => T[],
69
+ mapFn: (item: T | Signal<T>, index: number) => Node,
70
+ options?: { key?: (item: T) => string | number; raw?: boolean },
71
+ ): (parent: Node, marker?: Node | null) => Node;
72
+ export function spread(el: Element, props: Record<string, any>): void;
73
+ export function setProp(el: Element, key: string, value: any): void;
74
+ export function delegateEvents(eventNames: string[]): void;
75
+ export function on(el: Element, event: string, handler: (e: Event) => void): () => void;
76
+ export function classList(el: Element, classes: Record<string, boolean | (() => boolean)>): void;
74
77
 
75
- /** State hook - returns [value, setter] */
76
- export function useState<T>(initial: T | (() => T)): [T, (value: T | ((prev: T) => T)) => void];
78
+ // --- Hooks ---
77
79
 
78
- /** Signal hook - returns raw signal */
80
+ export function useState<T>(initial: T | (() => T)): [T, (value: Updater<T>) => void];
79
81
  export function useSignal<T>(initial: T | (() => T)): Signal<T>;
80
-
81
- /** Computed hook */
82
82
  export function useComputed<T>(fn: () => T): Computed<T>;
83
-
84
- /** Effect hook with optional dependencies */
85
- export function useEffect(fn: () => void | (() => void), deps?: any[]): void;
86
-
87
- /** Memoized value hook */
88
- export function useMemo<T>(fn: () => T, deps: any[]): T;
89
-
90
- /** Memoized callback hook */
91
- export function useCallback<T extends (...args: any[]) => any>(fn: T, deps: any[]): T;
92
-
93
- /** Ref hook */
83
+ export function useEffect(fn: () => void | (() => void), deps?: unknown[]): void;
84
+ export function useMemo<T>(fn: () => T, deps?: unknown[]): T;
85
+ export function useCallback<T extends (...args: any[]) => any>(fn: T, deps?: unknown[]): T;
94
86
  export function useRef<T>(initial: T): { current: T };
95
87
 
96
- /** Context hook */
97
- export function useContext<T>(context: Context<T>): T;
98
-
99
- /** Reducer hook */
100
- export function useReducer<S, A>(
101
- reducer: (state: S, action: A) => S,
102
- initialState: S,
103
- init?: (initial: S) => S
104
- ): [S, (action: A) => void];
105
-
106
- /** Create a context */
107
88
  export interface Context<T> {
108
- _value: T;
89
+ _defaultValue: T;
109
90
  Provider: Component<{ value: T; children?: VNodeChild }>;
110
91
  }
111
92
 
112
93
  export function createContext<T>(defaultValue: T): Context<T>;
94
+ export function useContext<T>(context: Context<T>): T;
95
+ export function useReducer<S, A>(
96
+ reducer: (state: S, action: A) => S,
97
+ initialState: S,
98
+ init?: (initial: S) => S,
99
+ ): [S, (action: A) => void];
100
+ export function onMount(fn: () => void): void;
101
+ export function onCleanup(fn: () => void): void;
113
102
 
114
- // --- Component Utilities ---
103
+ export function createResource<T = any, S = any>(
104
+ fetcher: (source?: S, ctx?: { signal: AbortSignal }) => Promise<T> | T,
105
+ options?: { initialValue?: T; source?: S },
106
+ ): [Signal<T | null>, {
107
+ loading: Signal<boolean>;
108
+ error: Signal<any>;
109
+ refetch: (source?: S) => Promise<any>;
110
+ mutate: (value: Updater<T | null>) => void;
111
+ }];
115
112
 
116
- /** Skip re-render if props are equal */
117
- export function memo<P>(
118
- component: Component<P>,
119
- areEqual?: (prev: P, next: P) => boolean
120
- ): Component<P>;
113
+ // --- Components ---
121
114
 
122
- /** Lazy-load a component */
123
115
  export function lazy<P>(
124
- loader: () => Promise<{ default: Component<P> } | Component<P>>
116
+ loader: () => Promise<{ default: Component<P> } | Component<P>>,
125
117
  ): Component<P>;
118
+ export function memo<P>(component: Component<P>, areEqual?: (prev: P, next: P) => boolean): Component<P>;
126
119
 
127
- /** Suspense boundary for lazy components */
128
120
  export function Suspense(props: {
129
121
  fallback: VNodeChild;
130
122
  children?: VNodeChild;
131
123
  }): VNode;
132
124
 
133
- /** Error boundary for catching component errors */
134
125
  export function ErrorBoundary(props: {
135
- fallback: VNodeChild | ((props: { error: Error; reset: () => void }) => VNodeChild);
126
+ fallback: VNodeChild | ((args: { error: Error; reset: () => void }) => VNodeChild);
136
127
  onError?: (error: Error) => void;
137
128
  children?: VNodeChild;
138
129
  }): VNode;
139
130
 
140
- // --- Store ---
141
-
142
- export interface StoreDefinition {
143
- [key: string]: any;
144
- }
145
-
146
- export type Store<T extends StoreDefinition> = {
147
- [K in keyof T]: T[K] extends (...args: any[]) => any ? T[K] : T[K];
148
- };
149
-
150
- /** Mark a function as a computed property in a store definition */
151
- export function storeComputed<T>(fn: (state: any) => T): (state: any) => T;
131
+ export function Show(props: {
132
+ when: boolean | (() => boolean);
133
+ fallback?: VNodeChild;
134
+ children?: VNodeChild;
135
+ }): VNodeChild;
152
136
 
153
- /** Create a global reactive store */
154
- export function createStore<T extends StoreDefinition>(definition: T): () => Store<T>;
137
+ export function For<T>(props: {
138
+ each: T[] | (() => T[]);
139
+ fallback?: VNodeChild;
140
+ children: ((item: T, index: number) => VNodeChild) | VNodeChild;
141
+ }): VNodeChild;
155
142
 
156
- /** Create a simple global atom */
157
- export function atom<T>(initial: T): Signal<T>;
143
+ export function Switch(props: {
144
+ fallback?: VNodeChild;
145
+ children?: VNodeChild;
146
+ }): VNodeChild;
158
147
 
159
- // --- Island ---
148
+ export function Match(props: {
149
+ when: boolean | (() => boolean);
150
+ children?: VNodeChild;
151
+ }): VNode;
160
152
 
161
153
  export interface IslandProps {
162
154
  component: Component<any>;
@@ -165,103 +157,351 @@ export interface IslandProps {
165
157
  [key: string]: any;
166
158
  }
167
159
 
168
- /** Island component for deferred hydration */
169
160
  export function Island(props: IslandProps): VNode;
170
161
 
171
- // --- Utilities ---
162
+ // --- State ---
172
163
 
173
- /** Conditional rendering helper */
174
- export function show<T extends VNodeChild>(condition: boolean, vnode: T, fallback?: VNodeChild): T | VNodeChild;
164
+ export type DerivedFn<T> = ((state: any) => T) & { _isDerived: true };
165
+ export function derived<T>(fn: (state: any) => T): DerivedFn<T>;
166
+ export function storeComputed<T>(fn: (state: any) => T): DerivedFn<T>;
167
+ export type StoreDefinition = Record<string, any>;
168
+ export type Store<T extends StoreDefinition> = T;
169
+ export function createStore<T extends StoreDefinition>(definition: T): () => Store<T>;
170
+ export function atom<T>(initial: T): Signal<T>;
171
+
172
+ // --- Helpers / Utilities ---
175
173
 
176
- /** List rendering helper with optional key function */
177
174
  export function each<T>(
178
175
  list: T[],
179
- fn: (item: T, index: number) => VNode,
180
- keyFn?: (item: T, index: number) => string | number
181
- ): VNode[];
182
-
183
- /** Conditional class names */
184
- export function cls(...args: (string | false | null | undefined | Record<string, boolean>)[]): string;
176
+ fn: (item: T, index: number) => VNodeChild,
177
+ keyFn?: (item: T, index: number) => string | number,
178
+ ): VNodeChild[];
185
179
 
186
- /** Convert style object to string */
180
+ export function cls(...args: Array<string | false | null | undefined | Record<string, boolean>>): string;
187
181
  export function style(obj: string | Record<string, string | number | null | undefined>): string;
188
-
189
- /** Debounce a function */
190
182
  export function debounce<T extends (...args: any[]) => any>(fn: T, ms: number): T;
191
-
192
- /** Throttle a function */
193
183
  export function throttle<T extends (...args: any[]) => any>(fn: T, ms: number): T;
194
-
195
- /** Reactive media query */
196
184
  export function useMediaQuery(query: string): Signal<boolean>;
197
-
198
- /** Signal synced with localStorage */
199
185
  export function useLocalStorage<T>(key: string, initial: T): Signal<T>;
200
-
201
- /** Render children in a different DOM container */
186
+ export function useClickOutside(ref: { current?: Element | null } | Element, handler: (e: Event) => void): void;
202
187
  export function Portal(props: { target: string | Element; children?: VNodeChild }): VNode | null;
203
-
204
- /** CSS transition helper */
205
188
  export function transition(name: string, active: boolean): { class: string };
206
189
 
207
- // --- Head Management ---
190
+ // --- Head ---
208
191
 
209
- /** Manage document head */
210
192
  export function Head(props: {
211
193
  title?: string;
212
- meta?: Record<string, string>[];
213
- link?: Record<string, string>[];
214
- script?: Record<string, string>[];
194
+ meta?: Array<Record<string, string>>;
195
+ link?: Array<Record<string, string>>;
196
+ script?: Array<Record<string, string>>;
215
197
  children?: VNodeChild;
216
198
  }): null;
217
-
218
- /** Clear managed head elements */
219
199
  export function clearHead(): void;
220
200
 
221
- // --- DOM Scheduler ---
201
+ // --- Scheduler ---
222
202
 
223
- /** Schedule a DOM read operation */
224
203
  export function scheduleRead(fn: () => void): () => void;
225
-
226
- /** Schedule a DOM write operation */
227
204
  export function scheduleWrite(fn: () => void): () => void;
228
-
229
- /** Flush all pending scheduler operations */
230
205
  export function flushScheduler(): void;
231
-
232
- /** Measure DOM (returns promise) */
233
206
  export function measure<T>(fn: () => T): Promise<T>;
234
-
235
- /** Mutate DOM (returns promise) */
236
207
  export function mutate(fn: () => void): Promise<void>;
237
-
238
- /** Effect that batches DOM operations */
239
- export function useScheduledEffect(
240
- readFn: () => any,
241
- writeFn?: (data: any) => void
242
- ): () => void;
243
-
244
- /** Returns promise that resolves on next animation frame */
208
+ export function useScheduledEffect(readFn: () => any, writeFn?: (data: any) => void): () => void;
245
209
  export function nextFrame(): Promise<void> & { cancel: () => void };
246
-
247
- /** Debounced requestAnimationFrame */
248
210
  export function raf(key: string, fn: () => void): void;
249
-
250
- /** Observe element resize */
251
- export function onResize(
252
- element: Element,
253
- callback: (rect: DOMRectReadOnly) => void
254
- ): () => void;
255
-
256
- /** Observe element intersection */
211
+ export function onResize(element: Element, callback: (rect: DOMRectReadOnly) => void): () => void;
257
212
  export function onIntersect(
258
213
  element: Element,
259
214
  callback: (entry: IntersectionObserverEntry) => void,
260
- options?: IntersectionObserverInit
215
+ options?: IntersectionObserverInit,
261
216
  ): () => void;
262
-
263
- /** Smooth scroll to element */
264
217
  export function smoothScrollTo(
265
218
  element: Element,
266
- options?: { duration?: number; easing?: (t: number) => number }
219
+ options?: { duration?: number; easing?: (t: number) => number },
220
+ ): Promise<void>;
221
+
222
+ // --- Animation ---
223
+
224
+ export interface SpringValue {
225
+ current(): number;
226
+ set(value: number): void;
227
+ stop(): void;
228
+ reset(): void;
229
+ }
230
+
231
+ export function spring(initialValue?: number, config?: Record<string, any>): SpringValue;
232
+ export function tween(initialValue?: number, config?: Record<string, any>): SpringValue;
233
+ export const easings: Record<string, (t: number) => number>;
234
+ export function useTransition(options?: Record<string, any>): {
235
+ mounted: Signal<boolean>;
236
+ styles: Computed<Record<string, any>>;
237
+ show: () => void;
238
+ hide: () => void;
239
+ };
240
+ export function useGesture(ref: { current?: Element | null } | Element, handlers?: Record<string, (payload: any) => void>): void;
241
+ export function useAnimatedValue(initialValue?: number): {
242
+ value: Signal<number>;
243
+ animateTo: (target: number, config?: Record<string, any>) => Promise<void>;
244
+ stop: () => void;
245
+ };
246
+ export function createTransitionClasses(name: string): string;
247
+ export function cssTransition(config: Record<string, any>): Record<string, any>;
248
+
249
+ // --- Accessibility ---
250
+
251
+ export function useFocus(): {
252
+ current: () => Element | null;
253
+ focus: (element?: Element | null) => void;
254
+ blur: () => void;
255
+ };
256
+
257
+ export function useFocusRestore(): {
258
+ capture: (target?: Element | null) => void;
259
+ restore: (fallbackTarget?: Element | null) => void;
260
+ previous: () => Element | null;
261
+ };
262
+
263
+ export function useFocusTrap(containerRef: { current?: Element | null } | Element): {
264
+ activate: () => void | (() => void);
265
+ deactivate: () => void;
266
+ };
267
+
268
+ export function FocusTrap(props: { children?: VNodeChild; active?: boolean }): VNode;
269
+ export function announce(message: string, options?: { priority?: 'polite' | 'assertive'; timeout?: number }): void;
270
+ export function announceAssertive(message: string): void;
271
+ export function SkipLink(props: { href?: string; children?: VNodeChild }): VNode;
272
+
273
+ export function useAriaExpanded(initialExpanded?: boolean): {
274
+ expanded: () => boolean;
275
+ toggle: () => void;
276
+ open: () => void;
277
+ close: () => void;
278
+ buttonProps: () => Record<string, any>;
279
+ panelProps: () => Record<string, any>;
280
+ };
281
+
282
+ export function useAriaSelected<T = any>(initialSelected?: T): {
283
+ selected: () => T;
284
+ select: (value: T) => void;
285
+ isSelected: (value: T) => boolean;
286
+ itemProps: (value: T) => Record<string, any>;
287
+ };
288
+
289
+ export function useAriaChecked(initialChecked?: boolean): {
290
+ checked: () => boolean;
291
+ toggle: () => void;
292
+ set: (value: boolean) => void;
293
+ checkboxProps: () => Record<string, any>;
294
+ };
295
+
296
+ export function useRovingTabIndex(itemCountOrSignal: number | (() => number)): {
297
+ focusIndex: () => number;
298
+ setFocusIndex: (index: number) => void;
299
+ getItemProps: (index: number) => Record<string, any>;
300
+ containerProps: () => Record<string, any>;
301
+ };
302
+
303
+ export function VisuallyHidden(props: { children?: VNodeChild; as?: string }): VNode;
304
+ export function LiveRegion(props: { children?: VNodeChild; priority?: 'polite' | 'assertive'; atomic?: boolean }): VNode;
305
+ export function useId(prefix?: string): () => string;
306
+ export function useIds(count: number, prefix?: string): string[];
307
+ export function useDescribedBy(description: VNodeChild): {
308
+ descriptionId: () => string;
309
+ descriptionProps: () => Record<string, any>;
310
+ describedByProps: () => Record<string, any>;
311
+ Description: () => VNode;
312
+ };
313
+ export function useLabelledBy(label: VNodeChild): {
314
+ labelId: () => string;
315
+ labelProps: () => Record<string, any>;
316
+ labelledByProps: () => Record<string, any>;
317
+ };
318
+
319
+ export const Keys: {
320
+ Enter: 'Enter';
321
+ Space: ' ';
322
+ Escape: 'Escape';
323
+ ArrowUp: 'ArrowUp';
324
+ ArrowDown: 'ArrowDown';
325
+ ArrowLeft: 'ArrowLeft';
326
+ ArrowRight: 'ArrowRight';
327
+ Home: 'Home';
328
+ End: 'End';
329
+ Tab: 'Tab';
330
+ };
331
+
332
+ export function onKey(key: string, handler: (e: KeyboardEvent) => void): (e: KeyboardEvent) => void;
333
+ export function onKeys(keys: string[], handler: (e: KeyboardEvent) => void): (e: KeyboardEvent) => void;
334
+
335
+ // --- Skeleton ---
336
+
337
+ export function Skeleton(props?: Record<string, any>): VNodeChild;
338
+ export function SkeletonText(props?: Record<string, any>): VNode;
339
+ export function SkeletonAvatar(props?: Record<string, any>): VNodeChild;
340
+ export function SkeletonCard(props?: Record<string, any>): VNode;
341
+ export function SkeletonTable(props?: Record<string, any>): VNode;
342
+ export function IslandSkeleton(props?: Record<string, any>): VNodeChild;
343
+ export function useSkeleton<T>(asyncFn: () => Promise<T> | T, deps?: unknown[]): {
344
+ isLoading: () => boolean;
345
+ data: () => T | null;
346
+ error: () => any;
347
+ Skeleton: (props?: Record<string, any>) => VNodeChild;
348
+ };
349
+ export function Placeholder(props?: Record<string, any>): VNode;
350
+ export function LoadingDots(props?: Record<string, any>): VNode;
351
+ export function Spinner(props?: Record<string, any>): VNode;
352
+
353
+ // --- Data Fetching ---
354
+
355
+ export function useFetch<T = any>(url: string, options?: Record<string, any>): {
356
+ data: () => T;
357
+ error: () => any;
358
+ isLoading: () => boolean;
359
+ refetch: () => Promise<void>;
360
+ mutate: (newData: T) => void;
361
+ };
362
+
363
+ export function useSWR<T = any>(key: string | null | false, fetcher: (key: string, ctx?: { signal: AbortSignal }) => Promise<T>, options?: Record<string, any>): {
364
+ data: () => T | null;
365
+ error: () => any;
366
+ isLoading: () => boolean;
367
+ isValidating: () => boolean;
368
+ mutate: (newData: T | ((prev: T | null) => T), shouldRevalidate?: boolean) => void;
369
+ revalidate: () => Promise<T | void>;
370
+ };
371
+
372
+ export function useQuery<T = any>(options: Record<string, any>): {
373
+ data: () => T | null;
374
+ error: () => any;
375
+ status: () => string;
376
+ isLoading: () => boolean;
377
+ isFetching: () => boolean;
378
+ isError: () => boolean;
379
+ isSuccess: () => boolean;
380
+ refetch: () => Promise<T | void>;
381
+ };
382
+
383
+ export function useInfiniteQuery<T = any>(options: Record<string, any>): {
384
+ data: () => T[];
385
+ error: () => any;
386
+ status: () => string;
387
+ isLoading: () => boolean;
388
+ isFetchingNextPage: () => boolean;
389
+ hasNextPage: () => boolean;
390
+ fetchNextPage: () => Promise<void>;
391
+ refetch: () => Promise<void>;
392
+ };
393
+
394
+ export function invalidateQueries(
395
+ keyOrPredicate: string | ((key: string) => boolean),
396
+ options?: { exact?: boolean },
267
397
  ): Promise<void>;
398
+
399
+ export function prefetchQuery<T = any>(key: string, fetcher: (key: string) => Promise<T>): Promise<T>;
400
+ export function setQueryData<T = any>(key: string, updater: T | ((prev: T | null) => T)): void;
401
+ export function getQueryData<T = any>(key: string): T | null;
402
+ export function clearCache(): void;
403
+
404
+ // --- Forms ---
405
+
406
+ export interface FieldError {
407
+ type?: string;
408
+ message?: string;
409
+ [key: string]: any;
410
+ }
411
+
412
+ export interface RegisterProps {
413
+ name: string;
414
+ value: any;
415
+ onInput: (e: any) => void;
416
+ onBlur: () => void;
417
+ onFocus: () => void;
418
+ ref?: any;
419
+ }
420
+
421
+ export interface FormState {
422
+ readonly values: Record<string, any>;
423
+ readonly errors: Record<string, FieldError>;
424
+ error: (name: string) => FieldError | null;
425
+ readonly touched: Record<string, boolean>;
426
+ isDirty: () => boolean;
427
+ isValid: Computed<boolean>;
428
+ isSubmitting: () => boolean;
429
+ isSubmitted: () => boolean;
430
+ submitCount: () => number;
431
+ dirtyFields: Computed<Record<string, boolean>>;
432
+ }
433
+
434
+ export interface UseFormReturn {
435
+ register: (name: string, options?: Record<string, any>) => RegisterProps;
436
+ handleSubmit: (
437
+ onValid: (values: Record<string, any>) => void | Promise<void>,
438
+ onInvalid?: (errors: Record<string, FieldError>) => void,
439
+ ) => (e?: Event) => Promise<void>;
440
+ setValue: (name: string, value: any, options?: Record<string, any>) => void;
441
+ getValue: (name: string) => any;
442
+ setError: (name: string, error: FieldError | null) => void;
443
+ clearError: (name: string) => void;
444
+ clearErrors: () => void;
445
+ reset: (newValues?: Record<string, any>) => void;
446
+ watch: (name?: string) => Computed<any>;
447
+ validate: (fieldName?: string) => Promise<boolean>;
448
+ formState: FormState;
449
+ }
450
+
451
+ export function useForm(options?: {
452
+ defaultValues?: Record<string, any>;
453
+ mode?: 'onSubmit' | 'onChange' | 'onBlur';
454
+ reValidateMode?: 'onChange' | 'onBlur';
455
+ resolver?: (values: Record<string, any>) => Promise<{ values: Record<string, any>; errors: Record<string, FieldError> }>;
456
+ }): UseFormReturn;
457
+
458
+ export function useField(name: string, options?: {
459
+ validate?: (value: any) => string | null | Promise<string | null>;
460
+ defaultValue?: any;
461
+ }): {
462
+ name: string;
463
+ value: () => any;
464
+ error: () => string | null;
465
+ isTouched: () => boolean;
466
+ isDirty: () => boolean;
467
+ setValue: (value: any) => void;
468
+ setError: (error: string | null) => void;
469
+ validate: () => Promise<boolean>;
470
+ reset: () => void;
471
+ inputProps: () => Record<string, any>;
472
+ };
473
+
474
+ export const rules: {
475
+ required: (message?: string) => (value: any) => string | void;
476
+ minLength: (min: number, message?: string) => (value: any) => string | void;
477
+ maxLength: (max: number, message?: string) => (value: any) => string | void;
478
+ min: (min: number, message?: string) => (value: any) => string | void;
479
+ max: (max: number, message?: string) => (value: any) => string | void;
480
+ pattern: (regex: RegExp, message?: string) => (value: any) => string | void;
481
+ email: (message?: string) => (value: any) => string | void;
482
+ url: (message?: string) => (value: any) => string | void;
483
+ match: (field: string, message?: string) => (value: any, values: Record<string, any>) => string | void;
484
+ custom: <T extends (...args: any[]) => any>(validator: T) => T;
485
+ };
486
+
487
+ export function simpleResolver(ruleMap: Record<string, Array<(value: any, values: Record<string, any>) => string | void>>):
488
+ (values: Record<string, any>) => Promise<{ values: Record<string, any>; errors: Record<string, FieldError> }>;
489
+
490
+ export function zodResolver(schema: { parseAsync: (values: any) => Promise<any> }):
491
+ (values: Record<string, any>) => Promise<{ values: Record<string, any>; errors: Record<string, FieldError> }>;
492
+
493
+ export function yupResolver(schema: { validate: (values: any, options?: any) => Promise<any> }):
494
+ (values: Record<string, any>) => Promise<{ values: Record<string, any>; errors: Record<string, FieldError> }>;
495
+
496
+ export function Input(props: Record<string, any>): VNode;
497
+ export function Textarea(props: Record<string, any>): VNode;
498
+ export function Select(props: Record<string, any>): VNode;
499
+ export function Checkbox(props: Record<string, any>): VNode;
500
+ export function Radio(props: Record<string, any>): VNode;
501
+
502
+ export function ErrorMessage(props: {
503
+ name: string;
504
+ formState?: FormState;
505
+ errors?: Record<string, FieldError> | (() => Record<string, FieldError>);
506
+ render?: (args: { message?: string; type?: string }) => VNodeChild;
507
+ }): VNodeChild;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "what-core",
3
- "version": "0.4.2",
3
+ "version": "0.5.1",
4
4
  "description": "What Framework - The closest framework to vanilla JS",
5
5
  "type": "module",
6
6
  "main": "dist/what.js",
@@ -9,8 +9,7 @@
9
9
  "exports": {
10
10
  ".": {
11
11
  "types": "./index.d.ts",
12
- "import": "./src/index.js",
13
- "require": "./dist/what.cjs"
12
+ "import": "./src/index.js"
14
13
  },
15
14
  "./jsx-runtime": {
16
15
  "import": "./src/jsx-runtime.js"
@@ -19,6 +18,7 @@
19
18
  "import": "./src/jsx-dev-runtime.js"
20
19
  },
21
20
  "./render": {
21
+ "types": "./render.d.ts",
22
22
  "import": "./src/render.js"
23
23
  },
24
24
  "./testing": {
@@ -30,6 +30,7 @@
30
30
  "src",
31
31
  "dist",
32
32
  "index.d.ts",
33
+ "render.d.ts",
33
34
  "testing.d.ts"
34
35
  ],
35
36
  "sideEffects": false,