fix: checkbox example for forms

This commit is contained in:
shadcn
2026-02-13 15:59:10 +04:00
parent 0e8a006adc
commit feff5b6a57
5 changed files with 154 additions and 137 deletions

1
.gitignore vendored
View File

@@ -41,3 +41,4 @@ tsconfig.tsbuildinfo
.vscode
.notes
.playwright-mcp

View File

@@ -22,7 +22,7 @@ We are going to build the following form. It has a simple text input and a texta
<ComponentPreview
name="form-rhf-demo"
className="sm:[&_.preview]:h-[700px] sm:[&_pre]:!h-[700px]"
className="sm:[&_.preview]:h-[700px]"
chromeLessOnMobile
/>
@@ -229,7 +229,7 @@ Display errors next to the field using `<FieldError />`. For styling and accessi
<ComponentPreview
name="form-rhf-input"
className="sm:[&_.preview]:h-[700px] sm:[&_pre]:!h-[700px]"
className="sm:[&_.preview]:h-[700px]"
chromeLessOnMobile
/>
@@ -256,7 +256,7 @@ For simple text inputs, spread the `field` object onto the input.
<ComponentPreview
name="form-rhf-textarea"
className="sm:[&_.preview]:h-[700px] sm:[&_pre]:!h-[700px]"
className="sm:[&_.preview]:h-[700px]"
chromeLessOnMobile
/>
@@ -293,7 +293,7 @@ For textarea fields, spread the `field` object onto the textarea.
<ComponentPreview
name="form-rhf-select"
className="sm:[&_.preview]:h-[500px] sm:[&_pre]:!h-[500px]"
className="sm:[&_.preview]:h-[500px]"
chromeLessOnMobile
/>
@@ -342,7 +342,7 @@ For textarea fields, spread the `field` object onto the textarea.
<ComponentPreview
name="form-rhf-checkbox"
className="sm:[&_.preview]:h-[700px] sm:[&_pre]:!h-[700px]"
className="sm:[&_.preview]:h-[700px]"
chromeLessOnMobile
/>
@@ -397,7 +397,7 @@ For textarea fields, spread the `field` object onto the textarea.
<ComponentPreview
name="form-rhf-radiogroup"
className="sm:[&_.preview]:h-[700px] sm:[&_pre]:!h-[700px]"
className="sm:[&_.preview]:h-[700px]"
chromeLessOnMobile
/>
@@ -445,7 +445,7 @@ For textarea fields, spread the `field` object onto the textarea.
<ComponentPreview
name="form-rhf-switch"
className="sm:[&_.preview]:h-[500px] sm:[&_pre]:!h-[500px]"
className="sm:[&_.preview]:h-[500px]"
chromeLessOnMobile
/>
@@ -482,7 +482,7 @@ Here is an example of a more complex form with multiple fields and validation.
<ComponentPreview
name="form-rhf-complex"
className="sm:[&_.preview]:h-[1300px] sm:[&_pre]:!h-[1300px]"
className="sm:[&_.preview]:h-[1300px]"
chromeLessOnMobile
/>
@@ -502,7 +502,7 @@ React Hook Form provides a `useFieldArray` hook for managing dynamic array field
<ComponentPreview
name="form-rhf-array"
className="sm:[&_.preview]:h-[700px] sm:[&_pre]:!h-[700px]"
className="sm:[&_.preview]:h-[700px]"
chromeLessOnMobile
/>

View File

