@ceed/cds 1.28.1 → 1.29.0-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 (63) hide show
  1. package/dist/components/CurrencyInput/CurrencyInput.d.ts +1 -1
  2. package/dist/components/CurrencyInput/hooks/use-currency-setting.d.ts +2 -2
  3. package/dist/components/SearchBar/SearchBar.d.ts +21 -0
  4. package/dist/components/SearchBar/index.d.ts +3 -0
  5. package/dist/components/data-display/DataTable.md +1 -1
  6. package/dist/components/data-display/InfoSign.md +91 -74
  7. package/dist/components/data-display/Typography.md +94 -411
  8. package/dist/components/feedback/Dialog.md +62 -76
  9. package/dist/components/feedback/Modal.md +138 -430
  10. package/dist/components/feedback/llms.txt +0 -2
  11. package/dist/components/index.d.ts +2 -1
  12. package/dist/components/inputs/Autocomplete.md +107 -356
  13. package/dist/components/inputs/ButtonGroup.md +104 -115
  14. package/dist/components/inputs/CurrencyInput.md +5 -183
  15. package/dist/components/inputs/DatePicker.md +431 -108
  16. package/dist/components/inputs/DateRangePicker.md +492 -131
  17. package/dist/components/inputs/FilterableCheckboxGroup.md +19 -145
  18. package/dist/components/inputs/IconButton.md +88 -137
  19. package/dist/components/inputs/Input.md +73 -204
  20. package/dist/components/inputs/MonthPicker.md +422 -95
  21. package/dist/components/inputs/MonthRangePicker.md +466 -89
  22. package/dist/components/inputs/PercentageInput.md +16 -185
  23. package/dist/components/inputs/RadioButton.md +35 -163
  24. package/dist/components/inputs/SearchBar.md +44 -0
  25. package/dist/components/inputs/Select.md +326 -222
  26. package/dist/components/inputs/Switch.md +376 -143
  27. package/dist/components/inputs/Textarea.md +10 -213
  28. package/dist/components/inputs/Uploader/Uploader.md +66 -145
  29. package/dist/components/inputs/llms.txt +1 -4
  30. package/dist/components/navigation/Breadcrumbs.md +308 -57
  31. package/dist/components/navigation/Drawer.md +0 -180
  32. package/dist/components/navigation/Dropdown.md +215 -98
  33. package/dist/components/navigation/IconMenuButton.md +502 -40
  34. package/dist/components/navigation/InsetDrawer.md +650 -281
  35. package/dist/components/navigation/Link.md +348 -31
  36. package/dist/components/navigation/Menu.md +285 -92
  37. package/dist/components/navigation/MenuButton.md +448 -55
  38. package/dist/components/navigation/Pagination.md +338 -47
  39. package/dist/components/navigation/Stepper.md +28 -160
  40. package/dist/components/navigation/Tabs.md +316 -57
  41. package/dist/components/surfaces/Accordions.md +804 -49
  42. package/dist/components/surfaces/Card.md +157 -97
  43. package/dist/components/surfaces/Divider.md +234 -83
  44. package/dist/components/surfaces/Sheet.md +328 -153
  45. package/dist/index.cjs +411 -574
  46. package/dist/index.d.ts +1 -1
  47. package/dist/index.js +400 -507
  48. package/dist/llms.txt +1 -9
  49. package/framer/index.js +1 -1
  50. package/package.json +17 -22
  51. package/dist/chunks/rehype-accent-FZRUD7VI.js +0 -39
  52. package/dist/components/RadioTileGroup/RadioTileGroup.d.ts +0 -56
  53. package/dist/components/RadioTileGroup/index.d.ts +0 -3
  54. package/dist/components/feedback/CircularProgress.md +0 -257
  55. package/dist/components/feedback/Skeleton.md +0 -280
  56. package/dist/components/inputs/FormControl.md +0 -361
  57. package/dist/components/inputs/RadioList.md +0 -241
  58. package/dist/components/inputs/RadioTileGroup.md +0 -507
  59. package/dist/components/inputs/Slider.md +0 -334
  60. package/dist/guides/ThemeProvider.md +0 -89
  61. package/dist/guides/llms.txt +0 -9
  62. package/dist/index.browser.js +0 -224
  63. package/dist/index.browser.js.map +0 -7
@@ -1,8 +1,8 @@
1
1
  # Tabs
2
2
 
