Home / File/ form-tanstack-array.json — ui Source File

form-tanstack-array.json — ui Source File

Architecture documentation for form-tanstack-array.json, a json file in the ui codebase.

Entity Profile

Source Code

{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "form-tanstack-array",
  "dependencies": [
    "@tanstack/react-form",
    "zod"
  ],
  "registryDependencies": [
    "field",
    "input",
    "input-group",
    "button",
    "card"
  ],
  "files": [
    {
      "path": "registry/new-york-v4/examples/form-tanstack-array.tsx",
      "content": "/* eslint-disable react/no-children-prop */\n\"use client\"\n\nimport * as React from \"react\"\nimport { useForm } from \"@tanstack/react-form\"\nimport { XIcon } from \"lucide-react\"\nimport { toast } from \"sonner\"\nimport { z } from \"zod\"\n\nimport { Button } from \"@/registry/new-york-v4/ui/button\"\nimport {\n  Card,\n  CardContent,\n  CardDescription,\n  CardFooter,\n  CardHeader,\n  CardTitle,\n} from \"@/registry/new-york-v4/ui/card\"\nimport {\n  Field,\n  FieldContent,\n  FieldDescription,\n  FieldError,\n  FieldGroup,\n  FieldLegend,\n  FieldSet,\n} from \"@/registry/new-york-v4/ui/field\"\nimport {\n  InputGroup,\n  InputGroupAddon,\n  InputGroupButton,\n  InputGroupInput,\n} from \"@/registry/new-york-v4/ui/input-group\"\n\nconst formSchema = z.object({\n  emails: z\n    .array(\n      z.object({\n        address: z.string().email(\"Enter a valid email address.\"),\n      })\n    )\n    .min(1, \"Add at least one email address.\")\n    .max(5, \"You can add up to 5 email addresses.\"),\n})\n\nexport default function FormTanstackArray() {\n  const form = useForm({\n    defaultValues: {\n      emails: [{ address: \"\" }],\n    },\n    validators: {\n      onBlur: formSchema,\n    },\n    onSubmit: async ({ value }) => {\n      toast(\"You submitted the following values:\", {\n        description: (\n          <pre className=\"bg-code text-code-foreground mt-2 w-[320px] overflow-x-auto rounded-md p-4\">\n            <code>{JSON.stringify(value, null, 2)}</code>\n          </pre>\n        ),\n        position: \"bottom-right\",\n        classNames: {\n          content: \"flex flex-col gap-2\",\n        },\n        style: {\n          \"--border-radius\": \"calc(var(--radius)  + 4px)\",\n        } as React.CSSProperties,\n      })\n    },\n  })\n\n  return (\n    <Card className=\"w-full sm:max-w-md\">\n      <CardHeader className=\"border-b\">\n        <CardTitle>Contact Emails</CardTitle>\n        <CardDescription>Manage your contact email addresses.</CardDescription>\n      </CardHeader>\n      <CardContent>\n        <form\n          id=\"form-tanstack-array\"\n          onSubmit={(e) => {\n            e.preventDefault()\n            form.handleSubmit()\n          }}\n        >\n          <form.Field name=\"emails\" mode=\"array\">\n            {(field) => {\n              const isInvalid =\n                field.state.meta.isTouched && !field.state.meta.isValid\n              return (\n                <FieldSet className=\"gap-4\">\n                  <FieldLegend variant=\"label\">Email Addresses</FieldLegend>\n                  <FieldDescription>\n                    Add up to 5 email addresses where we can contact you.\n                  </FieldDescription>\n                  <FieldGroup className=\"gap-4\">\n                    {field.state.value.map((_, index) => (\n                      <form.Field\n                        key={index}\n                        name={`emails[${index}].address`}\n                        children={(subField) => {\n                          const isSubFieldInvalid =\n                            subField.state.meta.isTouched &&\n                            !subField.state.meta.isValid\n                          return (\n                            <Field\n                              orientation=\"horizontal\"\n                              data-invalid={isSubFieldInvalid}\n                            >\n                              <FieldContent>\n                                <InputGroup>\n                                  <InputGroupInput\n                                    id={`form-tanstack-array-email-${index}`}\n                                    name={subField.name}\n                                    value={subField.state.value}\n                                    onBlur={subField.handleBlur}\n                                    onChange={(e) =>\n                                      subField.handleChange(e.target.value)\n                                    }\n                                    aria-invalid={isSubFieldInvalid}\n                                    placeholder=\"name@example.com\"\n                                    type=\"email\"\n                                    autoComplete=\"email\"\n                                  />\n                                  {field.state.value.length > 1 && (\n                                    <InputGroupAddon align=\"inline-end\">\n                                      <InputGroupButton\n                                        type=\"button\"\n                                        variant=\"ghost\"\n                                        size=\"icon-xs\"\n                                        onClick={() => field.removeValue(index)}\n                                        aria-label={`Remove email ${index + 1}`}\n                                      >\n                                        <XIcon />\n                                      </InputGroupButton>\n                                    </InputGroupAddon>\n                                  )}\n                                </InputGroup>\n                                {isSubFieldInvalid && (\n                                  <FieldError\n                                    errors={subField.state.meta.errors}\n                                  />\n                                )}\n                              </FieldContent>\n                            </Field>\n                          )\n                        }}\n                      />\n                    ))}\n                    <Button\n                      type=\"button\"\n                      variant=\"outline\"\n                      size=\"sm\"\n                      onClick={() => field.pushValue({ address: \"\" })}\n                      disabled={field.state.value.length >= 5}\n                    >\n                      Add Email Address\n                    </Button>\n                  </FieldGroup>\n                  {isInvalid && <FieldError errors={field.state.meta.errors} />}\n                </FieldSet>\n              )\n            }}\n          </form.Field>\n        </form>\n      </CardContent>\n      <CardFooter className=\"border-t\">\n        <Field orientation=\"horizontal\">\n          <Button type=\"button\" variant=\"outline\" onClick={() => form.reset()}>\n            Reset\n          </Button>\n          <Button type=\"submit\" form=\"form-tanstack-array\">\n            Save\n          </Button>\n        </Field>\n      </CardFooter>\n    </Card>\n  )\n}\n",
      "type": "registry:example"
    }
  ],
  "type": "registry:example"
}

Frequently Asked Questions

What does form-tanstack-array.json do?
form-tanstack-array.json is a source file in the ui codebase, written in json.
Where is form-tanstack-array.json in the architecture?
form-tanstack-array.json is located at apps/v4/public/r/styles/new-york-v4/form-tanstack-array.json (directory: apps/v4/public/r/styles/new-york-v4).

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free