Panel

Panel components provide a surface for contextual information alongside the main content area.

Beta

New and ready to use. We'll provide comms and support for any major changes.

Installation

Package installation information
Installyarn add @atlassian/panel-system
SourceBitbucket.org, (opens new window)
npm@atlassian/panel-system, (opens new window)
Bundleunpkg.com, (opens new window)

Props

PanelContainer props

children

Required
Description

The content of the panel container.

Typestring | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<ReactNode> | React.ReactPortal

isFocusLockEnabled

Description

When true, a focus trap is activated so that Tab / Shift+Tab cycles only through interactive elements inside the panel.

Useful for panels that require the user to complete an action before continuing.

Defaultfalse
Typeboolean

testId

Description

A unique string that appears as data attribute data-testid in the rendered code, serving as a hook for automated tests.

Typestring

PanelHeader props

children

Required
Description

The content of the panel header.

Typestring | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<ReactNode> | React.ReactPortal

testId

Description

A unique string that appears as data attribute data-testid in the rendered code, serving as a hook for automated tests.

Typestring

PanelTitle props

children

Required
Description

The title text content.

Typestring | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<ReactNode> | React.ReactPortal

icon

Description

Optional icon to display alongside the title.

Typestring | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<ReactNode> | React.ReactPortal

testId

Description

A unique string that appears as data attribute data-testid in the rendered code, serving as a hook for automated tests.

Typestring

PanelSubheader props

breadcrumbs

Description

An optional breadcrumbs element to display directly above the title. Designed for the @atlaskit/breadcrumbs component (small variant), which is 24px tall. The slot reserves a 24px-tall row and applies the correct gap between the breadcrumbs and title.

Typestring | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<ReactNode> | React.ReactPortal

coverImage

Description

An optional cover image to display above the subheader title. Accepts any React node — typically an <img> element, a media component, or a custom image wrapper.

The image fills the full width of the panel and is cropped to a fixed height of 160px.

Accessibility: any <img> passed here must include a meaningful alt attribute describing the image, or alt="" if it is purely decorative, to satisfy WCAG 1.1.1 (Non-text Content). This is not enforced at the type level, so consumers are responsible for providing it.

Typestring | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<ReactNode> | React.ReactPortal

inlineEdit

Description

An optional inline edit control to render in place of the static title, allowing the title to be edited in place. Typically a SubheaderInlineEdit, which is pre-styled to match the title.

When provided, this is rendered instead of the title text. The title prop should still be supplied as the current value passed to the inline edit control.

Typestring | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<ReactNode> | React.ReactPortal

stickyContent

Description

Optional content shown after the regular subheader scrolls out of view. Accepts any React node. Content is vertically centered in a 2rem-high slot, with 8px bottom padding, no top padding, and 24px inline padding around the slot. Consumers are responsible for content sizing and text truncation. Sticky state, refs, and observation are only mounted when this content is provided.

PanelSubheader must be a direct child of PanelContent for the sticky positioning to work.

Typestring | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<ReactNode> | React.ReactPortal

testId

Description

A unique string that appears as data attribute data-testid in the rendered code, serving as a hook for automated tests.

Typestring

title

Required
Description

The title text to display in the subheader.

Typestring

titleIcon

Description

An optional icon to display at the start of the title. Accepts any React node — typically an @atlaskit/icon component.

Typestring | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<ReactNode> | React.ReactPortal

SubheaderInlineEdit props

SubheaderInlineEdit accepts the same props as Inline Editable Textfield, except for isCompact, which is set internally so the component matches the PanelSubheader layout.

PanelBody props

children

Required
Description

The content of the panel body.

Typestring | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<ReactNode> | React.ReactPortal

spacing

Description

Controls the padding of the panel body.

Default"default"
Type"none" | "default"

testId

Description

A unique string that appears as data attribute data-testid in the rendered code, serving as a hook for automated tests.

Typestring

PanelFooter props

children

Description

The action buttons to display in the footer (e.g. Cancel / Save buttons). Content is laid out in a row with actions aligned to the right, justified space-between.

Typestring | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<ReactNode> | React.ReactPortal

disclaimer

Description

Optional footer disclaimer content to display below the footer actions.

Use PanelDisclaimer to apply the standard disclaimer styling.