3
- Tabs organize content into separate views where only one view is visible at a time. Users switch between views by selecting tab buttons, enabling efficient navigation within related content sections without leaving the current page. Built on Joy UI's Tabs, TabList, Tab, and TabPanel components, Tabs support horizontal and vertical orientations, multiple visual variants, semantic colors, and icon decorators.
3
+ ## Introduction
4
4
 
5
- Tabs follow a composition pattern: the `Tabs` container manages state, `TabList` holds the tab buttons, `Tab` is each individual button, and `TabPanel` displays the content for the active tab.
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
6
 
7
7
  ```
8
8
  <Canvas of={Tabs.Playground} />
@@ -35,11 +35,11 @@ function MyComponent() {
35
35
  }
36
36
  ```
37
37
 
38
- ## Features
38
+ ## Examples
39
39
 
40
40
  ### Basic Tabs
41
41
 
42
- Default horizontal tab navigation with tab panels.
42
+ Default tab navigation with horizontal layout.
43
43
 
44
44
  ```tsx
45
45
  <Tabs {...args}>
@@ -62,7 +62,7 @@ Default horizontal tab navigation with tab panels.
62
62
 
63
63
  ### Variants
64
64
 
65
- Tabs support `plain`, `outlined`, `soft`, and `solid` visual styles. Apply the variant to both TabList and individual Tab components for a consistent appearance.
65
+ Tabs support different visual styles through variants.
66
66
 
67
67
  ```
68
68
  <Canvas of={Tabs.Variants} />
@@ -70,7 +70,7 @@ Tabs support `plain`, `outlined`, `soft`, and `solid` visual styles. Apply the v
70
70
 
71
71
  ### Sizes
72
72
 
73
- Tabs come in `sm`, `md`, and `lg` sizes. Set the `size` prop on the Tabs container to affect all child components uniformly.
73
+ Tabs come in different sizes to fit various use cases.
74
74
 
75
75
  ```
76
76
  <Canvas of={Tabs.Sizes} />
@@ -78,7 +78,7 @@ Tabs come in `sm`, `md`, and `lg` sizes. Set the `size` prop on the Tabs contain
78
78
 
79
79
  ### Colors
80
80
 
81
- Apply semantic colors (`primary`, `neutral`, `success`, `warning`, `danger`) to individual tabs for color-coded navigation.
81
+ Apply semantic colors to tabs.
82
82
 
83
83
  ```
84
84
  <Canvas of={Tabs.Colors} />
@@ -86,7 +86,7 @@ Apply semantic colors (`primary`, `neutral`, `success`, `warning`, `danger`) to
86
86
 
87
87
  ### With Decorators
88
88
 
89
- Add icons or other elements before or after the tab label using `startDecorator` and `endDecorator` props.
89
+ Add icons or other elements to tab labels.
90
90
 
91
91
  ```tsx
92
92
  <Tabs {...args}>
@@ -109,7 +109,7 @@ Add icons or other elements before or after the tab label using `startDecorator`
109
109
 
110
110
  ### Vertical Orientation
111
111
 
112
- Set `orientation="vertical"` on the Tabs container for sidebar-style navigation layouts.
112
+ Tabs can be arranged vertically for sidebar-style navigation.
113
113
 
114
114
  ```
115
115
  <Canvas of={Tabs.Vertical} />
@@ -117,7 +117,7 @@ Set `orientation="vertical"` on the Tabs container for sidebar-style navigation
117
117
 
118
118
  ### Disabled Tabs
119
119
 
120
- Individual tabs can be disabled with the `disabled` prop while keeping other tabs interactive.
120
+ Individual tabs can be disabled while keeping others active.
121
121
 
122
122
  ```
123
123
  <Canvas of={Tabs.Disabled} />
@@ -125,12 +125,32 @@ Individual tabs can be disabled with the `disabled` prop while keeping other tab
125
125
 
126
126
  ### Controlled Tabs
127
127
 
128
- Use the `value` and `onChange` props for programmatic control of the active tab.
128
+ Programmatically control the active tab.
129
129
 
130
130
  ```
131
131
  <Canvas of={Tabs.Controlled} />
