{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "example-form", "type": "registry:component", "title": "Example Form", "description": "A contact form with Zod validation.", "dependencies": [ "@base-ui/react", "zod" ], "files": [ { "path": "registry/new-york/blocks/example-form/example-form.tsx", "content": "\"use client\"\n\nimport * as React from \"react\"\nimport {\n Card,\n CardTitle,\n CardHeader,\n CardDescription,\n CardContent,\n CardFooter,\n} from \"@/registry/new-york/ui/card\"\nimport { Input } from \"@/registry/new-york/ui/input\"\nimport { Label } from \"@/registry/new-york/ui/label\"\nimport { Button } from \"@/registry/new-york/ui/button\"\nimport { Textarea } from \"@/registry/new-york/ui/textarea\"\nimport { z } from \"zod\"\n\nconst exampleFormSchema = z.object({\n name: z.string().min(1),\n email: z.string().email(),\n message: z.string().min(1),\n})\n\nexport function ExampleForm() {\n const [pending, setPending] = React.useState(false)\n const [state, setState] = React.useState({\n defaultValues: {\n name: \"\",\n email: \"\",\n message: \"\",\n },\n success: false,\n errors: {\n name: \"\",\n email: \"\",\n message: \"\",\n },\n })\n\n const handleSubmit = React.useCallback(\n (e: React.FormEvent) => {\n e.preventDefault()\n setPending(true)\n\n const formData = new FormData(e.target as HTMLFormElement)\n const data = Object.fromEntries(formData.entries())\n const result = exampleFormSchema.safeParse(data)\n\n if (!result.success) {\n setState({\n ...state,\n errors: Object.fromEntries(\n Object.entries(result.error.flatten().fieldErrors).map(\n ([key, value]) => [key, value?.[0] ?? \"\"]\n )\n ) as Record,\n })\n setPending(false)\n return\n }\n\n setPending(false)\n },\n [state]\n )\n\n return (\n
\n \n \n How can we help?\n \n Need help with your project? We're here to assist you.\n \n \n \n \n \n Name *\n \n \n {state.errors?.name && (\n

\n {state.errors.name}\n

\n )}\n \n \n \n Email *\n \n \n {state.errors?.email && (\n

\n {state.errors.email}\n

\n )}\n \n \n \n Message *\n \n \n {state.errors?.message && (\n

\n {state.errors.message}\n

\n )}\n \n
\n \n \n \n
\n
\n )\n}\n", "type": "registry:component" }, { "path": "registry/new-york/ui/button.tsx", "content": "import * as React from \"react\"\nimport { Button as ButtonPrimitive } from \"@base-ui/react/button\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n outline:\n \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n secondary:\n \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n ghost:\n \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n icon: \"size-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n className,\n variant,\n size,\n ...props\n}: ButtonPrimitive.Props & VariantProps) {\n return (\n \n )\n}\n\nexport { Button, buttonVariants }\n", "type": "registry:ui" }, { "path": "registry/new-york/ui/input.tsx", "content": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n return (\n \n )\n}\n\nexport { Input }\n", "type": "registry:ui" }, { "path": "registry/new-york/ui/label.tsx", "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Label({\n className,\n ...props\n}: React.ComponentProps<\"label\">) {\n return (\n \n )\n}\n\nexport { Label }\n", "type": "registry:ui" }, { "path": "registry/new-york/ui/textarea.tsx", "content": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Textarea({ className, ...props }: React.ComponentProps<\"textarea\">) {\n return (\n \n )\n}\n\nexport { Textarea }\n", "type": "registry:ui" }, { "path": "registry/new-york/ui/card.tsx", "content": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Card({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n \n )\n}\n\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n}\n", "type": "registry:ui" } ] }