@@ -22,7 +22,7 @@ We'll start by building the following form. It has a simple text input and a tex
<ComponentPreview
name="form-tanstack-demo"
className="sm:[&_.preview]:h-[700px] sm:[&_pre]:!h-[700px]"
className="sm:[&_.preview]:h-[700px]"
chromeLessOnMobile
/>
@@ -259,7 +259,7 @@ Display errors next to the field using `<FieldError />`. For styling and accessi
<ComponentPreview
name="form-tanstack-input"
className="sm:[&_.preview]:h-[700px] sm:[&_pre]:!h-[700px]"
className="sm:[&_.preview]:h-[700px]"
chromeLessOnMobile
/>
@@ -299,7 +299,7 @@ Display errors next to the field using `<FieldError />`. For styling and accessi
<ComponentPreview
name="form-tanstack-textarea"
className="sm:[&_.preview]:h-[700px] sm:[&_pre]:!h-[700px]"
className="sm:[&_.preview]:h-[700px]"
chromeLessOnMobile
/>
@@ -341,7 +341,7 @@ Display errors next to the field using `<FieldError />`. For styling and accessi
<ComponentPreview
name="form-tanstack-select"
className="sm:[&_.preview]:h-[700px] sm:[&_pre]:!h-[700px]"
className="sm:[&_.preview]:h-[700px]"
chromeLessOnMobile
/>
@@ -393,7 +393,7 @@ Display errors next to the field using `<FieldError />`. For styling and accessi
<ComponentPreview
name="form-tanstack-checkbox"
className="sm:[&_.preview]:h-[700px] sm:[&_pre]:!h-[700px]"
className="sm:[&_.preview]:h-[700px]"
chromeLessOnMobile
/>
@@ -455,7 +455,7 @@ Display errors next to the field using `<FieldError />`. For styling and accessi
<ComponentPreview
name="form-tanstack-radiogroup"
className="sm:[&_.preview]:h-[700px] sm:[&_pre]:!h-[700px]"
className="sm:[&_.preview]:h-[700px]"
chromeLessOnMobile
/>
@@ -508,7 +508,7 @@ Display errors next to the field using `<FieldError />`. For styling and accessi
<ComponentPreview
name="form-tanstack-switch"
className="sm:[&_.preview]:h-[500px] sm:[&_pre]:!h-[500px]"
className="sm:[&_.preview]:h-[500px]"
chromeLessOnMobile
/>
@@ -547,7 +547,7 @@ Here is an example of a more complex form with multiple fields and validation.
<ComponentPreview
name="form-tanstack-complex"
className="sm:[&_.preview]:h-[1100px] sm:[&_pre]:!h-[1100px]"
className="sm:[&_.preview]:h-[1100px]"
chromeLessOnMobile
/>
@@ -567,7 +567,7 @@ TanStack Form provides powerful array field management with `mode="array"`. This
<ComponentPreview
name="form-tanstack-array"
className="sm:[&_.preview]:h-[700px] sm:[&_pre]:!h-[700px]"
className="sm:[&_.preview]:h-[700px]"
chromeLessOnMobile
/>

View File

