The Panel component is a container for grouping content in a subtly styled container.

Importing

The component can be imported via:

import { 
	Panel, 
	PanelHeader, 
	PanelFooter, 
	PanelTitle,
	PanelDescription,
	PanelActions, 
	PanelSection, 
	PanelInset 
} from '@customerio/pluma-components/react';

A Panel component can be composed with the following child components:

  • PanelHeader
    • a container component for a panel's header
  • PanelTitle
    • the panel's title, must be nested within a PanelHeader
  • PanelDescription
    • an optional description that provides additional context, must be nested within a PanelHeader after the PanelTitle
  • PanelFooter
    • a container component for a panel's footer
  • PanelActions
    • a container for actions, such as links or buttons. Must be nested within a PanelHeader or PanelFooter
  • PanelSection
    • a container component for content in the panel. Internally, PanelHeader and PanelFooter use this component, which sets the correct paddings and is responsible for adding borders between sections.
    • can be used for the main content of the panel, but is optional (not using it won't set paddings automatically)
  • PanelInset
    • a special component to stretch its contents to the edges of the panel (over the padding)

Usage

A complete example, using all the available child components, looks like:

Title

This is a description for the panel that provides additional context.

The panel's content

<Panel>
	<PanelHeader>
		<PanelTitle>Title</PanelTitle>
		<PanelDescription>This is a description for the panel that provides additional context.</PanelDescription>
		<PanelActions>
			<Button variant="secondary" size="small">
				Button
			</Button>

			<Button variant="primary" size="small">
				Button
			</Button>
		</PanelActions>
	</PanelHeader>
	<PanelSection>
		<Paragraph>The panel's content</Paragraph>
	</PanelSection>
	<PanelFooter>
		<PanelActions>
			<Button variant="secondary" size="small">
				Button
			</Button>

			<Button variant="primary" size="small">
				Button
			</Button>
		</PanelActions>
	</PanelFooter>
</Panel>

Header with Title and Description

The panel header can include both a title and an optional description. These components are arranged in a grid layout with the title and description stacked vertically on the left side and actions on the right side.

Title

This is a description that provides additional context for the panel content. It appears below the title and helps users understand the purpose of this panel.

The panel's content

<Panel>
	<PanelHeader>
		<PanelTitle>Title</PanelTitle>
		<PanelDescription>This is a description that provides additional context for the panel content. It appears below the title and helps users understand the purpose of this panel.</PanelDescription>
		<PanelActions>
			<Button variant="secondary" size="small">Cancel</Button>
			<Button variant="primary" size="small">Save</Button>
		</PanelActions>
	</PanelHeader>
	<PanelSection>
		<Paragraph>The panel's content</Paragraph>
	</PanelSection>
</Panel>

Borders

By default, the PanelHeader and PanelFooter components render without a border to separate them from the panel's content.

A border can be enabled by setting withSectionBorders to true on the Panel:

Title

The panel's content

<Panel withSectionBorders={true}>
	<PanelHeader>
		<PanelTitle>Title</PanelTitle>
		<PanelActions>
			<Button variant="secondary" size="small">
				Button
			</Button>

			<Button variant="primary" size="small">
				Button
			</Button>
		</PanelActions>
	</PanelHeader>
	<PanelSection>
		<Paragraph>The panel's content</Paragraph>
	</PanelSection>
	<PanelFooter>
		<PanelActions>
			<Button variant="secondary" size="small">
				Button
			</Button>

			<Button variant="primary" size="small">
				Button
			</Button>
		</PanelActions>
	</PanelFooter>
</Panel>

It is also possible to control the borders individually by setting withBorder on a PanelHeader or PanelFooter:

Title

The panel's content

<Panel withSectionBorders={true}>
	<PanelHeader>
		<PanelTitle>Title</PanelTitle>
		<PanelActions>
			<Button variant="secondary" size="small">
				Button
			</Button>

			<Button variant="primary" size="small">
				Button
			</Button>
		</PanelActions>
	</PanelHeader>
	<PanelSection>
		<Paragraph>The panel's content</Paragraph>
	</PanelSection>
	<PanelFooter withBorder={false}>
		<PanelActions>
			<Button variant="secondary" size="small">
				Button
			</Button>

			<Button variant="primary" size="small">
				Button
			</Button>
		</PanelActions>
	</PanelFooter>
</Panel>

Title

The panel's content

<Panel>
	<PanelHeader withBorder={true}>
		<PanelTitle>Title</PanelTitle>
		<PanelActions>
			<Button variant="secondary" size="small">
				Button
			</Button>

			<Button variant="primary" size="small">
				Button
			</Button>
		</PanelActions>
	</PanelHeader>
	<PanelSection>
		<Paragraph>The panel's content</Paragraph>
	</PanelSection>
	<PanelFooter>
		<PanelActions>
			<Button variant="secondary" size="small">
				Button
			</Button>

			<Button variant="primary" size="small">
				Button
			</Button>
		</PanelActions>
	</PanelFooter>
</Panel>

Title

The panel's content

<Panel>
	<PanelHeader>
		<PanelTitle>Title</PanelTitle>
		<PanelActions>
			<Button variant="secondary" size="small">
				Button
			</Button>

			<Button variant="primary" size="small">
				Button
			</Button>
		</PanelActions>
	</PanelHeader>
	<PanelSection withBorder={true}>
		<Paragraph>The panel's content</Paragraph>
	</PanelSection>
	<PanelFooter>
		<PanelActions>
			<Button variant="secondary" size="small">
				Button
			</Button>

			<Button variant="primary" size="small">
				Button
			</Button>
		</PanelActions>
	</PanelFooter>
</Panel>

When using a bordered panel, a PanelSection component will automatically add additional padding to separate the content from the borders.

Section Padding

By default, PanelSection components render with padding on all sides. You can disable this padding by setting withPadding={false}, which makes the section function like a PanelInset.

Section Padding

This section has default padding
This section has no padding and extends to the edges
Back to normal padding
<Panel>
  <PanelHeader>
    <PanelTitle>Section Padding</PanelTitle>
  </PanelHeader>
  
  <PanelSection>
    <Text>This section has default padding</Text>
  </PanelSection>
  
  <PanelSection withPadding={false} backgroundColor="accent-minimal">
    <Box p="100">
      <Text>This section has no padding and extends to the edges</Text>
    </Box>
  </PanelSection>
  
  <PanelSection>
    <Text>Back to normal padding</Text>
  </PanelSection>
</Panel>

PanelInset

By default, the Panel renders with padding on all sides, and content will render accordingly. The PanelInset component can be used to stretch content to the edges of the panel, ignoring those paddings.

This can be useful in situations like rendering a full-width table, or section dividers within the Panel.

Additionally, if the PanelInset is the first or last child, the top or bottom paddings will also be ignored accordingly.

Header

I stretch all the way to the edges
I don't stretch
<Panel>
	<PanelHeader>
		<PanelTitle>Header</PanelTitle>
	</PanelHeader>
	<PanelInset backgroundColor="accent-minimal" p="100">
		<Text>I stretch all the way to the edges</Text>
	</PanelInset>
	<Box backgroundColor="information-minimal" p="100">
		<Text>I don't stretch</Text>
	</Box>
</Panel>
I stretch all the way to the edges
I don't stretch
I stretch all the way to the edges
I don't stretch
I stretch all the way to the edges
<Panel>
	<PanelInset backgroundColor="accent-minimal" p="100">
		<Text>I stretch all the way to the edges</Text>
	</PanelInset>
	<Box backgroundColor="information-minimal" p="100">
		<Text>I don't stretch</Text>
	</Box>
	<PanelInset backgroundColor="caution-subtle" p="100">
		<Text>I stretch all the way to the edges</Text>
	</PanelInset>
	<Box backgroundColor="information-minimal" p="100">
		<Text>I don't stretch</Text>
	</Box>
	<PanelInset backgroundColor="accent-minimal" p="100">
		<Text>I stretch all the way to the edges</Text>
	</PanelInset>
</Panel>

Header

Australian birds
NameGenusSpecies
Australian MagpieGymnorhinatibicen
GalahEolophusroseicapilla
Rainbow lorikeetTrichoglossusmoluccanus
<Panel>
	<PanelHeader>
		<PanelTitle>Header</PanelTitle>
	</PanelHeader>
	<PanelInset>
		<Table caption="Australian birds">
			<TableThead>
				<TableTr>
					<TableTh>Name</TableTh>
					<TableTh>Genus</TableTh>
					<TableTh>Species</TableTh>
				</TableTr>
			</TableThead>

			<TableTbody>
				<TableTr>
					<TableTd>Australian Magpie</TableTd>
					<TableTd>Gymnorhina</TableTd>
					<TableTd>tibicen</TableTd>
				</TableTr>

				<TableTr>
					<TableTd>Galah</TableTd>
					<TableTd>Eolophus</TableTd>
					<TableTd>roseicapilla</TableTd>
				</TableTr>

				<TableTr>
					<TableTd>Rainbow lorikeet</TableTd>
					<TableTd>Trichoglossus</TableTd>
					<TableTd>moluccanus</TableTd>
				</TableTr>
			</TableTbody>
		</Table>
	</PanelInset>
</Panel>

API

PlumaPanel extends Box

Default:false

Whether the panel should render with borders between the Header, content and Footer.

Whether this panel renders attached to a Tabs component. This will apply a negative top margin and remove the top-left border radius, to visually connect the panel to the tabs.

Default:false

Whether the section should render a border to separate it from other sections.

Default:true

Whether the section should render with padding. If false, the section will function like PanelInset with no padding. When true (default), the section includes standard panel padding.

Default:false

Whether the section should render a border to separate it from other sections.

Default:true

Whether the section should render with padding. If false, the section will function like PanelInset with no padding. When true (default), the section includes standard panel padding.

Default:false

Whether the section should render a border to separate it from other sections.

Default:true

Whether the section should render with padding. If false, the section will function like PanelInset with no padding. When true (default), the section includes standard panel padding.