Section
A titled group of fields, rendered as a fieldset.
Installation
npx shadcn@latest add @formdef/sectionRegister it in the section structure slot in lib/formdef/index.tsx, as structure: { section: Section }. From then on every { section } entry of a layout renders through it.
Usage
export const = createForm({
: .({ : .(), : .(), : .() }),
: { : '', : '', : '' },
fields: {
name: { : 'text', : { : 'Name' } },
street: { : 'text', : { : 'Street' } },
city: { : 'text', : { : 'City' } },
},
: [
'name',
{
: 'Delivery address',
: ['street', 'city'],
: { : 'Where the parcel goes.' },
},
],
})The section renders a <fieldset>. Its <legend> is the entry's title, and a description sits
below it, tied to the fieldset with aria-describedby. For a section inside another one,
variant: 'label' sets the legend in the size of a field label.
Layout describes sections, rows and the other layout entries.
Props
Prop
Type
Source
'use client'
import type { SectionProps } from '@formdef/core'
import { type ComponentProps, useId } from 'react'
import { FieldDescription, FieldGroup, FieldLegend, FieldSet } from '@/components/ui/field'
type LegendVariant = NonNullable<ComponentProps<typeof FieldLegend>['variant']>
type SectionFrameProps = SectionProps &
Pick<ComponentProps<typeof FieldSet>, 'className'> & {
description?: string | undefined
variant?: LegendVariant | undefined
}
export const Section = ({
label,
description,
variant = 'legend',
className,
children,
}: SectionFrameProps) => {
const descriptionId = useId()
const hasDescription = description !== undefined && description !== ''
return (
<FieldSet className={className} aria-describedby={hasDescription ? descriptionId : undefined}>
<FieldLegend variant={variant}>{label}</FieldLegend>
{hasDescription && <FieldDescription id={descriptionId}>{description}</FieldDescription>}
<FieldGroup>{children}</FieldGroup>
</FieldSet>
)
}