Back to Sentry

SlideOverPanel

static/app/components/core/slideOverPanel/slideOverPanel.mdx

26.5.22.8 KB
Original Source

import * as Storybook from 'sentry/stories';

import { SlideOverPanelPlayground, SlideOverPanelSkeletonPlayground, } from 'sentry/stories/playground/slideOverPanel';

export const documentation = import('!!type-loader!@sentry/scraps/slideOverPanel');

The SlideOverPanel component is a panel that can appear on the right, left, or bottom of the page content to reveal more information. It's commonly used for UIs like the Widget Builder to open panels that provide more details or supplementary UIs.

<Storybook.Demo> <SlideOverPanelPlayground /> </Storybook.Demo>

Basic Usage

jsx
<Button onClick={() => setIsPanelOpen(true)}>Open Panel</Button>;

{
  isPanelOpen && (
    <SlideOverPanel position="right">
      <Container border="primary" height="100%" padding="md">
        <Button onClick={() => setIsPanelOpen(false)}>Close Panel</Button>
      </Container>
    </SlideOverPanel>
  );
}

Skeleton UI

SlideOverPanel defers rendering its contents. When the panel is rendered, it will open immediately, and its contents will render in a subsequent pass. This means the panel can respond immediately to user input even if the contents of the panel are expensive to render. This is much better UX, and improves INP.

In the example below, you can see that the panel contents take a very long time to render, but the panel opens right away, and can be closed while the content is still rendering.

<Storybook.Demo> <SlideOverPanelSkeletonPlayground /> </Storybook.Demo>

By default, the panel is empty while the contents render. If the contents are very expensive to render, we recommend providing a skeleton UI.

To enable a loading skeleton, pass a render prop as the children to SlideOverPanel, and conditionally render a skeleton based on the isOpening prop.

jsx
<Button onClick={() => setIsPanelOpen(true)}>Open Panel</Button>

{isPanelOpen && (
  <SlideOverPanel position="right">
    {(options: {isOpening: boolean}) => {
      return options.isOpening ? (
        <SkeletonPanelContents onClick={closePanel} />
      ) : (
        <PanelContents onClick={closePanel} />
      );
    }}
  </SlideOverPanel>
)}

Animating Panel Close

Generally, we recommend not animating the panel on close, and simply removing it from the UI. In cases where you need to animate closing it (e.g., if it's coordinated with another animation), please wrap the panel in <AnimatePresence>.

jsx
<Button onClick={() => setIsPanelOpen(true)}>Open Panel</Button>

<AnimatePresence>
  {isPanelOpen && (
    <SlideOverPanel position="right">
      {(options: {isOpening: boolean}) => {
        return options.isOpening ? (
          <SkeletonPanelContents onClick={closePanel} />
        ) : (
          <PanelContents onClick={closePanel} />
        );
      }}
    </SlideOverPanel>
  )}
</AnimatePresence>