132
132
  ```
133
133
 
134
+ ## When to Use
135
+
136
+ ### ✅ Good Use Cases
137
+
138
+ - **Related content sections**: When content can be logically grouped and users don't need to see all sections at once
139
+ - **Settings pages**: Organizing different categories of settings (Profile, Security, Notifications)
140
+ - **Dashboard views**: Switching between different data views or time periods
141
+ - **Product details**: Showing Description, Specifications, Reviews as separate tabs
142
+ - **Form sections**: Breaking long forms into logical steps (not for strict wizard flows)
143
+ - **Code examples**: Showing code in different languages or frameworks
144
+
145
+ ### ❌ When Not to Use
146
+
147
+ - **Primary navigation**: Use a navigation menu or sidebar for main app navigation
148
+ - **Sequential workflows**: Use Stepper for multi-step processes that must be completed in order
149
+ - **Comparing content**: If users need to see multiple sections simultaneously, use accordions or show all content
150
+ - **Very few items**: If there are only 2 options, consider using a toggle or radio buttons
151
+ - **Many items**: More than 5-6 tabs become hard to navigate; consider a dropdown or nested navigation
152
+ - **Mobile layouts**: Consider alternative patterns like accordions or stacked sections on small screens
153
+
134
154
  ## Common Use Cases
135
155
 
136
156
  ### Settings Page
@@ -143,92 +163,331 @@ function SettingsPage() {
143
163
  <Tab startDecorator={<PersonIcon />}>Profile</Tab>
144
164
  <Tab startDecorator={<SecurityIcon />}>Security</Tab>
145
165
  <Tab startDecorator={<NotificationsIcon />}>Notifications</Tab>
166
+ <Tab startDecorator={<PaletteIcon />}>Appearance</Tab>
167
+ </TabList>
168
+ <TabPanel value={0}>
169
+ <ProfileSettings />
170
+ </TabPanel>
171
+ <TabPanel value={1}>
172
+ <SecuritySettings />
173
+ </TabPanel>
174
+ <TabPanel value={2}>
175
+ <NotificationSettings />
176
+ </TabPanel>
177
+ <TabPanel value={3}>
178
+ <AppearanceSettings />
179
+ </TabPanel>
180
+ </Tabs>
181
+ );
182
+ }
183
+ ```
184
+
185
+ ### Product Detail Page
186
+
187
+ ```tsx
188
+ function ProductDetails({ product }) {
189
+ return (
190
+ <Tabs defaultValue={0}>
191
+ <TabList>
192
+ <Tab>Description</Tab>
193
+ <Tab>Specifications</Tab>
194
+ <Tab>Reviews ({product.reviewCount})</Tab>
195
+ <Tab>Q&A</Tab>
146
196
  </TabList>
147
- <TabPanel value={0}><ProfileSettings /></TabPanel>
148
- <TabPanel value={1}><SecuritySettings /></TabPanel>
149
- <TabPanel value={2}><NotificationSettings /></TabPanel>
197
+ <TabPanel value={0}>
198
+ <Typography>{product.description}</Typography>
199
+ </TabPanel>
200
+ <TabPanel value={1}>
201
+ <SpecificationTable specs={product.specifications} />
202
+ </TabPanel>
203
+ <TabPanel value={2}>
204
+ <ReviewList reviews={product.reviews} />
205
+ </TabPanel>
206
+ <TabPanel value={3}>
207
+ <QASection productId={product.id} />
208
+ </TabPanel>
150
209
  </Tabs>
151
210
  );
152
211
  }
153
212
  ```
154
213
 
155
- ### Dashboard Time Range
214
+ ### Dashboard with Time Filters
156
215
 
157
216
  ```tsx
158
217
  function DashboardTabs() {
159
- const [range, setRange] = useState('week');
218
+ const [timeRange, setTimeRange] = useState('week');
160
219
 
161
220
  return (
162
- <Tabs value={range} onChange={(e, val) => setRange(val as string)}>
221
+ <Tabs value={timeRange} onChange={(e, val) => setTimeRange(val as string)}>
163
222
  <TabList>
164
223
  <Tab value="day">Today</Tab>
165
224
  <Tab value="week">This Week</Tab>
166
225
  <Tab value="month">This Month</Tab>
226
+ <Tab value="year">This Year</Tab>
167
227
  </TabList>
168
- <TabPanel value="day"><DailyStats /></TabPanel>
169
- <TabPanel value="week"><WeeklyStats /></TabPanel>
170
- <TabPanel value="month"><MonthlyStats /></TabPanel>
228
+ <TabPanel value="day">
229
+ <DailyStats />
230
+ </TabPanel>
231
+ <TabPanel value="week">
232
+ <WeeklyStats />
233
+ </TabPanel>
234
+ <TabPanel value="month">
235
+ <MonthlyStats />
236
+ </TabPanel>
237
+ <TabPanel value="year">
238
+ <YearlyStats />
239
+ </TabPanel>
171
240
  </Tabs>
172
241
  );
173
242
  }
174
243
  ```
