shadcn-glass-ui 2.3.2 → 2.4.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.
@@ -3,7 +3,7 @@
3
3
  "name": "progress-glass",
4
4
  "type": "registry:component",
5
5
  "title": "Progress Glass",
6
- "description": "Glass-themed progress bar with:",
6
+ "description": "Glass-themed progress bar with enhanced features beyond shadcn/ui Progress.\n *\n * ## shadcn/ui Compatibility\n *\n * This component is **backward compatible** with shadcn/ui Progress:",
7
7
  "dependencies": [
8
8
  "class-variance-authority",
9
9
  "react"
@@ -16,7 +16,7 @@
16
16
  {
17
17
  "path": "components/glass/specialized/progress-glass.tsx",
18
18
  "type": "registry:component",
19
- "content": "/**\n * ProgressGlass Component\n *\n * Glass-themed progress bar with:\n * - Theme-aware styling (glass/light/aurora)\n * - Gradient fill with glow\n * - Size variants\n * - Optional label\n */\n\nimport { forwardRef, type CSSProperties } from 'react';\nimport { type VariantProps } from 'class-variance-authority';\nimport { cn } from '@/lib/utils';\nimport { progressSizes, type ProgressGradient } from '@/lib/variants/progress-glass-variants';\nimport '@/glass-theme.css';\n\n// ========================================\n// PROPS INTERFACE\n// ========================================\n\nexport interface ProgressGlassProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'style'>, VariantProps<typeof progressSizes> {\n readonly value: number;\n readonly gradient?: ProgressGradient;\n readonly showLabel?: boolean;\n}\n\n// ========================================\n// COMPONENT\n// ========================================\n\n// Map gradient to existing metric color variables\nconst getGradientColor = (\n gradient: ProgressGradient = 'violet'\n): { colorVar: string; glowVar: string } => {\n const gradients: Record<ProgressGradient, { colorVar: string; glowVar: string }> = {\n violet: { colorVar: '--metric-default-text', glowVar: '--progress-glow-violet' }, // Uses blue metric color\n blue: { colorVar: '--metric-default-text', glowVar: '--progress-glow-blue' },\n cyan: { colorVar: '--metric-secondary-text', glowVar: '--progress-glow-cyan' },\n amber: { colorVar: '--metric-warning-text', glowVar: '--progress-glow-amber' },\n emerald: { colorVar: '--metric-success-text', glowVar: '--progress-glow-emerald' },\n rose: { colorVar: '--metric-destructive-text', glowVar: '--progress-glow-rose' },\n };\n return gradients[gradient] || gradients.violet;\n};\n\nexport const ProgressGlass = forwardRef<HTMLDivElement, ProgressGlassProps>(\n ({ className, size = 'md', value = 0, gradient = 'violet', showLabel, ...props }, ref) => {\n const clampedValue = Math.min(100, Math.max(0, value));\n const { colorVar, glowVar } = getGradientColor(gradient);\n\n const trackStyles: CSSProperties = {\n background: 'var(--progress-bg)',\n };\n\n const fillStyles: CSSProperties = {\n width: `${clampedValue}%`,\n background: `var(${colorVar})`,\n boxShadow: `var(${glowVar})`,\n };\n\n return (\n <div ref={ref} data-slot=\"progress\" className={cn('w-full', className)} {...props}>\n {showLabel && (\n <div className=\"flex justify-between mb-1 md:mb-1.5\">\n <span className=\"text-(length:--font-size-2xs) md:text-xs text-(--text-muted)\">\n Progress\n </span>\n <span className=\"text-(length:--font-size-2xs) md:text-xs font-medium text-(--text-secondary)\">\n {clampedValue}%\n </span>\n </div>\n )}\n <div className={cn(progressSizes({ size }))} style={trackStyles}>\n <div\n data-slot=\"progress-indicator\"\n className=\"h-full rounded-full transition-all duration-700 ease-out\"\n style={fillStyles}\n role=\"progressbar\"\n aria-valuenow={clampedValue}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-label={`Progress: ${clampedValue}%`}\n />\n </div>\n </div>\n );\n }\n);\n\nProgressGlass.displayName = 'ProgressGlass';\n"
19
+ "content": "/**\n * ProgressGlass Component\n *\n * Glass-themed progress bar with enhanced features beyond shadcn/ui Progress.\n *\n * ## shadcn/ui Compatibility\n *\n * This component is **backward compatible** with shadcn/ui Progress:\n * - The `value` prop works identically\n * - Extra props (`size`, `gradient`, `showLabel`) have sensible defaults\n * - Drop-in replacement: `<Progress value={50} />` → `<ProgressGlass value={50} />`\n *\n * @example Drop-in replacement from shadcn/ui\n * ```tsx\n * // shadcn/ui\n * <Progress value={50} />\n *\n * // ProgressGlass (identical behavior)\n * <ProgressGlass value={50} />\n * ```\n *\n * @example Enhanced features (not in shadcn/ui)\n * ```tsx\n * <ProgressGlass\n * value={75}\n * size=\"lg\" // 'sm' | 'md' | 'lg' | 'xl' (default: 'md')\n * gradient=\"emerald\" // 'violet' | 'blue' | 'cyan' | 'amber' | 'emerald' | 'rose' (default: 'violet')\n * showLabel // Show percentage label (default: false)\n * />\n * ```\n *\n * ## Features\n * - Theme-aware styling (glass/light/aurora)\n * - Gradient fill with glow effects\n * - Responsive size variants\n * - Optional percentage label\n *\n * @accessibility\n * - role=\"progressbar\" with aria-valuenow, aria-valuemin, aria-valuemax\n */\n\nimport { forwardRef, type CSSProperties } from 'react';\nimport { type VariantProps } from 'class-variance-authority';\nimport { cn } from '@/lib/utils';\nimport { progressSizes, type ProgressGradient } from '@/lib/variants/progress-glass-variants';\nimport '@/glass-theme.css';\n\n// ========================================\n// PROPS INTERFACE\n// ========================================\n\nexport interface ProgressGlassProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'style'>, VariantProps<typeof progressSizes> {\n readonly value: number;\n readonly gradient?: ProgressGradient;\n readonly showLabel?: boolean;\n}\n\n// ========================================\n// COMPONENT\n// ========================================\n\n// Map gradient to existing metric color variables\nconst getGradientColor = (\n gradient: ProgressGradient = 'violet'\n): { colorVar: string; glowVar: string } => {\n const gradients: Record<ProgressGradient, { colorVar: string; glowVar: string }> = {\n violet: { colorVar: '--metric-default-text', glowVar: '--progress-glow-violet' }, // Uses blue metric color\n blue: { colorVar: '--metric-default-text', glowVar: '--progress-glow-blue' },\n cyan: { colorVar: '--metric-secondary-text', glowVar: '--progress-glow-cyan' },\n amber: { colorVar: '--metric-warning-text', glowVar: '--progress-glow-amber' },\n emerald: { colorVar: '--metric-success-text', glowVar: '--progress-glow-emerald' },\n rose: { colorVar: '--metric-destructive-text', glowVar: '--progress-glow-rose' },\n };\n return gradients[gradient] || gradients.violet;\n};\n\nexport const ProgressGlass = forwardRef<HTMLDivElement, ProgressGlassProps>(\n ({ className, size = 'md', value = 0, gradient = 'violet', showLabel, ...props }, ref) => {\n const clampedValue = Math.min(100, Math.max(0, value));\n const { colorVar, glowVar } = getGradientColor(gradient);\n\n const trackStyles: CSSProperties = {\n background: 'var(--progress-bg)',\n };\n\n const fillStyles: CSSProperties = {\n width: `${clampedValue}%`,\n background: `var(${colorVar})`,\n boxShadow: `var(${glowVar})`,\n };\n\n return (\n <div ref={ref} data-slot=\"progress\" className={cn('w-full', className)} {...props}>\n {showLabel && (\n <div className=\"flex justify-between mb-1 md:mb-1.5\">\n <span className=\"text-(length:--font-size-2xs) md:text-xs text-(--text-muted)\">\n Progress\n </span>\n <span className=\"text-(length:--font-size-2xs) md:text-xs font-medium text-(--text-secondary)\">\n {clampedValue}%\n </span>\n </div>\n )}\n <div className={cn(progressSizes({ size }))} style={trackStyles}>\n <div\n data-slot=\"progress-indicator\"\n className=\"h-full rounded-full transition-all duration-700 ease-out\"\n style={fillStyles}\n role=\"progressbar\"\n aria-valuenow={clampedValue}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-label={`Progress: ${clampedValue}%`}\n />\n </div>\n </div>\n );\n }\n);\n\nProgressGlass.displayName = 'ProgressGlass';\n"
20
20
  }
21
21
  ],