Typestring | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<ReactNode> | React.ReactPortal

testId

Description

Unique string that appears as a data attribute data-testid in the rendered code, often used for automated tests.

Typestring

PanelAction props

appearance

Description

Appearance style for buttons.

Type"default" | "subtle" | "primary" | "discovery"

aria-expanded

Description

Indicates whether the popup triggered by the action is currently expanded.

Use this when the action opens a popup and the open state is controlled by the consuming experience. Omit when the action does not open a popup.

Typeboolean | "true" | "false"

aria-haspopup

Description

Identifies the type of popup triggered by the action.

Use "menu" for menu popups, "dialog" for modal or drawer-style dialogs, and "listbox" for listbox popups. Use true only when the popup has menu semantics but a more specific string value is not available.

Typeboolean | "dialog" | "menu" | "listbox" | "tree" | "grid" | "true" | "false"

aria-label

Description

Aria-label for accessibility.

Typestring

children

Description

The content of the action button.

Typestring | number | boolean | ReactElement<any, string | JSXElementConstructor<any>> | Iterable<ReactNode> | ReactPortal

href

Description

URL for link actions.

Typestring

icon

Description

Icon component for icon-only buttons.

TypeComponentClass<any, any> | FunctionComponent<any>

label

Description

Label for icon buttons (used for accessibility).

Typestring

onClick

Description

Click handler for button and link actions.

The handler receives both the event and an optional analytics event for tracking user interactions.

Type((event: MouseEvent<HTMLButtonElement, globalThis.MouseEvent>, analyticsEvent?: UIAnalyticsEvent) => void) | ((event: MouseEvent<...>, analyticsEvent?: UIAnalyticsEvent) => void)

ref

Description

Allows getting a ref to the component instance. Once the component unmounts, React will set ref.current to null (or call the ref with null if you passed a callback ref).

@see {@link https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs}

Typestring | Ref<HTMLAnchorElement | HTMLButtonElement>

rel

Description

Rel attribute for links (e.g., "noopener noreferrer").

Typestring

spacing

Description

Spacing style for icon buttons.

Type"default" | "compact"

target

Description

Target attribute for links (e.g., "_blank").

Typestring

testId

Description

Unique string that appears as a data attribute data-testid in the rendered code, often used for automated tests

Typestring

PanelActionGroup props

children

Required
Description

The action components to group together.

Typestring | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<ReactNode> | React.ReactPortal

testId

Description

A unique string that appears as data attribute data-testid in the rendered code, serving as a hook for automated tests.

Typestring

PanelActionExpand props

label

Description

Label for icon buttons (used for accessibility).

Typestring

onClick

Description

Click handler for button and link actions.

The handler receives both the event and an optional analytics event for tracking user interactions.

Type((event: React.MouseEvent<HTMLButtonElement, MouseEvent>, analyticsEvent?: UIAnalyticsEvent) => void) | ((event: React.MouseEvent<HTMLAnchorElement, MouseEvent>, analyticsEvent?: UIAnalyticsEvent) => void)

testId

Description

Unique string that appears as a data attribute data-testid in the rendered code, often used for automated tests

Typestring

PanelActionNewTab props

href

Required
Description

URL to open in the new tab.

Typestring

label

Description

Label for icon buttons (used for accessibility).

Typestring

onClick

Description

Click handler for button and link actions.

The handler receives both the event and an optional analytics event for tracking user interactions.

Type((event: React.MouseEvent<HTMLButtonElement, MouseEvent>, analyticsEvent?: UIAnalyticsEvent) => void) | ((event: React.MouseEvent<HTMLAnchorElement, MouseEvent>, analyticsEvent?: UIAnalyticsEvent) => void)

testId

Description

Unique string that appears as a data attribute data-testid in the rendered code, often used for automated tests

Typestring

PanelActionMore props

label

Description

Label for icon buttons (used for accessibility).

Typestring

onClick

Description

Click handler for button and link actions.

The handler receives both the event and an optional analytics event for tracking user interactions.

Type((event: React.MouseEvent<HTMLButtonElement, MouseEvent>, analyticsEvent?: UIAnalyticsEvent) => void) | ((event: React.MouseEvent<HTMLAnchorElement, MouseEvent>, analyticsEvent?: UIAnalyticsEvent) => void)

testId

