shadcn-glass-ui 2.0.11 → 2.1.0

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 (59) hide show
  1. package/CHANGELOG.md +109 -5
  2. package/README.md +132 -43
  3. package/context7.json +2 -1
  4. package/dist/cli/index.cjs +1 -1
  5. package/dist/components.cjs +4 -4
  6. package/dist/components.d.ts +103 -29
  7. package/dist/components.js +1 -1
  8. package/dist/demo-screenshot-aurora.png +0 -0
  9. package/dist/demo-screenshot.png +0 -0
  10. package/dist/demo-screenshot.png.zip +0 -0
  11. package/dist/hooks.cjs +2 -2
  12. package/dist/index.cjs +5 -5
  13. package/dist/index.js +28 -28
  14. package/dist/index.js.map +1 -1
  15. package/dist/r/ai-card-glass.json +1 -1
  16. package/dist/r/avatar-glass.json +1 -1
  17. package/dist/r/badge-glass.json +1 -1
  18. package/dist/r/button-glass.json +1 -1
  19. package/dist/r/combobox-glass.json +1 -1
  20. package/dist/r/registry.json +2 -2
  21. package/dist/r/repository-card-glass.json +2 -1
  22. package/dist/r/slider-glass.json +4 -5
  23. package/dist/r/toggle-glass.json +2 -2
  24. package/dist/r/year-card-glass.json +1 -1
  25. package/dist/shadcn-glass-ui.css +1 -1
  26. package/dist/{theme-context-DNe_2vWJ.cjs → theme-context-BHXYJ4RE.cjs} +2 -2
  27. package/dist/{theme-context-DNe_2vWJ.cjs.map → theme-context-BHXYJ4RE.cjs.map} +1 -1
  28. package/dist/themes.cjs +1 -1
  29. package/dist/{trust-score-card-glass-Dgu46oWI.cjs → trust-score-card-glass-CGXmOIfq.cjs} +850 -150
  30. package/dist/trust-score-card-glass-CGXmOIfq.cjs.map +1 -0
  31. package/dist/{trust-score-card-glass-A7kas5OS.js → trust-score-card-glass-L9g0qamo.js} +1182 -482
  32. package/dist/trust-score-card-glass-L9g0qamo.js.map +1 -0
  33. package/dist/{use-focus-BRkQtQCj.cjs → use-focus-CeNHOiBa.cjs} +2 -2
  34. package/dist/{use-focus-BRkQtQCj.cjs.map → use-focus-CeNHOiBa.cjs.map} +1 -1
  35. package/dist/{use-wallpaper-tint-CfShPBo2.cjs → use-wallpaper-tint-Bt2G3g1v.cjs} +2 -2
  36. package/dist/{use-wallpaper-tint-CfShPBo2.cjs.map → use-wallpaper-tint-Bt2G3g1v.cjs.map} +1 -1
  37. package/dist/{utils-BXN7AcRu.cjs → utils-LYxxWvUn.cjs} +2 -2
  38. package/dist/{utils-BXN7AcRu.cjs.map → utils-LYxxWvUn.cjs.map} +1 -1
  39. package/dist/utils.cjs +1 -1
  40. package/docs/ADVANCED_PATTERNS.md +584 -0
  41. package/docs/AI_USAGE.md +135 -611
  42. package/docs/BEST_PRACTICES.md +2 -2
  43. package/docs/BREAKING_CHANGES.md +239 -0
  44. package/docs/COMPONENTS_CATALOG.md +8 -8
  45. package/docs/EXPORTS_STRUCTURE.md +3 -3
  46. package/docs/GETTING_STARTED.md +13 -8
  47. package/docs/PUBLISHING.md +1 -1
  48. package/docs/REGISTRY_SUMMARY.md +2 -2
  49. package/docs/REGISTRY_USAGE.md +1 -1
  50. package/docs/api/README.md +11 -11
  51. package/docs/api/interfaces/BadgeGlassProps.md +21 -14
  52. package/docs/api/interfaces/ButtonGlassProps.md +37 -30
  53. package/package.json +4 -3
  54. package/dist/trust-score-card-glass-A7kas5OS.js.map +0 -1
  55. package/dist/trust-score-card-glass-Dgu46oWI.cjs.map +0 -1
  56. package/dist/vite.svg +0 -1
  57. package/docs/migration/modal-glass-compound-api.md +0 -458
  58. package/docs/migration/select-to-combobox.md +0 -386
  59. package/docs/migration/tabs-glass-compound-api.md +0 -579
