Introducing PrimeReact v11-alpha 🎉Discover Now

useFieldset

Hook that manages collapsible fieldset state and ARIA attributes.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
basic-demo

Usage#

import { useFieldset } from '@primereact/headless/fieldset';
const { rootProps, triggerProps, contentProps, indicatorProps, state } = useFieldset({ defaultOpen: true });
 
<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#

  • Semantic form grouping — props are tuned for native fieldset and legend elements so built-in form semantics stay intact
  • Single-hook collapsible — built on useCollapsible, one call returns rootProps, triggerProps, contentProps, and indicatorProps
  • Controlled or uncontrolled open state — pass open/onOpenChange or rely on defaultOpen
  • Imperative controls — toggle(), open(), and close() flip state from anywhere outside the legend
  • Full render control — use state.open to mount, hide, or animate content on your terms

Working with callbacks#

Controlled open state#

Drive the fieldset's open state from parent state.

const [open, setOpen] = React.useState(true);
 
const fieldset = useFieldset({
    open,
    onOpenChange: (e) => setOpen(e.value ?? false)
});

onOpenChange receives { originalEvent, value } where value is the new boolean state.

Collapsing groups of form fields#

Pair useFieldset with form libraries by gating validation on state.open — skip validating hidden groups.

const fieldset = useFieldset({ defaultOpen: false });
 
const onSubmit = (data) => {
    if (fieldset.state.open) {
        validateAdvancedFields(data);
    }
    submit(data);
};

Imperative control from toolbar actions#

Use toggle, open, and close to drive the fieldset from "Expand all" / "Collapse all" buttons elsewhere on the page.

const fieldset = useFieldset({ defaultOpen: false });
 
<button onClick={(e) => fieldset.open(e)}>Show advanced options</button>;

Animated reveal#

Gate content mounting on state.open and wrap with your motion library of choice.

const { contentProps, state } = useFieldset({ defaultOpen: true });
 
<AnimatePresence>
    {state.open && (
        <motion.div {...contentProps} initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }}>
            Advanced fields
        </motion.div>
    )}
</AnimatePresence>;

Styling with data attributes#

Every prop object includes data-scope="fieldset" and a data-part attribute. State is reflected via data-open/data-closed/data-disabled, and triggerProps also gets data-content-open/data-content-closed.

[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;
}
 
[data-scope='fieldset'][data-part='trigger'][data-content-open] {
    color: blue;
}

API#

useFieldset#

NameTypeDefault
openbooleanfalse
Controls the open state of the collapsible.
defaultOpenbooleanfalse
Defines the initial open state of the collapsible.
disabledbooleanfalse
When disabled, the component cannot be interacted with.
tabIndexnumber0
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#

Enter or Space on the legend toggles when toggleable, otherwise standard fieldset semantics apply. See Primitive for full WAI-ARIA compliance details.