shadcn-glass-ui 1.0.10 → 2.0.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.
- package/CHANGELOG.md +259 -16
- package/README.md +248 -28
- package/context7.json +58 -0
- package/dist/cli/index.cjs +470 -0
- package/dist/cli/index.cjs.map +1 -0
- package/dist/cli/index.d.ts +18 -0
- package/dist/cli/index.js +469 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/components.cjs +4 -4
- package/dist/components.d.ts +153 -22
- package/dist/components.js +2 -2
- package/dist/hooks.cjs +2 -2
- package/dist/index.cjs +872 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +0 -2390
- package/dist/index.js +844 -3
- package/dist/index.js.map +1 -1
- package/dist/r/ai-card-glass.json +5 -12
- package/dist/r/avatar-glass.json +5 -15
- package/dist/r/circular-metric-glass.json +5 -11
- package/dist/r/circular-progress-glass.json +5 -12
- package/dist/r/combobox-glass.json +5 -13
- package/dist/r/flag-alert-glass.json +5 -11
- package/dist/r/flags-section-glass.json +5 -12
- package/dist/r/insight-card-glass.json +17 -0
- package/dist/r/interactive-card.json +5 -12
- package/dist/r/language-bar-glass.json +5 -11
- package/dist/r/metric-card-glass.json +6 -13
- package/dist/r/metrics-grid-glass.json +5 -11
- package/dist/r/modal-glass.json +5 -15
- package/dist/r/popover-glass.json +1 -1
- package/dist/r/progress-glass.json +5 -13
- package/dist/r/registry.json +20 -2
- package/dist/r/segmented-control-glass.json +5 -11
- package/dist/r/sparkline-glass.json +17 -0
- package/dist/r/stepper-glass.json +33 -0
- package/dist/r/tabs-glass.json +4 -9
- package/dist/r/trust-score-card-glass.json +5 -12
- package/dist/r/year-card-glass.json +5 -13
- package/dist/shadcn-glass-ui.css +1 -1
- package/dist/{theme-context-XtasSxRT.cjs → theme-context-CVW50BKW.cjs} +2 -2
- package/dist/{theme-context-XtasSxRT.cjs.map → theme-context-CVW50BKW.cjs.map} +1 -1
- package/dist/themes.cjs +1 -1
- package/dist/trust-score-card-glass-BcZbul0P.js +26895 -0
- package/dist/trust-score-card-glass-BcZbul0P.js.map +1 -0
- package/dist/trust-score-card-glass-r3qM09Jp.cjs +27689 -0
- package/dist/trust-score-card-glass-r3qM09Jp.cjs.map +1 -0
- package/dist/{use-focus-BbpE2qGq.cjs → use-focus-ZE8ozmZE.cjs} +2 -2
- package/dist/{use-focus-BbpE2qGq.cjs.map → use-focus-ZE8ozmZE.cjs.map} +1 -1
- package/dist/{use-wallpaper-tint-CIqtoETa.cjs → use-wallpaper-tint-BuS80tbN.cjs} +2 -2
- package/dist/{use-wallpaper-tint-CIqtoETa.cjs.map → use-wallpaper-tint-BuS80tbN.cjs.map} +1 -1
- package/dist/{utils-CGCOTvxT.js → utils-CcyeqpKQ.js} +1 -1
- package/dist/{utils-CGCOTvxT.js.map → utils-CcyeqpKQ.js.map} +1 -1
- package/dist/{utils-CriE74ig.cjs → utils-DLXayspX.cjs} +2 -2
- package/dist/{utils-CriE74ig.cjs.map → utils-DLXayspX.cjs.map} +1 -1
- package/dist/utils.cjs +1 -1
- package/dist/utils.js +1 -1
- package/docs/AI_IMPROVEMENTS_COMPLETE.md +574 -0
- package/docs/AI_USAGE.md +1328 -0
- package/docs/API_PATTERNS_COMPARISON.md +418 -0
- package/docs/BEST_PRACTICES.md +800 -0
- package/docs/COMPLIANCE_CHECKLIST.md +307 -0
- package/docs/COMPLIANCE_TESTING.md +436 -0
- package/docs/COMPONENTS_CATALOG.md +1076 -0
- package/docs/CSS_VARIABLES_AUDIT.md +306 -0
- package/docs/CSS_VARIABLES_REFACTORING_PLAN.md +330 -0
- package/docs/EXPORTS_MAP.json +875 -0
- package/docs/EXPORTS_STRUCTURE.md +729 -0
- package/docs/GETTING_STARTED.md +655 -0
- package/docs/METRIC_CARD_API_REDESIGN.md +354 -0
- package/docs/PRIMITIVE_MAPPING.md +404 -0
- package/docs/PUBLISHING.md +593 -0
- package/docs/REGISTRY_SUMMARY.md +96 -0
- package/docs/REGISTRY_USAGE.md +339 -0
- package/docs/SECURITY.md +117 -0
- package/docs/THEME_CREATION_GUIDE.md +455 -0
- package/docs/TOKEN_ARCHITECTURE.md +365 -0
- package/docs/announcements/v1.0.5-devto.md +363 -0
- package/docs/announcements/v1.0.5-reddit.md +115 -0
- package/docs/announcements/v1.0.5-twitter.md +70 -0
- package/docs/api/README.md +725 -0
- package/docs/api/functions/ThemeProvider.md +21 -0
- package/docs/api/functions/cn.md +27 -0
- package/docs/api/functions/getNextTheme.md +21 -0
- package/docs/api/functions/getThemeConfig.md +21 -0
- package/docs/api/functions/useFocus.md +53 -0
- package/docs/api/functions/useHover.md +47 -0
- package/docs/api/functions/useResponsive.md +31 -0
- package/docs/api/functions/useTheme.md +15 -0
- package/docs/api/functions/useWallpaperTint.md +36 -0
- package/docs/api/globals.md +139 -0
- package/docs/api/interfaces/AlertGlassProps.md +131 -0
- package/docs/api/interfaces/AvatarGlassProps.md +114 -0
- package/docs/api/interfaces/BadgeGlassProps.md +118 -0
- package/docs/api/interfaces/ButtonGlassProps.md +179 -0
- package/docs/api/interfaces/CheckboxGlassProps.md +125 -0
- package/docs/api/interfaces/DropdownGlassProps.md +123 -0
- package/docs/api/interfaces/DropdownItem.md +53 -0
- package/docs/api/interfaces/GlassCardProps.md +151 -0
- package/docs/api/interfaces/InputGlassProps.md +169 -0
- package/docs/api/interfaces/NotificationGlassProps.md +67 -0
- package/docs/api/interfaces/ProgressGlassProps.md +49 -0
- package/docs/api/interfaces/SkeletonGlassProps.md +41 -0
- package/docs/api/interfaces/SliderGlassProps.md +107 -0
- package/docs/api/interfaces/TabItem.md +25 -0
- package/docs/api/interfaces/ThemeConfig.md +25 -0
- package/docs/api/interfaces/ThemeContextValue.md +47 -0
- package/docs/api/interfaces/ToggleGlassProps.md +59 -0
- package/docs/api/interfaces/TooltipGlassProps.md +119 -0
- package/docs/api/type-aliases/AlertType.md +11 -0
- package/docs/api/type-aliases/AlertVariant.md +11 -0
- package/docs/api/type-aliases/AvatarSize.md +11 -0
- package/docs/api/type-aliases/AvatarStatus.md +13 -0
- package/docs/api/type-aliases/BadgeSize.md +11 -0
- package/docs/api/type-aliases/BadgeVariant.md +11 -0
- package/docs/api/type-aliases/ButtonGlassSize.md +11 -0
- package/docs/api/type-aliases/ButtonGlassVariant.md +11 -0
- package/docs/api/type-aliases/DropdownAlign.md +11 -0
- package/docs/api/type-aliases/GlowType.md +11 -0
- package/docs/api/type-aliases/InputGlassSize.md +11 -0
- package/docs/api/type-aliases/IntensityType.md +11 -0
- package/docs/api/type-aliases/ModalSize.md +11 -0
- package/docs/api/type-aliases/NotificationType.md +11 -0
- package/docs/api/type-aliases/PaddingType.md +11 -0
- package/docs/api/type-aliases/ProgressGradient.md +11 -0
- package/docs/api/type-aliases/ProgressSize.md +11 -0
- package/docs/api/type-aliases/SkeletonVariant.md +11 -0
- package/docs/api/type-aliases/Theme.md +11 -0
- package/docs/api/type-aliases/ToggleGlassSize.md +11 -0
- package/docs/api/type-aliases/TooltipPosition.md +11 -0
- package/docs/api/variables/AICardGlass.md +11 -0
- package/docs/api/variables/AlertGlass.md +11 -0
- package/docs/api/variables/AvatarGlass.md +11 -0
- package/docs/api/variables/BadgeGlass.md +11 -0
- package/docs/api/variables/BaseProgressGlass.md +11 -0
- package/docs/api/variables/ButtonGlass.md +11 -0
- package/docs/api/variables/CareerStatsGlass.md +11 -0
- package/docs/api/variables/CareerStatsHeaderGlass.md +11 -0
- package/docs/api/variables/CheckboxGlass.md +11 -0
- package/docs/api/variables/CircularMetricGlass.md +22 -0
- package/docs/api/variables/CircularProgressGlass.md +11 -0
- package/docs/api/variables/ComboBoxGlass.md +27 -0
- package/docs/api/variables/ContributionMetricsGlass.md +11 -0
- package/docs/api/variables/DropdownGlass.md +11 -0
- package/docs/api/variables/ExpandableHeaderGlass.md +11 -0
- package/docs/api/variables/FlagAlertGlass.md +11 -0
- package/docs/api/variables/FlagsSectionGlass.md +11 -0
- package/docs/api/variables/FormFieldWrapper.md +44 -0
- package/docs/api/variables/GlassCard.md +11 -0
- package/docs/api/variables/HeaderBrandingGlass.md +11 -0
- package/docs/api/variables/HeaderNavGlass.md +11 -0
- package/docs/api/variables/IconButtonGlass.md +11 -0
- package/docs/api/variables/InputGlass.md +11 -0
- package/docs/api/variables/InteractiveCard.md +45 -0
- package/docs/api/variables/LanguageBarGlass.md +11 -0
- package/docs/api/variables/MetricCardGlass.md +11 -0
- package/docs/api/variables/MetricsGridGlass.md +11 -0
- package/docs/api/variables/ModalGlass.md +72 -0
- package/docs/api/variables/NotificationGlass.md +11 -0
- package/docs/api/variables/PopoverGlass.md +11 -0
- package/docs/api/variables/ProfileAvatarGlass.md +11 -0
- package/docs/api/variables/ProfileHeaderGlass.md +11 -0
- package/docs/api/variables/ProgressGlass.md +11 -0
- package/docs/api/variables/ProjectsListGlass.md +11 -0
- package/docs/api/variables/RainbowProgressGlass.md +11 -0
- package/docs/api/variables/RepositoryCardGlass.md +11 -0
- package/docs/api/variables/RepositoryHeaderGlass.md +11 -0
- package/docs/api/variables/RepositoryMetadataGlass.md +11 -0
- package/docs/api/variables/SearchBoxGlass.md +11 -0
- package/docs/api/variables/SegmentedControlGlass.md +11 -0
- package/docs/api/variables/SkeletonGlass.md +11 -0
- package/docs/api/variables/SliderGlass.md +11 -0
- package/docs/api/variables/SortDropdownGlass.md +11 -0
- package/docs/api/variables/StatItemGlass.md +11 -0
- package/docs/api/variables/StatusIndicatorGlass.md +11 -0
- package/docs/api/variables/THEMES.md +11 -0
- package/docs/api/variables/THEME_CONFIG.md +11 -0
- package/docs/api/variables/TabsGlass.md +52 -0
- package/docs/api/variables/ThemeToggleGlass.md +11 -0
- package/docs/api/variables/ToggleGlass.md +11 -0
- package/docs/api/variables/TooltipGlass.md +11 -0
- package/docs/api/variables/TouchTarget.md +35 -0
- package/docs/api/variables/TrustScoreCardGlass.md +11 -0
- package/docs/api/variables/TrustScoreDisplayGlass.md +11 -0
- package/docs/api/variables/UserInfoGlass.md +11 -0
- package/docs/api/variables/UserStatsLineGlass.md +11 -0
- package/docs/api/variables/YearCardGlass.md +11 -0
- package/docs/api/variables/alertVariants.md +21 -0
- package/docs/api/variables/avatarSizes.md +21 -0
- package/docs/api/variables/badgeVariants.md +21 -0
- package/docs/api/variables/buttonGlassVariants.md +21 -0
- package/docs/api/variables/cardIntensity.md +21 -0
- package/docs/api/variables/dropdownAlign.md +21 -0
- package/docs/api/variables/inputVariants.md +21 -0
- package/docs/api/variables/modalSizes.md +21 -0
- package/docs/api/variables/notificationVariants.md +21 -0
- package/docs/api/variables/progressSizes.md +21 -0
- package/docs/api/variables/shadcnAlertVariants.md +21 -0
- package/docs/api/variables/shadcnBadgeVariants.md +21 -0
- package/docs/api/variables/shadcnButtonVariants.md +21 -0
- package/docs/api/variables/skeletonVariants.md +21 -0
- package/docs/api/variables/statusSizes.md +21 -0
- package/docs/api/variables/toggleSizes.md +21 -0
- package/docs/api/variables/tooltipPositions.md +21 -0
- package/docs/design-system/UI_DESIGN.md +628 -0
- package/docs/migration/CSS_VARIABLES_MIGRATION_2.0.md +325 -0
- package/docs/migration/modal-glass-compound-api.md +458 -0
- package/docs/migration/select-to-combobox.md +386 -0
- package/docs/migration/tabs-glass-compound-api.md +579 -0
- package/docs/technical/DEPENDENCIES.md +291 -0
- package/docs/visual-testing-guide.md +324 -0
- package/package.json +16 -3
- package/dist/trust-score-card-glass-CNcQveNY.cjs +0 -8231
- package/dist/trust-score-card-glass-CNcQveNY.cjs.map +0 -1
- package/dist/trust-score-card-glass-CowcDyxH.js +0 -7795
- package/dist/trust-score-card-glass-CowcDyxH.js.map +0 -1
|
@@ -0,0 +1,800 @@
|
|
|
1
|
+
# Best Practices for shadcn-glass-ui
|
|
2
|
+
|
|
3
|
+
A comprehensive guide for building applications with shadcn-glass-ui.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Theme Setup](#theme-setup)
|
|
8
|
+
- [Form Patterns](#form-patterns)
|
|
9
|
+
- [Modal Patterns](#modal-patterns)
|
|
10
|
+
- [Theme Switching](#theme-switching)
|
|
11
|
+
- [Accessibility Checklist](#accessibility-checklist)
|
|
12
|
+
- [Performance Tips](#performance-tips)
|
|
13
|
+
- [Common Patterns](#common-patterns)
|
|
14
|
+
- [TypeScript Best Practices](#typescript-best-practices)
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Theme Setup
|
|
19
|
+
|
|
20
|
+
Always wrap your app with ThemeProvider at the root level:
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
import { ThemeProvider } from 'shadcn-glass-ui';
|
|
24
|
+
import 'shadcn-glass-ui/dist/styles.css';
|
|
25
|
+
|
|
26
|
+
function App() {
|
|
27
|
+
return (
|
|
28
|
+
<ThemeProvider defaultTheme="glass">
|
|
29
|
+
<YourApp />
|
|
30
|
+
</ThemeProvider>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Available Themes
|
|
36
|
+
|
|
37
|
+
| Theme | Description |
|
|
38
|
+
| -------- | ------------------------------------ |
|
|
39
|
+
| `glass` | Dark glassmorphism (default) |
|
|
40
|
+
| `light` | Light mode with subtle glass effects |
|
|
41
|
+
| `aurora` | Gradient theme with aurora effects |
|
|
42
|
+
|
|
43
|
+
### Theme-Specific CSS Variables
|
|
44
|
+
|
|
45
|
+
```css
|
|
46
|
+
/* Custom styling using theme variables */
|
|
47
|
+
.custom-card {
|
|
48
|
+
background: var(--glass-bg);
|
|
49
|
+
backdrop-filter: var(--blur-md);
|
|
50
|
+
border: 1px solid var(--glass-border);
|
|
51
|
+
box-shadow: var(--focus-glow);
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Token Usage Best Practices (v2.0.0+)
|
|
58
|
+
|
|
59
|
+
### 3-Layer Token System
|
|
60
|
+
|
|
61
|
+
shadcn-glass-ui v2.0.0 introduced a 3-layer token architecture. **Always use tokens, never hardcode
|
|
62
|
+
colors.**
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
Layer 3: Component Tokens (--btn-primary-bg, --input-border)
|
|
66
|
+
↓
|
|
67
|
+
Layer 2: Semantic Tokens (--semantic-primary, --semantic-surface)
|
|
68
|
+
↓
|
|
69
|
+
Layer 1: Primitive Tokens (--oklch-purple-500, --oklch-white-8)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### DO ✅
|
|
73
|
+
|
|
74
|
+
**Use semantic tokens for custom components:**
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
// ✅ GOOD: Semantic tokens
|
|
78
|
+
function MyCustomCard({ children }: { children: React.ReactNode }) {
|
|
79
|
+
return (
|
|
80
|
+
<div
|
|
81
|
+
className="p-6 rounded-2xl"
|
|
82
|
+
style={{
|
|
83
|
+
background: 'var(--semantic-surface)',
|
|
84
|
+
color: 'var(--semantic-text)',
|
|
85
|
+
border: '1px solid var(--semantic-border)',
|
|
86
|
+
}}
|
|
87
|
+
>
|
|
88
|
+
{children}
|
|
89
|
+
</div>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Use Tailwind arbitrary values with semantic tokens:**
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
// ✅ GOOD: Tailwind + semantic tokens
|
|
98
|
+
<div className="bg-[var(--semantic-surface)] text-[var(--semantic-text)] border-[var(--semantic-border)]">
|
|
99
|
+
Content
|
|
100
|
+
</div>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Use component tokens for specific components:**
|
|
104
|
+
|
|
105
|
+
```css
|
|
106
|
+
/* ✅ GOOD: Component tokens */
|
|
107
|
+
.my-button {
|
|
108
|
+
background: var(--btn-primary-bg);
|
|
109
|
+
color: var(--btn-primary-text);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.my-button:hover {
|
|
113
|
+
background: var(--btn-primary-bg-hover);
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Use primitive tokens for specific effects:**
|
|
118
|
+
|
|
119
|
+
```css
|
|
120
|
+
/* ✅ GOOD: Primitive tokens for glow effects */
|
|
121
|
+
.my-card-glow {
|
|
122
|
+
box-shadow: 0 0 20px var(--oklch-purple-500-40);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.my-success-glow {
|
|
126
|
+
box-shadow: 0 0 30px var(--oklch-emerald-400-60);
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### DON'T ❌
|
|
131
|
+
|
|
132
|
+
**Never hardcode OKLCH values:**
|
|
133
|
+
|
|
134
|
+
```tsx
|
|
135
|
+
// ❌ BAD: Hardcoded OKLCH
|
|
136
|
+
<div style={{ background: 'oklch(66.6% 0.159 303)' }}>Content</div>
|
|
137
|
+
|
|
138
|
+
// ❌ BAD: Hardcoded OKLCH in CSS
|
|
139
|
+
.my-component {
|
|
140
|
+
background: oklch(100% 0 0 / 0.08);
|
|
141
|
+
color: oklch(66.6% 0.159 303);
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Don't use color names directly:**
|
|
146
|
+
|
|
147
|
+
```tsx
|
|
148
|
+
// ❌ BAD: Direct color reference
|
|
149
|
+
<div style={{ background: 'var(--oklch-purple-500)' }}>Content</div>
|
|
150
|
+
|
|
151
|
+
// ✅ GOOD: Use semantic token
|
|
152
|
+
<div style={{ background: 'var(--semantic-primary)' }}>Content</div>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Don't use removed v1.x variables:**
|
|
156
|
+
|
|
157
|
+
```css
|
|
158
|
+
/* ❌ BAD: Removed in v2.0.0 */
|
|
159
|
+
.my-metric {
|
|
160
|
+
background: var(--metric-emerald-bg); /* REMOVED */
|
|
161
|
+
color: var(--metric-amber-text); /* REMOVED */
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/* ✅ GOOD: v2.0.0 semantic replacements */
|
|
165
|
+
.my-metric {
|
|
166
|
+
background: var(--metric-success-bg);
|
|
167
|
+
color: var(--metric-warning-text);
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Custom Styling Workflow
|
|
172
|
+
|
|
173
|
+
**Step 1:** Check if a semantic token exists
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
# Search for semantic tokens
|
|
177
|
+
grep "semantic-" src/styles/themes/glass.css
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**Step 2:** Use existing semantic token
|
|
181
|
+
|
|
182
|
+
```tsx
|
|
183
|
+
// If --semantic-accent exists
|
|
184
|
+
<div style={{ color: 'var(--semantic-accent)' }}>Accent text</div>
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Step 3:** If no semantic token, check primitives
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# Search for primitive tokens
|
|
191
|
+
grep "oklch-cyan" src/styles/tokens/oklch-primitives.css
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**Step 4:** Use primitive for specific effects only
|
|
195
|
+
|
|
196
|
+
```tsx
|
|
197
|
+
// For special effects (glows, shadows)
|
|
198
|
+
<div
|
|
199
|
+
style={{
|
|
200
|
+
boxShadow: '0 0 20px var(--oklch-cyan-400-50)',
|
|
201
|
+
}}
|
|
202
|
+
>
|
|
203
|
+
Glowing card
|
|
204
|
+
</div>
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Theme Customization
|
|
208
|
+
|
|
209
|
+
**Creating custom semantic tokens:**
|
|
210
|
+
|
|
211
|
+
```css
|
|
212
|
+
/* Add to src/styles/themes/glass.css */
|
|
213
|
+
[data-theme='glass'] {
|
|
214
|
+
/* Custom semantic tokens */
|
|
215
|
+
--semantic-accent-secondary: var(--oklch-cyan-500);
|
|
216
|
+
--semantic-glow-primary: 0 0 30px var(--oklch-purple-500-60);
|
|
217
|
+
--semantic-glow-success: 0 0 20px var(--oklch-emerald-400-40);
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
**Then use in components:**
|
|
222
|
+
|
|
223
|
+
```tsx
|
|
224
|
+
<div
|
|
225
|
+
style={{
|
|
226
|
+
background: 'var(--semantic-surface)',
|
|
227
|
+
boxShadow: 'var(--semantic-glow-primary)',
|
|
228
|
+
}}
|
|
229
|
+
>
|
|
230
|
+
Custom card with semantic glow
|
|
231
|
+
</div>
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### v2.0.0 Migration Checklist
|
|
235
|
+
|
|
236
|
+
- [ ] Replace `--metric-emerald-*` → `--metric-success-*`
|
|
237
|
+
- [ ] Replace `--metric-amber-*` → `--metric-warning-*`
|
|
238
|
+
- [ ] Replace `--metric-blue-*` → `--metric-default-*`
|
|
239
|
+
- [ ] Replace `--metric-red-*` → `--metric-destructive-*`
|
|
240
|
+
- [ ] Remove all hardcoded `oklch()` values
|
|
241
|
+
- [ ] Use semantic tokens for component styling
|
|
242
|
+
- [ ] Use primitive tokens only for specific effects (glows, shadows)
|
|
243
|
+
|
|
244
|
+
**Automated migration:**
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
# macOS/Linux
|
|
248
|
+
find src/ -type f \( -name "*.tsx" -o -name "*.css" \) -exec sed -i '' \
|
|
249
|
+
-e 's/--metric-emerald-/--metric-success-/g' \
|
|
250
|
+
-e 's/--metric-amber-/--metric-warning-/g' \
|
|
251
|
+
-e 's/--metric-blue-/--metric-default-/g' \
|
|
252
|
+
-e 's/--metric-red-/--metric-destructive-/g' \
|
|
253
|
+
{} +
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Documentation
|
|
257
|
+
|
|
258
|
+
- [TOKEN_ARCHITECTURE.md](TOKEN_ARCHITECTURE.md) - Complete 3-layer system guide
|
|
259
|
+
- [THEME_CREATION_GUIDE.md](THEME_CREATION_GUIDE.md) - Create themes in 15 minutes
|
|
260
|
+
- [CSS_VARIABLES_MIGRATION_2.0.md](migration/CSS_VARIABLES_MIGRATION_2.0.md) - Migration guide
|
|
261
|
+
- [PRIMITIVE_MAPPING.md](PRIMITIVE_MAPPING.md) - OKLCH primitive reference
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Form Patterns
|
|
266
|
+
|
|
267
|
+
### Basic Form with Validation
|
|
268
|
+
|
|
269
|
+
```tsx
|
|
270
|
+
import { InputGlass, ButtonGlass } from 'shadcn-glass-ui';
|
|
271
|
+
import { useState } from 'react';
|
|
272
|
+
|
|
273
|
+
function LoginForm() {
|
|
274
|
+
const [email, setEmail] = useState('');
|
|
275
|
+
const [password, setPassword] = useState('');
|
|
276
|
+
const [errors, setErrors] = useState<Record<string, string>>({});
|
|
277
|
+
|
|
278
|
+
const handleSubmit = (e: React.FormEvent) => {
|
|
279
|
+
e.preventDefault();
|
|
280
|
+
const newErrors: Record<string, string> = {};
|
|
281
|
+
|
|
282
|
+
if (!email) newErrors.email = 'Email is required';
|
|
283
|
+
if (!password) newErrors.password = 'Password is required';
|
|
284
|
+
|
|
285
|
+
setErrors(newErrors);
|
|
286
|
+
if (Object.keys(newErrors).length === 0) {
|
|
287
|
+
// Submit form
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
return (
|
|
292
|
+
<form onSubmit={handleSubmit} className="space-y-4">
|
|
293
|
+
<InputGlass
|
|
294
|
+
label="Email"
|
|
295
|
+
type="email"
|
|
296
|
+
value={email}
|
|
297
|
+
onChange={(e) => setEmail(e.target.value)}
|
|
298
|
+
error={errors.email}
|
|
299
|
+
placeholder="you@example.com"
|
|
300
|
+
/>
|
|
301
|
+
<InputGlass
|
|
302
|
+
label="Password"
|
|
303
|
+
type="password"
|
|
304
|
+
value={password}
|
|
305
|
+
onChange={(e) => setPassword(e.target.value)}
|
|
306
|
+
error={errors.password}
|
|
307
|
+
placeholder="Enter password"
|
|
308
|
+
/>
|
|
309
|
+
<ButtonGlass type="submit" variant="primary" className="w-full">
|
|
310
|
+
Sign In
|
|
311
|
+
</ButtonGlass>
|
|
312
|
+
</form>
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### Form with Success States
|
|
318
|
+
|
|
319
|
+
```tsx
|
|
320
|
+
<InputGlass
|
|
321
|
+
label="Username"
|
|
322
|
+
value={username}
|
|
323
|
+
onChange={(e) => setUsername(e.target.value)}
|
|
324
|
+
error={!isValidUsername ? 'Username must be 3+ characters' : undefined}
|
|
325
|
+
success={isValidUsername ? 'Username is available' : undefined}
|
|
326
|
+
/>
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Form with FormFieldWrapper
|
|
330
|
+
|
|
331
|
+
```tsx
|
|
332
|
+
import { FormFieldWrapper } from 'shadcn-glass-ui';
|
|
333
|
+
|
|
334
|
+
<FormFieldWrapper label="Email" error={errors.email} required>
|
|
335
|
+
<input type="email" className="..." />
|
|
336
|
+
</FormFieldWrapper>;
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## Modal Patterns
|
|
342
|
+
|
|
343
|
+
### Confirmation Modal
|
|
344
|
+
|
|
345
|
+
```tsx
|
|
346
|
+
import { ModalGlass, ButtonGlass } from 'shadcn-glass-ui';
|
|
347
|
+
|
|
348
|
+
function ConfirmDialog({ open, onConfirm, onCancel, title, message }: ConfirmDialogProps) {
|
|
349
|
+
return (
|
|
350
|
+
<ModalGlass.Root open={open} onOpenChange={onCancel}>
|
|
351
|
+
<ModalGlass.Overlay />
|
|
352
|
+
<ModalGlass.Content size="sm">
|
|
353
|
+
<ModalGlass.Header>
|
|
354
|
+
<ModalGlass.Title>{title}</ModalGlass.Title>
|
|
355
|
+
</ModalGlass.Header>
|
|
356
|
+
<ModalGlass.Body>
|
|
357
|
+
<p>{message}</p>
|
|
358
|
+
</ModalGlass.Body>
|
|
359
|
+
<ModalGlass.Footer>
|
|
360
|
+
<ButtonGlass variant="ghost" onClick={onCancel}>
|
|
361
|
+
Cancel
|
|
362
|
+
</ButtonGlass>
|
|
363
|
+
<ButtonGlass variant="destructive" onClick={onConfirm}>
|
|
364
|
+
Confirm
|
|
365
|
+
</ButtonGlass>
|
|
366
|
+
</ModalGlass.Footer>
|
|
367
|
+
</ModalGlass.Content>
|
|
368
|
+
</ModalGlass.Root>
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### Form Modal with Validation
|
|
374
|
+
|
|
375
|
+
```tsx
|
|
376
|
+
function CreateProjectModal({ open, onClose, onSubmit }) {
|
|
377
|
+
const [name, setName] = useState('');
|
|
378
|
+
const [error, setError] = useState('');
|
|
379
|
+
|
|
380
|
+
const handleSubmit = () => {
|
|
381
|
+
if (!name.trim()) {
|
|
382
|
+
setError('Project name is required');
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
onSubmit({ name });
|
|
386
|
+
setName('');
|
|
387
|
+
onClose();
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
return (
|
|
391
|
+
<ModalGlass.Root open={open} onOpenChange={onClose}>
|
|
392
|
+
<ModalGlass.Overlay />
|
|
393
|
+
<ModalGlass.Content>
|
|
394
|
+
<ModalGlass.Header>
|
|
395
|
+
<ModalGlass.Title>Create Project</ModalGlass.Title>
|
|
396
|
+
<ModalGlass.Description>Enter details for your new project</ModalGlass.Description>
|
|
397
|
+
</ModalGlass.Header>
|
|
398
|
+
<ModalGlass.Body>
|
|
399
|
+
<InputGlass
|
|
400
|
+
label="Project Name"
|
|
401
|
+
value={name}
|
|
402
|
+
onChange={(e) => {
|
|
403
|
+
setName(e.target.value);
|
|
404
|
+
setError('');
|
|
405
|
+
}}
|
|
406
|
+
error={error}
|
|
407
|
+
placeholder="My Project"
|
|
408
|
+
/>
|
|
409
|
+
</ModalGlass.Body>
|
|
410
|
+
<ModalGlass.Footer>
|
|
411
|
+
<ButtonGlass variant="ghost" onClick={onClose}>
|
|
412
|
+
Cancel
|
|
413
|
+
</ButtonGlass>
|
|
414
|
+
<ButtonGlass variant="primary" onClick={handleSubmit}>
|
|
415
|
+
Create
|
|
416
|
+
</ButtonGlass>
|
|
417
|
+
</ModalGlass.Footer>
|
|
418
|
+
</ModalGlass.Content>
|
|
419
|
+
</ModalGlass.Root>
|
|
420
|
+
);
|
|
421
|
+
}
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
## Theme Switching
|
|
427
|
+
|
|
428
|
+
### Basic Theme Toggle
|
|
429
|
+
|
|
430
|
+
```tsx
|
|
431
|
+
import { useTheme, ButtonGlass } from 'shadcn-glass-ui';
|
|
432
|
+
import { Moon, Sun, Sparkles } from 'lucide-react';
|
|
433
|
+
|
|
434
|
+
function ThemeToggle() {
|
|
435
|
+
const { theme, setTheme, cycleTheme } = useTheme();
|
|
436
|
+
|
|
437
|
+
const icons = {
|
|
438
|
+
glass: <Moon className="h-4 w-4" />,
|
|
439
|
+
light: <Sun className="h-4 w-4" />,
|
|
440
|
+
aurora: <Sparkles className="h-4 w-4" />,
|
|
441
|
+
};
|
|
442
|
+
|
|
443
|
+
return (
|
|
444
|
+
<ButtonGlass
|
|
445
|
+
variant="ghost"
|
|
446
|
+
size="icon"
|
|
447
|
+
onClick={cycleTheme}
|
|
448
|
+
aria-label={`Switch to next theme (current: ${theme})`}
|
|
449
|
+
>
|
|
450
|
+
{icons[theme]}
|
|
451
|
+
</ButtonGlass>
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
### Theme Selector Dropdown
|
|
457
|
+
|
|
458
|
+
```tsx
|
|
459
|
+
import { useTheme, DropdownGlass, ButtonGlass } from 'shadcn-glass-ui';
|
|
460
|
+
|
|
461
|
+
function ThemeSelector() {
|
|
462
|
+
const { theme, setTheme } = useTheme();
|
|
463
|
+
|
|
464
|
+
return (
|
|
465
|
+
<DropdownGlass
|
|
466
|
+
trigger={<ButtonGlass variant="ghost">Theme: {theme}</ButtonGlass>}
|
|
467
|
+
items={[
|
|
468
|
+
{ label: 'Glass (Dark)', onClick: () => setTheme('glass') },
|
|
469
|
+
{ label: 'Light', onClick: () => setTheme('light') },
|
|
470
|
+
{ label: 'Aurora', onClick: () => setTheme('aurora') },
|
|
471
|
+
]}
|
|
472
|
+
/>
|
|
473
|
+
);
|
|
474
|
+
}
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
---
|
|
478
|
+
|
|
479
|
+
## Accessibility Checklist
|
|
480
|
+
|
|
481
|
+
### Essential Requirements
|
|
482
|
+
|
|
483
|
+
- [ ] All interactive elements have visible focus states
|
|
484
|
+
- [ ] Icon-only buttons have `aria-label`
|
|
485
|
+
- [ ] Forms have proper label associations
|
|
486
|
+
- [ ] Color contrast meets WCAG 2.1 AA (4.5:1 for text)
|
|
487
|
+
- [ ] Touch targets are at least 44x44px
|
|
488
|
+
- [ ] Modals trap focus correctly
|
|
489
|
+
- [ ] Content is navigable via keyboard
|
|
490
|
+
|
|
491
|
+
### Icon Button Accessibility
|
|
492
|
+
|
|
493
|
+
```tsx
|
|
494
|
+
// BAD - No accessible name
|
|
495
|
+
<ButtonGlass size="icon">
|
|
496
|
+
<X />
|
|
497
|
+
</ButtonGlass>
|
|
498
|
+
|
|
499
|
+
// GOOD - Has aria-label
|
|
500
|
+
<ButtonGlass size="icon" aria-label="Close dialog">
|
|
501
|
+
<X />
|
|
502
|
+
</ButtonGlass>
|
|
503
|
+
|
|
504
|
+
// BETTER - With tooltip for sighted users
|
|
505
|
+
<TooltipGlass content="Close dialog">
|
|
506
|
+
<ButtonGlass size="icon" aria-label="Close dialog">
|
|
507
|
+
<X />
|
|
508
|
+
</ButtonGlass>
|
|
509
|
+
</TooltipGlass>
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
### Form Field Accessibility
|
|
513
|
+
|
|
514
|
+
```tsx
|
|
515
|
+
// GOOD - Label associated with input
|
|
516
|
+
<InputGlass
|
|
517
|
+
id="email"
|
|
518
|
+
label="Email Address"
|
|
519
|
+
type="email"
|
|
520
|
+
required
|
|
521
|
+
aria-describedby="email-error"
|
|
522
|
+
/>;
|
|
523
|
+
{
|
|
524
|
+
error && (
|
|
525
|
+
<p id="email-error" role="alert">
|
|
526
|
+
{error}
|
|
527
|
+
</p>
|
|
528
|
+
);
|
|
529
|
+
}
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
### Expandable Sections
|
|
533
|
+
|
|
534
|
+
```tsx
|
|
535
|
+
// ExpandableHeaderGlass has built-in ARIA attributes
|
|
536
|
+
<ExpandableHeaderGlass title="Advanced Options" defaultExpanded={false}>
|
|
537
|
+
<p>Hidden content</p>
|
|
538
|
+
</ExpandableHeaderGlass>
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
---
|
|
542
|
+
|
|
543
|
+
## Performance Tips
|
|
544
|
+
|
|
545
|
+
### 1. Memoize ComboBox Options
|
|
546
|
+
|
|
547
|
+
```tsx
|
|
548
|
+
// BAD - Creates new array on every render
|
|
549
|
+
<ComboBoxGlass
|
|
550
|
+
options={[
|
|
551
|
+
{ value: '1', label: 'One' },
|
|
552
|
+
{ value: '2', label: 'Two' },
|
|
553
|
+
]}
|
|
554
|
+
value={value}
|
|
555
|
+
onChange={setValue}
|
|
556
|
+
/>;
|
|
557
|
+
|
|
558
|
+
// GOOD - Memoized options
|
|
559
|
+
const options = useMemo(
|
|
560
|
+
() => [
|
|
561
|
+
{ value: '1', label: 'One' },
|
|
562
|
+
{ value: '2', label: 'Two' },
|
|
563
|
+
],
|
|
564
|
+
[]
|
|
565
|
+
);
|
|
566
|
+
|
|
567
|
+
<ComboBoxGlass options={options} value={value} onChange={setValue} />;
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
### 2. Lazy Load Modal Content
|
|
571
|
+
|
|
572
|
+
```tsx
|
|
573
|
+
import { lazy, Suspense } from 'react';
|
|
574
|
+
|
|
575
|
+
const HeavyModalContent = lazy(() => import('./HeavyModalContent'));
|
|
576
|
+
|
|
577
|
+
<ModalGlass.Root open={open} onOpenChange={setOpen}>
|
|
578
|
+
<ModalGlass.Content>
|
|
579
|
+
<Suspense fallback={<SkeletonGlass height={200} />}>
|
|
580
|
+
<HeavyModalContent />
|
|
581
|
+
</Suspense>
|
|
582
|
+
</ModalGlass.Content>
|
|
583
|
+
</ModalGlass.Root>;
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
### 3. Use CSS Variables for Custom Styles
|
|
587
|
+
|
|
588
|
+
```css
|
|
589
|
+
/* GOOD - Uses theme CSS variables */
|
|
590
|
+
.custom-card {
|
|
591
|
+
background: var(--glass-bg);
|
|
592
|
+
backdrop-filter: var(--blur-md);
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
/* BAD - Hardcoded values */
|
|
596
|
+
.custom-card {
|
|
597
|
+
background: rgba(255, 255, 255, 0.1);
|
|
598
|
+
backdrop-filter: blur(16px);
|
|
599
|
+
}
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
### 4. Prefer GlassCard Intensity Variants
|
|
603
|
+
|
|
604
|
+
```tsx
|
|
605
|
+
// Use intensity variants instead of custom blur
|
|
606
|
+
<GlassCard intensity="subtle">Low blur content</GlassCard>
|
|
607
|
+
<GlassCard intensity="medium">Normal blur content</GlassCard>
|
|
608
|
+
<GlassCard intensity="strong">High blur content</GlassCard>
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
### 5. RainbowProgressGlass Performance
|
|
612
|
+
|
|
613
|
+
RainbowProgressGlass uses GPU-optimized animations with `will-change`. Avoid having many instances
|
|
614
|
+
on a single page:
|
|
615
|
+
|
|
616
|
+
```tsx
|
|
617
|
+
// GOOD - Single prominent progress
|
|
618
|
+
<RainbowProgressGlass value={progress} />;
|
|
619
|
+
|
|
620
|
+
// For multiple progress bars, use ProgressGlass instead
|
|
621
|
+
{
|
|
622
|
+
items.map((item) => <ProgressGlass key={item.id} value={item.progress} />);
|
|
623
|
+
}
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
---
|
|
627
|
+
|
|
628
|
+
## Common Patterns
|
|
629
|
+
|
|
630
|
+
### Button as Link (asChild)
|
|
631
|
+
|
|
632
|
+
```tsx
|
|
633
|
+
import { Link } from 'react-router-dom'; // or next/link
|
|
634
|
+
|
|
635
|
+
<ButtonGlass asChild variant="ghost">
|
|
636
|
+
<Link href="/dashboard">Go to Dashboard</Link>
|
|
637
|
+
</ButtonGlass>;
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
### Card as Link (asChild)
|
|
641
|
+
|
|
642
|
+
```tsx
|
|
643
|
+
<GlassCard asChild>
|
|
644
|
+
<a href="/project/123" className="block">
|
|
645
|
+
<h3>Project Name</h3>
|
|
646
|
+
<p>Project description</p>
|
|
647
|
+
</a>
|
|
648
|
+
</GlassCard>
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
### Segmented Control for Exclusive Selection
|
|
652
|
+
|
|
653
|
+
```tsx
|
|
654
|
+
// Use instead of radio buttons for glass-styled exclusive selection
|
|
655
|
+
<SegmentedControlGlass
|
|
656
|
+
options={['Day', 'Week', 'Month', 'Year']}
|
|
657
|
+
value={period}
|
|
658
|
+
onChange={setPeriod}
|
|
659
|
+
/>
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
### Status Display
|
|
663
|
+
|
|
664
|
+
```tsx
|
|
665
|
+
<div className="flex items-center gap-2">
|
|
666
|
+
<StatusIndicatorGlass status="online" />
|
|
667
|
+
<span>User is online</span>
|
|
668
|
+
</div>
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
### Metric Dashboard Card
|
|
672
|
+
|
|
673
|
+
```tsx
|
|
674
|
+
<MetricCardGlass label="Total Revenue" value="$45,678" change={12.5} trend="up" progress={75} />
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
---
|
|
678
|
+
|
|
679
|
+
## TypeScript Best Practices
|
|
680
|
+
|
|
681
|
+
### Component Props Types
|
|
682
|
+
|
|
683
|
+
```tsx
|
|
684
|
+
import type { ButtonGlassProps } from 'shadcn-glass-ui';
|
|
685
|
+
|
|
686
|
+
// Extend component props
|
|
687
|
+
interface MyButtonProps extends ButtonGlassProps {
|
|
688
|
+
analyticsId: string;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
function MyButton({ analyticsId, onClick, ...props }: MyButtonProps) {
|
|
692
|
+
const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
|
|
693
|
+
trackClick(analyticsId);
|
|
694
|
+
onClick?.(e);
|
|
695
|
+
};
|
|
696
|
+
|
|
697
|
+
return <ButtonGlass onClick={handleClick} {...props} />;
|
|
698
|
+
}
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
### Theme Type Safety
|
|
702
|
+
|
|
703
|
+
```tsx
|
|
704
|
+
import type { Theme } from 'shadcn-glass-ui';
|
|
705
|
+
|
|
706
|
+
function saveThemePreference(theme: Theme) {
|
|
707
|
+
localStorage.setItem('theme', theme);
|
|
708
|
+
}
|
|
709
|
+
```
|
|
710
|
+
|
|
711
|
+
### Strict Mode Compliance
|
|
712
|
+
|
|
713
|
+
```tsx
|
|
714
|
+
// All components are strict TypeScript compliant
|
|
715
|
+
// No 'any' types - use proper typing
|
|
716
|
+
|
|
717
|
+
// BAD
|
|
718
|
+
const handleChange = (value: any) => setValue(value);
|
|
719
|
+
|
|
720
|
+
// GOOD
|
|
721
|
+
const handleChange = (value: string) => setValue(value);
|
|
722
|
+
```
|
|
723
|
+
|
|
724
|
+
---
|
|
725
|
+
|
|
726
|
+
## Testing Guidelines
|
|
727
|
+
|
|
728
|
+
### Test All 3 Themes
|
|
729
|
+
|
|
730
|
+
Before shipping, test components with all themes:
|
|
731
|
+
|
|
732
|
+
```tsx
|
|
733
|
+
describe('MyComponent', () => {
|
|
734
|
+
const themes = ['glass', 'light', 'aurora'] as const;
|
|
735
|
+
|
|
736
|
+
themes.forEach((theme) => {
|
|
737
|
+
it(`renders correctly in ${theme} theme`, () => {
|
|
738
|
+
render(
|
|
739
|
+
<ThemeProvider defaultTheme={theme}>
|
|
740
|
+
<MyComponent />
|
|
741
|
+
</ThemeProvider>
|
|
742
|
+
);
|
|
743
|
+
expect(screen.getByRole('button')).toBeVisible();
|
|
744
|
+
});
|
|
745
|
+
});
|
|
746
|
+
});
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
### Accessibility Testing
|
|
750
|
+
|
|
751
|
+
```tsx
|
|
752
|
+
import { axe, toHaveNoViolations } from 'jest-axe';
|
|
753
|
+
|
|
754
|
+
expect.extend(toHaveNoViolations);
|
|
755
|
+
|
|
756
|
+
it('has no accessibility violations', async () => {
|
|
757
|
+
const { container } = render(<MyComponent />);
|
|
758
|
+
const results = await axe(container);
|
|
759
|
+
expect(results).toHaveNoViolations();
|
|
760
|
+
});
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
---
|
|
764
|
+
|
|
765
|
+
## Migration Notes
|
|
766
|
+
|
|
767
|
+
### From variant="danger" to variant="destructive"
|
|
768
|
+
|
|
769
|
+
```tsx
|
|
770
|
+
// OLD (removed in v1.0)
|
|
771
|
+
<ButtonGlass variant="danger">Delete</ButtonGlass>
|
|
772
|
+
|
|
773
|
+
// NEW
|
|
774
|
+
<ButtonGlass variant="destructive">Delete</ButtonGlass>
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
### From type prop to variant prop
|
|
778
|
+
|
|
779
|
+
```tsx
|
|
780
|
+
// OLD (AlertGlass, NotificationGlass)
|
|
781
|
+
<AlertGlass type="error" title="Error">...</AlertGlass>
|
|
782
|
+
|
|
783
|
+
// NEW
|
|
784
|
+
<AlertGlass variant="destructive" title="Error">...</AlertGlass>
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
### From SelectGlass to ComboBoxGlass
|
|
788
|
+
|
|
789
|
+
```tsx
|
|
790
|
+
// OLD (SelectGlass removed in v1.0)
|
|
791
|
+
<SelectGlass options={options} value={value} onChange={setValue} />
|
|
792
|
+
|
|
793
|
+
// NEW
|
|
794
|
+
<ComboBoxGlass options={options} value={value} onChange={setValue} />
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
---
|
|
798
|
+
|
|
799
|
+
**Total Components:** 55 **TypeScript:** Full strict mode support **Accessibility:** WCAG 2.1 AA
|
|
800
|
+
compliant **Themes:** 3 (glass, light, aurora)
|