Panel
An unstyled, accessible panel component with optional collapsible content.
Build fully custom content panels with complete control over layout and styling.
Pre-styled Versions
Features#
- Compound component API with seven sub-components:
Root,Header,Title,Trigger,Indicator,Content,Footer
Usage#
import { Panel } from 'primereact/panel';<Panel.Root>
<Panel.Header>
<Panel.Title />
<Panel.Trigger>
<Panel.Indicator />
</Panel.Trigger>
</Panel.Header>
<Panel.Content />
<Panel.Footer />
</Panel.Root>Behavior#
Motion Animation#
Use motionProps on Root to configure open/close animations.
<Panel.Root motionProps={{ name: 'p-collapsible', cssVarPrefix: 'panel-content', hideStrategy: 'none' }}>...</Panel.Root>See Motion for animation phases, CSS variables, and hide strategies.
Polymorphic Rendering#
Use as on any sub-component to change the rendered HTML element.
<Panel.Root as="section">
<Panel.Header as="nav">
<Panel.Title as="h2">...</Panel.Title>
</Panel.Header>
<Panel.Content as="article">...</Panel.Content>
<Panel.Footer as="nav">...</Panel.Footer>
</Panel.Root>Default elements: Root=div, Header=div, Title=div, Trigger=button, Content=div, Footer=div, Indicator=span.
Render Function Children#
Content accepts a render function as children, providing access to the component instance. The instance exposes panel (root instance) and motion (animation state).
<Panel.Content>{(instance) => <div>Panel is {instance.panel?.state.open ? 'open' : 'closed'}</div>}</Panel.Content>Pass Through#
Some parts may not be visible in the preview depending on the component's current state.
/* Select a part to see its CSS selector for custom styling */API#
PanelRoot#
| Name | Type | Default |
|---|---|---|
ref | Ref<unknown> | — |
| The reference to the component instance. | ||
pIf | boolean | true |
| Whether the component should be rendered. | ||
style | CSSProperties | ((instance?: PanelRootInstance) => CSSProperties) | — |
| The style to apply to the component. | ||
className | string | ((instance?: PanelRootInstance) => string) | — |
| The class name to apply to the component. | ||
as | string | number | bigint | boolean | ComponentClass<any, any> | FunctionComponent<any> | ReactElement<unknown, string | JSXElementConstructor<any>> | Iterable<ReactNode, any, any> | ReactPortal | Promise<AwaitedReactNode> | — |
| The component type to render. | ||
asChild | boolean | false |
| Whether the component should be rendered as a child component. | ||
instance | PanelRootInstance | — |
| The instance to pass to the component. | ||
pt | SafeRecord<PanelRootPassThrough> | — |
| The pass-through props to pass to the component. | ||
ptOptions | PassThroughOptions | — |
| The pass-through options to pass to the component. | ||
unstyled | boolean | — |
| Whether the component should be rendered without classes. | ||
dt | unknown | — |
| The design token to use for the component. | ||
styles | StylesOptions<ComponentInstance> | — |
| The styles to use for the component. | ||
render | (instance: PanelRootInstance) => ReactNode | — |
| The render function to render the component with instance access. | ||
children | any | — |
| The children to render. Accepts `React.ReactNode` for static content or a render function `(instance: I) => React.ReactNode` for instance access. Typed as `any` to avoid JSX type errors when used directly in templates. | ||
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. | ||
toggleable | boolean | false |
| When enabled, the content of panel can be expanded and collapsed by clicking the header. | ||
lazy | boolean | false |
| When enabled, hidden content is not rendered at all. Defaults to false that hides content with css. | ||
motionProps | MotionOptions | — |
| Used to configure the motion of the panel content. | ||
onOpenChange | (event: PanelRootOpenChangeEvent) => void | — |
| Callback fired when the panel's open state changes. | ||
[key: string] | any | — |
pt-{optionName}-* | - | — |
| Pass through attributes for customizing component. For more info, see Pass Through tab. | ||
| Attribute | Value |
|---|---|
data-scope | "panel" |
data-part | "root" |
data-open | Present when expanded |
data-closed | Present when collapsed |
data-disabled | Present when disabled |
Defines passthrough(pt) options of Panel component.
| label | type | description |
|---|---|---|
| root | PanelRootPassThroughType<HTMLAttributes<HTMLDivElement>> | Used to pass attributes to the root's DOM element. |
| header | PanelRootPassThroughType<HTMLAttributes<HTMLDivElement>> | Used to pass attributes to the header's DOM element. |
| trigger | PanelRootPassThroughType<HTMLAttributes<HTMLButtonElement>> | Used to pass attributes to the trigger's DOM element. |
| title | PanelRootPassThroughType<HTMLAttributes<HTMLDivElement>> | Used to pass attributes to the title's DOM element. |
| content | PanelRootPassThroughType<HTMLAttributes<HTMLDivElement>> | Used to pass attributes to the content's DOM element. |
| contentOuter | PanelRootPassThroughType<HTMLAttributes<HTMLDivElement>> | Used to pass attributes to the content outer wrapper's DOM element. |
| contentInner | PanelRootPassThroughType<HTMLAttributes<HTMLDivElement>> | Used to pass attributes to the content inner wrapper's DOM element. |
| footer | PanelRootPassThroughType<HTMLAttributes<HTMLDivElement>> | Used to pass attributes to the footer's DOM element. |
| indicator | PanelRootPassThroughType<HTMLAttributes<HTMLSpanElement>> | Used to pass attributes to the indicator's DOM element. |
PanelHeader#
| Name | Type | Default |
|---|---|---|
ref | Ref<unknown> | — |
| The reference to the component instance. | ||
pIf | boolean | true |
| Whether the component should be rendered. | ||
style | CSSProperties | ((instance?: PanelHeaderInstance) => CSSProperties) | — |
| The style to apply to the component. | ||
className | string | ((instance?: PanelHeaderInstance) => string) | — |
| The class name to apply to the component. | ||
as | string | number | bigint | boolean | ComponentClass<any, any> | FunctionComponent<any> | ReactElement<unknown, string | JSXElementConstructor<any>> | Iterable<ReactNode, any, any> | ReactPortal | Promise<AwaitedReactNode> | — |
| The component type to render. | ||
asChild | boolean | false |
| Whether the component should be rendered as a child component. | ||
instance | PanelHeaderInstance | — |
| The instance to pass to the component. | ||
pt | SafeRecord<PanelHeaderPassThrough> | — |
| The pass-through props to pass to the component. | ||
ptOptions | PassThroughOptions | — |
| The pass-through options to pass to the component. | ||
unstyled | boolean | — |
| Whether the component should be rendered without classes. | ||
dt | unknown | — |
| The design token to use for the component. | ||
styles | StylesOptions<ComponentInstance> | — |
| The styles to use for the component. | ||
render | (instance: PanelHeaderInstance) => ReactNode | — |
| The render function to render the component with instance access. | ||
children | any | — |
| The children to render. Accepts `React.ReactNode` for static content or a render function `(instance: I) => React.ReactNode` for instance access. Typed as `any` to avoid JSX type errors when used directly in templates. | ||
[key: string] | any | — |
pt-{optionName}-* | - | — |
| Pass through attributes for customizing component. For more info, see Pass Through tab. | ||
Defines passthrough(pt) options of PanelHeadercomponent.
| label | type | description |
|---|---|---|
| root | PanelHeaderPassThroughType<HTMLAttributes<HTMLDivElement>> | Used to pass attributes to the root's DOM element. |
PanelTitle#
| Name | Type | Default |
|---|---|---|
ref | Ref<unknown> | — |
| The reference to the component instance. | ||
pIf | boolean | true |
| Whether the component should be rendered. | ||
style | CSSProperties | ((instance?: PanelTitleInstance) => CSSProperties) | — |
| The style to apply to the component. | ||
className | string | ((instance?: PanelTitleInstance) => string) | — |
| The class name to apply to the component. | ||
as | string | number | bigint | boolean | ComponentClass<any, any> | FunctionComponent<any> | ReactElement<unknown, string | JSXElementConstructor<any>> | Iterable<ReactNode, any, any> | ReactPortal | Promise<AwaitedReactNode> | — |
| The component type to render. | ||
asChild | boolean | false |
| Whether the component should be rendered as a child component. | ||
instance | PanelTitleInstance | — |
| The instance to pass to the component. | ||
pt | SafeRecord<PanelTitlePassThrough> | — |
| The pass-through props to pass to the component. | ||
ptOptions | PassThroughOptions | — |
| The pass-through options to pass to the component. | ||
unstyled | boolean | — |
| Whether the component should be rendered without classes. | ||
dt | unknown | — |
| The design token to use for the component. | ||
styles | StylesOptions<ComponentInstance> | — |
| The styles to use for the component. | ||
render | (instance: PanelTitleInstance) => ReactNode | — |
| The render function to render the component with instance access. | ||
children | any | — |
| The children to render. Accepts `React.ReactNode` for static content or a render function `(instance: I) => React.ReactNode` for instance access. Typed as `any` to avoid JSX type errors when used directly in templates. | ||
[key: string] | any | — |
pt-{optionName}-* | - | — |
| Pass through attributes for customizing component. For more info, see Pass Through tab. | ||
Defines passthrough(pt) options of PanelTitlecomponent.
| label | type | description |
|---|---|---|
| root | PanelTitlePassThroughType<HTMLAttributes<HTMLDivElement>> | Used to pass attributes to the root's DOM element. |
PanelTrigger#
| Name | Type | Default |
|---|---|---|
ref | Ref<unknown> | — |
| The reference to the component instance. | ||
pIf | boolean | true |
| Whether the component should be rendered. | ||
style | CSSProperties | ((instance?: PanelTriggerInstance) => CSSProperties) | — |
| The style to apply to the component. | ||
className | string | ((instance?: PanelTriggerInstance) => string) | — |
| The class name to apply to the component. | ||
as | string | number | bigint | boolean | ComponentClass<any, any> | FunctionComponent<any> | ReactElement<unknown, string | JSXElementConstructor<any>> | Iterable<ReactNode, any, any> | ReactPortal | Promise<AwaitedReactNode> | — |
| The component type to render. | ||
asChild | boolean | false |
| Whether the component should be rendered as a child component. | ||
instance | PanelTriggerInstance | — |
| The instance to pass to the component. | ||
pt | SafeRecord<PanelTriggerPassThrough> | — |
| The pass-through props to pass to the component. | ||
ptOptions | PassThroughOptions | — |
| The pass-through options to pass to the component. | ||
unstyled | boolean | — |
| Whether the component should be rendered without classes. | ||
dt | unknown | — |
| The design token to use for the component. | ||
styles | StylesOptions<ComponentInstance> | — |
| The styles to use for the component. | ||
render | (instance: PanelTriggerInstance) => ReactNode | — |
| The render function to render the component with instance access. | ||
children | any | — |
| The children to render. Accepts `React.ReactNode` for static content or a render function `(instance: I) => React.ReactNode` for instance access. Typed as `any` to avoid JSX type errors when used directly in templates. | ||
[key: string] | any | — |
pt-{optionName}-* | - | — |
| Pass through attributes for customizing component. For more info, see Pass Through tab. | ||
| Attribute | Value |
|---|---|
data-scope | "panel" |
data-part | "trigger" |
data-content-open | Present when content open |
data-content-closed | Present when content closed |
Defines passthrough(pt) options of PanelTrigger component.
| label | type | description |
|---|---|---|
| root | PanelTriggerPassThroughType<HTMLAttributes<HTMLButtonElement>> | Used to pass attributes to the root's DOM element. |
PanelIndicator#
| Name | Type | Default |
|---|---|---|
ref | Ref<unknown> | — |
| The reference to the component instance. | ||
pIf | boolean | true |
| Whether the component should be rendered. | ||
style | CSSProperties | ((instance?: PanelIndicatorInstance) => CSSProperties) | — |
| The style to apply to the component. | ||
className | string | ((instance?: PanelIndicatorInstance) => string) | — |
| The class name to apply to the component. | ||
as | string | number | bigint | boolean | ComponentClass<any, any> | FunctionComponent<any> | ReactElement<unknown, string | JSXElementConstructor<any>> | Iterable<ReactNode, any, any> | ReactPortal | Promise<AwaitedReactNode> | — |
| The component type to render. | ||
asChild | boolean | false |
| Whether the component should be rendered as a child component. | ||
instance | PanelIndicatorInstance | — |
| The instance to pass to the component. | ||
pt | SafeRecord<PanelIndicatorPassThrough> | — |
| The pass-through props to pass to the component. | ||
ptOptions | PassThroughOptions | — |
| The pass-through options to pass to the component. | ||
unstyled | boolean | — |
| Whether the component should be rendered without classes. | ||
dt | unknown | — |
| The design token to use for the component. | ||
styles | StylesOptions<ComponentInstance> | — |
| The styles to use for the component. | ||
render | (instance: PanelIndicatorInstance) => ReactNode | — |
| The render function to render the component with instance access. | ||
children | any | — |
| The children to render. Accepts `React.ReactNode` for static content or a render function `(instance: I) => React.ReactNode` for instance access. Typed as `any` to avoid JSX type errors when used directly in templates. | ||
match | "always" | "open" | "closed" | — |
| Determines the visibility of the indicator based on the state of the panel. Valid values are: - "open": Indicator is visible when the panel is expanded. - "closed": Indicator is visible when the panel is collapsed. - "always": Indicator is always visible. | ||
[key: string] | any | — |
pt-{optionName}-* | - | — |
| Pass through attributes for customizing component. For more info, see Pass Through tab. | ||
| Attribute | Value |
|---|---|
data-scope | "panel" |
data-part | "indicator" |
data-open | Present when expanded |
data-closed | Present when collapsed |
Defines passthrough(pt) options of PanelIndicator component.
| label | type | description |
|---|---|---|
| root | PanelIndicatorPassThroughType<HTMLAttributes<HTMLSpanElement>> | Used to pass attributes to the root's DOM element. |
PanelContent#
| Name | Type | Default |
|---|---|---|
ref | Ref<unknown> | — |
| The reference to the component instance. | ||
pIf | boolean | true |
| Whether the component should be rendered. | ||
style | CSSProperties | ((instance?: PanelContentInstance) => CSSProperties) | — |
| The style to apply to the component. | ||
className | string | ((instance?: PanelContentInstance) => string) | — |
| The class name to apply to the component. | ||
as | string | number | bigint | boolean | ComponentClass<any, any> | FunctionComponent<any> | ReactElement<unknown, string | JSXElementConstructor<any>> | Iterable<ReactNode, any, any> | ReactPortal | Promise<AwaitedReactNode> | — |
| The component type to render. | ||
asChild | boolean | false |
| Whether the component should be rendered as a child component. | ||
instance | PanelContentInstance | — |
| The instance to pass to the component. | ||
pt | SafeRecord<PanelContentPassThrough> | — |
| The pass-through props to pass to the component. | ||
ptOptions | PassThroughOptions | — |
| The pass-through options to pass to the component. | ||
unstyled | boolean | — |
| Whether the component should be rendered without classes. | ||
dt | unknown | — |
| The design token to use for the component. | ||
styles | StylesOptions<ComponentInstance> | — |
| The styles to use for the component. | ||
render | (instance: PanelContentInstance) => ReactNode | — |
| The render function to render the component with instance access. | ||
children | any | — |
| The children to render. Accepts `React.ReactNode` for static content or a render function `(instance: I) => React.ReactNode` for instance access. Typed as `any` to avoid JSX type errors when used directly in templates. | ||
[key: string] | any | — |
pt-{optionName}-* | - | — |
| Pass through attributes for customizing component. For more info, see Pass Through tab. | ||
| Attribute | Value |
|---|---|
data-scope | "panel" |
data-part | "content" |
data-open | Present when expanded |
data-closed | Present when collapsed |
Defines passthrough(pt) options of PanelContent component.
| label | type | description |
|---|---|---|
| root | PanelContentPassThroughType<HTMLAttributes<HTMLDivElement>> | Used to pass attributes to the root's DOM element. |
PanelFooter#
| Name | Type | Default |
|---|---|---|
ref | Ref<unknown> | — |
| The reference to the component instance. | ||
pIf | boolean | true |
| Whether the component should be rendered. | ||
style | CSSProperties | ((instance?: PanelFooterInstance) => CSSProperties) | — |
| The style to apply to the component. | ||
className | string | ((instance?: PanelFooterInstance) => string) | — |
| The class name to apply to the component. | ||
as | string | number | bigint | boolean | ComponentClass<any, any> | FunctionComponent<any> | ReactElement<unknown, string | JSXElementConstructor<any>> | Iterable<ReactNode, any, any> | ReactPortal | Promise<AwaitedReactNode> | — |
| The component type to render. | ||
asChild | boolean | false |
| Whether the component should be rendered as a child component. | ||
instance | PanelFooterInstance | — |
| The instance to pass to the component. | ||
pt | SafeRecord<PanelFooterPassThrough> | — |
| The pass-through props to pass to the component. | ||
ptOptions | PassThroughOptions | — |
| The pass-through options to pass to the component. | ||
unstyled | boolean | — |
| Whether the component should be rendered without classes. | ||
dt | unknown | — |
| The design token to use for the component. | ||
styles | StylesOptions<ComponentInstance> | — |
| The styles to use for the component. | ||
render | (instance: PanelFooterInstance) => ReactNode | — |
| The render function to render the component with instance access. | ||
children | any | — |
| The children to render. Accepts `React.ReactNode` for static content or a render function `(instance: I) => React.ReactNode` for instance access. Typed as `any` to avoid JSX type errors when used directly in templates. | ||
[key: string] | any | — |
pt-{optionName}-* | - | — |
| Pass through attributes for customizing component. For more info, see Pass Through tab. | ||
Defines passthrough(pt) options of PanelFooter component.
| label | type | description |
|---|---|---|
| root | PanelFooterPassThroughType<HTMLAttributes<HTMLDivElement>> | Used to pass attributes to the root's DOM element. |
Accessibility#
Screen Reader#
For toggleable panels, the trigger button uses aria-controls to reference the content region and aria-expanded to reflect visibility state. The content uses role="region" and an id that matches the trigger's aria-controls. Accessible labels can be customized with aria-label or aria-labelledby.
Keyboard Support#
| Key | Function |
|---|---|
tab | Moves focus to the next focusable element in the page tab sequence. |
shift + tab | Moves focus to the previous focusable element in the page tab sequence. |
enter | Toggles the visibility of the content. |
space | Toggles the visibility of the content. |