what-core 0.4.2 → 0.5.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.
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,106 @@ 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 delegateEvents(eventNames: string[]): void;
74
+ export function on(el: Element, event: string, handler: (e: Event) => void): () => void;
75
+ export function classList(el: Element, classes: Record<string, boolean | (() => boolean)>): void;
74
76
 
75
- /** State hook - returns [value, setter] */
76
- export function useState<T>(initial: T | (() => T)): [T, (value: T | ((prev: T) => T)) => void];
77
+ // --- Hooks ---
77
78
 
78
- /** Signal hook - returns raw signal */
79
+ export function useState<T>(initial: T | (() => T)): [T, (value: Updater<T>) => void];
79
80
  export function useSignal<T>(initial: T | (() => T)): Signal<T>;
80
-
81
- /** Computed hook */
82
81
  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 */
82
+ export function useEffect(fn: () => void | (() => void), deps?: unknown[]): void;
83
+ export function useMemo<T>(fn: () => T, deps?: unknown[]): T;
84
+ export function useCallback<T extends (...args: any[]) => any>(fn: T, deps?: unknown[]): T;
94
85
  export function useRef<T>(initial: T): { current: T };
95
86
 
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
87
  export interface Context<T> {
108
- _value: T;
88
+ _defaultValue: T;
109
89
  Provider: Component<{ value: T; children?: VNodeChild }>;
110
90
  }
111
91
 
112
92
  export function createContext<T>(defaultValue: T): Context<T>;
93
+ export function useContext<T>(context: Context<T>): T;
94
+ export function useReducer<S, A>(
95
+ reducer: (state: S, action: A) => S,
96
+ initialState: S,
97
+ init?: (initial: S) => S,
98
+ ): [S, (action: A) => void];
99
+ export function onMount(fn: () => void): void;
100
+ export function onCleanup(fn: () => void): void;
113
101
 
114
- // --- Component Utilities ---
102
+ export function createResource<T = any, S = any>(
103
+ fetcher: (source?: S, ctx?: { signal: AbortSignal }) => Promise<T> | T,
104
+ options?: { initialValue?: T; source?: S },
105
+ ): [Signal<T | null>, {
106
+ loading: Signal<boolean>;
107
+ error: Signal<any>;
108
+ refetch: (source?: S) => Promise<any>;
109
+ mutate: (value: Updater<T | null>) => void;
110
+ }];
115
111
 
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>;
112
+ // --- Components ---
121
113
 
122
- /** Lazy-load a component */
123
114
  export function lazy<P>(
124
- loader: () => Promise<{ default: Component<P> } | Component<P>>
115
+ loader: () => Promise<{ default: Component<P> } | Component<P>>,
125
116
  ): Component<P>;
117
+ export function memo<P>(component: Component<P>, areEqual?: (prev: P, next: P) => boolean): Component<P>;
126
118
 
127
- /** Suspense boundary for lazy components */
128
119
  export function Suspense(props: {
129
120
  fallback: VNodeChild;
130
121
  children?: VNodeChild;
131
122
  }): VNode;
132
123
 
133
- /** Error boundary for catching component errors */
134
124
  export function ErrorBoundary(props: {
135
- fallback: VNodeChild | ((props: { error: Error; reset: () => void }) => VNodeChild);
125
+ fallback: VNodeChild | ((args: { error: Error; reset: () => void }) => VNodeChild);
136
126
  onError?: (error: Error) => void;
137
127
  children?: VNodeChild;
138
128
  }): VNode;
139
129
 
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;
130
+ export function Show(props: {
131
+ when: boolean | (() => boolean);
132
+ fallback?: VNodeChild;
133
+ children?: VNodeChild;
134
+ }): VNodeChild;
152
135
 
153
- /** Create a global reactive store */
154
- export function createStore<T extends StoreDefinition>(definition: T): () => Store<T>;
136
+ export function For<T>(props: {
137
+ each: T[] | (() => T[]);
138
+ fallback?: VNodeChild;
139
+ children: ((item: T, index: number) => VNodeChild) | VNodeChild;
140
+ }): VNodeChild;
155
141
 
156
- /** Create a simple global atom */
157
- export function atom<T>(initial: T): Signal<T>;
142
+ export function Switch(props: {
143
+ fallback?: VNodeChild;
144
+ children?: VNodeChild;
145
+ }): VNodeChild;
158
146
 
159
- // --- Island ---
147
+ export function Match(props: {
148
+ when: boolean | (() => boolean);
149
+ children?: VNodeChild;
150
+ }): VNode;
160
151
 