@@ -0,0 +1,584 @@
1
+ # Advanced Patterns
2
+
3
+ This guide covers advanced component patterns in shadcn-glass-ui: Compound Components, asChild
4
+ polymorphism, and composition techniques.
5
+
6
+ ---
7
+
8
+ ## Table of Contents
9
+
10
+ 1. [Compound Components](#compound-components)
11
+ - [ModalGlass](#modalglass)
12
+ - [TabsGlass](#tabsglass)
13
+ - [StepperGlass](#stepperglass)
14
+ 2. [asChild Pattern](#aschild-pattern)
15
+ - [ButtonGlass with Next.js Link](#buttonglass-with-nextjs-link)
16
+ - [ButtonGlass with React Router](#buttonglass-with-react-router)
17
+ - [GlassCard with Custom Element](#glasscard-with-custom-element)
18
+ 3. [Composition Patterns](#composition-patterns)
19
+ - [Form Validation](#form-validation)
20
+ - [Controlled vs Uncontrolled](#controlled-vs-uncontrolled)
21
+
22
+ ---
23
+
24
+ ## Compound Components
25
+
26
+ Compound components provide flexible, composable APIs for complex UI patterns. Each sub-component
27
+ handles a specific concern.
28
+
29
+ ### ModalGlass
30
+
31
+ **Sub-components:**
32
+
33
+ - `ModalGlass.Root` - Context provider with open/close state
34
+ - `ModalGlass.Overlay` - Backdrop with blur effect
35
+ - `ModalGlass.Content` - Main modal container
36
+ - `ModalGlass.Header` - Header layout
37
+ - `ModalGlass.Body` - Content area
38
+ - `ModalGlass.Footer` - Footer with actions
39
+ - `ModalGlass.Title` - Accessible title (ARIA)
40
+ - `ModalGlass.Description` - Accessible description (ARIA)
41
+ - `ModalGlass.Close` - Close button
42
+
43
+ #### Basic Usage
44
+
45
+ ```tsx
46
+ import { ModalGlass, ButtonGlass } from 'shadcn-glass-ui';
47
+
48
+ function MyModal() {
49
+ const [open, setOpen] = useState(false);
50
+
51
+ return (
52
+ <>
53
+ <ButtonGlass onClick={() => setOpen(true)}>Open Modal</ButtonGlass>
54
+
55
+ <ModalGlass.Root open={open} onOpenChange={setOpen}>
56
+ <ModalGlass.Overlay />
57
+ <ModalGlass.Content>
58
+ <ModalGlass.Header>
59
+ <ModalGlass.Title>Confirm Action</ModalGlass.Title>
60
+ <ModalGlass.Close />
61
+ </ModalGlass.Header>
62
+
63
+ <ModalGlass.Body>
64
+ <p>Are you sure you want to proceed?</p>
65
+ </ModalGlass.Body>
66
+
67
+ <ModalGlass.Footer>
68
+ <ButtonGlass variant="ghost" onClick={() => setOpen(false)}>
69
+ Cancel
70
+ </ButtonGlass>
71
+ <ButtonGlass variant="default">Confirm</ButtonGlass>
72
+ </ModalGlass.Footer>
73
+ </ModalGlass.Content>
74
+ </ModalGlass.Root>
75
+ </>
76
+ );
77
+ }
78
+ ```
79
+
80
+ #### With Form
81
+
82
+ ```tsx
83
+ <ModalGlass.Root open={open} onOpenChange={setOpen}>
84
+ <ModalGlass.Overlay />
85
+ <ModalGlass.Content size="lg">
86
+ <ModalGlass.Header>
87
+ <ModalGlass.Title>Create Account</ModalGlass.Title>
88
+ <ModalGlass.Description>Fill in your details to get started.</ModalGlass.Description>
89
+ <ModalGlass.Close />
90
+ </ModalGlass.Header>
91
+
92
+ <ModalGlass.Body>
93
+ <form onSubmit={handleSubmit} className="space-y-4">
94
+ <InputGlass label="Email" type="email" placeholder="you@example.com" required />
95
+ <InputGlass label="Password" type="password" placeholder="••••••••" required />
96
+ </form>
97
+ </ModalGlass.Body>
98
+
99
+ <ModalGlass.Footer>
100
+ <ButtonGlass variant="ghost" onClick={() => setOpen(false)}>
101
+ Cancel
102
+ </ButtonGlass>
103
+ <ButtonGlass variant="default" type="submit">
104
+ Create Account
105
+ </ButtonGlass>
106
+ </ModalGlass.Footer>
107
+ </ModalGlass.Content>
108
+ </ModalGlass.Root>
109
+ ```
110
+
111
+ #### Size Variants
112
+
113
+ ```tsx
114
+ // Small modal (alerts, confirmations)
115
+ <ModalGlass.Content size="sm">
116
+
117
+ // Default size
118
+ <ModalGlass.Content size="default">
119
+
120
+ // Large modal (forms, complex content)
121
+ <ModalGlass.Content size="lg">
122
+
123
+ // Full-width modal
124
+ <ModalGlass.Content size="full">
125
+ ```
126
+
127
+ ---
128
+
129
+ ### TabsGlass
130
+
131
+ **Sub-components:**
132
+
133
+ - `TabsGlass.Root` - Context provider with value state
134
+ - `TabsGlass.List` - Container for tab triggers
135
+ - `TabsGlass.Trigger` - Individual tab button
136
+ - `TabsGlass.Content` - Content panel for each tab
137
+
138
+ #### Basic Usage
139
+
140
+ ```tsx
141
+ import { TabsGlass } from 'shadcn-glass-ui';
142
+
143
+ function MyTabs() {
144
+ const [tab, setTab] = useState('overview');
145
+
146
+ return (
147
+ <TabsGlass.Root value={tab} onValueChange={setTab}>
148
+ <TabsGlass.List>
149
+ <TabsGlass.Trigger value="overview">Overview</TabsGlass.Trigger>
150
+ <TabsGlass.Trigger value="analytics">Analytics</TabsGlass.Trigger>
151
+ <TabsGlass.Trigger value="settings">Settings</TabsGlass.Trigger>
152
+ </TabsGlass.List>
153
+
154
+ <TabsGlass.Content value="overview">
155
+ <OverviewPanel />
156
+ </TabsGlass.Content>
157
+
158
+ <TabsGlass.Content value="analytics">
159
+ <AnalyticsPanel />
160
+ </TabsGlass.Content>
161
+
162
+ <TabsGlass.Content value="settings">
163
+ <SettingsPanel />
164
+ </TabsGlass.Content>
165
+ </TabsGlass.Root>
166
+ );
167
+ }
168
+ ```
169
+
170
+ #### With Icons and Badges
171
+
172
+ ```tsx
173
+ import { Home, BarChart, Settings, Inbox } from 'lucide-react';
174
+ import { TabsGlass, BadgeGlass } from 'shadcn-glass-ui';
175
+
176
+ <TabsGlass.Root value={tab} onValueChange={setTab}>
177
+ <TabsGlass.List>
178
+ <TabsGlass.Trigger value="home">
179
+ <Home className="w-4 h-4 mr-2" />
180
+ Home
181
+ </TabsGlass.Trigger>
182
+
183
+ <TabsGlass.Trigger value="inbox">
184
+ <Inbox className="w-4 h-4 mr-2" />
185
+ Inbox
186
+ <BadgeGlass variant="destructive" className="ml-2">
187
+ 5
188
+ </BadgeGlass>
189
+ </TabsGlass.Trigger>
190
+
191
+ <TabsGlass.Trigger value="stats">
192
+ <BarChart className="w-4 h-4 mr-2" />
193
+ Statistics
194
+ </TabsGlass.Trigger>
195
+ </TabsGlass.List>
196
+
197
+ {/* Content panels */}
198
+ </TabsGlass.Root>;
199
+ ```
200
+
201
+ #### Vertical Layout
202
+
203
+ ```tsx
204
+ <TabsGlass.Root value={tab} onValueChange={setTab}>
205
+ <div className="flex gap-6">
206
+ {/* Vertical tab list */}
207
+ <TabsGlass.List className="flex-col w-48">
208
+ <TabsGlass.Trigger value="general">General</TabsGlass.Trigger>
209
+ <TabsGlass.Trigger value="security">Security</TabsGlass.Trigger>
210
+ <TabsGlass.Trigger value="privacy">Privacy</TabsGlass.Trigger>
211
+ </TabsGlass.List>
212
+
213
+ {/* Content area */}
214
+ <div className="flex-1">
215
+ <TabsGlass.Content value="general">
216
+ <GeneralSettings />
217
+ </TabsGlass.Content>
218
+ <TabsGlass.Content value="security">
219
+ <SecuritySettings />
220
+ </TabsGlass.Content>
221
+ <TabsGlass.Content value="privacy">
222
+ <PrivacySettings />
223
+ </TabsGlass.Content>
224
+ </div>
225
+ </div>
226
+ </TabsGlass.Root>
227
+ ```
228
+
229
+ #### Dynamic Tabs
230
+
231
+ ```tsx
232
+ const tabs = [
233
+ { id: 'tab1', label: 'First', content: <FirstContent /> },
234
+ { id: 'tab2', label: 'Second', content: <SecondContent /> },
235
+ { id: 'tab3', label: 'Third', content: <ThirdContent /> },
236
+ ];
237
+
238
+ <TabsGlass.Root value={activeTab} onValueChange={setActiveTab}>
239
+ <TabsGlass.List>
240
+ {tabs.map((tab) => (
241
+ <TabsGlass.Trigger key={tab.id} value={tab.id}>
242
+ {tab.label}
243
+ </TabsGlass.Trigger>
244
+ ))}
245
+ </TabsGlass.List>
246
+
247
+ {tabs.map((tab) => (
248
+ <TabsGlass.Content key={tab.id} value={tab.id}>
249
+ {tab.content}
250
+ </TabsGlass.Content>
251
+ ))}
252
+ </TabsGlass.Root>;
253
+ ```
254
+
255
+ ---
256
+
257
+ ### StepperGlass
258
+
259
+ **Sub-components:**
260
+
261
+ - `StepperGlass.Root` - Context provider with step state
262
+ - `StepperGlass.Step` - Individual step container
263
+ - `StepperGlass.Indicator` - Step number/icon/dot
264
+ - `StepperGlass.Title` - Step title
265
+ - `StepperGlass.Description` - Step description
266
+
267
+ #### Basic Usage
268
+
269
+ ```tsx
270
+ import { StepperGlass } from 'shadcn-glass-ui';
271
+
272
+ function CheckoutStepper() {
273
+ const [step, setStep] = useState(0);
274
+
275
+ return (
276
+ <StepperGlass.Root value={step} onValueChange={setStep}>
277
+ <StepperGlass.Step value={0}>
278
+ <StepperGlass.Indicator />
279
+ <StepperGlass.Title>Cart</StepperGlass.Title>
280
+ <StepperGlass.Description>Review items</StepperGlass.Description>
281
+ </StepperGlass.Step>
282
+
283
+ <StepperGlass.Step value={1}>
284
+ <StepperGlass.Indicator />
285
+ <StepperGlass.Title>Shipping</StepperGlass.Title>
286
+ <StepperGlass.Description>Enter address</StepperGlass.Description>
287
+ </StepperGlass.Step>
288
+
289
+ <StepperGlass.Step value={2}>
290
+ <StepperGlass.Indicator />
291
+ <StepperGlass.Title>Payment</StepperGlass.Title>
292
+ <StepperGlass.Description>Add payment method</StepperGlass.Description>
293
+ </StepperGlass.Step>
294
+
295
+ <StepperGlass.Step value={3}>
296
+ <StepperGlass.Indicator />
297
+ <StepperGlass.Title>Confirm</StepperGlass.Title>
298
+ <StepperGlass.Description>Place order</StepperGlass.Description>
299
+ </StepperGlass.Step>
300
+ </StepperGlass.Root>
301
+ );
302
+ }
303
+ ```
304
+
305
+ #### Variants
306
+
307
+ ```tsx
308
+ // Numbered steps (default)
309
+ <StepperGlass.Root variant="numbered">
310
+
311
+ // With icons
312
+ <StepperGlass.Root variant="icon">
313
+ <StepperGlass.Step value={0}>
314
+ <StepperGlass.Indicator icon={<ShoppingCart />} />
315
+ ...
316
+ </StepperGlass.Step>
317
+ </StepperGlass.Root>
318
+
319
+ // Dot indicators
320
+ <StepperGlass.Root variant="dots">
321
+ ```
322
+
323
+ #### Linear Mode (Wizard)
324
+
325
+ Locks future steps until previous ones are completed:
326
+
327
+ ```tsx
328
+ <StepperGlass.Root
329
+ value={step}
330
+ onValueChange={setStep}
331
+ linear // Prevents clicking future steps
332
+ >
333
+ {/* Steps */}
334
+ </StepperGlass.Root>
335
+ ```
336
+
337
+ #### Vertical Orientation
338
+
339
+ ```tsx
340
+ <StepperGlass.Root orientation="vertical">{/* Steps render vertically */}</StepperGlass.Root>
341
+ ```
342
+
343
+ ---
344
+
345
+ ## asChild Pattern
346
+
347
+ The `asChild` pattern allows components to render as different elements while preserving styles and
348
+ behavior. Powered by Radix UI's Slot.
349
+
350
+ ### Why asChild?
351
+
352
+ - **Semantic HTML** - Render as `<a>`, `<Link>`, or any element
353
+ - **No wrapper divs** - Clean DOM structure
354
+ - **Style preservation** - All glass effects maintained
355
+ - **Accessibility** - Proper element semantics
356
+
357
+ ### ButtonGlass with Next.js Link
358
+
359
+ ```tsx
360
+ import Link from 'next/link';
361
+ import { ButtonGlass } from 'shadcn-glass-ui';
362
+
363
+ // Renders as <a> with ButtonGlass styles
364
+ <ButtonGlass asChild variant="default">
365
+ <Link href="/dashboard">Go to Dashboard</Link>
366
+ </ButtonGlass>;
367
+ ```
368
+
369
+ **HTML output:**
370
+
371
+ ```html
372
+ <a href="/dashboard" class="btn-glass btn-primary ..."> Go to Dashboard </a>
373
+ ```
374
+
375
+ ### ButtonGlass with React Router
376
+
377
+ ```tsx
378
+ import { Link } from 'react-router-dom';
379
+ import { ButtonGlass } from 'shadcn-glass-ui';
380
+
381
+ <ButtonGlass asChild variant="secondary">
382
+ <Link to="/settings">Settings</Link>
383
+ </ButtonGlass>;
384
+ ```
385
+
386
+ ### ButtonGlass as External Link
387
+
388
+ ```tsx
389
+ <ButtonGlass asChild variant="ghost">
390
+ <a href="https://github.com" target="_blank" rel="noopener noreferrer">
391
+ View on GitHub
392
+ </a>
393
+ </ButtonGlass>
394
+ ```
395
+
396
+ ### GlassCard with Custom Element
397
+
398
+ ```tsx
399
+ import { GlassCard } from 'shadcn-glass-ui';
400
+
401
+ // Render card as article
402
+ <GlassCard asChild>
403
+ <article>
404
+ <h2>Blog Post Title</h2>
405
+ <p>Content...</p>
406
+ </article>
407
+ </GlassCard>
408
+
409
+ // Render card as link
410
+ <GlassCard asChild>
411
+ <a href="/product/123">
412
+ <img src="product.jpg" alt="Product" />
413
+ <h3>Product Name</h3>
414
+ </a>
415
+ </GlassCard>
416
+ ```
417
+
418
+ ### With Icons
419
+
420
+ ```tsx
421
+ import { ExternalLink } from 'lucide-react';
422
+
423
+ <ButtonGlass asChild variant="default">
424
+ <a href="https://docs.example.com" target="_blank">
425
+ Documentation
426
+ <ExternalLink className="w-4 h-4 ml-2" />
427
+ </a>
428
+ </ButtonGlass>;
429
+ ```
430
+
431
+ ---
432
+
433
+ ## Composition Patterns
434
+
435
+ ### Form Validation
436
+
437
+ Use `FormFieldWrapper` with `InputGlass` for consistent validation UI:
438
+
439
+ ```tsx
440
+ import { InputGlass, FormFieldWrapper } from 'shadcn-glass-ui';
441
+
442
+ function ValidatedInput({ label, error, success, ...props }) {
443
+ return (
444
+ <FormFieldWrapper label={label} error={error} success={success}>
445
+ <InputGlass error={error} success={success} {...props} />
446
+ </FormFieldWrapper>
447
+ );
448
+ }
449
+
450
+ // Usage
451
+ <ValidatedInput
452
+ label="Email"
453
+ error={errors.email?.message}
454
+ success={isEmailValid ? 'Email is available' : undefined}
455
+ placeholder="you@example.com"
456
+ />;
457
+ ```
458
+
459
+ ### Controlled vs Uncontrolled
460
+
461
+ #### Controlled (recommended for forms)
462
+
463
+ ```tsx
464
+ function ControlledTabs() {
465
+ const [value, setValue] = useState('tab1');
466
+
467
+ return (
468
+ <TabsGlass.Root value={value} onValueChange={setValue}>
469
+ {/* ... */}
470
+ </TabsGlass.Root>
471
+ );
472
+ }
473
+ ```
474
+
475
+ #### Uncontrolled (simple cases)
476
+
477
+ ```tsx
478
+ function UncontrolledTabs() {
479
+ return <TabsGlass.Root defaultValue="tab1">{/* ... */}</TabsGlass.Root>;
480
+ }
481
+ ```
482
+
483
+ ### Combining Patterns
484
+
485
+ Complex form with modal, tabs, and validation:
486
+
487
+ ```tsx
488
+ function SettingsModal({ open, onOpenChange }) {
489
+ const [tab, setTab] = useState('profile');
490
+
491
+ return (
492
+ <ModalGlass.Root open={open} onOpenChange={onOpenChange}>
493
+ <ModalGlass.Overlay />
494
+ <ModalGlass.Content size="lg">
495
+ <ModalGlass.Header>
496
+ <ModalGlass.Title>Settings</ModalGlass.Title>
497
+ <ModalGlass.Close />
498
+ </ModalGlass.Header>
499
+
500
+ <ModalGlass.Body>
501
+ <TabsGlass.Root value={tab} onValueChange={setTab}>
502
+ <TabsGlass.List>
503
+ <TabsGlass.Trigger value="profile">Profile</TabsGlass.Trigger>
504
+ <TabsGlass.Trigger value="notifications">Notifications</TabsGlass.Trigger>
505
+ </TabsGlass.List>
506
+
507
+ <TabsGlass.Content value="profile">
508
+ <ProfileForm />
509
+ </TabsGlass.Content>
510
+
511
+ <TabsGlass.Content value="notifications">
512
+ <NotificationSettings />
513
+ </TabsGlass.Content>
514
+ </TabsGlass.Root>
515
+ </ModalGlass.Body>
516
+
517
+ <ModalGlass.Footer>
518
+ <ButtonGlass variant="ghost" onClick={() => onOpenChange(false)}>
519
+ Cancel
520
+ </ButtonGlass>
521
+ <ButtonGlass variant="default">Save Changes</ButtonGlass>
522
+ </ModalGlass.Footer>
523
+ </ModalGlass.Content>
524
+ </ModalGlass.Root>
525
+ );
526
+ }
527
+ ```
528
+
529
+ ---
530
+
531
+ ## Common Pitfalls
532
+
533
+ ### Mismatched Tab Values
534
+
535
+ ```tsx
536
+ // Wrong - values don't match
537
+ <TabsGlass.Trigger value="profile">Profile</TabsGlass.Trigger>
538
+ <TabsGlass.Content value="user">...</TabsGlass.Content>
539
+
540
+ // Correct
541
+ <TabsGlass.Trigger value="profile">Profile</TabsGlass.Trigger>
542
+ <TabsGlass.Content value="profile">...</TabsGlass.Content>
543
+ ```
544
+
545
+ ### Missing List Wrapper
546
+
547
+ ```tsx
548
+ // Wrong - triggers without List
549
+ <TabsGlass.Root>
550
+ <TabsGlass.Trigger value="tab1">Tab 1</TabsGlass.Trigger>
551
+ </TabsGlass.Root>
552
+
553
+ // Correct
554
+ <TabsGlass.Root>
555
+ <TabsGlass.List>
556
+ <TabsGlass.Trigger value="tab1">Tab 1</TabsGlass.Trigger>
557
+ </TabsGlass.List>
558
+ </TabsGlass.Root>
559
+ ```
560
+
561
+ ### Forgetting onValueChange (Controlled)
562
+
563
+ ```tsx
564
+ // Wrong - controlled without handler
565
+ <TabsGlass.Root value={tab}>
566
+
567
+ // Correct - controlled
568
+ <TabsGlass.Root value={tab} onValueChange={setTab}>
569
+
570
+ // Or - uncontrolled
571
+ <TabsGlass.Root defaultValue="overview">
572
+ ```
573
+
574
+ ---
575
+
576
+ ## Related Documentation
577
+
578
+ - [Compound Components Guide](migration/compound-components-v2.md)
579
+ - [Component Catalog](COMPONENTS_CATALOG.md)
580
+ - [Breaking Changes](BREAKING_CHANGES.md)
581
+
582
+ ---
583
+
584
+ **Last updated:** 2025-12-14