@nativetail/ui 0.1.8 → 0.1.9
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/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,
|
@@ -39,7 +49,41 @@ export type FormBuilderProps<
|
|
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
|