161
152
  export interface IslandProps {
162
153
  component: Component<any>;
@@ -165,103 +156,351 @@ export interface IslandProps {
165
156
  [key: string]: any;
166
157
  }
167
158
 
168
- /** Island component for deferred hydration */
169
159
  export function Island(props: IslandProps): VNode;
170
160
 
171
- // --- Utilities ---
161
+ // --- State ---
172
162
 
173
- /** Conditional rendering helper */
174
- export function show<T extends VNodeChild>(condition: boolean, vnode: T, fallback?: VNodeChild): T | VNodeChild;
163
+ export type DerivedFn<T> = ((state: any) => T) & { _isDerived: true };
164
+ export function derived<T>(fn: (state: any) => T): DerivedFn<T>;
165
+ export function storeComputed<T>(fn: (state: any) => T): DerivedFn<T>;
166
+ export type StoreDefinition = Record<string, any>;
167
+ export type Store<T extends StoreDefinition> = T;
168
+ export function createStore<T extends StoreDefinition>(definition: T): () => Store<T>;
169
+ export function atom<T>(initial: T): Signal<T>;
170
+
171
+ // --- Helpers / Utilities ---
175
172
 
176
- /** List rendering helper with optional key function */
177
173
  export function each<T>(
178
174
  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;
175
+ fn: (item: T, index: number) => VNodeChild,
176
+ keyFn?: (item: T, index: number) => string | number,
177
+ ): VNodeChild[];
185
178
 
186
- /** Convert style object to string */
179
+ export function cls(...args: Array<string | false | null | undefined | Record<string, boolean>>): string;
187
180
  export function style(obj: string | Record<string, string | number | null | undefined>): string;
188
-
189
- /** Debounce a function */
190
181
  export function debounce<T extends (...args: any[]) => any>(fn: T, ms: number): T;
191
-
192
- /** Throttle a function */
193
182
  export function throttle<T extends (...args: any[]) => any>(fn: T, ms: number): T;
194
-
195
- /** Reactive media query */
196
183
  export function useMediaQuery(query: string): Signal<boolean>;
197
-
198
- /** Signal synced with localStorage */
199
184
  export function useLocalStorage<T>(key: string, initial: T): Signal<T>;
200
-
201
- /** Render children in a different DOM container */
185
+ export function useClickOutside(ref: { current?: Element | null } | Element, handler: (e: Event) => void): void;
202
186
  export function Portal(props: { target: string | Element; children?: VNodeChild }): VNode | null;
203
-
204
- /** CSS transition helper */
205
187
  export function transition(name: string, active: boolean): { class: string };
206
188
 
207
- // --- Head Management ---
189
+ // --- Head ---
208
190
 
209
- /** Manage document head */
210
191
  export function Head(props: {
211
192
  title?: string;
212
- meta?: Record<string, string>[];
213
- link?: Record<string, string>[];
214
- script?: Record<string, string>[];
193
+ meta?: Array<Record<string, string>>;
194
+ link?: Array<Record<string, string>>;
195
+ script?: Array<Record<string, string>>;
215
196
  children?: VNodeChild;
216
197
  }): null;
217
-
218
- /** Clear managed head elements */
219
198
  export function clearHead(): void;
220
199
 
221
- // --- DOM Scheduler ---
200
+ // --- Scheduler ---
222
201
 
223
- /** Schedule a DOM read operation */
224
202
  export function scheduleRead(fn: () => void): () => void;
225
-
226
- /** Schedule a DOM write operation */
227
203
  export function scheduleWrite(fn: () => void): () => void;
228
-
229
- /** Flush all pending scheduler operations */
230
204
  export function flushScheduler(): void;
231
-
232
- /** Measure DOM (returns promise) */
233
205
  export function measure<T>(fn: () => T): Promise<T>;
234
-
235
- /** Mutate DOM (returns promise) */
236
206
  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 */
207
+ export function useScheduledEffect(readFn: () => any, writeFn?: (data: any) => void): () => void;
245
208
  export function nextFrame(): Promise<void> & { cancel: () => void };
246
-
247
- /** Debounced requestAnimationFrame */
248
209
  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 */
210
+ export function onResize(element: Element, callback: (rect: DOMRectReadOnly) => void): () => void;
257
211
  export function onIntersect(
258
212
  element: Element,
259
213
  callback: (entry: IntersectionObserverEntry) => void,
260
- options?: IntersectionObserverInit
214
+ options?: IntersectionObserverInit,
261
215
  ): () => void;
262
-
263
- /** Smooth scroll to element */
264
216
  export function smoothScrollTo(
265
217
  element: Element,
266
- options?: { duration?: number; easing?: (t: number) => number }
218
+ options?: { duration?: number; easing?: (t: number) => number },
219
+ ): Promise<void>;
220
+
221
+ // --- Animation ---
222
+
223
+ export interface SpringValue {
224
+ current(): number;
225
+ set(value: number): void;
226
+ stop(): void;
227
+ reset(): void;
228
+ }
229
+
230
+ export function spring(initialValue?: number, config?: Record<string, any>): SpringValue;
231
+ export function tween(initialValue?: number, config?: Record<string, any>): SpringValue;
232
+ export const easings: Record<string, (t: number) => number>;
233
+ export function useTransition(options?: Record<string, any>): {
234
+ mounted: Signal<boolean>;
235
+ styles: Computed<Record<string, any>>;
236
+ show: () => void;
237
+ hide: () => void;
238
+ };
239
+ export function useGesture(ref: { current?: Element | null } | Element, handlers?: Record<string, (payload: any) => void>): void;
240
+ export function useAnimatedValue(initialValue?: number): {
241
+ value: Signal<number>;
242
+ animateTo: (target: number, config?: Record<string, any>) => Promise<void>;
243
+ stop: () => void;
244
+ };
245
+ export function createTransitionClasses(name: string): string;
246
+ export function cssTransition(config: Record<string, any>): Record<string, any>;
247
+
248
+ // --- Accessibility ---
249
+
250
+ export function useFocus(): {
251
+ current: () => Element | null;
252
+ focus: (element?: Element | null) => void;
253
+ blur: () => void;
254
+ };
255
+
256
+ export function useFocusRestore(): {
257
+ capture: (target?: Element | null) => void;
258
+ restore: (fallbackTarget?: Element | null) => void;
259
+ previous: () => Element | null;
260
+ };
261
+
262
+ export function useFocusTrap(containerRef: { current?: Element | null } | Element): {
263
+ activate: () => void | (() => void);
264
+ deactivate: () => void;
265
+ };
266
+
267
+ export function FocusTrap(props: { children?: VNodeChild; active?: boolean }): VNode;
268
+ export function announce(message: string, options?: { priority?: 'polite' | 'assertive'; timeout?: number }): void;
269
+ export function announceAssertive(message: string): void;
270
+ export function SkipLink(props: { href?: string; children?: VNodeChild }): VNode;
271
+
272
+ export function useAriaExpanded(initialExpanded?: boolean): {
273
+ expanded: () => boolean;
274
+ toggle: () => void;
275
+ open: () => void;
276
+ close: () => void;
277
+ buttonProps: () => Record<string, any>;
278
+ panelProps: () => Record<string, any>;
279
+ };
280
+
281
+ export function useAriaSelected<T = any>(initialSelected?: T): {
282
+ selected: () => T;
283
+ select: (value: T) => void;
284
+ isSelected: (value: T) => boolean;
285
+ itemProps: (value: T) => Record<string, any>;
286
+ };
287
+
288
+ export function useAriaChecked(initialChecked?: boolean): {
289
+ checked: () => boolean;
290
+ toggle: () => void;
291
+ set: (value: boolean) => void;
292
+ checkboxProps: () => Record<string, any>;
293
+ };
294
+
295
+ export function useRovingTabIndex(itemCountOrSignal: number | (() => number)): {
296
+ focusIndex: () => number;
297
+ setFocusIndex: (index: number) => void;
298
+ getItemProps: (index: number) => Record<string, any>;
299
+ containerProps: () => Record<string, any>;
300
+ };
301
+
302
+ export function VisuallyHidden(props: { children?: VNodeChild; as?: string }): VNode;
303
+ export function LiveRegion(props: { children?: VNodeChild; priority?: 'polite' | 'assertive'; atomic?: boolean }): VNode;
304
+ export function useId(prefix?: string): () => string;
305
+ export function useIds(count: number, prefix?: string): string[];
306
+ export function useDescribedBy(description: VNodeChild): {
307
+ descriptionId: () => string;
308
+ descriptionProps: () => Record<string, any>;
309
+ describedByProps: () => Record<string, any>;
310
+ Description: () => VNode;
311
+ };
312
+ export function useLabelledBy(label: VNodeChild): {
313
+ labelId: () => string;
314
+ labelProps: () => Record<string, any>;
315
+ labelledByProps: () => Record<string, any>;
316
+ };
317
+
318
+ export const Keys: {
319
+ Enter: 'Enter';
320
+ Space: ' ';
321
+ Escape: 'Escape';
322
+ ArrowUp: 'ArrowUp';
323
+ ArrowDown: 'ArrowDown';
324
+ ArrowLeft: 'ArrowLeft';
325
+ ArrowRight: 'ArrowRight';
326
+ Home: 'Home';
327
+ End: 'End';
328
+ Tab: 'Tab';
329
+ };
330
+
331
+ export function onKey(key: string, handler: (e: KeyboardEvent) => void): (e: KeyboardEvent) => void;
332
+ export function onKeys(keys: string[], handler: (e: KeyboardEvent) => void): (e: KeyboardEvent) => void;
333
+
334
+ // --- Skeleton ---
335
+
336
+ export function Skeleton(props?: Record<string, any>): VNodeChild;
337
+ export function SkeletonText(props?: Record<string, any>): VNode;
338
+ export function SkeletonAvatar(props?: Record<string, any>): VNodeChild;
339
+ export function SkeletonCard(props?: Record<string, any>): VNode;
340
+ export function SkeletonTable(props?: Record<string, any>): VNode;
341
+ export function IslandSkeleton(props?: Record<string, any>): VNodeChild;
342
+ export function useSkeleton<T>(asyncFn: () => Promise<T> | T, deps?: unknown[]): {
343
+ isLoading: () => boolean;
344
+ data: () => T | null;
345
+ error: () => any;
346
+ Skeleton: (props?: Record<string, any>) => VNodeChild;
347
+ };
348
+ export function Placeholder(props?: Record<string, any>): VNode;
349
+ export function LoadingDots(props?: Record<string, any>): VNode;
350
+ export function Spinner(props?: Record<string, any>): VNode;
351
+
352
+ // --- Data Fetching ---
353
+
354
+ export function useFetch<T = any>(url: string, options?: Record<string, any>): {
355
+ data: () => T;
356
+ error: () => any;
357
+ isLoading: () => boolean;
358
+ refetch: () => Promise<void>;
359
+ mutate: (newData: T) => void;
360
+ };
361
+
362
+ export function useSWR<T = any>(key: string | null | false, fetcher: (key: string, ctx?: { signal: AbortSignal }) => Promise<T>, options?: Record<string, any>): {
363
+ data: () => T | null;
364
+ error: () => any;
365
+ isLoading: () => boolean;
366
+ isValidating: () => boolean;
367
+ mutate: (newData: T | ((prev: T | null) => T), shouldRevalidate?: boolean) => void;
368
+ revalidate: () => Promise<T | void>;
369
+ };
370
+
371
+ export function useQuery<T = any>(options: Record<string, any>): {
372
+ data: () => T | null;
373
+ error: () => any;
374
+ status: () => string;
375
+ isLoading: () => boolean;
376
+ isFetching: () => boolean;
377
+ isError: () => boolean;
378
+ isSuccess: () => boolean;
379
+ refetch: () => Promise<T | void>;
380
+ };
381
+
382
+ export function useInfiniteQuery<T = any>(options: Record<string, any>): {
383
+ data: () => T[];
384
+ error: () => any;
385
+ status: () => string;
386
+ isLoading: () => boolean;
387
+ isFetchingNextPage: () => boolean;
388
+ hasNextPage: () => boolean;
389
+ fetchNextPage: () => Promise<void>;
390
+ refetch: () => Promise<void>;
391
+ };
392
+
393
+ export function invalidateQueries(
394
+ keyOrPredicate: string | ((key: string) => boolean),
395
+ options?: { exact?: boolean },
267
396
  ): Promise<void>;
397
+
398
+ export function prefetchQuery<T = any>(key: string, fetcher: (key: string) => Promise<T>): Promise<T>;
399
+ export function setQueryData<T = any>(key: string, updater: T | ((prev: T | null) => T)): void;
400
+ export function getQueryData<T = any>(key: string): T | null;
401
+ export function clearCache(): void;
402
+
403
+ // --- Forms ---
404
+
405
+ export interface FieldError {
406
+ type?: string;
407
+ message?: string;
408
+ [key: string]: any;
409
+ }
410
+
411
+ export interface RegisterProps {
412
+ name: string;
413
+ value: any;
414
+ onInput: (e: any) => void;
415
+ onBlur: () => void;
416
+ onFocus: () => void;
417
+ ref?: any;
418
+ }
419
+
420
+ export interface FormState {
421
+ readonly values: Record<string, any>;
422
+ readonly errors: Record<string, FieldError>;
423
+ error: (name: string) => FieldError | null;
424
+ readonly touched: Record<string, boolean>;
425
+ isDirty: () => boolean;
426
+ isValid: Computed<boolean>;
427
+ isSubmitting: () => boolean;
428
+ isSubmitted: () => boolean;
429
+ submitCount: () => number;
430
+ dirtyFields: Computed<Record<string, boolean>>;
431
+ }
432
+
433
+ export interface UseFormReturn {
434
+ register: (name: string, options?: Record<string, any>) => RegisterProps;
435
+ handleSubmit: (
436
+ onValid: (values: Record<string, any>) => void | Promise<void>,
437
+ onInvalid?: (errors: Record<string, FieldError>) => void,
438
+ ) => (e?: Event) => Promise<void>;
439
+ setValue: (name: string, value: any, options?: Record<string, any>) => void;
440
+ getValue: (name: string) => any;
441
+ setError: (name: string, error: FieldError | null) => void;
442
+ clearError: (name: string) => void;
443
+ clearErrors: () => void;
444
+ reset: (newValues?: Record<string, any>) => void;
445
+ watch: (name?: string) => Computed<any>;
446
+ validate: (fieldName?: string) => Promise<boolean>;
447
+ formState: FormState;
448
+ }
449
+
450
+ export function useForm(options?: {
451
+ defaultValues?: Record<string, any>;
452
+ mode?: 'onSubmit' | 'onChange' | 'onBlur';
453
+ reValidateMode?: 'onChange' | 'onBlur';
454
+ resolver?: (values: Record<string, any>) => Promise<{ values: Record<string, any>; errors: Record<string, FieldError> }>;
455
+ }): UseFormReturn;
456
+
457
+ export function useField(name: string, options?: {
458
+ validate?: (value: any) => string | null | Promise<string | null>;
459
+ defaultValue?: any;
460
+ }): {
461
+ name: string;
462
+ value: () => any;
463
+ error: () => string | null;
464
+ isTouched: () => boolean;
465
+ isDirty: () => boolean;
466
+ setValue: (value: any) => void;
467
+ setError: (error: string | null) => void;
468
+ validate: () => Promise<boolean>;
469
+ reset: () => void;
470
+ inputProps: () => Record<string, any>;
471
+ };
472
+
473
+ export const rules: {
474
+ required: (message?: string) => (value: any) => string | void;
475
+ minLength: (min: number, message?: string) => (value: any) => string | void;
476
+ maxLength: (max: number, message?: string) => (value: any) => string | void;
477
+ min: (min: number, message?: string) => (value: any) => string | void;
478
+ max: (max: number, message?: string) => (value: any) => string | void;
479
+ pattern: (regex: RegExp, message?: string) => (value: any) => string | void;
480
+ email: (message?: string) => (value: any) => string | void;
481
+ url: (message?: string) => (value: any) => string | void;
482
+ match: (field: string, message?: string) => (value: any, values: Record<string, any>) => string | void;
483
+ custom: <T extends (...args: any[]) => any>(validator: T) => T;
484
+ };
485
+
486
+ export function simpleResolver(ruleMap: Record<string, Array<(value: any, values: Record<string, any>) => string | void>>):
487
+ (values: Record<string, any>) => Promise<{ values: Record<string, any>; errors: Record<string, FieldError> }>;
488
+
489
+ export function zodResolver(schema: { parseAsync: (values: any) => Promise<any> }):
490
+ (values: Record<string, any>) => Promise<{ values: Record<string, any>; errors: Record<string, FieldError> }>;
491
+
492
+ export function yupResolver(schema: { validate: (values: any, options?: any) => Promise<any> }):
493
+ (values: Record<string, any>) => Promise<{ values: Record<string, any>; errors: Record<string, FieldError> }>;
494
+
495
+ export function Input(props: Record<string, any>): VNode;
496
+ export function Textarea(props: Record<string, any>): VNode;
497
+ export function Select(props: Record<string, any>): VNode;
498
+ export function Checkbox(props: Record<string, any>): VNode;
499
+ export function Radio(props: Record<string, any>): VNode;
500
+
501
+ export function ErrorMessage(props: {
502
+ name: string;
503
+ formState?: FormState;
504
+ errors?: Record<string, FieldError> | (() => Record<string, FieldError>);
505
+ render?: (args: { message?: string; type?: string }) => VNodeChild;
506
+ }): 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.0",
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,