Description

Unique string that appears as a data attribute data-testid in the rendered code, often used for automated tests

Typestring

PanelActionClose props

label

Description

Label for icon buttons (used for accessibility).

Typestring

onBeforeClose

Description

Optional callback that runs before closing the panel. Return false or Promise<false> to prevent the panel from closing. Useful for showing discard confirmation modals when there are unsaved changes.

@example

<PanelActionClose
  onBeforeClose={async () => {
    if (hasUnsavedChanges) {
      const confirmed = await showDiscardModal();
      return confirmed;
    }
    return true;
  }}
/>
Type() => boolean | Promise<boolean>

onClick

Description

Click handler for closing the panel.

Typically, this should trigger the panel close logic. For automatic panel closing via context, use PanelActionCloseSmart instead.

Can be omitted when close behavior is handled externally (e.g., via ref-based modal triggers or other interceptors).

The event parameter provides access to the click event, and the optional analyticsEvent parameter enables analytics tracking.

Defaultundefined
Type(event: MouseEvent<HTMLButtonElement, globalThis.MouseEvent>, analyticsEvent?: UIAnalyticsEvent) => void

ref

Description

Allows getting a ref to the component instance. Once the component unmounts, React will set ref.current to null (or call the ref with null if you passed a callback ref).

@see {@link https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs}

Typestring | Ref<HTMLButtonElement>

testId

Description

Unique string that appears as a data attribute data-testid in the rendered code, often used for automated tests

Typestring

PanelActionCloseSmart props

label

Description

Label for icon buttons (used for accessibility).

Typestring

onClick

Description

Optional click handler for additional side effects (e.g., analytics). If provided, it will be called before closing the panel via context.

Type() => void

testId

Description

Unique string that appears as a data attribute data-testid in the rendered code, often used for automated tests

Typestring

PanelActionBack props

label

Description

Label for icon buttons (used for accessibility).

Typestring

onClick

Description

Click handler for button and link actions.

The handler receives both the event and an optional analytics event for tracking user interactions.

Type((event: MouseEvent<HTMLButtonElement, globalThis.MouseEvent>, analyticsEvent?: UIAnalyticsEvent) => void) | ((event: MouseEvent<...>, analyticsEvent?: UIAnalyticsEvent) => void)

ref

Description

Allows getting a ref to the component instance. Once the component unmounts, React will set ref.current to null (or call the ref with null if you passed a callback ref).

@see {@link https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs}

Typestring | Ref<HTMLButtonElement>

testId

Description

Unique string that appears as a data attribute data-testid in the rendered code, often used for automated tests

Typestring

PanelProvider props

children

Required
Description

Child components that will have access to the panel manager

Typestring | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal

initialState

Description

Optional initial state for the panel system.

initialState.panelWidth can seed the provider width during SSR. LayoutWithPanel mirrors its requested width into provider state after mounting. CSS may constrain the visible width without changing the requested value.

Type{ activePanel?: AllPanels<Record<string, any>>; preloadedPanels?: PreloadedPanel[]; panelWidth?: number; }

Trigger props

children

Required
Description
No description.
Type({ ref }: { ref: React.RefObject<HTMLElement>; }) => React.ReactNode

entryPointProps

Description
No description.
Type{ [x: string]: any; }

forwardedRef

Description
No description.
Type((instance: HTMLElement) => void) | React.RefObject<HTMLElement>

instanceId

Description

Optional instance ID for this panel. If not provided, a unique ID will be automatically generated.

Best Practice: Let Trigger generate the ID automatically unless you need to reference the panel elsewhere (e.g., for programmatic closing). This keeps ID generation co-located with the trigger rather than managed at the manager level.

@example

// Good: Let Trigger generate the ID
<Trigger panel={myEntryPoint} params={{ id: '123' }}>
  {({ ref }) => <button ref={ref}>Open Panel</button>}
</Trigger>

// Also good: Provide ID if you need to reference it elsewhere
<Trigger panel={myEntryPoint} instanceId="my-panel-123" params={{ id: '123' }}>
  {({ ref }) => <button ref={ref}>Open Panel</button>}
</Trigger>
Typestring

onClose

Description

Callback fired when the panel is closed. Useful for analytics tracking.

Type() => void

onOpen

Description