175
244
 
176
- ### Vertical Sidebar
245
+ ### Code Examples
177
246
 
178
247
  ```tsx
179
- function SidebarTabs() {
248
+ function CodeExamples() {
180
249
  return (
181
- <Tabs orientation="vertical" defaultValue={0} sx={{ minWidth: 300 }}>
250
+ <Tabs defaultValue="react">
182
251
  <TabList>
183
- <Tab startDecorator={<DashboardIcon />}>Dashboard</Tab>
184
- <Tab startDecorator={<AnalyticsIcon />}>Analytics</Tab>
185
- <Tab startDecorator={<SettingsIcon />}>Settings</Tab>
252
+ <Tab value="react">React</Tab>
253
+ <Tab value="vue">Vue</Tab>
254
+ <Tab value="angular">Angular</Tab>
186
255
  </TabList>
187
- <TabPanel value={0}>Dashboard content</TabPanel>
188
- <TabPanel value={1}>Analytics content</TabPanel>
189
- <TabPanel value={2}>Settings content</TabPanel>
256
+ <TabPanel value="react">
257
+ <CodeBlock language="jsx">{reactCode}</CodeBlock>
258
+ </TabPanel>
259
+ <TabPanel value="vue">
260
+ <CodeBlock language="vue">{vueCode}</CodeBlock>
261
+ </TabPanel>
262
+ <TabPanel value="angular">
263
+ <CodeBlock language="typescript">{angularCode}</CodeBlock>
264
+ </TabPanel>
190
265
  </Tabs>
191
266
  );
192
267
  }
193
268
  ```
194
269
 
195
- ## Best Practices
270
+ ### Vertical Sidebar Navigation
196
271
 
197
- - **Use clear, concise tab labels.** Each label should describe the content it reveals. Avoid generic names like "Tab 1" or "Other".
272
+ ```tsx
273
+ function SidebarTabs() {
274
+ return (
275
+ <Box sx={{ display: 'flex' }}>
276
+ <Tabs orientation="vertical" defaultValue={0} sx={{ minWidth: 200 }}>
277
+ <TabList>
278
+ <Tab startDecorator={<DashboardIcon />}>Dashboard</Tab>
279
+ <Tab startDecorator={<AnalyticsIcon />}>Analytics</Tab>
280
+ <Tab startDecorator={<ReportsIcon />}>Reports</Tab>
281
+ <Tab startDecorator={<SettingsIcon />}>Settings</Tab>
282
+ </TabList>
283
+ </Tabs>
284
+ <Box sx={{ flex: 1, p: 2 }}>
285
+ <TabPanel value={0}>Dashboard content</TabPanel>
286
+ <TabPanel value={1}>Analytics content</TabPanel>
287
+ <TabPanel value={2}>Reports content</TabPanel>
288
+ <TabPanel value={3}>Settings content</TabPanel>
289
+ </Box>
290
+ </Box>
291
+ );
292
+ }
293
+ ```
198
294
 
199
- ```tsx
200
- {/* ✅ Good: Descriptive labels */}
201
- <Tab>Account Settings</Tab>
202
- <Tab>Notifications</Tab>
295
+ ## Component Structure
203
296
 
204
- {/* Bad: Vague labels */}
205
- <Tab>Tab 1</Tab>
206
- <Tab>Other</Tab>
207
- ```
297
+ Tabs uses a composition pattern with multiple sub-components:
208
298
 
209
- - **Limit the number of tabs.** Aim for 3-6 tabs. More than 6 tabs become difficult to scan and navigate. If you need more sections, consider a sidebar navigation, nested navigation, or a different layout pattern.
299
+ ```tsx
300
+ <Tabs> {/* Container - manages state */}
301
+ <TabList> {/* Tab button container */}
302
+ <Tab>Tab 1</Tab> {/* Individual tab buttons */}
303
+ <Tab>Tab 2</Tab>
304
+ </TabList>
305
+ <TabPanel value={0}> {/* Content panels */}
306
+ Content 1
307
+ </TabPanel>
308
+ <TabPanel value={1}>
309
+ Content 2
310
+ </TabPanel>
311
+ </Tabs>
312
+ ```
210
313
 