@@ -90,33 +90,35 @@ export default function FormRhfCheckbox() {
name="responses"
control={form.control}
render={({ field, fieldState }) => (
<FieldSet data-invalid={fieldState.invalid}>
<FieldLegend variant="label">Responses</FieldLegend>
<FieldDescription>
Get notified for requests that take time, like research or
image generation.
</FieldDescription>
<FieldGroup data-slot="checkbox-group">
<Field orientation="horizontal">
<Checkbox
id="form-rhf-checkbox-responses"
name={field.name}
checked={field.value}
onCheckedChange={field.onChange}
disabled
/>
<FieldLabel
htmlFor="form-rhf-checkbox-responses"
className="font-normal"
>
Push notifications
</FieldLabel>
</Field>
</FieldGroup>
<div>
<FieldSet data-invalid={fieldState.invalid}>
<FieldLegend variant="label">Responses</FieldLegend>
<FieldDescription>
Get notified for requests that take time, like research or
image generation.
</FieldDescription>
<FieldGroup data-slot="checkbox-group">
<Field orientation="horizontal">
<Checkbox
id="form-rhf-checkbox-responses"
name={field.name}
checked={field.value}
onCheckedChange={field.onChange}
disabled
/>
<FieldLabel
htmlFor="form-rhf-checkbox-responses"
className="font-normal"
>
Push notifications
</FieldLabel>
</Field>
</FieldGroup>
</FieldSet>
{fieldState.invalid && (
<FieldError errors={[fieldState.error]} />
)}
</FieldSet>
</div>
)}
/>
<FieldSeparator />
@@ -124,43 +126,47 @@ export default function FormRhfCheckbox() {
name="tasks"
control={form.control}
render={({ field, fieldState }) => (
<FieldSet data-invalid={fieldState.invalid}>
<FieldLegend variant="label">Tasks</FieldLegend>
<FieldDescription>
Get notified when tasks you&apos;ve created have updates.
</FieldDescription>
<FieldGroup data-slot="checkbox-group">
{tasks.map((task) => (
<Field
key={task.id}
orientation="horizontal"
data-invalid={fieldState.invalid}
>
<Checkbox
id={`form-rhf-checkbox-${task.id}`}
name={field.name}
aria-invalid={fieldState.invalid}
checked={field.value.includes(task.id)}
onCheckedChange={(checked) => {
const newValue = checked
? [...field.value, task.id]
: field.value.filter((value) => value !== task.id)
field.onChange(newValue)
}}
/>
<FieldLabel
htmlFor={`form-rhf-checkbox-${task.id}`}
className="font-normal"
<div>
<FieldSet data-invalid={fieldState.invalid}>
<FieldLegend variant="label">Tasks</FieldLegend>
<FieldDescription>
Get notified when tasks you&apos;ve created have updates.
</FieldDescription>
<FieldGroup data-slot="checkbox-group">
{tasks.map((task) => (
<Field
key={task.id}
orientation="horizontal"
data-invalid={fieldState.invalid}
>
{task.label}
</FieldLabel>
</Field>
))}
</FieldGroup>
<Checkbox
id={`form-rhf-checkbox-${task.id}`}
name={field.name}
aria-invalid={fieldState.invalid}
checked={field.value.includes(task.id)}
onCheckedChange={(checked) => {
const newValue = checked
? [...field.value, task.id]
: field.value.filter(
(value) => value !== task.id
)
field.onChange(newValue)
}}
/>
<FieldLabel
htmlFor={`form-rhf-checkbox-${task.id}`}
className="font-normal"
>
{task.label}
</FieldLabel>
</Field>
))}
</FieldGroup>
</FieldSet>
{fieldState.invalid && (
<FieldError errors={[fieldState.error]} />
)}
</FieldSet>
</div>
)}
/>
</FieldGroup>

View File

@@ -98,35 +98,40 @@ export default function FormTanstackCheckbox() {
const isInvalid =
field.state.meta.isTouched && !field.state.meta.isValid
return (
<FieldSet>
<FieldLegend variant="label">Responses</FieldLegend>
<FieldDescription>
Get notified for requests that take time, like research or
image generation.
</FieldDescription>
<FieldGroup data-slot="checkbox-group">
<Field orientation="horizontal" data-invalid={isInvalid}>
<Checkbox
id="form-tanstack-checkbox-responses"
name={field.name}
checked={field.state.value}
onCheckedChange={(checked) =>
field.handleChange(checked === true)
}
disabled
/>
<FieldLabel
htmlFor="form-tanstack-checkbox-responses"
className="font-normal"
<div>
<FieldSet>
<FieldLegend variant="label">Responses</FieldLegend>
<FieldDescription>
Get notified for requests that take time, like research
or image generation.
</FieldDescription>
<FieldGroup data-slot="checkbox-group">
<Field
orientation="horizontal"
data-invalid={isInvalid}
>
Push notifications
</FieldLabel>
</Field>
</FieldGroup>
<Checkbox
id="form-tanstack-checkbox-responses"
name={field.name}
checked={field.state.value}
onCheckedChange={(checked) =>
field.handleChange(checked === true)
}
disabled
/>
<FieldLabel
htmlFor="form-tanstack-checkbox-responses"
className="font-normal"
>
Push notifications
</FieldLabel>
</Field>
</FieldGroup>
</FieldSet>
{isInvalid && (
<FieldError errors={field.state.meta.errors} />
)}
</FieldSet>
</div>
)
}}
/>
@@ -138,47 +143,52 @@ export default function FormTanstackCheckbox() {
const isInvalid =
field.state.meta.isTouched && !field.state.meta.isValid
return (
<FieldSet>
<FieldLegend variant="label">Tasks</FieldLegend>
<FieldDescription>
Get notified when tasks you&apos;ve created have updates.
</FieldDescription>
<FieldGroup data-slot="checkbox-group">
{tasks.map((task) => (
<Field
key={task.id}
orientation="horizontal"
data-invalid={isInvalid}
>
<Checkbox
id={`form-tanstack-checkbox-${task.id}`}
name={field.name}
aria-invalid={isInvalid}
checked={field.state.value.includes(task.id)}
onCheckedChange={(checked) => {
if (checked) {
field.pushValue(task.id)
} else {
const index = field.state.value.indexOf(task.id)
if (index > -1) {
field.removeValue(index)
}
}
}}
/>
<FieldLabel
htmlFor={`form-tanstack-checkbox-${task.id}`}
className="font-normal"
<div>
<FieldSet>
<FieldLegend variant="label">Tasks</FieldLegend>
<FieldDescription>
Get notified when tasks you&apos;ve created have
updates.
</FieldDescription>
<FieldGroup data-slot="checkbox-group">
{tasks.map((task) => (
<Field
key={task.id}
orientation="horizontal"
data-invalid={isInvalid}
>
{task.label}
</FieldLabel>
</Field>
))}
</FieldGroup>
<Checkbox
id={`form-tanstack-checkbox-${task.id}`}
name={field.name}
aria-invalid={isInvalid}
checked={field.state.value.includes(task.id)}
onCheckedChange={(checked) => {
if (checked) {
field.pushValue(task.id)
} else {
const index = field.state.value.indexOf(
task.id
)
if (index > -1) {
field.removeValue(index)
}
}
}}
/>
<FieldLabel
htmlFor={`form-tanstack-checkbox-${task.id}`}
className="font-normal"
>
{task.label}
</FieldLabel>
</Field>
))}
</FieldGroup>
</FieldSet>
{isInvalid && (
<FieldError errors={field.state.meta.errors} />
)}
</FieldSet>
</div>
)
}}
/>