Fieldset
Fieldset is a container component with a legend and optional collapsible content.
Usage#
import { Fieldset } from '@primereact/ui/fieldset';<Fieldset.Root>
<Fieldset.Legend>
<Fieldset.Trigger>
<Fieldset.Indicator />
<Fieldset.Title />
</Fieldset.Trigger>
</Fieldset.Legend>
<Fieldset.Content />
</Fieldset.Root>Examples#
Basic#
Groups related form elements under a toggleable legend.
import { Divider } from '@primereact/ui/divider';
import { Fieldset } from '@primereact/ui/fieldset';
export default function BasicDemo() {
return (
<Fieldset.Root className="max-w-xs mx-auto">
<Fieldset.Legend>
<Fieldset.Title>Invoice #1024</Fieldset.Title>
</Fieldset.Legend>
<Fieldset.Content>
<div className="flex flex-col text-sm p-2">
<div className="flex justify-between">
<span className="text-color">Design Service</span>
<span className="text-muted-color">$120.00</span>
</div>
<div className="flex justify-between mt-3">
<span className="text-color">Hosting</span>
<span className="text-muted-color">$30.00</span>
</div>
<Divider.Root />
<div className="flex justify-between">
<span className="text-color font-medium">Total</span>
<span className="text-color font-medium">$150.00</span>
</div>
</div>
</Fieldset.Content>
</Fieldset.Root>
);
}
Toggleable#
Use Fieldset.Trigger inside the legend to make the fieldset collapsible. The defaultOpen prop sets the initial state, and content visibility is animated by default.
'use client';
import { Minus } from '@primeicons/react/minus';
import { Plus } from '@primeicons/react/plus';
import { Divider } from '@primereact/ui/divider';
import { Fieldset } from '@primereact/ui/fieldset';
export default function ToggleableDemo() {
return (
<Fieldset.Root defaultOpen className="max-w-xs mx-auto">
<Fieldset.Legend>
<Fieldset.Trigger className="flex items-center gap-2">
<Fieldset.Indicator match="open">
<Minus />
</Fieldset.Indicator>
<Fieldset.Indicator match="closed">
<Plus />
</Fieldset.Indicator>
<Fieldset.Title>Invoice #1024</Fieldset.Title>
</Fieldset.Trigger>
</Fieldset.Legend>
<Fieldset.Content>
<div className="flex flex-col text-sm p-2">
<div className="flex justify-between">
<span className="text-color">Design Service</span>
<span className="text-muted-color">$120.00</span>
</div>
<div className="flex justify-between mt-3">
<span className="text-color">Hosting</span>
<span className="text-muted-color">$30.00</span>
</div>
<Divider.Root />
<div className="flex justify-between">
<span className="text-color font-medium">Total</span>
<span className="text-color font-medium">$150.00</span>
</div>
</div>
</Fieldset.Content>
</Fieldset.Root>
);
}
Controlled#
Control fieldset state from outside with the open and onOpenChange props.
'use client';
import { Minus } from '@primeicons/react/minus';
import { Plus } from '@primeicons/react/plus';
import { Button } from '@primereact/ui/button';
import { Divider } from '@primereact/ui/divider';
import { Fieldset, type FieldsetRootOpenChangeEvent } from '@primereact/ui/fieldset';
import { useState } from 'react';
export default function ControlledToggleableDemo() {
const [open, setOpen] = useState(true);
return (
<div className="space-y-4 max-w-xs mx-auto">
<div className="flex gap-2 justify-center">
<Button onClick={() => setOpen(true)} severity={open ? 'primary' : 'secondary'}>
Open
</Button>
<Button onClick={() => setOpen(false)} severity={!open ? 'primary' : 'secondary'}>
Close
</Button>
</div>
<Fieldset.Root open={open} onOpenChange={(e: FieldsetRootOpenChangeEvent) => setOpen(e.value ?? false)}>
<Fieldset.Legend>
<Fieldset.Trigger className="flex items-center gap-2">
<Fieldset.Indicator match="open">
<Minus />
</Fieldset.Indicator>
<Fieldset.Indicator match="closed">
<Plus />
</Fieldset.Indicator>
<Fieldset.Title>Invoice #1024</Fieldset.Title>
</Fieldset.Trigger>
</Fieldset.Legend>
<Fieldset.Content>
<div className="flex flex-col text-sm p-2">
<div className="flex justify-between">
<span className="text-color">Design Service</span>
<span className="text-muted-color">$120.00</span>
</div>
<div className="flex justify-between mt-3">
<span className="text-color">Hosting</span>
<span className="text-muted-color">$30.00</span>
</div>
<Divider.Root />
<div className="flex justify-between">
<span className="text-color font-medium">Total</span>
<span className="text-color font-medium">$150.00</span>
</div>
</div>
</Fieldset.Content>
</Fieldset.Root>
</div>
);
}
Indicator#
Fieldset.Indicator supports conditional rendering based on fieldset state. Use the match prop to render content only when the state matches.
<Fieldset.Legend>
<Fieldset.Trigger>
<Fieldset.Title>Header</Fieldset.Title>
<Fieldset.Indicator match="open">
<Minus />
</Fieldset.Indicator>
<Fieldset.Indicator match="closed">
<Plus />
</Fieldset.Indicator>
</Fieldset.Trigger>
</Fieldset.Legend>Available values: open, closed. Without the match prop, the indicator renders in all states.
Match open / closed
CSS-only with data attributes
import { ChevronDown } from '@primeicons/react/chevron-down';
import { Minus } from '@primeicons/react/minus';
import { Plus } from '@primeicons/react/plus';
import { Divider } from '@primereact/ui/divider';
import { Fieldset } from '@primereact/ui/fieldset';
export default function IndicatorDemo() {
return (
<div className="flex flex-col gap-8 max-w-xs mx-auto">
<div>
<h3 className="text-sm font-medium text-surface-500 mb-2">Match open / closed</h3>
<Fieldset.Root defaultOpen>
<Fieldset.Legend>
<Fieldset.Trigger className="flex items-center gap-2">
<Fieldset.Indicator match="open">
<Minus />
</Fieldset.Indicator>
<Fieldset.Indicator match="closed">
<Plus />
</Fieldset.Indicator>
<Fieldset.Title>Invoice #1024</Fieldset.Title>
</Fieldset.Trigger>
</Fieldset.Legend>
<Fieldset.Content>
<div className="flex flex-col text-sm p-2">
<div className="flex justify-between">
<span className="text-color">Design Service</span>
<span className="text-muted-color">$120.00</span>
</div>
<div className="flex justify-between mt-3">
<span className="text-color">Hosting</span>
<span className="text-muted-color">$30.00</span>
</div>
<Divider.Root />
<div className="flex justify-between">
<span className="text-color font-medium">Total</span>
<span className="text-color font-medium">$150.00</span>
</div>
</div>
</Fieldset.Content>
</Fieldset.Root>
</div>
<div>
<h3 className="text-sm font-medium text-surface-500 mb-2">CSS-only with data attributes</h3>
<Fieldset.Root defaultOpen>
<Fieldset.Legend>
<Fieldset.Trigger className="flex items-center gap-2">
<Fieldset.Indicator>
<ChevronDown className="transition-transform duration-200 in-data-open:rotate-180" />
</Fieldset.Indicator>
<Fieldset.Title>Invoice #1024</Fieldset.Title>
</Fieldset.Trigger>
</Fieldset.Legend>
<Fieldset.Content>
<div className="flex flex-col text-sm p-2">
<div className="flex justify-between">
<span className="text-color">Design Service</span>
<span className="text-muted-color">$120.00</span>
</div>
<div className="flex justify-between mt-3">
<span className="text-color">Hosting</span>
<span className="text-muted-color">$30.00</span>
</div>
<Divider.Root />
<div className="flex justify-between">
<span className="text-color font-medium">Total</span>
<span className="text-color font-medium">$150.00</span>
</div>
</div>
</Fieldset.Content>
</Fieldset.Root>
</div>
</div>
);
}
API#
Sub-Components#
See Primitive API for FieldsetRoot, FieldsetLegend, FieldsetIndicator, FieldsetContent, FieldsetTitle, FieldsetTrigger component documentation.
Hooks#
See Headless API for useFieldset hook documentation.
Accessibility#
See Fieldset Primitive for WAI-ARIA compliance details and keyboard support.