Files
shadcn/apps/v4/public/r/styles/new-york-v4/form-tanstack-checkbox.json
zeekay 05fc512820 feat: sync upstream shadcn/ui — [email protected], v4 app, font system, chart improvements
Upstream sync from shadcn-ui/ui (1686 commits since last merge base).

Key changes:
- packages/shadcn upgraded to 4.1.0 (CLI font transformers, scaffold from github, chart colors)
- apps/v4 replaces apps/www as the primary docs/registry app
- Font system: 25+ heading font registries, font markers utility, @supports override
- Chart improvements: recharts v3 compat, radial chart fixes
- templates/ updated with monorepo variants (astro, vite, react-router, start)
- skills/shadcn AI skill definitions added
- deprecated/ removed (auth, auth-firebase, cli, www)

Preserved Hanzo-only paths: app/, pkg/, demo/, docs/, template/next/
2026-03-24 19:04:31 -07:00

22 lines
7.4 KiB
JSON

{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "form-tanstack-checkbox",
"dependencies": [
"@tanstack/react-form",
"zod"
],
"registryDependencies": [
"field",
"checkbox",
"button",
"card"
],
"files": [
{
"path": "registry/new-york-v4/examples/form-tanstack-checkbox.tsx",
"content": "/* eslint-disable react/no-children-prop */\n\"use client\"\n\nimport { useForm } from \"@tanstack/react-form\"\nimport { toast } from \"sonner\"\nimport * as 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 { Checkbox } from \"@/registry/new-york-v4/ui/checkbox\"\nimport {\n Field,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldLegend,\n FieldSeparator,\n FieldSet,\n} from \"@/registry/new-york-v4/ui/field\"\n\nconst tasks = [\n {\n id: \"push\",\n label: \"Push notifications\",\n },\n {\n id: \"email\",\n label: \"Email notifications\",\n },\n] as const\n\nconst formSchema = z.object({\n responses: z.boolean(),\n tasks: z\n .array(z.string())\n .min(1, \"Please select at least one notification type.\")\n .refine(\n (value) => value.every((task) => tasks.some((t) => t.id === task)),\n {\n message: \"Invalid notification type selected.\",\n }\n ),\n})\n\nexport default function FormTanstackCheckbox() {\n const form = useForm({\n defaultValues: {\n responses: true,\n tasks: [] as string[],\n },\n validators: {\n onSubmit: formSchema,\n },\n onSubmit: async ({ value }) => {\n toast(\"You submitted the following values:\", {\n description: (\n <pre className=\"mt-2 w-[320px] overflow-x-auto rounded-md bg-code p-4 text-code-foreground\">\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>\n <CardTitle>Notifications</CardTitle>\n <CardDescription>Manage your notification preferences.</CardDescription>\n </CardHeader>\n <CardContent>\n <form\n id=\"form-tanstack-checkbox\"\n onSubmit={(e) => {\n e.preventDefault()\n form.handleSubmit()\n }}\n >\n <FieldGroup>\n <form.Field\n name=\"responses\"\n children={(field) => {\n const isInvalid =\n field.state.meta.isTouched && !field.state.meta.isValid\n return (\n <div>\n <FieldSet>\n <FieldLegend variant=\"label\">Responses</FieldLegend>\n <FieldDescription>\n Get notified for requests that take time, like research\n or image generation.\n </FieldDescription>\n <FieldGroup data-slot=\"checkbox-group\">\n <Field\n orientation=\"horizontal\"\n data-invalid={isInvalid}\n >\n <Checkbox\n id=\"form-tanstack-checkbox-responses\"\n name={field.name}\n checked={field.state.value}\n onCheckedChange={(checked) =>\n field.handleChange(checked === true)\n }\n disabled\n />\n <FieldLabel\n htmlFor=\"form-tanstack-checkbox-responses\"\n className=\"font-normal\"\n >\n Push notifications\n </FieldLabel>\n </Field>\n </FieldGroup>\n </FieldSet>\n {isInvalid && (\n <FieldError errors={field.state.meta.errors} />\n )}\n </div>\n )\n }}\n />\n <FieldSeparator />\n <form.Field\n name=\"tasks\"\n mode=\"array\"\n children={(field) => {\n const isInvalid =\n field.state.meta.isTouched && !field.state.meta.isValid\n return (\n <FieldGroup>\n <FieldSet data-invalid={isInvalid}>\n <FieldLegend variant=\"label\">Tasks</FieldLegend>\n <FieldDescription>\n Get notified when tasks you&apos;ve created have\n updates.\n </FieldDescription>\n <FieldGroup data-slot=\"checkbox-group\">\n {tasks.map((task) => (\n <Field\n key={task.id}\n orientation=\"horizontal\"\n data-invalid={isInvalid}\n >\n <Checkbox\n id={`form-tanstack-checkbox-${task.id}`}\n name={field.name}\n aria-invalid={isInvalid}\n checked={field.state.value.includes(task.id)}\n onCheckedChange={(checked) => {\n if (checked) {\n field.pushValue(task.id)\n } else {\n const index = field.state.value.indexOf(\n task.id\n )\n if (index > -1) {\n field.removeValue(index)\n }\n }\n }}\n />\n <FieldLabel\n htmlFor={`form-tanstack-checkbox-${task.id}`}\n className=\"font-normal\"\n >\n {task.label}\n </FieldLabel>\n </Field>\n ))}\n </FieldGroup>\n </FieldSet>\n {isInvalid && (\n <FieldError errors={field.state.meta.errors} />\n )}\n </FieldGroup>\n )\n }}\n />\n </FieldGroup>\n </form>\n </CardContent>\n <CardFooter>\n <Field orientation=\"horizontal\">\n <Button type=\"button\" variant=\"outline\" onClick={() => form.reset()}>\n Reset\n </Button>\n <Button type=\"submit\" form=\"form-tanstack-checkbox\">\n Save\n </Button>\n </Field>\n </CardFooter>\n </Card>\n )\n}\n",
"type": "registry:example"
}
],
"type": "registry:example"
}