Home / File/ form-next-complex.json — ui Source File

form-next-complex.json — ui Source File

Architecture documentation for form-next-complex.json, a json file in the ui codebase.

Entity Profile

Source Code

{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "form-next-complex",
  "type": "registry:example",
  "registryDependencies": [
    "field",
    "input",
    "textarea",
    "button",
    "card",
    "spinner",
    "checkbox",
    "dialog",
    "radio-group",
    "select",
    "switch"
  ],
  "files": [
    {
      "path": "registry/new-york-v4/examples/form-next-complex.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport Form from \"next/form\"\nimport { toast } from \"sonner\"\n\nimport { Button } from \"@/registry/new-york-v4/ui/button\"\nimport { Card, CardContent, CardFooter } from \"@/registry/new-york-v4/ui/card\"\nimport { Checkbox } from \"@/registry/new-york-v4/ui/checkbox\"\nimport {\n  Field,\n  FieldContent,\n  FieldDescription,\n  FieldError,\n  FieldGroup,\n  FieldLabel,\n  FieldLegend,\n  FieldSeparator,\n  FieldSet,\n  FieldTitle,\n} from \"@/registry/new-york-v4/ui/field\"\nimport {\n  RadioGroup,\n  RadioGroupItem,\n} from \"@/registry/new-york-v4/ui/radio-group\"\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/registry/new-york-v4/ui/select\"\nimport { Spinner } from \"@/registry/new-york-v4/ui/spinner\"\nimport { Switch } from \"@/registry/new-york-v4/ui/switch\"\n\nimport { complexFormAction } from \"./form-next-complex-action\"\nimport { addons, type FormState } from \"./form-next-complex-schema\"\n\nexport default function FormNextComplex() {\n  const [formState, formAction, pending] = React.useActionState<\n    FormState,\n    FormData\n  >(complexFormAction, {\n    values: {\n      plan: \"basic\",\n      billingPeriod: \"monthly\",\n      addons: [],\n      emailNotifications: false,\n    },\n    errors: null,\n    success: false,\n  })\n\n  React.useEffect(() => {\n    if (formState.success) {\n      toast.success(\"Preferences saved\", {\n        description: \"Your subscription plan has been updated.\",\n      })\n    }\n  }, [formState.success])\n\n  return (\n    <Card className=\"w-full max-w-sm\">\n      <CardContent>\n        <Form action={formAction} id=\"subscription-form\">\n          <FieldGroup>\n            <FieldSet data-invalid={!!formState.errors?.plan?.length}>\n              <FieldLegend>Subscription Plan</FieldLegend>\n              <FieldDescription>\n                Choose your subscription plan.\n              </FieldDescription>\n              <RadioGroup\n                name=\"plan\"\n                defaultValue={formState.values.plan}\n                disabled={pending}\n                aria-invalid={!!formState.errors?.plan?.length}\n              >\n                <FieldLabel htmlFor=\"basic\">\n                  <Field orientation=\"horizontal\">\n                    <FieldContent>\n                      <FieldTitle>Basic</FieldTitle>\n                      <FieldDescription>\n                        For individuals and small teams\n                      </FieldDescription>\n                    </FieldContent>\n                    <RadioGroupItem value=\"basic\" id=\"basic\" />\n                  </Field>\n                </FieldLabel>\n                <FieldLabel htmlFor=\"pro\">\n                  <Field orientation=\"horizontal\">\n                    <FieldContent>\n                      <FieldTitle>Pro</FieldTitle>\n                      <FieldDescription>\n                        For businesses with higher demands\n                      </FieldDescription>\n                    </FieldContent>\n                    <RadioGroupItem value=\"pro\" id=\"pro\" />\n                  </Field>\n                </FieldLabel>\n              </RadioGroup>\n              {formState.errors?.plan && (\n                <FieldError>{formState.errors.plan[0]}</FieldError>\n              )}\n            </FieldSet>\n            <FieldSeparator />\n            <Field data-invalid={!!formState.errors?.billingPeriod?.length}>\n              <FieldLabel htmlFor=\"billingPeriod\">Billing Period</FieldLabel>\n              <Select\n                name=\"billingPeriod\"\n                defaultValue={formState.values.billingPeriod}\n                disabled={pending}\n                aria-invalid={!!formState.errors?.billingPeriod?.length}\n              >\n                <SelectTrigger id=\"billingPeriod\">\n                  <SelectValue placeholder=\"Select\" />\n                </SelectTrigger>\n                <SelectContent>\n                  <SelectItem value=\"monthly\">Monthly</SelectItem>\n                  <SelectItem value=\"yearly\">Yearly</SelectItem>\n                </SelectContent>\n              </Select>\n              <FieldDescription>\n                Choose how often you want to be billed.\n              </FieldDescription>\n              {formState.errors?.billingPeriod && (\n                <FieldError>{formState.errors.billingPeriod[0]}</FieldError>\n              )}\n            </Field>\n            <FieldSeparator />\n            <FieldSet>\n              <FieldLegend>Add-ons</FieldLegend>\n              <FieldDescription>\n                Select additional features you&apos;d like to include.\n              </FieldDescription>\n              <FieldGroup data-slot=\"checkbox-group\">\n                {addons.map((addon) => (\n                  <Field\n                    key={addon.id}\n                    orientation=\"horizontal\"\n                    data-invalid={!!formState.errors?.addons?.length}\n                  >\n                    <Checkbox\n                      id={addon.id}\n                      name=\"addons\"\n                      value={addon.id}\n                      defaultChecked={formState.values.addons.includes(\n                        addon.id\n                      )}\n                      disabled={pending}\n                      aria-invalid={!!formState.errors?.addons?.length}\n                    />\n                    <FieldContent>\n                      <FieldLabel htmlFor={addon.id}>{addon.title}</FieldLabel>\n                      <FieldDescription>{addon.description}</FieldDescription>\n                    </FieldContent>\n                  </Field>\n                ))}\n              </FieldGroup>\n              {formState.errors?.addons && (\n                <FieldError>{formState.errors.addons[0]}</FieldError>\n              )}\n            </FieldSet>\n            <FieldSeparator />\n            <Field orientation=\"horizontal\">\n              <FieldContent>\n                <FieldLabel htmlFor=\"emailNotifications\">\n                  Email Notifications\n                </FieldLabel>\n                <FieldDescription>\n                  Receive email updates about your subscription\n                </FieldDescription>\n              </FieldContent>\n              <Switch\n                id=\"emailNotifications\"\n                name=\"emailNotifications\"\n                defaultChecked={formState.values.emailNotifications}\n                disabled={pending}\n                aria-invalid={!!formState.errors?.emailNotifications?.length}\n              />\n            </Field>\n          </FieldGroup>\n        </Form>\n      </CardContent>\n      <CardFooter>\n        <Field orientation=\"horizontal\" className=\"justify-end\">\n          <Button type=\"submit\" disabled={pending} form=\"subscription-form\">\n            {pending && <Spinner />}\n            Save Preferences\n          </Button>\n        </Field>\n      </CardFooter>\n    </Card>\n  )\n}\n",
      "type": "registry:example"
    },
    {
      "path": "registry/new-york-v4/examples/form-next-complex-schema.ts",
      "content": "import { z } from \"zod\"\n\nexport const formSchema = z.object({\n  plan: z\n    .string({\n      required_error: \"Please select a subscription plan\",\n    })\n    .min(1, \"Please select a subscription plan\")\n    .refine((value) => value === \"basic\" || value === \"pro\", {\n      message: \"Invalid plan selection. Please choose Basic or Pro\",\n    }),\n  billingPeriod: z\n    .string({\n      required_error: \"Please select a billing period\",\n    })\n    .min(1, \"Please select a billing period\"),\n  addons: z\n    .array(z.string())\n    .min(1, \"Please select at least one add-on\")\n    .max(3, \"You can select up to 3 add-ons\")\n    .refine(\n      (value) => value.every((addon) => addons.some((a) => a.id === addon)),\n      {\n        message: \"You selected an invalid add-on\",\n      }\n    ),\n  emailNotifications: z.boolean(),\n})\n\nexport type FormState = {\n  values: z.infer<typeof formSchema>\n  errors: null | Partial<Record<keyof z.infer<typeof formSchema>, string[]>>\n  success: boolean\n}\n\nexport const addons = [\n  {\n    id: \"analytics\",\n    title: \"Analytics\",\n    description: \"Advanced analytics and reporting\",\n  },\n  {\n    id: \"backup\",\n    title: \"Backup\",\n    description: \"Automated daily backups\",\n  },\n  {\n    id: \"support\",\n    title: \"Priority Support\",\n    description: \"24/7 premium customer support\",\n  },\n] as const\n",
      "type": "registry:example"
    },
    {
      "path": "registry/new-york-v4/examples/form-next-complex-action.ts",
      "content": "\"use server\"\n\nimport { formSchema, type FormState } from \"./form-next-complex-schema\"\n\nexport async function complexFormAction(\n  _prevState: FormState,\n  formData: FormData\n) {\n  // Sleep for 1 second\n  await new Promise((resolve) => setTimeout(resolve, 1000))\n\n  const values = {\n    plan: formData.get(\"plan\") as FormState[\"values\"][\"plan\"],\n    billingPeriod: formData.get(\"billingPeriod\") as string,\n    addons: formData.getAll(\"addons\") as string[],\n    emailNotifications: formData.get(\"emailNotifications\") === \"on\",\n  }\n\n  const result = formSchema.safeParse(values)\n\n  if (!result.success) {\n    return {\n      values,\n      success: false,\n      errors: result.error.flatten().fieldErrors,\n    }\n  }\n\n  // Do something with the values.\n  // Call your database or API here.\n\n  return {\n    values,\n    errors: null,\n    success: true,\n  }\n}\n",
      "type": "registry:example"
    }
  ]
}

Frequently Asked Questions

What does form-next-complex.json do?
form-next-complex.json is a source file in the ui codebase, written in json.
Where is form-next-complex.json in the architecture?
form-next-complex.json is located at apps/v4/public/r/styles/new-york-v4/form-next-complex.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