Try Live
Add Docs
Rankings
Pricing
Enterprise
Docs
Install
Theme
Install
Docs
Pricing
Enterprise
More...
More...
Try Live
Rankings
Create API Key
Add Docs
Shadcn Glass UI
https://github.com/yhooi2/shadcn-glass-ui-library
Admin
A Glassmorphism UI library for React that is AI-friendly, featuring 55+ components, strict
...
Tokens:
157,672
Snippets:
1,243
Trust Score:
6.1
Update:
4 months ago
Context
Skills
Chat
Benchmark
77.6
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# shadcn-glass-ui Component Library shadcn-glass-ui is a production-ready glassmorphism UI component library for React applications. Built with React 19.2, TypeScript 5.9, and Tailwind CSS 4.1, it provides 58 components with strict accessibility compliance (WCAG 2.1 AA), three built-in themes, and comprehensive visual regression testing. The library is optimized for AI coding assistants with rich JSDoc documentation and supports both npm package installation and shadcn CLI registry installation. The library features a multi-tier component architecture: 18 core UI primitives (buttons, inputs, cards), 7 atomic components (specialized single-purpose elements), 9 specialized components (progress bars, status indicators), 13 composite components (pre-built complex widgets), and 7 full-page sections. It implements advanced patterns including compound components (Modal, Tabs, Stepper), polymorphic rendering via the asChild pattern, and touch-optimized interactions with 44×44px minimum touch targets. The design system is powered by a 3-layer CSS token architecture with 207 OKLCH primitive tokens, enabling 15-minute theme creation (90% faster than v1.x). ## Installation and Setup ### Install via npm package ```bash npm install shadcn-glass-ui # Peer dependencies (React 18+ or 19+, Tailwind CSS 4+) npm install react react-dom tailwindcss ``` ### Install via shadcn CLI (recommended) ```json // components.json { "registries": { "@shadcn-glass-ui": { "url": "https://raw.githubusercontent.com/Yhooi2/shadcn-glass-ui-library/main/public/r" } } } ``` ```bash # Install single component with dependencies npx shadcn@latest add @shadcn-glass-ui/button-glass --deps # Install multiple components npx shadcn@latest add @shadcn-glass-ui/button-glass @shadcn-glass-ui/input-glass @shadcn-glass-ui/modal-glass # Install new StepperGlass component (v2.0.0+) npx shadcn@latest add @shadcn-glass-ui/stepper-glass ``` ### Basic setup with theme provider ```tsx import { ThemeProvider, ButtonGlass, InputGlass } from 'shadcn-glass-ui'; import 'shadcn-glass-ui/dist/styles.css'; function App() { return ( <ThemeProvider defaultTheme="glass"> <div className="p-8 space-y-4"> <ButtonGlass variant="primary" size="lg"> Click me </ButtonGlass> <InputGlass placeholder="Enter text..." /> </div> </ThemeProvider> ); } export default App; ``` ## Theme Management ### ThemeProvider component ```tsx import { ThemeProvider, useTheme } from 'shadcn-glass-ui'; // Wrap your app with ThemeProvider function Root() { return ( <ThemeProvider defaultTheme="glass" storageKey="my-app-theme"> <App /> </ThemeProvider> ); } // Access theme context in child components function ThemeSwitcher() { const { theme, setTheme, cycleTheme } = useTheme(); return ( <div> <p>Current theme: {theme}</p> {/* Direct theme selection */} <button onClick={() => setTheme('glass')}>Glass Theme</button> <button onClick={() => setTheme('light')}>Light Theme</button> <button onClick={() => setTheme('aurora')}>Aurora Theme</button> {/* Cycle through themes */} <button onClick={cycleTheme}>Next Theme</button> </div> ); } ``` ### Theme types and configuration ```tsx import { THEMES, THEME_CONFIG, getNextTheme } from 'shadcn-glass-ui'; // Available themes: "light" | "aurora" | "glass" const allThemes = THEMES; // ["light", "aurora", "glass"] // Get theme configuration with icon const glassConfig = THEME_CONFIG.glass; // { label: "Glass", icon: Palette } // Programmatically get next theme const currentTheme = "glass"; const nextTheme = getNextTheme(currentTheme); // "light" ``` ## Core UI Components ### ButtonGlass with variants and loading state ```tsx import { ButtonGlass } from 'shadcn-glass-ui'; import { Check, X, Mail } from 'lucide-react'; import { Link } from 'react-router-dom'; function ButtonExamples() { const [loading, setLoading] = useState(false); const handleSubmit = async () => { setLoading(true); try { await submitForm(); } finally { setLoading(false); } }; return ( <div className="space-y-4"> {/* Variants */} <ButtonGlass variant="primary" size="lg"> Primary Action </ButtonGlass> <ButtonGlass variant="secondary">Secondary</ButtonGlass> <ButtonGlass variant="ghost">Ghost Button</ButtonGlass> <ButtonGlass variant="destructive">Delete</ButtonGlass> <ButtonGlass variant="success">Confirm</ButtonGlass> {/* With icons */} <ButtonGlass icon={Check} iconPosition="left"> Save Changes </ButtonGlass> <ButtonGlass icon={Mail} iconPosition="right"> Send Email </ButtonGlass> {/* Icon-only button (requires aria-label) */} <ButtonGlass icon={X} size="icon" aria-label="Close dialog" /> {/* Loading state */} <ButtonGlass loading={loading} onClick={handleSubmit}> {loading ? 'Processing...' : 'Submit'} </ButtonGlass> {/* Polymorphic rendering with asChild */} <ButtonGlass asChild variant="primary"> <Link to="/dashboard">Go to Dashboard</Link> </ButtonGlass> {/* As anchor tag */} <ButtonGlass asChild> <a href="https://example.com" target="_blank"> External Link </a> </ButtonGlass> {/* Form submit button */} <form onSubmit={handleSubmit}> <ButtonGlass type="submit" variant="primary"> Submit Form </ButtonGlass> </form> </div> ); } ``` ### InputGlass with validation and icons ```tsx import { InputGlass } from 'shadcn-glass-ui'; import { Search, Mail, Lock, Eye, EyeOff } from 'lucide-react'; function FormExample() { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [showPassword, setShowPassword] = useState(false); const [errors, setErrors] = useState<Record<string, string>>({}); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); const newErrors: Record<string, string> = {}; if (!email) newErrors.email = 'Email is required'; if (!password) newErrors.password = 'Password is required'; if (password.length < 8) newErrors.password = 'Password must be 8+ characters'; setErrors(newErrors); }; return ( <form onSubmit={handleSubmit} className="space-y-4"> {/* Basic input with label */} <InputGlass label="Email" placeholder="you@example.com" value={email} onChange={(e) => setEmail(e.target.value)} /> {/* With icon and validation */} <InputGlass label="Email Address" type="email" icon={Mail} iconPosition="left" placeholder="Enter your email" value={email} onChange={(e) => setEmail(e.target.value)} error={errors.email} aria-invalid={!!errors.email} required /> {/* Password with toggle visibility */} <div className="relative"> <InputGlass label="Password" type={showPassword ? 'text' : 'password'} icon={Lock} value={password} onChange={(e) => setPassword(e.target.value)} error={errors.password} success={password.length >= 8 ? 'Strong password' : undefined} /> <button type="button" onClick={() => setShowPassword(!showPassword)} className="absolute right-3 top-1/2 -translate-y-1/2" aria-label={showPassword ? 'Hide password' : 'Show password'} > {showPassword ? <EyeOff size={16} /> : <Eye size={16} />} </button> </div> {/* Search input with icon */} <InputGlass icon={Search} placeholder="Search products..." aria-label="Search products" /> {/* Disabled state */} <InputGlass label="Username" disabled value="locked@example.com" /> {/* Size variants */} <InputGlass size="sm" placeholder="Small input" /> <InputGlass size="md" placeholder="Medium input (default)" /> <InputGlass size="lg" placeholder="Large input" /> <ButtonGlass type="submit" variant="primary"> Sign In </ButtonGlass> </form> ); } ``` ### GlassCard with intensity levels ```tsx import { GlassCard } from 'shadcn-glass-ui'; function CardExamples() { return ( <div className="space-y-4"> {/* Subtle glass effect (8px blur) */} <GlassCard intensity="subtle" className="p-6"> <h3>Subtle Card</h3> <p>Light glass effect for subtle emphasis</p> </GlassCard> {/* Standard glassmorphism (16px blur - default) */} <GlassCard intensity="medium" className="p-6"> <h3>Standard Card</h3> <p>Default glassmorphism effect</p> </GlassCard> {/* Strong glass effect (24px blur) */} <GlassCard intensity="strong" className="p-6"> <h3>Featured Card</h3> <p>Prominent glass effect for featured content</p> </GlassCard> {/* Polymorphic rendering */} <GlassCard asChild> <article className="p-6"> <h2>Article Title</h2> <p>Article content with semantic HTML</p> </article> </GlassCard> {/* Interactive card with hover effects */} <GlassCard className="p-6 cursor-pointer transition-transform hover:scale-105"> <h3>Clickable Card</h3> <p>Hover for interaction</p> </GlassCard> </div> ); } ``` ## Compound Components ### StepperGlass - Multi-step workflows (NEW in v2.0.0) ```tsx import { StepperGlass, ButtonGlass } from 'shadcn-glass-ui'; import { User, Mail, Check } from 'lucide-react'; import { useState } from 'react'; function RegistrationWizard() { const [currentStep, setCurrentStep] = useState('account'); return ( <div className="max-w-2xl mx-auto p-6"> {/* Numbered stepper (default) */} <StepperGlass.Root value={currentStep} onValueChange={setCurrentStep}> <StepperGlass.List> <StepperGlass.Step value="account" label="Account" description="Create your account" /> <StepperGlass.Step value="profile" label="Profile" description="Setup your profile" /> <StepperGlass.Step value="complete" label="Complete" description="Finish setup" /> </StepperGlass.List> <StepperGlass.Content value="account"> <div className="p-6 space-y-4"> <h2>Account Information</h2> <InputGlass label="Email" type="email" required /> <InputGlass label="Password" type="password" required /> </div> </StepperGlass.Content> <StepperGlass.Content value="profile"> <div className="p-6 space-y-4"> <h2>Profile Details</h2> <InputGlass label="Full Name" required /> <InputGlass label="Bio" /> </div> </StepperGlass.Content> <StepperGlass.Content value="complete"> <div className="p-6"> <h2>All Done!</h2> <p>Your account is ready to use.</p> </div> </StepperGlass.Content> </StepperGlass.Root> {/* Icon variant stepper */} <StepperGlass.Root value={currentStep} onValueChange={setCurrentStep} variant="icon" orientation="horizontal" > <StepperGlass.List> <StepperGlass.Step value="step1" label="Account" icon={User} /> <StepperGlass.Step value="step2" label="Verify" icon={Mail} /> <StepperGlass.Step value="step3" label="Done" icon={Check} /> </StepperGlass.List> <StepperGlass.Content value="step1">Step 1 content</StepperGlass.Content> <StepperGlass.Content value="step2">Step 2 content</StepperGlass.Content> <StepperGlass.Content value="step3">Step 3 content</StepperGlass.Content> </StepperGlass.Root> {/* Dots variant stepper (compact) */} <StepperGlass.Root value={currentStep} onValueChange={setCurrentStep} variant="dots" size="sm" > <StepperGlass.List> <StepperGlass.Step value="intro" label="Introduction" /> <StepperGlass.Step value="details" label="Details" /> <StepperGlass.Step value="review" label="Review" /> </StepperGlass.List> <StepperGlass.Content value="intro">Introduction content</StepperGlass.Content> <StepperGlass.Content value="details">Details content</StepperGlass.Content> <StepperGlass.Content value="review">Review content</StepperGlass.Content> </StepperGlass.Root> {/* Linear mode (wizard) - locks future steps */} <StepperGlass.Root value={currentStep} onValueChange={setCurrentStep} linear={true} > <StepperGlass.List> <StepperGlass.Step value="step1" label="Step 1" /> <StepperGlass.Step value="step2" label="Step 2" /> <StepperGlass.Step value="step3" label="Step 3" /> </StepperGlass.List> <StepperGlass.Content value="step1"> <ButtonGlass onClick={() => setCurrentStep('step2')}> Continue to Step 2 </ButtonGlass> </StepperGlass.Content> <StepperGlass.Content value="step2"> <ButtonGlass onClick={() => setCurrentStep('step3')}> Continue to Step 3 </ButtonGlass> </StepperGlass.Content> <StepperGlass.Content value="step3"> Complete! </StepperGlass.Content> </StepperGlass.Root> {/* Vertical orientation */} <StepperGlass.Root value={currentStep} onValueChange={setCurrentStep} orientation="vertical" size="lg" > <StepperGlass.List> <StepperGlass.Step value="a" label="Planning" description="Define requirements" /> <StepperGlass.Step value="b" label="Development" description="Build features" /> <StepperGlass.Step value="c" label="Testing" description="Quality assurance" /> <StepperGlass.Step value="d" label="Deployment" description="Go live" /> </StepperGlass.List> <StepperGlass.Content value="a">Planning phase</StepperGlass.Content> <StepperGlass.Content value="b">Development phase</StepperGlass.Content> <StepperGlass.Content value="c">Testing phase</StepperGlass.Content> <StepperGlass.Content value="d">Deployment phase</StepperGlass.Content> </StepperGlass.Root> </div> ); } ``` ### ModalGlass with compound API ```tsx import { ModalGlass, ButtonGlass, InputGlass } from 'shadcn-glass-ui'; import { useState } from 'react'; function ModalExample() { const [isOpen, setIsOpen] = useState(false); const [formData, setFormData] = useState({ name: '', email: '' }); const handleSubmit = () => { console.log('Submitted:', formData); setIsOpen(false); }; return ( <> <ButtonGlass onClick={() => setIsOpen(true)}> Open Modal </ButtonGlass> {/* Confirmation modal */} <ModalGlass.Root open={isOpen} onOpenChange={setIsOpen}> <ModalGlass.Overlay /> <ModalGlass.Content> <ModalGlass.Header> <ModalGlass.Title>Confirm Action</ModalGlass.Title> <ModalGlass.Description> This action cannot be undone. </ModalGlass.Description> <ModalGlass.Close /> </ModalGlass.Header> <ModalGlass.Body> <p>Are you sure you want to proceed with this action?</p> </ModalGlass.Body> <ModalGlass.Footer> <ButtonGlass variant="ghost" onClick={() => setIsOpen(false)}> Cancel </ButtonGlass> <ButtonGlass variant="destructive" onClick={handleSubmit}> Confirm </ButtonGlass> </ModalGlass.Footer> </ModalGlass.Content> </ModalGlass.Root> {/* Form modal with different size */} <ModalGlass.Root open={isOpen} onOpenChange={setIsOpen} size="lg"> <ModalGlass.Overlay /> <ModalGlass.Content> <ModalGlass.Header> <ModalGlass.Title>Create Account</ModalGlass.Title> <ModalGlass.Close /> </ModalGlass.Header> <ModalGlass.Body> <form id="signup-form" onSubmit={handleSubmit} className="space-y-4"> <InputGlass label="Full Name" value={formData.name} onChange={(e) => setFormData({ ...formData, name: e.target.value })} required /> <InputGlass label="Email" type="email" value={formData.email} onChange={(e) => setFormData({ ...formData, email: e.target.value })} required /> </form> </ModalGlass.Body> <ModalGlass.Footer> <ButtonGlass variant="ghost" onClick={() => setIsOpen(false)}> Cancel </ButtonGlass> <ButtonGlass type="submit" form="signup-form" variant="primary"> Sign Up </ButtonGlass> </ModalGlass.Footer> </ModalGlass.Content> </ModalGlass.Root> </> ); } ``` ### TabsGlass with compound API ```tsx import { TabsGlass } from 'shadcn-glass-ui'; import { Home, Search, Settings } from 'lucide-react'; import { useState } from 'react'; function TabsExample() { const [activeTab, setActiveTab] = useState('overview'); return ( <div className="space-y-8"> {/* Basic tabs */} <TabsGlass.Root value={activeTab} onValueChange={setActiveTab}> <TabsGlass.List> <TabsGlass.Trigger value="overview">Overview</TabsGlass.Trigger> <TabsGlass.Trigger value="analytics">Analytics</TabsGlass.Trigger> <TabsGlass.Trigger value="settings">Settings</TabsGlass.Trigger> </TabsGlass.List> <TabsGlass.Content value="overview"> <div className="p-4"> <h2 className="text-xl font-bold">Overview</h2> <p>Dashboard overview content goes here</p> </div> </TabsGlass.Content> <TabsGlass.Content value="analytics"> <div className="p-4"> <h2 className="text-xl font-bold">Analytics</h2> <p>Analytics charts and data</p> </div> </TabsGlass.Content> <TabsGlass.Content value="settings"> <div className="p-4"> <h2 className="text-xl font-bold">Settings</h2> <p>Application settings</p> </div> </TabsGlass.Content> </TabsGlass.Root> {/* Tabs with icons and accessibility labels */} <TabsGlass.Root value={activeTab} onValueChange={setActiveTab}> <TabsGlass.List aria-label="Main navigation"> <TabsGlass.Trigger value="home" aria-label="Home dashboard"> <Home className="w-4 h-4" /> </TabsGlass.Trigger> <TabsGlass.Trigger value="search" aria-label="Search"> <Search className="w-4 h-4" /> </TabsGlass.Trigger> <TabsGlass.Trigger value="settings" aria-label="Settings"> <Settings className="w-4 h-4" /> </TabsGlass.Trigger> </TabsGlass.List> <TabsGlass.Content value="home"> Dashboard content </TabsGlass.Content> <TabsGlass.Content value="search"> Search interface </TabsGlass.Content> <TabsGlass.Content value="settings"> Settings panel </TabsGlass.Content> </TabsGlass.Root> </div> ); } ``` ## Custom Hooks ### useFocus for focus state management (NEW in v2.0.0) ```tsx import { useFocus } from 'shadcn-glass-ui'; function FocusableInput() { const { isFocused, focusProps } = useFocus(); return ( <div> <input {...focusProps} className={isFocused ? 'ring-2 ring-blue-500' : ''} placeholder="Focus me" /> <p>{isFocused ? 'Input is focused' : 'Input is blurred'}</p> </div> ); } // With glow effect callback function GlowInput() { const { isFocused, focusProps } = useFocus({ onFocusChange: (focused) => { if (focused) { console.log('Apply glow effect'); } } }); return ( <input {...focusProps} style={{ boxShadow: isFocused ? '0 0 20px var(--focus-glow)' : 'none', }} /> ); } ``` ### useHover for interactive states ```tsx import { useHover } from 'shadcn-glass-ui'; // Basic hover state function HoverCard() { const { isHovered, hoverProps } = useHover(); return ( <div {...hoverProps} style={{ padding: '16px', background: isHovered ? '#f0f0f0' : '#ffffff', transform: isHovered ? 'scale(1.05)' : 'scale(1)', transition: 'all 0.2s', }} > Hover me </div> ); } // With delays and focus support function TooltipTrigger() { const { isHovered, hoverProps } = useHover({ enterDelay: 300, // Wait 300ms before showing leaveDelay: 100, // Wait 100ms before hiding includeFocus: true, // Also trigger on focus (keyboard accessibility) onHoverChange: (hover) => console.log('Hover state:', hover), }); return ( <div> <button {...hoverProps}> Hover or focus me </button> {isHovered && ( <div className="tooltip"> Tooltip content </div> )} </div> ); } ``` ### useResponsive for breakpoint detection (NEW in v2.0.0) ```tsx import { useResponsive } from 'shadcn-glass-ui'; function ResponsiveComponent() { const { isMobile, isTablet, isDesktop, breakpoint } = useResponsive(); return ( <div> <p>Current breakpoint: {breakpoint}</p> {isMobile && <MobileLayout />} {isTablet && <TabletLayout />} {isDesktop && <DesktopLayout />} </div> ); } // With custom breakpoints function CustomBreakpoints() { const { matches } = useResponsive({ breakpoints: { sm: 640, md: 768, lg: 1024, xl: 1280, } }); return ( <div> {matches.sm && <p>Small screen</p>} {matches.lg && <p>Large screen</p>} </div> ); } ``` ### useWallpaperTint for adaptive theming (NEW in v2.0.0) ```tsx import { useWallpaperTint } from 'shadcn-glass-ui'; function AdaptiveBackground() { const { tint, isDark, isLight } = useWallpaperTint(); return ( <div style={{ background: tint || 'transparent', color: isDark ? 'white' : 'black', }} > <p>Background adapts to wallpaper</p> <p>Detected tint: {tint}</p> </div> ); } // Conditional rendering based on wallpaper function ThemedContent() { const { isDark } = useWallpaperTint(); return isDark ? <DarkThemeContent /> : <LightThemeContent />; } ``` ## Utility Functions and Primitives ### cn() utility for className merging ```tsx import { cn } from 'shadcn-glass-ui'; // Merge conditional classes with Tailwind conflict resolution function Component({ isActive, className }) { return ( <div className={cn( // Base classes 'px-4 py-2 rounded-lg bg-gray-100', // Conditional classes isActive && 'bg-blue-500 text-white', // External classes (last = highest priority) className )} > Content </div> ); } // Complex example with multiple conditions function Button({ variant, size, disabled, className }) { return ( <button className={cn( // Base styles 'font-medium transition-all duration-200', // Variant styles variant === 'primary' && 'bg-blue-500 text-white', variant === 'secondary' && 'bg-gray-200 text-gray-900', // Size styles size === 'sm' && 'px-3 py-1 text-sm', size === 'lg' && 'px-6 py-3 text-lg', // State styles disabled && 'opacity-50 cursor-not-allowed', // Custom overrides className )} > Click me </button> ); } ``` ### FormFieldWrapper primitive ```tsx import { FormFieldWrapper } from 'shadcn-glass-ui'; function CustomFormField() { return ( <FormFieldWrapper label="Email Address" error="Invalid email format" success="Email is valid" required > <input type="email" className="w-full px-4 py-2 rounded-lg" placeholder="you@example.com" /> </FormFieldWrapper> ); } ``` ### InteractiveCard primitive ```tsx import { InteractiveCard } from 'shadcn-glass-ui'; function ProductCard({ product }) { return ( <InteractiveCard onClick={() => console.log('Card clicked')} className="p-6" > <h3>{product.name}</h3> <p>{product.description}</p> <span>${product.price}</span> </InteractiveCard> ); } ``` ### TouchTarget primitive ```tsx import { TouchTarget } from 'shadcn-glass-ui'; function IconButton({ icon: Icon, onClick, label }) { return ( <TouchTarget onClick={onClick} aria-label={label}> <Icon className="w-5 h-5" /> </TouchTarget> ); } ``` ## Data Visualization Components ### SparklineGlass for compact time series (NEW in v2.0.0) ```tsx import { SparklineGlass, InsightCardGlass } from 'shadcn-glass-ui'; function AnalyticsDashboard() { const weeklyData = [120, 132, 101, 134, 90, 230, 210]; const monthlyRevenue = [45000, 52000, 48000, 61000, 55000, 67000]; return ( <div className="space-y-4"> {/* Basic sparkline */} <SparklineGlass data={weeklyData} width={200} height={50} color="var(--semantic-primary)" /> {/* With filled area */} <SparklineGlass data={monthlyRevenue} width={300} height={80} filled={true} color="var(--metric-success-bg)" /> {/* Inside metric card */} <InsightCardGlass title="Weekly Revenue" value="$12,450" change={15.2} trend="up" sparkline={weeklyData} /> </div> ); } ``` ### CircularProgressGlass for percentage displays ```tsx import { CircularProgressGlass } from 'shadcn-glass-ui'; function ProgressIndicators() { return ( <div className="flex gap-4"> {/* Basic circular progress */} <CircularProgressGlass value={75} size={100} /> {/* With custom colors */} <CircularProgressGlass value={85} size={120} color="var(--metric-success-bg)" trackColor="var(--semantic-border)" /> {/* With label */} <CircularProgressGlass value={60} size={150} showLabel={true} label="Complete" /> </div> ); } ``` ## 3-Layer Token System (v2.0.0+) ### Using semantic tokens in components ```css /* ✅ DO: Use semantic tokens for theming */ .my-component { background: var(--semantic-surface); color: var(--semantic-text); border: 1px solid var(--semantic-border); } .my-component:hover { background: var(--semantic-surface-elevated); border-color: var(--semantic-primary); } /* ✅ DO: Use component tokens for specific components */ .my-button { background: var(--btn-primary-bg); color: var(--btn-primary-text); border: 1px solid var(--btn-primary-border); } .my-button:hover { background: var(--btn-primary-bg-hover); box-shadow: var(--btn-primary-glow); } /* ✅ DO: Use primitive tokens for specific effects */ .my-glow-effect { box-shadow: 0 0 20px var(--oklch-purple-500-40); } /* ❌ DON'T: Hardcode OKLCH values */ .my-component { background: oklch(66.6% 0.159 303); /* NEVER do this */ } ``` ### Creating custom themes in 15 minutes ```css /* Example: Creating "neon" theme */ [data-theme='neon'] { /* Layer 2: Define ~15 semantic tokens */ --semantic-primary: var(--oklch-cyan-400); --semantic-surface: var(--oklch-black-90); --semantic-surface-elevated: var(--oklch-slate-900-80); --semantic-text: var(--oklch-white-95); --semantic-text-muted: var(--oklch-slate-400); --semantic-border: var(--oklch-cyan-500-20); --semantic-success: var(--oklch-green-400); --semantic-warning: var(--oklch-amber-400); --semantic-destructive: var(--oklch-red-400); /* Layer 3: Component tokens inherit automatically! */ /* All 296+ component variables work without modification */ } ``` ### Breaking changes from v1.x to v2.0.0 ```css /* ❌ REMOVED in v2.0.0 */ background: var(--metric-emerald-bg); color: var(--metric-amber-text); border: 1px solid var(--metric-blue-border); box-shadow: var(--metric-red-glow); /* ✅ Use in v2.0.0+ */ background: var(--metric-success-bg); color: var(--metric-warning-text); border: 1px solid var(--metric-default-border); box-shadow: var(--metric-destructive-glow); ``` ## Additional Components ### AlertGlass and NotificationGlass ```tsx import { AlertGlass, NotificationGlass } from 'shadcn-glass-ui'; import { AlertTriangle, CheckCircle } from 'lucide-react'; function AlertExamples() { const [notifications, setNotifications] = useState([]); const showNotification = (variant, title, message) => { const id = Date.now(); setNotifications([...notifications, { id, variant, title, message }]); }; return ( <div className="space-y-4"> {/* Alert variants */} <AlertGlass variant="default" title="Information"> This is an informational message. </AlertGlass> <AlertGlass variant="destructive" title="Error" icon={AlertTriangle}> Something went wrong. Please try again. </AlertGlass> <AlertGlass variant="success" title="Success" icon={CheckCircle}> Your changes have been saved successfully. </AlertGlass> <AlertGlass variant="warning" title="Warning"> This action requires your attention. </AlertGlass> {/* Notification toasts */} <div className="fixed top-4 right-4 space-y-2"> {notifications.map((notif) => ( <NotificationGlass key={notif.id} variant={notif.variant} title={notif.title} message={notif.message} onClose={() => setNotifications(notifications.filter(n => n.id !== notif.id))} /> ))} </div> <ButtonGlass onClick={() => showNotification('success', 'Success', 'Operation completed')}> Show Success </ButtonGlass> </div> ); } ``` ### ComboBoxGlass for searchable selects ```tsx import { ComboBoxGlass } from 'shadcn-glass-ui'; function ComboBoxExample() { const [value, setValue] = useState(''); const options = [ { value: 'react', label: 'React' }, { value: 'vue', label: 'Vue' }, { value: 'angular', label: 'Angular' }, { value: 'svelte', label: 'Svelte' }, ]; return ( <ComboBoxGlass options={options} value={value} onChange={setValue} placeholder="Select framework..." searchPlaceholder="Search frameworks..." emptyText="No framework found" /> ); } ``` ### BadgeGlass and TooltipGlass ```tsx import { BadgeGlass, TooltipGlass } from 'shadcn-glass-ui'; function BadgeExamples() { return ( <div className="flex gap-2 flex-wrap"> {/* Badge variants */} <BadgeGlass variant="default">Default</BadgeGlass> <BadgeGlass variant="secondary">Secondary</BadgeGlass> <BadgeGlass variant="destructive">Error</BadgeGlass> <BadgeGlass variant="success">Success</BadgeGlass> <BadgeGlass variant="warning">Warning</BadgeGlass> <BadgeGlass variant="info">Info</BadgeGlass> {/* Badge with tooltip */} <TooltipGlass content="This is a helpful tooltip"> <BadgeGlass variant="info">Hover me</BadgeGlass> </TooltipGlass> {/* Status badge with count */} <BadgeGlass variant="destructive"> Errors: 5 </BadgeGlass> </div> ); } ``` ## Summary shadcn-glass-ui v2.0.0 provides a complete glassmorphism design system with 58 production-ready components, supporting React 18/19 and Tailwind CSS 4. The library excels in accessibility (WCAG 2.1 AA compliance with 1,570+ tests), developer experience (TypeScript strict mode, rich JSDoc), and modern patterns (compound components, polymorphic rendering, 3-layer token architecture). Installation is flexible via npm package or shadcn CLI registry, with automatic dependency resolution and tree-shakeable ESM exports for optimal bundle sizes. The new 3-layer token system enables 90% faster theme creation (2-3 hours → 15 minutes) with zero hardcoded OKLCH values across all themes. Common use cases include building modern dashboard applications with glass-themed UI, creating accessible forms with validation states and keyboard navigation, implementing multi-step wizards with StepperGlass compound components, and developing theme-aware applications with automatic dark/light/aurora mode switching. The library integrates seamlessly with existing shadcn/ui projects, React frameworks (Next.js, Remix, Vite), and AI coding assistants (Claude Code, GitHub Copilot) through comprehensive documentation and type definitions. All components support touch-optimized interactions (44×44px minimum), reduced motion preferences, and screen reader announcements for inclusive user experiences. New in v2.0.0: StepperGlass compound component (3 variants, 2 orientations), 4 exported custom hooks (useFocus, useHover, useResponsive, useWallpaperTint), SparklineGlass for data visualization, and complete token architecture migration.