211
- - **Order tabs by importance.** Place the most frequently used or most important tab first. Users expect the default (leftmost or topmost) tab to contain the primary content.
314
+ ## Props and Customization
212
315
 
213
- - **Do not use Tabs for sequential workflows.** Tabs are for parallel content sections that can be accessed in any order. For ordered multi-step processes, use a Stepper component instead.
316
+ ### Tabs Props
214
317
 
215
- ```tsx
216
- {/* Bad: Sequential steps as tabs */}
217
- <Tab>Step 1: Info</Tab>
218
- <Tab>Step 2: Payment</Tab>
219
- <Tab>Step 3: Confirm</Tab>
318
+ | Prop | Type | Default | Description |
319
+ | -------------- | ---------------------------- | -------------- | ----------------------------------- |
320
+ | `defaultValue` | `string \| number` | - | Default selected tab (uncontrolled) |
321
+ | `value` | `string \| number` | - | Selected tab (controlled) |
322
+ | `onChange` | `function` | - | Callback when tab changes |
323
+ | `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Tab layout direction |
324
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Size of all child components |
220
325
 
221
- {/* Good: Independent content sections */}
222
- <Tab>Profile</Tab>
223
- <Tab>Security</Tab>
224
- <Tab>Billing</Tab>
225
- ```
326
+ ### Tab Props
226
327
 
227
- - **Keep styling consistent.** All tabs in a group should share the same variant and color. Mixing styles within the same TabList creates visual inconsistency.
328
+ | Prop | Type | Default | Description |
329
+ | ---------------- | -------------------------------------------------------------- | --------- | ---------------------------------- |
330
+ | `value` | `string \| number` | - | Tab identifier (defaults to index) |
331
+ | `variant` | `'plain' \| 'outlined' \| 'soft' \| 'solid'` | `'plain'` | Visual style |
332
+ | `color` | `'primary' \| 'neutral' \| 'danger' \| 'success' \| 'warning'` | - | Color scheme |
333
+ | `disabled` | `boolean` | `false` | Disable the tab |
334
+ | `startDecorator` | `ReactNode` | - | Element before tab label |
335
+ | `endDecorator` | `ReactNode` | - | Element after tab label |
336
+
337
+ ### TabPanel Props
338
+
339
+ | Prop | Type | Default | Description |
340
+ | ------------- | ------------------ | ------- | ----------------------------- |
341
+ | `value` | `string \| number` | - | Matching tab value |
342
+ | `keepMounted` | `boolean` | `false` | Keep panel in DOM when hidden |
343
+
344
+ ### Custom Styling
345
+
346
+ ```tsx
347
+ <Tabs
348
+ sx={{
349
+ '--Tabs-gap': '8px',
350
+ }}
351
+ >
352
+ <TabList
353
+ sx={{
354
+ borderBottom: '1px solid',
355
+ borderColor: 'divider',
356
+ }}
357
+ >
358
+ <Tab
359
+ sx={{
360
+ '&.Mui-selected': {
361
+ borderBottom: '2px solid',
362
+ borderColor: 'primary.500',
363
+ },
364
+ }}
365
+ >
366
+ Custom Tab
367
+ </Tab>
368
+ </TabList>
369
+ </Tabs>
370
+ ```
228
371
 
229
372
  ## Accessibility
230
373
 
231
- - **WAI-ARIA Tabs pattern**: TabList receives `role="tablist"`, each Tab receives `role="tab"`, and each TabPanel receives `role="tabpanel"`. The `aria-selected`, `aria-controls`, and `aria-labelledby` attributes are set automatically.
232
- - **Keyboard navigation**: Arrow Left/Right moves between tabs in horizontal orientation. Arrow Up/Down moves between tabs in vertical orientation. Home jumps to the first tab, End to the last. Enter or Space activates the focused tab.
233
- - **Tab key behavior**: Pressing Tab from outside the tab list focuses the active tab. Pressing Tab again moves focus into the active panel content, not to the next tab button.
234
- - **Provide an accessible label**: Use `aria-label` on the Tabs container to give screen readers context for the tab group (e.g., `aria-label="Account settings"`).
374
+ Tabs components follow WAI-ARIA Tabs pattern for comprehensive accessibility:
375
+
376
+ ### ARIA Attributes
377
+
378
+ - `role="tablist"` on TabList
379
+ - `role="tab"` on each Tab
380
+ - `role="tabpanel"` on each TabPanel
381
+ - `aria-selected` indicates the active tab
382
+ - `aria-controls` links tabs to their panels
383
+ - `aria-labelledby` links panels to their tabs
384
+
385
+ ### Keyboard Navigation
386
+
387
+ - **Tab**: Move focus to the tab list, then to the active panel
388
+ - **Arrow Left/Right**: Move between tabs (horizontal orientation)
389
+ - **Arrow Up/Down**: Move between tabs (vertical orientation)
390
+ - **Home**: Move to first tab
391
+ - **End**: Move to last tab
392
+ - **Enter/Space**: Activate the focused tab
393
+
394
+ ### Screen Reader Support
395
+
396
+ ```tsx
397
+ <Tabs aria-label="Account settings tabs">
398
+ <TabList>
399
+ <Tab>Profile</Tab>
400
+ <Tab>Security</Tab>
401
+ </TabList>
402
+ <TabPanel value={0}>
403
+ <h2 id="profile-heading">Profile Settings</h2>
404
+ {/* Content */}
405
+ </TabPanel>
406
+ </Tabs>
407
+ ```
408
+
409
+ ## Best Practices
410
+
411
+ ### ✅ Do
412
+
413
+ 1. **Use clear, concise labels**: Tab labels should clearly describe the content
414
+
415
+ ```tsx
416
+ // ✅ Good: Clear labels
417
+ <Tab>Account Settings</Tab>
418
+ <Tab>Notifications</Tab>
419
+
420
+ // ❌ Bad: Vague labels
421
+ <Tab>Tab 1</Tab>
422
+ <Tab>Other</Tab>
423
+ ```
424
+
425
+ 2. **Keep tab count manageable**: Limit to 5-6 tabs maximum
426
+
427
+ 3. **Order tabs logically**: Place most important or frequently used tabs first
428
+
429
+ 4. **Use consistent styling**: All tabs should have the same visual weight
430
+
431
+ 5. **Show active state clearly**: Users should always know which tab is selected
432
+
433
+ ### ❌ Don't
434
+
435
+ 1. **Don't hide critical information**: Important content shouldn't be buried in secondary tabs
436
+
437
+ 2. **Don't use for sequential processes**: Use Stepper for ordered workflows
438
+
439
+ ```tsx
440
+ // ❌ Bad: Sequential steps as tabs
441
+ <Tab>Step 1: Personal Info</Tab>
442
+ <Tab>Step 2: Payment</Tab>
443
+ <Tab>Step 3: Confirm</Tab>
444
+
445
+ // ✅ Good: Use Stepper instead
446
+ <Stepper activeStep={activeStep}>
447
+ <Step>Personal Info</Step>
448
+ <Step>Payment</Step>
449
+ <Step>Confirm</Step>
450
+ </Stepper>
451
+ ```
452
+
453
+ 3. **Don't nest tabs within tabs**: Creates confusing navigation
454
+
455
+ 4. **Don't use inconsistent tab counts**: If tabs are dynamic, consider alternative UI patterns
456
+
457
+ ## Performance Considerations
458
+
459
+ ### Lazy Loading Tab Content
460
+
461
+ By default, inactive tab panels are not rendered. For complex content, this provides automatic lazy loading:
462
+
463
+ ```tsx
464
+ <TabPanel value={0}>
465
+ {/* Only rendered when this tab is active */}
466
+ <HeavyComponent />
467
+ </TabPanel>
468
+ ```
469
+
470
+ ### Keep Mounted
471
+
472
+ Use `keepMounted` when tab content needs to maintain state:
473
+
474
+ ```tsx
475
+ <TabPanel value={0} keepMounted>
476
+ {/* Stays in DOM, maintains form state */}
477
+ <FormWithState />
478
+ </TabPanel>
479
+ ```
480
+
481
+ ### Avoid Heavy Re-renders
482
+
483
+ Memoize tab content when it depends on complex calculations:
484
+
485
+ ```tsx
486
+ const tabContent = useMemo(() => (
487
+ <ExpensiveComponent data={data} />
488
+ ), [data]);
489
+
490
+ <TabPanel value={0}>{tabContent}</TabPanel>
491
+ ```
492
+
493
+ 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.