@ceed/ads 1.20.0 → 1.20.1-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/components/ProfileMenu/ProfileMenu.d.ts +1 -1
  2. package/dist/components/data-display/Markdown.md +832 -0
  3. package/dist/components/feedback/Dialog.md +605 -3
  4. package/dist/components/feedback/Modal.md +656 -24
  5. package/dist/components/feedback/llms.txt +1 -1
  6. package/dist/components/inputs/Autocomplete.md +734 -2
  7. package/dist/components/inputs/Calendar.md +655 -1
  8. package/dist/components/inputs/DatePicker.md +699 -3
  9. package/dist/components/inputs/DateRangePicker.md +815 -1
  10. package/dist/components/inputs/MonthPicker.md +626 -4
  11. package/dist/components/inputs/MonthRangePicker.md +682 -4
  12. package/dist/components/inputs/Select.md +600 -0
  13. package/dist/components/layout/Container.md +507 -0
  14. package/dist/components/navigation/Breadcrumbs.md +582 -0
  15. package/dist/components/navigation/IconMenuButton.md +693 -0
  16. package/dist/components/navigation/InsetDrawer.md +1150 -3
  17. package/dist/components/navigation/Link.md +526 -0
  18. package/dist/components/navigation/MenuButton.md +632 -0
  19. package/dist/components/navigation/NavigationGroup.md +401 -1
  20. package/dist/components/navigation/NavigationItem.md +311 -0
  21. package/dist/components/navigation/Navigator.md +373 -0
  22. package/dist/components/navigation/Pagination.md +521 -0
  23. package/dist/components/navigation/ProfileMenu.md +605 -0
  24. package/dist/components/navigation/Tabs.md +609 -7
  25. package/dist/components/surfaces/Accordions.md +947 -3
  26. package/dist/index.cjs +3 -1
  27. package/dist/index.js +3 -1
  28. package/dist/llms.txt +1 -1
  29. package/framer/index.js +1 -1
  30. package/package.json +3 -2
@@ -2,6 +2,60 @@
2
2
 
3
3
  ## Introduction
4
4
 
5
+ The Tabs component provides a way to organize content into separate views where only one view is visible at a time. Built on Joy UI's Tabs, TabList, Tab, and TabPanel components, it enables users to switch between different sections of related content without leaving the current page. Tabs are ideal for organizing related information that doesn't need to be viewed simultaneously.
6
+
7
+ ```tsx
8
+ <Tabs {...args} defaultValue={0}>
9
+ <TabList>
10
+ <Tab color={color} variant={variant}>
11
+ First Tab
12
+ </Tab>
13
+ <Tab color={color} variant={variant}>
14
+ Second Tab
15
+ </Tab>
16
+ <Tab color={color} variant={variant}>
17
+ Third Tab
18
+ </Tab>
19
+ </TabList>
20
+ <TabPanel value={0}>Content for the first tab panel.</TabPanel>
21
+ <TabPanel value={1}>Content for the second tab panel.</TabPanel>
22
+ <TabPanel value={2}>Content for the third tab panel.</TabPanel>
23
+ </Tabs>
24
+ ```
25
+
26
+ | Field | Description | Default |
27
+ | ------- | ----------- | --------- |
28
+ | color | — | "primary" |
29
+ | size | — | "md" |
30
+ | variant | — | "plain" |
31
+
32
+ ## Usage
33
+
34
+ ```tsx
35
+ import { Tabs, TabList, Tab, TabPanel } from '@ceed/ads';
36
+
37
+ function MyComponent() {
38
+ return (
39
+ <Tabs defaultValue={0}>
40
+ <TabList>
41
+ <Tab>First Tab</Tab>
42
+ <Tab>Second Tab</Tab>
43
+ <Tab>Third Tab</Tab>
44
+ </TabList>
45
+ <TabPanel value={0}>Content for the first tab</TabPanel>
46
+ <TabPanel value={1}>Content for the second tab</TabPanel>
47
+ <TabPanel value={2}>Content for the third tab</TabPanel>
48
+ </Tabs>
49
+ );
50
+ }
51
+ ```
52
+
53
+ ## Examples
54
+
55
+ ### Basic Tabs
56
+
57
+ Default tab navigation with horizontal layout.
58
+
5
59
  ```tsx
6
60
  <Tabs {...args}>
7
61
  <TabList>
@@ -21,14 +75,562 @@
21
75
  </Tabs>
22
76
  ```
