Files
o11y-components/apps/docs/stories/resizable-handle.stories.tsx
zeekay 464e1eece0 State a version once
A version written into a manifest is written into every manifest that wants it,
which is how eslint came to exist in a hundred and four forms across this estate
and how a package came to resolve twice at run time. The catalog moves the number
out of the manifest: a manifest names the package, the workspace names the
version.

Four are held below their latest because the newer release cannot be used, and
the reason is recorded rather than the version alone: @noble/hashes 2 renamed
every subpath the web3 stack imports, @splinetool/runtime 2 depends on a package
that was never published, @dynamic-labs 5.4.1 the same, and react-resizable-panels
3 points its types condition at the bundle.
2026-09-15 11:45:32 -07:00

532 lines
14 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from '@signozhq/ui';
import type { Meta, StoryObj } from '@storybook/react-vite';
const meta: Meta<typeof ResizableHandle> = {
title: 'Primitive Components/Resizable/ResizableHandle',
component: ResizableHandle,
argTypes: {
withHandle: {
control: 'boolean',
description: 'Show a visible drag indicator.',
table: {
category: 'Appearance',
type: { summary: 'boolean' },
defaultValue: { summary: 'false' },
},
},
disabled: {
control: 'boolean',
description:
'When disabled, the separator cannot be used to resize its neighboring panels. ℹ️ The panels may still be resized indirectly (while other panels are being resized). To prevent a panel from being resized at all, it needs to also be disabled.',
table: {
category: 'Behavior',
type: { summary: 'boolean' },
defaultValue: { summary: 'false' },
},
},
style: {
control: false,
description:
'CSS properties. ℹ️ Use the data-separator attribute for custom hover and active styles. ⚠️ The following properties cannot be overridden: flex-grow, flex-shrink.',
table: { category: 'Styling', type: { summary: 'CSSProperties' } },
},
id: {
control: 'text',
description:
'Uniquely identifies the separator within the parent group. Falls back to useId when not provided. This value will also be assigned to the data-separator attribute.',
table: { category: 'Accessibility', type: { summary: 'string' } },
},
className: {
control: 'text',
description:
'CSS class name. ℹ️ Use the data-separator attribute for custom hover and active styles. ⚠️ The following properties cannot be overridden: flex-grow, flex-shrink.',
table: { category: 'Styling', type: { summary: 'string' } },
},
children: {
control: false,
description: 'Custom content to be rendered inside the handle.',
table: { category: 'Content', type: { summary: 'ReactNode' } },
},
testId: {
control: 'text',
description: 'The testId associated with the handle for testing purposes.',
table: { category: 'Testing', type: { summary: 'string' } },
},
ref: {
control: false,
description: 'Ref attached to the root `HTMLDivElement`.',
table: { category: 'Advanced', type: { summary: 'Ref<HTMLDivElement> | undefined' } },
},
},
parameters: {
layout: 'fullscreen',
},
tags: ['autodocs'],
};
export default meta;
type Story = StoryObj<typeof ResizableHandle>;
export const Default: Story = {
args: {
withHandle: false,
disabled: false,
},
render: (args) => (
<div
style={{
height: 400,
borderStyle: 'solid',
borderWidth: 1,
borderRadius: 4,
overflow: 'hidden',
margin: 24,
}}
>
<ResizablePanelGroup orientation="horizontal">
<ResizablePanel defaultSize="50%">
<div
style={{
display: 'flex',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'var(--muted)',
}}
>
<span style={{ fontSize: 14, lineHeight: 1.42857, fontWeight: 500 }}>Panel 1</span>
</div>
</ResizablePanel>
<ResizableHandle {...args} />
<ResizablePanel defaultSize="50%">
<div
style={{
display: 'flex',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
}}
>
<span style={{ fontSize: 14, lineHeight: 1.42857, fontWeight: 500 }}>Panel 2</span>
</div>
</ResizablePanel>
</ResizablePanelGroup>
</div>
),
};
export const WithVisibleHandle: Story = {
args: {
withHandle: true,
disabled: false,
},
render: (args) => (
<div style={{ margin: 24 }}>
<div
style={{ marginBottom: 16, padding: 16, backgroundColor: 'var(--muted)', borderRadius: 4 }}
>
<h3 style={{ fontWeight: 500, marginBottom: 8 }}>Visible Handle:</h3>
<p style={{ fontSize: 14, lineHeight: 1.42857, color: 'var(--muted-foreground)' }}>
The dots icon makes the draggable area more discoverable for users
</p>
</div>
<div
style={{
height: 400,
borderStyle: 'solid',
borderWidth: 1,
borderRadius: 4,
overflow: 'hidden',
}}
>
<ResizablePanelGroup orientation="horizontal">
<ResizablePanel defaultSize="50%">
<div
style={{
display: 'flex',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'var(--muted)',
}}
>
<div style={{ textAlign: 'center' }}>
<span style={{ fontSize: 14, lineHeight: 1.42857, fontWeight: 500 }}>
Left Panel
</span>
<p
style={{
fontSize: 12,
lineHeight: 1.33333,
color: 'var(--muted-foreground)',
marginTop: 4,
}}
>
Drag the dots to resize
</p>
</div>
</div>
</ResizablePanel>
<ResizableHandle {...args} />
<ResizablePanel defaultSize="50%">
<div
style={{
display: 'flex',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
}}
>
<span style={{ fontSize: 14, lineHeight: 1.42857, fontWeight: 500 }}>
Right Panel
</span>
</div>
</ResizablePanel>
</ResizablePanelGroup>
</div>
</div>
),
};
export const Disabled: Story = {
args: {
withHandle: true,
disabled: true,
},
render: (args) => (
<div style={{ margin: 24 }}>
<div
style={{ marginBottom: 16, padding: 16, backgroundColor: 'var(--muted)', borderRadius: 4 }}
>
<h3 style={{ fontWeight: 500, marginBottom: 8 }}>Disabled Handle:</h3>
<p style={{ fontSize: 14, lineHeight: 1.42857, color: 'var(--muted-foreground)' }}>
This handle cannot be dragged. Try dragging it - nothing will happen!
</p>
</div>
<div
style={{
height: 400,
borderStyle: 'solid',
borderWidth: 1,
borderRadius: 4,
overflow: 'hidden',
}}
>
<ResizablePanelGroup orientation="horizontal">
<ResizablePanel defaultSize="30%">
<div
style={{
display: 'flex',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'var(--muted)',
}}
>
<div style={{ textAlign: 'center' }}>
<span style={{ fontSize: 14, lineHeight: 1.42857, fontWeight: 500 }}>
Fixed Panel
</span>
<p
style={{
fontSize: 12,
lineHeight: 1.33333,
color: 'var(--muted-foreground)',
marginTop: 4,
}}
>
30% width
</p>
</div>
</div>
</ResizablePanel>
<ResizableHandle {...args} />
<ResizablePanel defaultSize="70%">
<div
style={{
display: 'flex',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
}}
>
<div style={{ textAlign: 'center' }}>
<span style={{ fontSize: 14, lineHeight: 1.42857, fontWeight: 500 }}>
Fixed Panel
</span>
<p
style={{
fontSize: 12,
lineHeight: 1.33333,
color: 'var(--muted-foreground)',
marginTop: 4,
}}
>
70% width
</p>
</div>
</div>
</ResizablePanel>
</ResizablePanelGroup>
</div>
</div>
),
};
export const VerticalHandle: Story = {
args: {
withHandle: true,
disabled: false,
},
render: (args) => (
<div style={{ margin: 24 }}>
<div
style={{ marginBottom: 16, padding: 16, backgroundColor: 'var(--muted)', borderRadius: 4 }}
>
<h3 style={{ fontWeight: 500, marginBottom: 8 }}>Vertical Handle:</h3>
<p style={{ fontSize: 14, lineHeight: 1.42857, color: 'var(--muted-foreground)' }}>
Handles work the same way in vertical layouts
</p>
</div>
<div
style={{
height: 500,
borderStyle: 'solid',
borderWidth: 1,
borderRadius: 4,
overflow: 'hidden',
}}
>
<ResizablePanelGroup orientation="vertical">
<ResizablePanel defaultSize="60%">
<div
style={{
display: 'flex',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
}}
>
<span style={{ fontSize: 14, lineHeight: 1.42857, fontWeight: 500 }}>Top Panel</span>
</div>
</ResizablePanel>
<ResizableHandle {...args} />
<ResizablePanel defaultSize="40%">
<div
style={{
display: 'flex',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'var(--muted)',
}}
>
<span style={{ fontSize: 14, lineHeight: 1.42857, fontWeight: 500 }}>
Bottom Panel
</span>
</div>
</ResizablePanel>
</ResizablePanelGroup>
</div>
</div>
),
};
export const MultipleHandles: Story = {
render: () => (
<div style={{ margin: 24 }}>
<div
style={{ marginBottom: 16, padding: 16, backgroundColor: 'var(--muted)', borderRadius: 4 }}
>
<h3 style={{ fontWeight: 500, marginBottom: 8 }}>Multiple Handles:</h3>
<p style={{ fontSize: 14, lineHeight: 1.42857, color: 'var(--muted-foreground)' }}>
Each handle can have different configurations
</p>
</div>
<div
style={{
height: 400,
borderStyle: 'solid',
borderWidth: 1,
borderRadius: 4,
overflow: 'hidden',
}}
>
<ResizablePanelGroup orientation="horizontal">
<ResizablePanel defaultSize="25%">
<div
style={{
display: 'flex',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'var(--muted)',
}}
>
<div style={{ textAlign: 'center' }}>
<span style={{ fontSize: 14, lineHeight: 1.42857, fontWeight: 500 }}>Panel 1</span>
</div>
</div>
</ResizablePanel>
<ResizableHandle withHandle={false} />
<ResizablePanel defaultSize="50%">
<div
style={{
display: 'flex',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
}}
>
<div style={{ textAlign: 'center' }}>
<span style={{ fontSize: 14, lineHeight: 1.42857, fontWeight: 500 }}>Panel 2</span>
<p
style={{
fontSize: 12,
lineHeight: 1.33333,
color: 'var(--muted-foreground)',
marginTop: 4,
}}
>
Left: no visible handle
</p>
<p style={{ fontSize: 12, lineHeight: 1.33333, color: 'var(--muted-foreground)' }}>
Right: with visible handle
</p>
</div>
</div>
</ResizablePanel>
<ResizableHandle withHandle={true} />
<ResizablePanel defaultSize="25%">
<div
style={{
display: 'flex',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'var(--muted)',
}}
>
<div style={{ textAlign: 'center' }}>
<span style={{ fontSize: 14, lineHeight: 1.42857, fontWeight: 500 }}>Panel 3</span>
</div>
</div>
</ResizablePanel>
</ResizablePanelGroup>
</div>
</div>
),
};
export const MixedHandles: Story = {
render: () => (
<div style={{ margin: 24 }}>
<div
style={{ marginBottom: 16, padding: 16, backgroundColor: 'var(--muted)', borderRadius: 4 }}
>
<h3 style={{ fontWeight: 500, marginBottom: 8 }}>Mixed Handle Configuration:</h3>
<ul
className="stack-4"
style={{ fontSize: 14, lineHeight: 1.42857, color: 'var(--muted-foreground)' }}
>
<li>• First handle: Active with visible indicator</li>
<li>• Second handle: Disabled (cannot drag)</li>
</ul>
</div>
<div
style={{
height: 400,
borderStyle: 'solid',
borderWidth: 1,
borderRadius: 4,
overflow: 'hidden',
}}
>
<ResizablePanelGroup orientation="horizontal">
<ResizablePanel defaultSize="33%">
<div
className="panel-blue"
style={{
display: 'flex',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
}}
>
<div style={{ textAlign: 'center' }}>
<span style={{ fontSize: 14, lineHeight: 1.42857, fontWeight: 500 }}>
Resizable
</span>
<p
style={{
fontSize: 12,
lineHeight: 1.33333,
color: 'var(--muted-foreground)',
marginTop: 4,
}}
>
Can resize right
</p>
</div>
</div>
</ResizablePanel>
<ResizableHandle withHandle={true} disabled={false} />
<ResizablePanel defaultSize="34%">
<div
style={{
display: 'flex',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
}}
>
<div style={{ textAlign: 'center' }}>
<span style={{ fontSize: 14, lineHeight: 1.42857, fontWeight: 500 }}>Flexible</span>
<p
style={{
fontSize: 12,
lineHeight: 1.33333,
color: 'var(--muted-foreground)',
marginTop: 4,
}}
>
Can resize left
</p>
<p style={{ fontSize: 12, lineHeight: 1.33333, color: 'var(--muted-foreground)' }}>
Cannot resize right
</p>
</div>
</div>
</ResizablePanel>
<ResizableHandle withHandle={true} disabled={true} />
<ResizablePanel defaultSize="33%">
<div
className="panel-amber"
style={{
display: 'flex',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
}}
>
<div style={{ textAlign: 'center' }}>
<span style={{ fontSize: 14, lineHeight: 1.42857, fontWeight: 500 }}>Fixed</span>
<p
style={{
fontSize: 12,
lineHeight: 1.33333,
color: 'var(--muted-foreground)',
marginTop: 4,
}}
>
Cannot resize
</p>
</div>
</div>
</ResizablePanel>
</ResizablePanelGroup>
</div>
</div>
),
};