Skip to main content

Panel

Use Panels to structure a screen. Panels may contain Tiles, may be scrollable, and optionally searchable.

tip

To learn more about how to use Panels refer to the Panel pattern documentation.

Example

Live Editor
<Panel title="Very important and long" onSearch={() => {}}>
  <div>Some example content</div>
</Panel>
Result
Loading...

Usage Rules

Do:

  • Use Panels to establish the basic layout structure of any Adjust application
  • Use the default Panel variant most of the time
  • Use the contrast variant exclusively to create areas where you want to place Tiles.

Don’t:

  • Nest panel deeper than one level
  • Use search input without title

Variants

Appearance

Panels come with two different background color variations: default and contrast. Use the contrast variant exclusively to create areas where you want to place Tiles.

Live Editor
<div
  style={{
    display: 'grid',
    gridTemplateColumns: '1fr 1fr',
    gap: Spacing20,
    height: 200
  }}
>
  <Panel />
  <Panel appearance="contrast" />
</div>
Result
Loading...

Custom Borders

You can decide whether a border should be rendered on every side in the Panel. Use borders props for this. It should be an array with 4 items where every items defines a border for an appropriate side: first value - top side, second - right side, third - bottom side, fourth - left side.

Live Editor
<div style={{ display: 'flex', height: 200 }}>
  <Panel
    title="Panel with no border on the right"
    borders={[true, false, true, true]}
  />
  <Panel
    title="Panel with soft border on the left"
    borders={[true, true, true, true]}
  />
</div>
Result
Loading...

Searchable

Panels can be searchable. The search query may life-update the Panel’s content. Use onSearch callback for this.

Live Editor
function searchablePanel() {
  const initialItems = ['A Item', 'B Item ', 'C Item', 'D Item'];
  const [content, setContent] = useState(initialItems);

  return (
    <Panel
      title="Searchable Panel"
      placeholderSearchInput="Filter content of the panel"
      onSearch={(searchInput) => {
        const filteredItems = initialItems.filter((item) =>
          item.startsWith(searchInput)
        );
        setContent(filteredItems);
      }}
    >
      <ul>
        {content.map((item) => (
          <li>{item}</li>
        ))}
      </ul>
    </Panel>
  );
}
Result
Loading...

Title

Live Editor
<Panel title="My title">Sample Content</Panel>
Result
Loading...

Examples

Tiles

Use the contrast variant exclusively to create areas where you want to place Tiles.

Live Editor
<Panel title="Panel with Tiles inside" css={{ height: 300 }}>
  <Tile
    actions={[
      <IconButton key="edit" iconName="Edit" aria-label="Edit" />,
      <IconButton key="settings" iconName="CogWheel" aria-label="Settings" />
    ]}
  />
  <Tile
    css={{ marginTop: Spacing20 }}
    actions={[
      <Input
        key="search"
        aria-label="Search"
        onChange={() => {}}
        type="search"
      />
    ]}
  />
</Panel>
Result
Loading...

Scrollable

Use the css prop and set height to make the Panel scrollable. When there is a scroll you'll have a shadow on top and bottom depending on scroll position.

Live Editor
<div style={{ display: 'flex' }}>
  <Panel
    title="Header title"
    css={{ maxHeight: '200px', flex: 1, marginRight: '20px' }}
  >
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
  </Panel>
  <Panel
    title="Header title"
    appearance="contrast"
    css={{ maxHeight: '200px', flex: 1 }}
  >
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
    <div>Some example content</div>
  </Panel>
</div>
Result
Loading...

Page Layout with the Panels

The following example demonstrates the usage of borders prop to correctly set up borders when you layout your application with Panels.

Live Editor
<div
  style={{
    display: 'grid',
    gridTemplateColumns: 'repeat(1fr, 6)',
    gridTemplateRows: '240px 1fr',
    gridTemplateAreas: `"panel1 panel1 panel2 panel2 panel3 panel3"
                        "panel4 panel4 panel4 panel5 panel5 panel5"`,
    height: '70vh',
    width: 800
  }}
>
  <Panel css={{ gridArea: 'panel1' }} borders={[true, false, false, true]}>
    Panel1
  </Panel>
  <Panel css={{ gridArea: 'panel2' }} borders={[true, false, false, true]}>
    Panel2
  </Panel>
  <Panel css={{ gridArea: 'panel3' }} borders={[true, true, false, true]}>
    Panel3
  </Panel>
  <Panel
    title="Panel4 with a Tile inside"
    appearance="contrast"
    borders={[true, false, true, true]}
    css={{ gridArea: 'panel4' }}
  >
    <div style={{ display: 'flex', height: '100%' }}>
      <Tile css={{ flexGrow: 1, marginTop: Spacing20 }} />
    </div>
  </Panel>
  <Panel title="Panel5" css={{ gridArea: 'panel5' }}>
    Panel5
  </Panel>
</div>
Result
Loading...

Props

NameTypeDefault
title
The title of the Panel
string
onSearch
This callback fires when a user types into the search input. Provide this prop to make the Panel searchable.
((text: string) => void)
placeholderSearchInput
Placeholder for the search input. Native HTML attribute: Link
string
"Search"
padding
"default" will create a default paddding in the body of the panel.
"default" | "none"
"default"
appearance
Use 'contrast' appearance when placing a Tile inside the Panel
"default" | "contrast"
"default"
borders
This array should contain 4 values, where every value will render a border for the appropriate side. The order: top, right, bottom, left
boolean[]
"[true, true, true, true]"
children
The content of the panel
ReactNode
css
Add custom styles to this component. Use with caution. Learn more here: Link
SupportedStyleAttributes
inputFieldCss
SupportedStyleAttributes
data-{foo}
Data attributes can be used by testing libraries to retrieve components or assert their existence
string
* - the prop is required.