Skip to content

Commit

Permalink
feat: enabled nested rendering of schema with SchemaRenderer component
Browse files Browse the repository at this point in the history
  • Loading branch information
keyurparalkar committed Apr 15, 2024
1 parent f6816c2 commit 4121026
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 19 deletions.
21 changes: 3 additions & 18 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useForm } from "react-hook-form";
import InputField from "./components/fields/InputField";
import personalInfoSchema from "./schemas/forms/personal_info.json";
import { SchemaDef } from "./interfaces/schema";
import SchemaRenderer from "./components/ui/SchemaRenderer";

const schema = SchemaDef.parse(personalInfoSchema);

Expand All @@ -12,7 +12,7 @@ const FormValues = schema.fields.reduce((acc, currValue) => {
return acc;
}, {} as Record<string, string>);

type TFormValues = typeof FormValues;
export type TFormValues = typeof FormValues;

function App() {
const {
Expand All @@ -30,22 +30,7 @@ function App() {
<h1 className="text-4xl font-bold tracking-tight mb-5">JSON to Form</h1>

<form onSubmit={handleSubmit(onSubmit)}>
{/* TODO(Keyur): Make the below logic recursive*/}
{schema &&
schema.fields.map(
(field) =>
field.type === "field" && (
<InputField
key={`key-${field.accessorKey}`}
register={register}
labelText={field.fieldName}
htmlFor={field.accessorKey}
type={field.dataType}
validation={field.validation}
error={errors[field.accessorKey]}
/>
)
)}
<SchemaRenderer schema={schema} errors={errors} register={register} />
<input type="submit" />
</form>
</div>
Expand Down
3 changes: 2 additions & 1 deletion src/components/fields/InputField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import { FieldError, UseFormRegister } from "react-hook-form";
import { Input, InputProps } from "../ui/input";
import { Label } from "../ui/label";
import { TField } from "@/interfaces/field";
import { TFormValues } from "@/App";

interface InputFieldProps extends InputProps {
labelText: string;
htmlFor: string;
register: UseFormRegister<any>;
register: UseFormRegister<TFormValues>;
validation?: TField["validation"];
error?: FieldError;
}
Expand Down
36 changes: 36 additions & 0 deletions src/components/ui/SchemaRenderer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { SchemaType } from "@/interfaces/schema";
import InputField from "../fields/InputField";
import { FieldErrors, UseFormRegister } from "react-hook-form";
import { TFormValues } from "@/App";

type SchemaRendererProps = {
schema: SchemaType;
errors: FieldErrors<Record<string, string>>;
register: UseFormRegister<TFormValues>;
};

const SchemaRenderer = (props: SchemaRendererProps) => {
const { schema, errors, register } = props;

return schema.fields.map((field) => {
if (field.type === "field") {
return (
<InputField
key={`key-${field.accessorKey}`}
register={register}
labelText={field.fieldName}
htmlFor={field.accessorKey}
type={field.dataType}
validation={field.validation}
error={errors[field.accessorKey]}
/>
);
}

return (
<SchemaRenderer schema={field} errors={errors} register={register} />
);
});
};

export default SchemaRenderer;
23 changes: 23 additions & 0 deletions src/schemas/forms/personal_info.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,29 @@
"message": "Email Address is required"
}
}
},
{
"type": "group",
"fields": [
{
"type": "field",
"dataType": "text",
"fieldName": "UAN",
"accessorKey": "uan"
},
{
"type": "field",
"dataType": "text",
"fieldName": "PAN",
"accessorKey": "pan"
},
{
"type": "field",
"dataType": "number",
"fieldName": "Aadhar card number",
"accessorKey": "aadharCardNum"
}
]
}
]
}

0 comments on commit 4121026

Please sign in to comment.