0
# Layout and Navigation
1
2
Bar components, separators, tabs, and navigation utilities for building complex interfaces with consistent layout patterns.
3
4
## Capabilities
5
6
### Bar Components
7
8
Container components for organizing actions and content in horizontal bars.
9
10
```typescript { .api }
11
/**
12
* Generic bar container component for organizing content horizontally
13
*/
14
const Bar: React.ComponentType<{
15
/** Bar content */
16
children: React.ReactNode;
17
/** Additional styling and configuration */
18
[key: string]: any;
19
}>;
20
21
/**
22
* Flexible bar container with advanced layout options
23
* Provides better control over item spacing and alignment
24
*/
25
const FlexBar: React.ComponentType<{
26
/** Bar content */
27
children: React.ReactNode;
28
/** Flex layout configuration */
29
[key: string]: any;
30
}>;
31
```
32
33
### Separator Components
34
35
Visual separators for organizing content and creating visual hierarchy.
36
37
```typescript { .api }
38
/**
39
* Visual separator component for dividing content
40
*/
41
const Separator: React.ComponentType<{
42
/** Separator styling options */
43
[key: string]: any;
44
}>;
45
46
/**
47
* Utility function to add separators between array items
48
* Inserts separator elements between each item in an array
49
*/
50
function interleaveSeparators<T>(items: T[]): (T | React.ReactElement)[];
51
```
52
53
### Tab Components
54
55
Complete tab system for organizing content into switchable panels.
56
57
```typescript { .api }
58
/**
59
* Main tab container component that manages tab state and content
60
*/
61
const Tabs: React.ComponentType<{
62
/** Currently active tab */
63
active?: string;
64
/** Tab change handler */
65
onSelect?: (id: string) => void;
66
/** Tab configuration and content */
67
children: React.ReactNode;
68
/** Additional tab options */
69
[key: string]: any;
70
}>;
71
72
/**
73
* Tab state management component for controlled tab behavior
74
*/
75
const TabsState: React.ComponentType<{
76
/** Initial active tab */
77
initial?: string;
78
/** Tab state change handler */
79
children: (state: { active: string; onSelect: (id: string) => void }) => React.ReactNode;
80
}>;
81
82
/**
83
* Tab bar component that displays tab headers/buttons
84
*/
85
const TabBar: React.ComponentType<{
86
/** Tab items to display */
87
children: React.ReactNode;
88
/** Bar styling options */
89
[key: string]: any;
90
}>;
91
92
/**
93
* Individual tab wrapper component
94
*/
95
const TabWrapper: React.ComponentType<{
96
/** Tab content */
97
children: React.ReactNode;
98
/** Tab identifier */
99
id: string;
100
/** Tab title */
101
title: string;
102
/** Tab configuration */
103
[key: string]: any;
104
}>;
105
106
/**
107
* Empty state component for tab content when no content is available
108
*/
109
const EmptyTabContent: React.ComponentType<{
110
/** Empty state message */
111
children?: React.ReactNode;
112
/** Styling options */
113
[key: string]: any;
114
}>;
115
```
116
117
### Button Components for Bars
118
119
Specialized button components optimized for use in bars and toolbars.
120
121
```typescript { .api }
122
/**
123
* Loading skeleton for icon buttons in bars
124
*/
125
const IconButtonSkeleton: React.ComponentType<{
126
/** Skeleton configuration */
127
[key: string]: any;
128
}>;
129
130
/**
131
* Tab button component for tab navigation
132
*/
133
const TabButton: React.ComponentType<{
134
/** Button content */
135
children: React.ReactNode;
136
/** Active state */
137
active?: boolean;
138
/** Click handler */
139
onClick?: () => void;
140
/** Button configuration */
141
[key: string]: any;
142
}>;
143
```
144
145
### Addon Panel
146
147
Container component for Storybook addon panels.
148
149
```typescript { .api }
150
/**
151
* Addon panel container component for displaying addon content
152
*/
153
const AddonPanel: React.ComponentType<{
154
/** Panel content */
155
children: React.ReactNode;
156
/** Panel configuration */
157
[key: string]: any;
158
}>;
159
```
160
161
## Usage Examples
162
163
**Basic Bar Components:**
164
165
```typescript
166
import { Bar, FlexBar, Button, IconButton } from "@storybook/components";
167
168
// Basic bar with actions
169
<Bar>
170
<Button variant="outline">Cancel</Button>
171
<Button variant="solid">Save</Button>
172
</Bar>
173
174
// Flexible bar with space distribution
175
<FlexBar>
176
<div>Left content</div>
177
<div style={{ marginLeft: 'auto' }}>Right content</div>
178
</FlexBar>
179
```
180
181
**Separators:**
182
183
```typescript
184
import { Separator, interleaveSeparators, Button } from "@storybook/components";
185
186
// Manual separator
187
<div>
188
<Button>Action 1</Button>
189
<Separator />
190
<Button>Action 2</Button>
191
<Separator />
192
<Button>Action 3</Button>
193
</div>
194
195
// Automatic separators using utility
196
const actions = [
197
<Button key="1">Action 1</Button>,
198
<Button key="2">Action 2</Button>,
199
<Button key="3">Action 3</Button>
200
];
201
202
<div>
203
{interleaveSeparators(actions)}
204
</div>
205
```
206
207
**Tab System:**
208
209
```typescript
210
import {
211
Tabs,
212
TabsState,
213
TabBar,
214
TabWrapper,
215
TabButton,
216
EmptyTabContent
217
} from "@storybook/components";
218
219
// Basic tabs with state management
220
<TabsState initial="tab1">
221
{({ active, onSelect }) => (
222
<Tabs active={active} onSelect={onSelect}>
223
<TabBar>
224
<TabButton
225
active={active === 'tab1'}
226
onClick={() => onSelect('tab1')}
227
>
228
Tab 1
229
</TabButton>
230
<TabButton
231
active={active === 'tab2'}
232
onClick={() => onSelect('tab2')}
233
>
234
Tab 2
235
</TabButton>
236
<TabButton
237
active={active === 'tab3'}
238
onClick={() => onSelect('tab3')}
239
>
240
Tab 3
241
</TabButton>
242
</TabBar>
243
244
<TabWrapper id="tab1" title="Tab 1">
245
<div>Content for tab 1</div>
246
</TabWrapper>
247
248
<TabWrapper id="tab2" title="Tab 2">
249
<div>Content for tab 2</div>
250
</TabWrapper>
251
252
<TabWrapper id="tab3" title="Tab 3">
253
<EmptyTabContent>
254
No content available for this tab
255
</EmptyTabContent>
256
</TabWrapper>
257
</Tabs>
258
)}
259
</TabsState>
260
```
261
262
**Controlled Tabs:**
263
264
```typescript
265
import { Tabs, TabBar, TabWrapper, TabButton } from "@storybook/components";
266
import { useState } from "react";
267
268
function ControlledTabs() {
269
const [activeTab, setActiveTab] = useState('overview');
270
271
return (
272
<Tabs active={activeTab} onSelect={setActiveTab}>
273
<TabBar>
274
<TabButton
275
active={activeTab === 'overview'}
276
onClick={() => setActiveTab('overview')}
277
>
278
Overview
279
</TabButton>
280
<TabButton
281
active={activeTab === 'details'}
282
onClick={() => setActiveTab('details')}
283
>
284
Details
285
</TabButton>
286
<TabButton
287
active={activeTab === 'settings'}
288
onClick={() => setActiveTab('settings')}
289
>
290
Settings
291
</TabButton>
292
</TabBar>
293
294
<TabWrapper id="overview" title="Overview">
295
<h3>Project Overview</h3>
296
<p>General information about the project.</p>
297
</TabWrapper>
298
299
<TabWrapper id="details" title="Details">
300
<h3>Project Details</h3>
301
<p>Detailed information and specifications.</p>
302
</TabWrapper>
303
304
<TabWrapper id="settings" title="Settings">
305
<h3>Project Settings</h3>
306
<p>Configuration options and preferences.</p>
307
</TabWrapper>
308
</Tabs>
309
);
310
}
311
```
312
313
**Button Skeletons:**
314
315
```typescript
316
import { IconButtonSkeleton, Bar } from "@storybook/components";
317
318
// Loading state for toolbar
319
<Bar>
320
<IconButtonSkeleton />
321
<IconButtonSkeleton />
322
<IconButtonSkeleton />
323
</Bar>
324
```
325
326
**Complex Layout Example:**
327
328
```typescript
329
import {
330
FlexBar,
331
Separator,
332
TabsState,
333
Tabs,
334
TabBar,
335
TabButton,
336
TabWrapper,
337
AddonPanel,
338
Button
339
} from "@storybook/components";
340
341
function ComplexInterface() {
342
return (
343
<div>
344
{/* Top toolbar */}
345
<FlexBar>
346
<div>
347
<Button variant="ghost">Menu</Button>
348
<Separator />
349
<Button variant="ghost">File</Button>
350
<Button variant="ghost">Edit</Button>
351
</div>
352
<div style={{ marginLeft: 'auto' }}>
353
<Button variant="outline">Settings</Button>
354
</div>
355
</FlexBar>
356
357
{/* Main content with tabs */}
358
<TabsState initial="content">
359
{({ active, onSelect }) => (
360
<Tabs active={active} onSelect={onSelect}>
361
<TabBar>
362
<TabButton
363
active={active === 'content'}
364
onClick={() => onSelect('content')}
365
>
366
Content
367
</TabButton>
368
<TabButton
369
active={active === 'addons'}
370
onClick={() => onSelect('addons')}
371
>
372
Addons
373
</TabButton>
374
</TabBar>
375
376
<TabWrapper id="content" title="Content">
377
<div>Main content area</div>
378
</TabWrapper>
379
380
<TabWrapper id="addons" title="Addons">
381
<AddonPanel>
382
<div>Addon content and controls</div>
383
</AddonPanel>
384
</TabWrapper>
385
</Tabs>
386
)}
387
</TabsState>
388
</div>
389
);
390
}
391
```
392
393
## Layout Patterns
394
395
**Toolbar Pattern:**
396
```typescript
397
// Standard toolbar with actions and separators
398
<FlexBar>
399
<div>
400
<Button variant="ghost">Action 1</Button>
401
<Separator />
402
<Button variant="ghost">Action 2</Button>
403
</div>
404
<div style={{ marginLeft: 'auto' }}>
405
<Button variant="outline">Settings</Button>
406
</div>
407
</FlexBar>
408
```
409
410
**Tab Navigation Pattern:**
411
```typescript
412
// Consistent tab navigation across interfaces
413
<TabsState>
414
{({ active, onSelect }) => (
415
<>
416
<TabBar>
417
{/* Tab buttons */}
418
</TabBar>
419
<div>
420
{/* Tab content */}
421
</div>
422
</>
423
)}
424
</TabsState>
425
```
426
427
## Integration Notes
428
429
Layout components are designed to work seamlessly with Storybook's theming system and automatically adapt to different screen sizes and orientations. They provide consistent spacing, alignment, and visual hierarchy across different interface contexts.
430
431
The tab system includes proper accessibility features including keyboard navigation, ARIA labels, and focus management for screen readers and keyboard-only users.