22
22
  "categories": [
@@ -39,6 +39,12 @@
39
39
  "title": "Skeleton Glass",
40
40
  "description": "Glass-themed loading skeleton with:"
41
41
  },
42
+ {
43
+ "name": "sheet-glass",
44
+ "type": "registry:ui",
45
+ "title": "Sheet Glass",
46
+ "description": "SheetGlass Component (Radix UI Dialog-based)"
47
+ },
42
48
  {
43
49
  "name": "popover-glass",
44
50
  "type": "registry:ui",
@@ -157,7 +163,7 @@
157
163
  "name": "progress-glass",
158
164
  "type": "registry:component",
159
165
  "title": "Progress Glass",
160
- "description": "Glass-themed progress bar with:"
166
+ "description": "Glass-themed progress bar with enhanced features beyond shadcn/ui Progress.\n *\n * ## shadcn/ui Compatibility\n *\n * This component is **backward compatible** with shadcn/ui Progress:"
161
167
  },
162
168
  {
163
169
  "name": "profile-avatar-glass",
@@ -0,0 +1,44 @@
1
+ {
2
+ "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
+ "name": "sheet-glass",
4
+ "type": "registry:ui",
5
+ "title": "Sheet Glass",
6
+ "description": "SheetGlass Component (Radix UI Dialog-based)",
7
+ "dependencies": [
8
+ "@radix-ui/react-dialog",
9
+ "lucide-react",
10
+ "react",
11
+ "shadcn-glass-ui"
12
+ ],
13
+ "registryDependencies": [
14
+ "cn",
15
+ "primitives",
16
+ "variants"
17
+ ],
18
+ "files": [
19
+ {
20
+ "path": "components/glass/ui/sheet-glass.tsx",
21
+ "type": "registry:component",
22
+ "content": "/* eslint-disable react-refresh/only-export-components */\n/**\n * SheetGlass Component (Radix UI Dialog-based)\n *\n * Glass-themed sheet/drawer with full shadcn/ui Sheet API compatibility.\n * Built on @radix-ui/react-dialog for accessibility and state management.\n *\n * @example Basic usage\n * ```tsx\n * <SheetGlass.Root>\n * <SheetGlass.Trigger asChild>\n * <ButtonGlass>Open Sheet</ButtonGlass>\n * </SheetGlass.Trigger>\n * <SheetGlass.Content side=\"right\">\n * <SheetGlass.Header>\n * <SheetGlass.Title>Sheet Title</SheetGlass.Title>\n * <SheetGlass.Description>Description</SheetGlass.Description>\n * </SheetGlass.Header>\n * <p>Content here</p>\n * <SheetGlass.Footer>\n * <SheetGlass.Close asChild>\n * <ButtonGlass variant=\"ghost\">Cancel</ButtonGlass>\n * </SheetGlass.Close>\n * </SheetGlass.Footer>\n * </SheetGlass.Content>\n * </SheetGlass.Root>\n * ```\n *\n * @example shadcn/ui compatible imports\n * ```tsx\n * import { Sheet, SheetContent, SheetTrigger, SheetHeader, SheetTitle } from 'shadcn-glass-ui'\n *\n * <Sheet>\n * <SheetTrigger asChild>\n * <Button>Open</Button>\n * </SheetTrigger>\n * <SheetContent side=\"left\">\n * <SheetHeader>\n * <SheetTitle>Navigation</SheetTitle>\n * </SheetHeader>\n * <nav>...</nav>\n * </SheetContent>\n * </Sheet>\n * ```\n *\n * @accessibility\n * - Built on Radix UI Dialog with full WCAG 2.1 AA compliance\n * - Keyboard: Escape to close, Tab for focus trap\n * - Screen Readers: role=\"dialog\", aria-modal, aria-labelledby, aria-describedby\n * - Focus Management: Auto-focus on open, return focus on close\n *\n * @since v2.4.0 - Initial implementation for shadcn/ui API compatibility\n */\n\nimport * as React from 'react';\nimport * as DialogPrimitive from '@radix-ui/react-dialog';\nimport { X } from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport { sheetVariants, type SheetSide } from '@/lib/variants/sheet-glass-variants';\nimport { ICON_SIZES } from '@/components/glass/primitives';\nimport '@/glass-theme.css';\n\n// ========================================\n// COMPOUND COMPONENT: ROOT\n// ========================================\n\n/**\n * SheetGlass.Root - Sheet root component\n *\n * Supports both controlled (open/onOpenChange) and uncontrolled (with Trigger) modes.\n */\nfunction SheetRoot({ ...props }: React.ComponentProps<typeof DialogPrimitive.Root>) {\n return <DialogPrimitive.Root data-slot=\"sheet\" {...props} />;\n}\n\n// ========================================\n// COMPOUND COMPONENT: TRIGGER\n// ========================================\n\n/**\n * SheetGlass.Trigger - Opens the sheet when clicked\n *\n * Use `asChild` to render as the child element instead of a button.\n */\nfunction SheetTrigger({ ...props }: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n return <DialogPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />;\n}\n\n// ========================================\n// COMPOUND COMPONENT: PORTAL\n// ========================================\n\n/**\n * SheetGlass.Portal - Renders children into a portal\n */\nfunction SheetPortal({ ...props }: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n return <DialogPrimitive.Portal data-slot=\"sheet-portal\" {...props} />;\n}\n\n// ========================================\n// COMPOUND COMPONENT: OVERLAY\n// ========================================\n\n/**\n * SheetGlass.Overlay - Backdrop with glass blur effect\n */\nconst SheetOverlay = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Overlay\n ref={ref}\n data-slot=\"sheet-overlay\"\n className={cn(\n 'fixed inset-0 z-50',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n className\n )}\n style={{\n background: 'var(--modal-overlay)',\n backdropFilter: 'blur(var(--blur-sm))',\n WebkitBackdropFilter: 'blur(var(--blur-sm))',\n }}\n {...props}\n />\n));\nSheetOverlay.displayName = 'SheetOverlay';\n\n// ========================================\n// COMPOUND COMPONENT: CONTENT\n// ========================================\n\ninterface SheetContentProps extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> {\n /** Side from which the sheet slides in */\n side?: SheetSide;\n /** Show close button in top-right corner */\n showCloseButton?: boolean;\n}\n\n/**\n * SheetGlass.Content - Main sheet container with glass styling\n *\n * Automatically renders Portal and Overlay.\n *\n * @param side - Direction to slide in from: 'top' | 'right' | 'bottom' | 'left' (default: 'right')\n * @param showCloseButton - Show X button in corner (default: true)\n */\nconst SheetContent = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Content>,\n SheetContentProps\n>(({ className, children, side = 'right', showCloseButton = true, ...props }, ref) => (\n <SheetPortal>\n <SheetOverlay />\n <DialogPrimitive.Content\n ref={ref}\n data-slot=\"sheet-content\"\n data-side={side}\n className={cn(sheetVariants({ side }), className)}\n style={{\n background: 'var(--modal-bg)',\n border: '1px solid var(--modal-border)',\n boxShadow: 'var(--modal-glow)',\n backdropFilter: 'blur(var(--blur-lg))',\n WebkitBackdropFilter: 'blur(var(--blur-lg))',\n }}\n {...props}\n >\n {/* Glow effect layer */}\n <div\n className=\"absolute inset-0 pointer-events-none\"\n style={{\n background: 'var(--modal-glow-effect)',\n borderRadius: 'inherit',\n }}\n aria-hidden=\"true\"\n />\n {/* Content */}\n <div className=\"relative flex-1 flex flex-col overflow-auto\">{children}</div>\n {/* Close button */}\n {showCloseButton && (\n <DialogPrimitive.Close\n data-slot=\"sheet-close\"\n className={cn(\n 'absolute top-4 right-4',\n 'p-1.5 md:p-2 rounded-xl',\n 'transition-all duration-300',\n 'ring-offset-background',\n 'focus:outline-none focus:ring-2 focus:ring-(--semantic-primary) focus:ring-offset-2',\n 'hover:opacity-100 opacity-70',\n 'disabled:pointer-events-none'\n )}\n style={{\n background: 'var(--modal-close-btn-bg)',\n border: 'var(--modal-close-btn-border)',\n color: 'var(--text-muted)',\n }}\n >\n <X className={ICON_SIZES.md} />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Content>\n </SheetPortal>\n));\nSheetContent.displayName = 'SheetContent';\n\n// ========================================\n// COMPOUND COMPONENT: HEADER\n// ========================================\n\n/**\n * SheetGlass.Header - Header section with flex layout\n */\nfunction SheetHeader({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn('flex flex-col gap-2 text-center sm:text-left', className)}\n {...props}\n />\n );\n}\n\n// ========================================\n// COMPOUND COMPONENT: FOOTER\n// ========================================\n\n/**\n * SheetGlass.Footer - Footer section with flex layout for actions\n */\nfunction SheetFooter({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sheet-footer\"\n className={cn(\n 'flex flex-col-reverse gap-2 sm:flex-row sm:justify-end mt-auto pt-4',\n className\n )}\n {...props}\n />\n );\n}\n\n// ========================================\n// COMPOUND COMPONENT: TITLE\n// ========================================\n\n/**\n * SheetGlass.Title - Sheet title with proper accessibility\n */\nconst SheetTitle = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Title\n ref={ref}\n data-slot=\"sheet-title\"\n className={cn('text-lg md:text-xl font-semibold leading-none tracking-tight', className)}\n style={{ color: 'var(--text-primary)' }}\n {...props}\n />\n));\nSheetTitle.displayName = 'SheetTitle';\n\n// ========================================\n// COMPOUND COMPONENT: DESCRIPTION\n// ========================================\n\n/**\n * SheetGlass.Description - Sheet description text\n */\nconst SheetDescription = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Description\n ref={ref}\n data-slot=\"sheet-description\"\n className={cn('text-sm', className)}\n style={{ color: 'var(--text-muted)' }}\n {...props}\n />\n));\nSheetDescription.displayName = 'SheetDescription';\n\n// ========================================\n// COMPOUND COMPONENT: CLOSE\n// ========================================\n\n/**\n * SheetGlass.Close - Closes the sheet when clicked\n *\n * Use `asChild` to render as the child element.\n *\n * @example\n * ```tsx\n * <SheetGlass.Close asChild>\n * <ButtonGlass variant=\"ghost\">Cancel</ButtonGlass>\n * </SheetGlass.Close>\n * ```\n */\nfunction SheetClose({ ...props }: React.ComponentProps<typeof DialogPrimitive.Close>) {\n return <DialogPrimitive.Close data-slot=\"sheet-close\" {...props} />;\n}\n\n// ========================================\n// EXPORT COMPOUND COMPONENT\n// ========================================\n\n/**\n * SheetGlass - Glass-themed Sheet with shadcn/ui API compatibility\n *\n * Built on @radix-ui/react-dialog for full accessibility support.\n *\n * @example Compound component pattern\n * ```tsx\n * <SheetGlass.Root>\n * <SheetGlass.Trigger asChild>\n * <ButtonGlass>Open</ButtonGlass>\n * </SheetGlass.Trigger>\n * <SheetGlass.Content side=\"right\">\n * <SheetGlass.Header>\n * <SheetGlass.Title>Title</SheetGlass.Title>\n * </SheetGlass.Header>\n * <p>Content</p>\n * <SheetGlass.Footer>\n * <SheetGlass.Close asChild>\n * <ButtonGlass>Close</ButtonGlass>\n * </SheetGlass.Close>\n * </SheetGlass.Footer>\n * </SheetGlass.Content>\n * </SheetGlass.Root>\n * ```\n */\nexport const SheetGlass = {\n Root: SheetRoot,\n Trigger: SheetTrigger,\n Portal: SheetPortal,\n Overlay: SheetOverlay,\n Content: SheetContent,\n Header: SheetHeader,\n Footer: SheetFooter,\n Title: SheetTitle,\n Description: SheetDescription,\n Close: SheetClose,\n};\n\n// Named exports for direct imports\nexport {\n SheetRoot,\n SheetTrigger,\n SheetPortal,\n SheetOverlay,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n SheetClose,\n};\n\n// ========================================\n// SHADCN/UI COMPATIBLE ALIASES\n// ========================================\n\n/**\n * Sheet - shadcn/ui compatible alias for SheetGlass.Root\n */\nexport const Sheet = SheetRoot;\n\nexport type { SheetContentProps, SheetSide };\n"
23
+ }
24
+ ],
25
+ "categories": [
26
+ "ui"
27
+ ],
28
+ "cssVars": {
29
+ "light": {
30
+ "--glass-bg": "rgba(255, 255, 255, 0.1)",
31
+ "--glass-border": "rgba(255, 255, 255, 0.2)",
32
+ "--blur-sm": "8px",
33
+ "--blur-md": "16px",
34
+ "--blur-lg": "24px"
35
+ },
36
+ "dark": {
37
+ "--glass-bg": "rgba(255, 255, 255, 0.05)",
38
+ "--glass-border": "rgba(255, 255, 255, 0.1)",
39
+ "--blur-sm": "8px",
40
+ "--blur-md": "16px",
41
+ "--blur-lg": "24px"
42
+ }
43
+ }
44
+ }