23
77
 
24
- | Field | Description | Default |
25
- | ------- | ----------- | --------- |
26
- | color | — | "primary" |
27
- | size | — | "md" |
28
- | variant | — | "plain" |
78
+ ### Variants
29
79
 
30
- ## Usage
80
+ Tabs support different visual styles through variants.
81
+
82
+ ```tsx
83
+ <div style={{
84
+ display: 'flex',
85
+ flexDirection: 'column',
86
+ gap: 24
87
+ }}>
88
+ <Tabs defaultValue={0}>
89
+ <TabList variant="plain">
90
+ <Tab variant="plain">Plain</Tab>
91
+ <Tab variant="plain">Tabs</Tab>
92
+ <Tab variant="plain">Example</Tab>
93
+ </TabList>
94
+ </Tabs>
95
+ <Tabs defaultValue={0}>
96
+ <TabList variant="outlined">
97
+ <Tab variant="outlined">Outlined</Tab>
98
+ <Tab variant="outlined">Tabs</Tab>
99
+ <Tab variant="outlined">Example</Tab>
100
+ </TabList>
101
+ </Tabs>
102
+ <Tabs defaultValue={0}>
103
+ <TabList variant="soft">
104
+ <Tab variant="soft">Soft</Tab>
105
+ <Tab variant="soft">Tabs</Tab>
106
+ <Tab variant="soft">Example</Tab>
107
+ </TabList>
108
+ </Tabs>
109
+ <Tabs defaultValue={0}>
110
+ <TabList variant="solid">
111
+ <Tab variant="solid">Solid</Tab>
112
+ <Tab variant="solid">Tabs</Tab>
113
+ <Tab variant="solid">Example</Tab>
114
+ </TabList>
115
+ </Tabs>
116
+ </div>
117
+ ```
118
+
119
+ ### Sizes
120
+
121
+ Tabs come in different sizes to fit various use cases.
122
+
123
+ ```tsx
124
+ <div style={{
125
+ display: 'flex',
126
+ flexDirection: 'column',
127
+ gap: 24
128
+ }}>
129
+ <Tabs defaultValue={0} size="sm">
130
+ <TabList>
131
+ <Tab>Small</Tab>
132
+ <Tab>Size</Tab>
133
+ <Tab>Tabs</Tab>
134
+ </TabList>
135
+ </Tabs>
136
+ <Tabs defaultValue={0} size="md">
137
+ <TabList>
138
+ <Tab>Medium</Tab>
139
+ <Tab>Size</Tab>
140
+ <Tab>Tabs</Tab>
141
+ </TabList>
142
+ </Tabs>
143
+ <Tabs defaultValue={0} size="lg">
144
+ <TabList>
145
+ <Tab>Large</Tab>
146
+ <Tab>Size</Tab>
147
+ <Tab>Tabs</Tab>
148
+ </TabList>
149
+ </Tabs>
150
+ </div>
151
+ ```
152
+
153
+ ### Colors
154
+
155
+ Apply semantic colors to tabs.
156
+
157
+ ```tsx
158
+ <div style={{
159
+ display: 'flex',
160
+ flexDirection: 'column',
161
+ gap: 24
162
+ }}>
163
+ <Tabs defaultValue={0}>
164
+ <TabList>
165
+ <Tab color="primary">Primary</Tab>
166
+ <Tab color="primary">Tabs</Tab>
167
+ </TabList>
168
+ </Tabs>
169
+ <Tabs defaultValue={0}>
170
+ <TabList>
171
+ <Tab color="neutral">Neutral</Tab>
172
+ <Tab color="neutral">Tabs</Tab>
173
+ </TabList>
174
+ </Tabs>
175
+ <Tabs defaultValue={0}>
176
+ <TabList>
177
+ <Tab color="success">Success</Tab>
178
+ <Tab color="success">Tabs</Tab>
179
+ </TabList>
180
+ </Tabs>
181
+ <Tabs defaultValue={0}>
182
+ <TabList>
183
+ <Tab color="warning">Warning</Tab>
184
+ <Tab color="warning">Tabs</Tab>
185
+ </TabList>
186
+ </Tabs>
187
+ <Tabs defaultValue={0}>
188
+ <TabList>
189
+ <Tab color="danger">Danger</Tab>
190
+ <Tab color="danger">Tabs</Tab>
191
+ </TabList>
192
+ </Tabs>
193
+ </div>
194
+ ```
195
+
196
+ ### With Decorators
197
+
198
+ Add icons or other elements to tab labels.
199
+
200
+ ```tsx
201
+ <Tabs {...args}>
202
+ <TabList>
203
+ <Tab startDecorator={<Call />} color={color} variant={variant}>
204
+ Tab1
205
+ </Tab>
206
+ <Tab endDecorator={<Sms />} color={color} variant={variant}>
207
+ Tab2
208
+ </Tab>
209
+ <Tab startDecorator={<Email />} endDecorator={<MoreVert />} color={color} variant={variant}>
210
+ Tab3
211
+ </Tab>
212
+ </TabList>
213
+ <TabPanel value={0}>Tab list1</TabPanel>
214
+ <TabPanel value={1}>Tab list2</TabPanel>
215
+ <TabPanel value={2}>Tab list3</TabPanel>
216
+ </Tabs>
217
+ ```
218
+
219
+ ### Vertical Orientation
220
+
221
+ Tabs can be arranged vertically for sidebar-style navigation.
222
+
223
+ ```tsx
224
+ <Tabs defaultValue={0} orientation="vertical" sx={{
225
+ minWidth: 300
226
+ }}>
227
+ <TabList>
228
+ <Tab>Profile</Tab>
229
+ <Tab>Settings</Tab>
230
+ <Tab>Notifications</Tab>
231
+ </TabList>
232
+ <TabPanel value={0}>Profile content</TabPanel>
233
+ <TabPanel value={1}>Settings content</TabPanel>
234
+ <TabPanel value={2}>Notifications content</TabPanel>
235
+ </Tabs>
236
+ ```
237
+
238
+ ### Disabled Tabs
239
+
240
+ Individual tabs can be disabled while keeping others active.
241
+
242
+ ```tsx
243
+ <Tabs defaultValue={0}>
244
+ <TabList>
245
+ <Tab>Active Tab</Tab>
246
+ <Tab disabled>Disabled Tab</Tab>
247
+ <Tab>Another Tab</Tab>
248
+ </TabList>
249
+ <TabPanel value={0}>First panel content</TabPanel>
250
+ <TabPanel value={1}>Second panel content (disabled)</TabPanel>
251
+ <TabPanel value={2}>Third panel content</TabPanel>
252
+ </Tabs>
253
+ ```
254
+
255
+ ### Controlled Tabs
256
+
257
+ Programmatically control the active tab.
258
+
259
+ ```tsx
260
+ <div>
261
+ <Tabs value={value} onChange={(event, newValue) => setValue(newValue as number)}>
262
+ <TabList>
263
+ <Tab>First</Tab>
264
+ <Tab>Second</Tab>
265
+ <Tab>Third</Tab>
266
+ </TabList>
267
+ <TabPanel value={0}>First panel</TabPanel>
268
+ <TabPanel value={1}>Second panel</TabPanel>
269
+ <TabPanel value={2}>Third panel</TabPanel>
270
+ </Tabs>
271
+ <div style={{
272
+ marginTop: 16
273
+ }}>Current tab index: {value}</div>
274
+ </div>
275
+ ```
276
+
277
+ ## When to Use
278
+
279
+ ### ✅ Good Use Cases
280
+
281
+ - **Related content sections**: When content can be logically grouped and users don't need to see all sections at once
282
+ - **Settings pages**: Organizing different categories of settings (Profile, Security, Notifications)
283
+ - **Dashboard views**: Switching between different data views or time periods
284
+ - **Product details**: Showing Description, Specifications, Reviews as separate tabs
285
+ - **Form sections**: Breaking long forms into logical steps (not for strict wizard flows)
286
+ - **Code examples**: Showing code in different languages or frameworks
287
+
288
+ ### ❌ When Not to Use
289
+
290
+ - **Primary navigation**: Use a navigation menu or sidebar for main app navigation
291
+ - **Sequential workflows**: Use Stepper for multi-step processes that must be completed in order
292
+ - **Comparing content**: If users need to see multiple sections simultaneously, use accordions or show all content
293
+ - **Very few items**: If there are only 2 options, consider using a toggle or radio buttons
294
+ - **Many items**: More than 5-6 tabs become hard to navigate; consider a dropdown or nested navigation
295
+ - **Mobile layouts**: Consider alternative patterns like accordions or stacked sections on small screens
296
+
297
+ ## Common Use Cases
298
+
299
+ ### Settings Page
300
+
301
+ ```tsx
302
+ function SettingsPage() {
303
+ return (
304
+ <Tabs defaultValue={0}>
305
+ <TabList>
306
+ <Tab startDecorator={<PersonIcon />}>Profile</Tab>
307
+ <Tab startDecorator={<SecurityIcon />}>Security</Tab>
308
+ <Tab startDecorator={<NotificationsIcon />}>Notifications</Tab>
309
+ <Tab startDecorator={<PaletteIcon />}>Appearance</Tab>
310
+ </TabList>
311
+ <TabPanel value={0}>
312
+ <ProfileSettings />
313
+ </TabPanel>
314
+ <TabPanel value={1}>
315
+ <SecuritySettings />
316
+ </TabPanel>
317
+ <TabPanel value={2}>
318
+ <NotificationSettings />
319
+ </TabPanel>
320
+ <TabPanel value={3}>
321
+ <AppearanceSettings />
322
+ </TabPanel>
323
+ </Tabs>
324
+ );
325
+ }
326
+ ```
327
+
328
+ ### Product Detail Page
329
+
330
+ ```tsx
331
+ function ProductDetails({ product }) {
332
+ return (
333
+ <Tabs defaultValue={0}>
334
+ <TabList>
335
+ <Tab>Description</Tab>
336
+ <Tab>Specifications</Tab>
337
+ <Tab>Reviews ({product.reviewCount})</Tab>
338
+ <Tab>Q&A</Tab>
339
+ </TabList>
340
+ <TabPanel value={0}>
341
+ <Typography>{product.description}</Typography>
342
+ </TabPanel>
343
+ <TabPanel value={1}>
344
+ <SpecificationTable specs={product.specifications} />
345
+ </TabPanel>
346
+ <TabPanel value={2}>
347
+ <ReviewList reviews={product.reviews} />
348
+ </TabPanel>
349
+ <TabPanel value={3}>
350
+ <QASection productId={product.id} />
351
+ </TabPanel>
352
+ </Tabs>
353
+ );
354
+ }
355
+ ```
356
+
357
+ ### Dashboard with Time Filters
358
+
359
+ ```tsx
360
+ function DashboardTabs() {
361
+ const [timeRange, setTimeRange] = useState('week');
362
+
363
+ return (
364
+ <Tabs value={timeRange} onChange={(e, val) => setTimeRange(val as string)}>
365
+ <TabList>
366
+ <Tab value="day">Today</Tab>
367
+ <Tab value="week">This Week</Tab>
368
+ <Tab value="month">This Month</Tab>
369
+ <Tab value="year">This Year</Tab>
370
+ </TabList>
371
+ <TabPanel value="day">
372
+ <DailyStats />
373
+ </TabPanel>
374
+ <TabPanel value="week">
375
+ <WeeklyStats />
376
+ </TabPanel>
377
+ <TabPanel value="month">
378
+ <MonthlyStats />
379
+ </TabPanel>
380
+ <TabPanel value="year">
381
+ <YearlyStats />
382
+ </TabPanel>
383
+ </Tabs>
384
+ );
385
+ }
386
+ ```
387
+
388
+ ### Code Examples
389
+
390
+ ```tsx
391
+ function CodeExamples() {
392
+ return (
393
+ <Tabs defaultValue="react">
394
+ <TabList>
395
+ <Tab value="react">React</Tab>
396
+ <Tab value="vue">Vue</Tab>
397
+ <Tab value="angular">Angular</Tab>
398
+ </TabList>
399
+ <TabPanel value="react">
400
+ <CodeBlock language="jsx">{reactCode}</CodeBlock>
401
+ </TabPanel>
402
+ <TabPanel value="vue">
403
+ <CodeBlock language="vue">{vueCode}</CodeBlock>
404
+ </TabPanel>
405
+ <TabPanel value="angular">
406
+ <CodeBlock language="typescript">{angularCode}</CodeBlock>
407
+ </TabPanel>
408
+ </Tabs>
409
+ );
410
+ }
411
+ ```
412
+
413
+ ### Vertical Sidebar Navigation
414
+
415
+ ```tsx
416
+ function SidebarTabs() {
417
+ return (
418
+ <Box sx={{ display: 'flex' }}>
419
+ <Tabs orientation="vertical" defaultValue={0} sx={{ minWidth: 200 }}>
420
+ <TabList>
421
+ <Tab startDecorator={<DashboardIcon />}>Dashboard</Tab>
422
+ <Tab startDecorator={<AnalyticsIcon />}>Analytics</Tab>
423
+ <Tab startDecorator={<ReportsIcon />}>Reports</Tab>
424
+ <Tab startDecorator={<SettingsIcon />}>Settings</Tab>
425
+ </TabList>
426
+ </Tabs>
427
+ <Box sx={{ flex: 1, p: 2 }}>
428
+ <TabPanel value={0}>Dashboard content</TabPanel>
429
+ <TabPanel value={1}>Analytics content</TabPanel>
430
+ <TabPanel value={2}>Reports content</TabPanel>
431
+ <TabPanel value={3}>Settings content</TabPanel>
432
+ </Box>
433
+ </Box>
434
+ );
435
+ }
436
+ ```
437
+
438
+ ## Component Structure
439
+
440
+ Tabs uses a composition pattern with multiple sub-components:
441
+
442
+ ```tsx
443
+ <Tabs> {/* Container - manages state */}
444
+ <TabList> {/* Tab button container */}
445
+ <Tab>Tab 1</Tab> {/* Individual tab buttons */}
446
+ <Tab>Tab 2</Tab>
447
+ </TabList>
448
+ <TabPanel value={0}> {/* Content panels */}
449
+ Content 1
450
+ </TabPanel>
451
+ <TabPanel value={1}>
452
+ Content 2
453
+ </TabPanel>
454
+ </Tabs>
455
+ ```
456
+
457
+ ## Props and Customization
458
+
459
+ ### Tabs Props
460
+
461
+ | Prop | Type | Default | Description |
462
+ | -------------- | ---------------------------- | -------------- | ----------------------------------- |
463
+ | `defaultValue` | `string \| number` | - | Default selected tab (uncontrolled) |
464
+ | `value` | `string \| number` | - | Selected tab (controlled) |
465
+ | `onChange` | `function` | - | Callback when tab changes |
466
+ | `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Tab layout direction |
467
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Size of all child components |
468
+
469
+ ### Tab Props
470
+
471
+ | Prop | Type | Default | Description |
472
+ | ---------------- | -------------------------------------------------------------- | --------- | ---------------------------------- |
473
+ | `value` | `string \| number` | - | Tab identifier (defaults to index) |
474
+ | `variant` | `'plain' \| 'outlined' \| 'soft' \| 'solid'` | `'plain'` | Visual style |
475
+ | `color` | `'primary' \| 'neutral' \| 'danger' \| 'success' \| 'warning'` | - | Color scheme |
476
+ | `disabled` | `boolean` | `false` | Disable the tab |
477
+ | `startDecorator` | `ReactNode` | - | Element before tab label |
478
+ | `endDecorator` | `ReactNode` | - | Element after tab label |
479
+
480
+ ### TabPanel Props
481
+
482
+ | Prop | Type | Default | Description |
483
+ | ------------- | ------------------ | ------- | ----------------------------- |
484
+ | `value` | `string \| number` | - | Matching tab value |
485
+ | `keepMounted` | `boolean` | `false` | Keep panel in DOM when hidden |
486
+
487
+ ### Custom Styling
488
+
489
+ ```tsx
490
+ <Tabs
491
+ sx={{
492
+ '--Tabs-gap': '8px',
493
+ }}
494
+ >
495
+ <TabList
496
+ sx={{
497
+ borderBottom: '1px solid',
498
+ borderColor: 'divider',
499
+ }}
500
+ >
501
+ <Tab
502
+ sx={{
503
+ '&.Mui-selected': {
504
+ borderBottom: '2px solid',
505
+ borderColor: 'primary.500',
506
+ },
507
+ }}
508
+ >
509
+ Custom Tab
510
+ </Tab>
511
+ </TabList>
512
+ </Tabs>
513
+ ```
514
+
515
+ ## Accessibility
516
+
517
+ Tabs components follow WAI-ARIA Tabs pattern for comprehensive accessibility:
518
+
519
+ ### ARIA Attributes
520
+
521
+ - `role="tablist"` on TabList
522
+ - `role="tab"` on each Tab
523
+ - `role="tabpanel"` on each TabPanel
524
+ - `aria-selected` indicates the active tab
525
+ - `aria-controls` links tabs to their panels
526
+ - `aria-labelledby` links panels to their tabs
527
+
528
+ ### Keyboard Navigation
529
+
530
+ - **Tab**: Move focus to the tab list, then to the active panel
531
+ - **Arrow Left/Right**: Move between tabs (horizontal orientation)
532
+ - **Arrow Up/Down**: Move between tabs (vertical orientation)
533
+ - **Home**: Move to first tab
534
+ - **End**: Move to last tab
535
+ - **Enter/Space**: Activate the focused tab
536
+
537
+ ### Screen Reader Support
31
538
 
32
539
  ```tsx
