@nativetail/ui 0.1.7 → 0.1.9
Sign up to get free protection for your applications and to get access to all the features.
package/package.json
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
import { zodResolver } from "@hookform/resolvers/zod";
|
2
|
+
import { typeboxResolver } from "@hookform/resolvers/typebox";
|
3
|
+
|
2
4
|
import { cn, TextInputProps, View } from "@nativetail/core";
|
3
5
|
import React, { ComponentPropsWithoutRef } from "react";
|
4
|
-
import { Control, DefaultValues, useForm } from "react-hook-form";
|
6
|
+
import { Control, DefaultValues, FieldValues, useForm } from "react-hook-form";
|
5
7
|
import { z } from "zod";
|
6
8
|
import { Button } from "../button";
|
7
9
|
import {
|
@@ -14,12 +16,20 @@ import {
|
|
14
16
|
PinInputProps,
|
15
17
|
} from "../input";
|
16
18
|
import { MultiSelect, MultiSelectProps, Select, SelectProps } from "../select";
|
19
|
+
import {
|
20
|
+
Type,
|
21
|
+
TSchema,
|
22
|
+
Static,
|
23
|
+
JavaScriptTypeBuilder,
|
24
|
+
TObject,
|
25
|
+
TProperties,
|
26
|
+
} from "@sinclair/typebox";
|
17
27
|
|
18
|
-
|
19
|
-
T extends z.ZodRawShape
|
20
|
-
IValues = z.infer<
|
28
|
+
type ZodFormBuilderProps<
|
29
|
+
T extends z.ZodObject<z.ZodRawShape>,
|
30
|
+
IValues = z.infer<T>,
|
21
31
|
> = {
|
22
|
-
schema:
|
32
|
+
schema: T;
|
23
33
|
inputs?: Partial<
|
24
34
|
Record<
|
25
35
|
keyof T,
|
@@ -33,13 +43,47 @@ export type FormBuilderProps<
|
|
33
43
|
>;
|
34
44
|
containerClassname?: string;
|
35
45
|
submitButtonProps?: ComponentPropsWithoutRef<typeof Button>;
|
36
|
-
onSubmit?: (values: IValues) => void;
|
46
|
+
onSubmit?: (values: IValues, reset?: () => void) => void;
|
37
47
|
onError?: (values: Partial<Record<keyof T, any>>) => void;
|
38
48
|
isSubmitting?: boolean;
|
39
49
|
defaultValues?: DefaultValues<IValues>;
|
40
50
|
inputContainerClassname?: string;
|
41
51
|
};
|
42
|
-
|
52
|
+
type TypeboxFormBuilderProps<T extends TSchema, IValues = Static<T>> = {
|
53
|
+
schema: TSchema;
|
54
|
+
inputs?: Partial<
|
55
|
+
Record<
|
56
|
+
keyof IValues,
|
57
|
+
{
|
58
|
+
render?: (props: {
|
59
|
+
control: Control<IValues, any>;
|
60
|
+
name: string;
|
61
|
+
}) => React.ReactElement;
|
62
|
+
} & InputType
|
63
|
+
>
|
64
|
+
>;
|
65
|
+
containerClassname?: string;
|
66
|
+
submitButtonProps?: ComponentPropsWithoutRef<typeof Button>;
|
67
|
+
onSubmit?: (values: IValues, reset?: () => void) => void;
|
68
|
+
onError?: (values: Partial<Record<string, any>>) => void;
|
69
|
+
isSubmitting?: boolean;
|
70
|
+
defaultValues?: DefaultValues<IValues>;
|
71
|
+
inputContainerClassname?: string;
|
72
|
+
};
|
73
|
+
|
74
|
+
export type FormBuilderProps<T extends z.ZodObject<z.ZodRawShape> | TSchema> =
|
75
|
+
T extends z.ZodObject<z.ZodRawShape>
|
76
|
+
? ZodFormBuilderProps<T>
|
77
|
+
: T extends TSchema
|
78
|
+
? TypeboxFormBuilderProps<T>
|
79
|
+
: never;
|
80
|
+
const isTypebox = (shape: any): shape is TObject<TProperties> => {
|
81
|
+
return shape instanceof JavaScriptTypeBuilder;
|
82
|
+
};
|
83
|
+
const isZod = (shape: any): shape is z.ZodObject<z.ZodRawShape> => {
|
84
|
+
return shape instanceof z.ZodObject;
|
85
|
+
};
|
86
|
+
export function FormBuilder<T extends z.ZodObject<z.ZodRawShape> | TSchema>({
|
43
87
|
schema,
|
44
88
|
inputs,
|
45
89
|
containerClassname,
|
@@ -52,9 +96,20 @@ export function FormBuilder<T extends z.ZodRawShape>({
|
|
52
96
|
}: FormBuilderProps<T>) {
|
53
97
|
const shape = schema.shape;
|
54
98
|
const keys = Object.keys(shape);
|
55
|
-
|
99
|
+
|
100
|
+
type SchemaType = typeof schema;
|
101
|
+
type FormSchemaType =
|
102
|
+
SchemaType extends z.ZodObject<z.ZodRawShape>
|
103
|
+
? z.infer<SchemaType>
|
104
|
+
: SchemaType extends TSchema
|
105
|
+
? Static<SchemaType>
|
106
|
+
: any;
|
56
107
|
const form = useForm<FormSchemaType>({
|
57
|
-
resolver:
|
108
|
+
resolver: isTypebox(schema)
|
109
|
+
? typeboxResolver(schema)
|
110
|
+
: isZod(schema)
|
111
|
+
? zodResolver(schema)
|
112
|
+
: undefined,
|
58
113
|
defaultValues: defaultValues,
|
59
114
|
});
|
60
115
|
return (
|
@@ -62,8 +117,8 @@ export function FormBuilder<T extends z.ZodRawShape>({
|
|
62
117
|
<View className={cn("flex-1 gap-2", inputContainerClassname)}>
|
63
118
|
{keys.map((inputKey) => {
|
64
119
|
const Input = inputs[inputKey];
|
65
|
-
const Render = Input.render;
|
66
120
|
if (!Input) return null;
|
121
|
+
const Render = Input.render;
|
67
122
|
if (!Render) {
|
68
123
|
return (
|
69
124
|
<InputComponent
|
@@ -83,7 +138,9 @@ export function FormBuilder<T extends z.ZodRawShape>({
|
|
83
138
|
className="w-full"
|
84
139
|
children={"Submit"}
|
85
140
|
{...submitButtonProps}
|
86
|
-
onPress={form.handleSubmit(
|
141
|
+
onPress={form.handleSubmit((data) => {
|
142
|
+
onSubmit?.(data, form.reset);
|
143
|
+
}, onError)}
|
87
144
|
isLoading={isSubmitting}
|
88
145
|
/>
|
89
146
|
</View>
|