Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions static/app/components/core/slideOverPanel/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {SlideOverPanel} from './slideOverPanel';
38 changes: 38 additions & 0 deletions static/app/components/core/slideOverPanel/slideOverPanel.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
title: SlideOverPanel
description: A multi-purpose panel that can be used to reveal more information in a UI without directing to another page.
source: 'sentry/components/core/slideOverPanel'
resources:
js: https://github.com/getsentry/sentry/blob/master/static/app/components/slideOverPanel.tsx
---

import * as Storybook from 'sentry/stories';

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

import SlideOverDocumentation from '!!type-loader!@sentry/scraps/slideOverPanel';

export const documentation = SlideOverDocumentation;

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>

<br />

## Basic Usage

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

<SlideOverPanel collapsed={!isPanelOpen} slidePosition="right">
<Container border="primary" height="100%" padding="md">
<Button onClick={() => setIsPanelOpen(false)}>Close Panel</Button>
</Container>
</SlideOverPanel>
```

> [!NOTE]
> To enable exit animations, you'll need to wrap `<SlideOverPanel />` in an `<AnimatePresence />` component, and render the panel conditionally (e.g., `{isPanelOpen &&}`) instead of using the `collapsed` prop.
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,27 @@ const COLLAPSED_STYLES = {

type SlideOverPanelProps = {
children: React.ReactNode;
/**
* Whether the panel is visible. In most cases it's better to conditionally render this component rather than use this prop, since it'll defer rendering the panel contents until they're needed.
*/
collapsed: boolean;
ariaLabel?: string;
className?: string;
'data-test-id'?: string;
/**
* Callback that fires every time the panel opens.
*/
onOpen?: () => void;
panelWidth?: string;
ref?: React.Ref<HTMLDivElement>;
slidePosition?: 'right' | 'bottom' | 'left';
/**
* A Framer Motion `Transition` object that specifies the transition properties that apply when the panel opens and closes.
*/
transitionProps?: Transition;
};

export default SlideOverPanel;

function SlideOverPanel({
export function SlideOverPanel({
'data-test-id': testId,
ariaLabel,
collapsed,
Expand Down
3 changes: 2 additions & 1 deletion static/app/components/globalDrawer/components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import styled from '@emotion/styled';
import {mergeRefs} from '@react-aria/utils';
import type {Transition} from 'framer-motion';

import {SlideOverPanel} from '@sentry/scraps/slideOverPanel';

import {Button} from 'sentry/components/core/button';
import type {DrawerOptions} from 'sentry/components/globalDrawer';
import SlideOverPanel from 'sentry/components/slideOverPanel';
import {IconClose} from 'sentry/icons/iconClose';
import {t} from 'sentry/locale';
import {space} from 'sentry/styles/space';
Expand Down
26 changes: 26 additions & 0 deletions static/app/stories/playground/slideOverPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {Fragment, useState} from 'react';
import {AnimatePresence} from 'framer-motion';

import {Button} from '@sentry/scraps/button';
import {Container} from '@sentry/scraps/layout';
import {SlideOverPanel} from '@sentry/scraps/slideOverPanel';

export function SlideOverPanelPlayground() {
const [isPanelOpen, setIsPanelOpen] = useState<boolean>(false);

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

<AnimatePresence>
{isPanelOpen && (
<SlideOverPanel collapsed={false} slidePosition="right">
<Container border="primary" height="100%" padding="md">
<Button onClick={() => setIsPanelOpen(false)}>Close Panel</Button>
</Container>
</SlideOverPanel>
)}
</AnimatePresence>
</Fragment>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import {useTheme} from '@emotion/react';
import styled from '@emotion/styled';
import isEqual from 'lodash/isEqual';

import {SlideOverPanel} from '@sentry/scraps/slideOverPanel';

import {Breadcrumbs} from 'sentry/components/breadcrumbs';
import {openConfirmModal} from 'sentry/components/confirm';
import {Alert} from 'sentry/components/core/alert';
import {Button} from 'sentry/components/core/button';
import {ExternalLink, Link} from 'sentry/components/core/link';
import ErrorBoundary from 'sentry/components/errorBoundary';
import SlideOverPanel from 'sentry/components/slideOverPanel';
import {IconClose} from 'sentry/icons';
import {t, tctCode} from 'sentry/locale';
import {space} from 'sentry/styles/space';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import {AnimatePresence, motion} from 'framer-motion';

import {Button} from '@sentry/scraps/button';
import {Flex} from '@sentry/scraps/layout';
import {SlideOverPanel} from '@sentry/scraps/slideOverPanel';
import {Heading} from '@sentry/scraps/text/heading';

import {PageHeadingQuestionTooltip} from 'sentry/components/pageHeadingQuestionTooltip';
import SlideOverPanel from 'sentry/components/slideOverPanel';
import {IconClose, IconGrabbable} from 'sentry/icons';
import {t} from 'sentry/locale';
import {useResizableDrawer} from 'sentry/utils/useResizableDrawer';
Expand Down
3 changes: 2 additions & 1 deletion static/app/views/prevent/preventAI/manageReposPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {Fragment} from 'react';

import {SlideOverPanel} from '@sentry/scraps/slideOverPanel';

import {Alert} from 'sentry/components/core/alert';
import {Button} from 'sentry/components/core/button';
import {CompactSelect} from 'sentry/components/core/compactSelect';
Expand All @@ -9,7 +11,6 @@ import {Switch} from 'sentry/components/core/switch';
import {Heading, Text} from 'sentry/components/core/text';
import FieldGroup from 'sentry/components/forms/fieldGroup';
import LoadingIndicator from 'sentry/components/loadingIndicator';
import SlideOverPanel from 'sentry/components/slideOverPanel';
import {IconClose} from 'sentry/icons';
import {t, tct} from 'sentry/locale';
import type {OrganizationIntegration, Repository} from 'sentry/types/integrations';
Expand Down
Loading