useFieldset
Hook that manages collapsible fieldset state and ARIA attributes.
Usage#
import { useFieldset } from '@primereact/headless/fieldset';
const { rootProps, triggerProps, contentProps, indicatorProps, state } = useFieldset({ defaultOpen: true });
return (
<fieldset {...rootProps}>
<legend>
<button {...triggerProps}>
<span {...indicatorProps} />
</button>
</legend>
{state.open && <div {...contentProps}></div>}
</fieldset>
);useFieldset wraps useCollapsible and returns spread-ready prop objects for semantic fieldset/legend grouping — see Primitive for a component-based API.
Features#
- Single-hook architecture built on
useCollapsible - Returns spread-ready prop objects (
rootProps,triggerProps,contentProps,indicatorProps) - Controlled and uncontrolled open state management
- Exposes
toggle,open, andclosemethods for imperative control - Semantic
fieldset/legendstructure for native form grouping
Behavior#
Default Open#
Use defaultOpen to set the initial open state.
const fieldset = useFieldset({ defaultOpen: true });Controlled#
Use open and onOpenChange for full programmatic control. The hook never updates its own state in controlled mode.
const [open, setOpen] = React.useState(true);
const fieldset = useFieldset({
open,
onOpenChange: (e) => setOpen(e.value ?? false)
});The onOpenChange callback receives { originalEvent, value } where value is the new boolean state.
Disabled#
Set disabled to prevent interaction. When disabled, triggerProps sets tabIndex to -1, adds aria-disabled, and suppresses onClick.
const fieldset = useFieldset({ disabled: true });Using toggle, open, and close#
The hook exposes imperative methods for custom logic outside the standard trigger flow.
const fieldset = useFieldset({ defaultOpen: false });
// Open programmatically
fieldset.open(syntheticEvent);
// Close programmatically
fieldset.close(syntheticEvent);
// Toggle
fieldset.toggle(syntheticEvent);Conditional Rendering with state.open#
Use state.open to conditionally mount or unmount content.
const { contentProps, state } = useFieldset({ defaultOpen: true });
{
state.open && <div {...contentProps}>Fieldset content — only in DOM when open</div>;
}Alternatively, always render content and use CSS to show/hide:
<div {...contentProps} style={{ display: state.open ? 'block' : 'none' }}>
Fieldset content — always in DOM, toggled with CSS
</div>Custom Styling with Data Attributes#
Every prop object includes data-scope="fieldset" and a data-part attribute. State-dependent attributes (data-open, data-closed, data-disabled) are added automatically.
[data-scope='fieldset'][data-part='trigger'] {
font-weight: 600;
}
[data-scope='fieldset'][data-part='content'][data-open] {
animation: slideDown 200ms ease-out;
}
[data-scope='fieldset'][data-part='content'][data-closed] {
animation: slideUp 200ms ease-out;
}triggerProps also includes data-content-open/data-content-closed for styling the trigger based on content state.
[data-scope='fieldset'][data-part='trigger'][data-content-open] {
color: blue;
}API#
useFieldset#
| Name | Type | Default |
|---|---|---|
open | boolean | false |
| Controls the open state of the collapsible. | ||
defaultOpen | boolean | false |
| Defines the initial open state of the collapsible. | ||
disabled | boolean | false |
| When disabled, the component cannot be interacted with. | ||
tabIndex | number | 0 |
| Index of the element in tabbing order. | ||
onOpen | (event?: SyntheticEvent) => void | — |
| Callback triggered when the content is opened. | ||
onClose | (event?: SyntheticEvent) => void | — |
| Callback triggered when the content is closed. | ||
onOpenChange | (event: useFieldsetOpenChangeEvent) => void | — |
| Callback triggered when the content's toggle state changes. | ||
Accessibility#
See Fieldset Primitive for WAI-ARIA compliance details and keyboard support.