Callback fired when the panel is opened. Useful for analytics tracking.

Type() => void

panel

Required
Description
No description.
TypeInternalEntryPointRepresentation<any, any, any, any, any>TEntryPoint

params

Description
No description.
Type{ [x: string]: any; }

shouldLoadOnFocus

Description

Load entry point on focus (for keyboard navigation).

Defaultfalse
Typeboolean

shouldOpenPanel

Description

Whether to open the panel on click. Set this to false to keep preloading behaviour without opening the panel on click.

Defaulttrue
Typeboolean

shouldPreloadOnFocus

Description

Preload entry point on focus (for keyboard navigation).

Defaultfalse
Typeboolean

PanelsRenderer props

children

Description

Component to render for the active panel. The panel instance is automatically wrapped in PanelContext.Provider, so you can use useCurrentPanel() within your component to access panel data.

@example

<PanelsRenderer>
  <CustomPanel />
</PanelsRenderer>

function CustomPanel() {
  const panel = useCurrentPanel();

  return (
    <PanelContainer>
      <PanelHeader>
        <PanelTitle>{panel.params?.title}</PanelTitle>
        <PanelActionClose />
      </PanelHeader>
      <PanelBody>{panel.params?.content}</PanelBody>
    </PanelContainer>
  );
}
Typestring | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal

PanelRouter props

errorFallback

Description

Error fallback function to render when entry point loading fails. Defaults to a simple "Error loading panel" text.

Default() => <Text as="p">Error loading panel</Text>
Type(props: { error: Error; onClose: () => void; }) => React.ReactElement<any, any>

fallback

Description

Fallback UI to show while the entry point is loading. Defaults to a skeleton state that indicates header and body content. Can be customised and composed with different skeleton components.

Default<PanelSkeleton />
Typestring | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal

wrapper

Description

Optional wrapper component to wrap the rendered entry point. Useful for adding styling, resizing functionality, or other wrapper behavior.

@example

<PanelRouter
  wrapper={({ children }) => (
    <Box xcss={styles.panelWrapper}>{children}</Box>
  )}
/>
Type(props: { children: React.ReactNode; }) => React.ReactNode

Hooks

The package exports a set of hooks for managing panel state. These must be used within a PanelProvider. As hooks do not have a props interface, their signatures and return types are described below.

usePanelManager

Returns both the panel state and the manager actions. Must be called within a PanelProvider. If you only need to trigger actions, prefer usePanelActions to avoid re-rendering when panel state changes.

const { state, manager } = usePanelManager();

The returned state is of type PanelSystemState:

activePanel

Required
Description

The active panel, or null when the slot is closed.

TypeEntryPointPanel<Record<string, any>> | Panel<Record<string, any>>

panelWidth

Description

Explicit requested/resized width in pixels, retained for the provider's lifetime. Undefined means no saved preference: navigation supplies responsive defaults. This is not the rendered width; available space may constrain it without changing the preference.

Typenumber

preloadedPanels

Required
Description
No description.
TypePreloadedPanel[]

usePanelActions

Returns only the panel manager actions (for example openPanel, closePanel, setPanelWidth). Components using this hook do not re-render when panels open, close, or resize.

const manager = usePanelActions();

usePanelState

Returns only the panel state (of type PanelSystemState). Use this when you only need to read panel state.

const state = usePanelState();

useCurrentPanel

Returns the panel currently being rendered. Must be used within a PanelsRenderer render function that wraps panels in PanelContext.Provider. Accepts an optional generic for the panel's params.

const panel = useCurrentPanel<{ title: string }>();

useCloseCurrentPanel

Returns a function that closes the current panel. Must be used within a PanelsRenderer that provides PanelContext.

const closePanel = useCloseCurrentPanel();

usePanel

Convenience hook that returns both the current panel and a closePanel function, reducing boilerplate when you need both.

const { panel, closePanel } = usePanel();

Context

PanelContext

A React context that provides the current panel being rendered. PanelsRenderer wraps each panel in a PanelContext.Provider. Prefer the useCurrentPanel, useCloseCurrentPanel, and usePanel hooks over consuming this context directly.

const panel = useContext(PanelContext);
Was this page helpful?
We use this feedback to improve our documentation.
© 2026 AtlassianTrademark, (opens new window)Privacy, (opens new window)License