33
- import { Tabs } from '@ceed/ads';
540
+ <Tabs aria-label="Account settings tabs">
541
+ <TabList>
542
+ <Tab>Profile</Tab>
543
+ <Tab>Security</Tab>
544
+ </TabList>
545
+ <TabPanel value={0}>
546
+ <h2 id="profile-heading">Profile Settings</h2>
547
+ {/* Content */}
548
+ </TabPanel>
549
+ </Tabs>
34
550
  ```
551
+
552
+ ## Best Practices
553
+
554
+ ### ✅ Do
555
+
556
+ 1. **Use clear, concise labels**: Tab labels should clearly describe the content
557
+
558
+ ```tsx
559
+ // ✅ Good: Clear labels
560
+ <Tab>Account Settings</Tab>
561
+ <Tab>Notifications</Tab>
562
+
563
+ // ❌ Bad: Vague labels
564
+ <Tab>Tab 1</Tab>
565
+ <Tab>Other</Tab>
566
+ ```
567
+
568
+ 2. **Keep tab count manageable**: Limit to 5-6 tabs maximum
569
+
570
+ 3. **Order tabs logically**: Place most important or frequently used tabs first
571
+
572
+ 4. **Use consistent styling**: All tabs should have the same visual weight
573
+
574
+ 5. **Show active state clearly**: Users should always know which tab is selected
575
+
576
+ ### ❌ Don't
577
+
578
+ 1. **Don't hide critical information**: Important content shouldn't be buried in secondary tabs
579
+
580
+ 2. **Don't use for sequential processes**: Use Stepper for ordered workflows
581
+
582
+ ```tsx
583
+ // ❌ Bad: Sequential steps as tabs
584
+ <Tab>Step 1: Personal Info</Tab>
585
+ <Tab>Step 2: Payment</Tab>
586
+ <Tab>Step 3: Confirm</Tab>
587
+
588
+ // ✅ Good: Use Stepper instead
589
+ <Stepper activeStep={activeStep}>
590
+ <Step>Personal Info</Step>
591
+ <Step>Payment</Step>
592
+ <Step>Confirm</Step>
593
+ </Stepper>
594
+ ```
595
+
596
+ 3. **Don't nest tabs within tabs**: Creates confusing navigation
597
+
598
+ 4. **Don't use inconsistent tab counts**: If tabs are dynamic, consider alternative UI patterns
599
+
600
+ ## Performance Considerations
601
+
602
+ ### Lazy Loading Tab Content
603
+
604
+ By default, inactive tab panels are not rendered. For complex content, this provides automatic lazy loading:
605
+
606
+ ```tsx
607
+ <TabPanel value={0}>
608
+ {/* Only rendered when this tab is active */}
609
+ <HeavyComponent />
610
+ </TabPanel>
611
+ ```
612
+
613
+ ### Keep Mounted
614
+
615
+ Use `keepMounted` when tab content needs to maintain state:
616
+
617
+ ```tsx
618
+ <TabPanel value={0} keepMounted>
619
+ {/* Stays in DOM, maintains form state */}
620
+ <FormWithState />
621
+ </TabPanel>
622
+ ```
623
+
624
+ ### Avoid Heavy Re-renders
625
+
626
+ Memoize tab content when it depends on complex calculations:
627
+
628
+ ```tsx
629
+ const tabContent = useMemo(() => (
630
+ <ExpensiveComponent data={data} />
631
+ ), [data]);
632
+
633
+ <TabPanel value={0}>{tabContent}</TabPanel>
634
+ ```
635
+
636
+ Tabs provide an intuitive way to organize related content while keeping the interface clean and navigable. Use them thoughtfully to enhance content discoverability without overwhelming users.