{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "hover-card-glass", "type": "registry:ui", "title": "Hover Card Glass", "description": "Hover-triggered floating glass-themed container for rich content previews.\n * Unlike PopoverGlass (click-triggered), HoverCardGlass opens on hover after a configurable delay.\n *\n * ## Features", "dependencies": [ "@radix-ui/react-hover-card", "react", "shadcn-glass-ui" ], "registryDependencies": [ "cn" ], "files": [ { "path": "components/glass/ui/hover-card-glass.tsx", "type": "registry:component", "content": "/**\n * HoverCardGlass Component\n *\n * Hover-triggered floating glass-themed container for rich content previews.\n * Unlike PopoverGlass (click-triggered), HoverCardGlass opens on hover after a configurable delay.\n *\n * ## Features\n * - Hover-triggered (vs click for PopoverGlass)\n * - Configurable delays: openDelay (200ms) and closeDelay (100ms)\n * - Arrow pointer with glass styling (shown by default)\n * - 12 positioning options: 4 sides × 3 alignments\n * - Fade animations with slide-in effects\n * - Portal rendering (always in document.body)\n * - Compound component API (recommended)\n * - Legacy API for backward compatibility\n * - Theme-aware glass styling via CSS variables\n * - 100% shadcn/ui compatible API\n *\n * ## Sub-Components\n * - **HoverCardGlass / HoverCard**: Root component with delay configuration\n * - **HoverCardGlassTrigger / HoverCardTrigger**: Element that triggers hover (supports asChild)\n * - **HoverCardGlassContent / HoverCardContent**: Content container with glass styling and arrow\n *\n * ## CSS Variables\n * Customize appearance via theme CSS variables:\n * - `--hovercard-bg`: Card background color (glass effect)\n * - `--hovercard-border`: Card border color\n * - `--hovercard-shadow`: Card shadow/glow effect\n * - `--hovercard-arrow-bg`: Arrow pointer background color\n *\n * @example User preview card\n * ```tsx\n * import { HoverCardGlass, HoverCardGlassTrigger, HoverCardGlassContent } from 'shadcn-glass-ui'\n *\n * function UserPreview() {\n * return (\n * \n * \n * @shadcn\n * \n * \n *
\n * \n *
\n *

shadcn

\n *

Creator of shadcn/ui

\n *
\n *
\n *
\n *
\n * )\n * }\n * ```\n *\n * @example Link preview with metadata\n * ```tsx\n * \n * \n * GitHub\n * \n * \n *

GitHub

\n *

Where developers shape the future of software

\n *
\n *
\n * ```\n *\n * @example Rich tooltip with image\n * ```tsx\n * \n * \n * \n * \n * \n * \"Preview\"\n *

Product Details

\n *

Full description here...

\n *
\n *
\n * ```\n *\n * @example Custom delays configuration\n * ```tsx\n * \n * \n * Slow to open, fast to close\n * \n * \n *

Content with custom timing

\n *
\n *
\n * ```\n *\n * @accessibility\n * - Built on Radix UI HoverCard with full WCAG 2.1 AA compliance\n * - Keyboard: Not keyboard-navigable (hover-only), use TooltipGlass or PopoverGlass for keyboard access\n * - Screen Readers: Content announced when hovered\n * - Focus Management: Does not steal focus from trigger element\n * - Motion: Respects prefers-reduced-motion when configured\n *\n * @since v1.0.0\n */\n\n'use client';\n\nimport * as React from 'react';\nimport * as HoverCardPrimitive from '@radix-ui/react-hover-card';\nimport { cn } from '@/lib/utils';\nimport '@/glass-theme.css';\n\n// ========================================\n// COMPOUND COMPONENT: ROOT\n// ========================================\n\n/**\n * Props for HoverCardGlass root component.\n *\n * @example\n * ```tsx\n * const props: HoverCardGlassRootProps = {\n * openDelay: 300,\n * closeDelay: 100,\n * open: true,\n * onOpenChange: (open) => console.log(open),\n * };\n * ```\n */\ninterface HoverCardGlassRootProps extends React.ComponentPropsWithoutRef<\n typeof HoverCardPrimitive.Root\n> {\n /**\n * Delay in milliseconds before the hover card opens.\n *\n * @default 200\n * @example\n * ```tsx\n * ...\n * ```\n */\n openDelay?: number;\n\n /**\n * Delay in milliseconds before the hover card closes.\n *\n * @default 100\n * @example\n * ```tsx\n * ...\n * ```\n */\n closeDelay?: number;\n}\n\nconst HoverCardGlassRoot = ({\n openDelay = 200,\n closeDelay = 100,\n ...props\n}: HoverCardGlassRootProps) => (\n \n);\nHoverCardGlassRoot.displayName = 'HoverCardGlass';\n\n// ========================================\n// COMPOUND COMPONENT: TRIGGER\n// ========================================\n\nconst HoverCardGlassTrigger = React.forwardRef<\n React.ComponentRef,\n React.ComponentPropsWithoutRef\n>((props, ref) => (\n \n));\nHoverCardGlassTrigger.displayName = 'HoverCardGlassTrigger';\n\n// ========================================\n// COMPOUND COMPONENT: CONTENT\n// ========================================\n\n/**\n * Props for HoverCardGlassContent component.\n *\n * @example\n * ```tsx\n * const props: HoverCardGlassContentProps = {\n * side: 'bottom',\n * align: 'start',\n * sideOffset: 8,\n * showArrow: true,\n * };\n * ```\n */\ninterface HoverCardGlassContentProps extends React.ComponentPropsWithoutRef<\n typeof HoverCardPrimitive.Content\n> {\n /**\n * Whether to show the arrow pointer.\n *\n * @default true\n * @example\n * ```tsx\n * ...\n * ```\n */\n showArrow?: boolean;\n}\n\n/**\n * HoverCardGlassContent - Content container for HoverCardGlass\n *\n * Defaults (matches shadcn/ui):\n * - `p-4` (16px padding)\n * - `w-80` (320px width)\n * - Both can be overridden via className prop\n *\n * @example\n * \n *

Content

\n *
\n */\nconst HoverCardGlassContent = React.forwardRef<\n React.ElementRef,\n HoverCardGlassContentProps\n>(({ className, align = 'center', sideOffset = 8, showArrow = true, children, ...props }, ref) => {\n // HoverCard content styles with CSS variables\n const hoverCardStyles: React.CSSProperties = {\n background: 'var(--hovercard-bg)',\n border: '1px solid var(--hovercard-border)',\n boxShadow: 'var(--hovercard-shadow)',\n backdropFilter: 'blur(var(--blur-md))',\n WebkitBackdropFilter: 'blur(var(--blur-md))',\n };\n\n // Arrow styles\n const arrowStyles: React.CSSProperties = {\n fill: 'var(--hovercard-arrow-bg)',\n };\n\n return (\n \n \n {children}\n\n {showArrow && (\n \n )}\n \n \n );\n});\n\nHoverCardGlassContent.displayName = 'HoverCardGlassContent';\n\n// ========================================\n// LEGACY API (backward compatible)\n// ========================================\n\n/**\n * Props for HoverCardGlassLegacy component (backward compatible API).\n *\n * @example\n * ```tsx\n * const props: HoverCardGlassLegacyProps = {\n * trigger: Hover me,\n * children:
Content
,\n * side: 'bottom',\n * align: 'center',\n * openDelay: 200,\n * };\n * ```\n */\nexport interface HoverCardGlassLegacyProps {\n /**\n * The trigger element that opens the hover card on hover.\n *\n * @example\n * ```tsx\n * Hover}>...\n * ```\n */\n readonly trigger: React.ReactNode;\n\n /**\n * The content to display inside the hover card.\n */\n readonly children: React.ReactNode;\n\n /**\n * The preferred side of the trigger to render against.\n *\n * @default 'bottom'\n * @example\n * ```tsx\n * ...\n * ```\n */\n readonly side?: 'top' | 'right' | 'bottom' | 'left';\n\n /**\n * The preferred alignment against the trigger.\n *\n * @default 'center'\n * @example\n * ```tsx\n * ...\n * ```\n */\n readonly align?: 'start' | 'center' | 'end';\n\n /**\n * The distance in pixels from the trigger.\n *\n * @default 8\n * @example\n * ```tsx\n * ...\n * ```\n */\n readonly sideOffset?: number;\n\n /**\n * Delay in milliseconds before opening.\n *\n * @default 200\n * @example\n * ```tsx\n * ...\n * ```\n */\n readonly openDelay?: number;\n\n /**\n * Delay in milliseconds before closing.\n *\n * @default 100\n * @example\n * ```tsx\n * ...\n * ```\n */\n readonly closeDelay?: number;\n\n /**\n * Controlled open state.\n *\n * @default undefined\n * @example\n * ```tsx\n * ...\n * ```\n */\n readonly open?: boolean;\n\n /**\n * Callback when open state changes.\n *\n * @example\n * ```tsx\n * console.log(open)}>...\n * ```\n */\n readonly onOpenChange?: (open: boolean) => void;\n\n /**\n * Whether to show the arrow pointer.\n *\n * @default true\n * @example\n * ```tsx\n * ...\n * ```\n */\n readonly showArrow?: boolean;\n\n /**\n * Additional class name for the content wrapper.\n *\n * @example\n * ```tsx\n * ...\n * ```\n */\n readonly className?: string;\n}\n\nconst HoverCardGlassLegacy = React.forwardRef(\n (\n {\n trigger,\n children,\n side = 'bottom',\n align = 'center',\n sideOffset = 8,\n openDelay = 200,\n closeDelay = 100,\n open,\n onOpenChange,\n showArrow = true,\n className,\n },\n ref\n ) => {\n return (\n \n {trigger}\n \n {children}\n \n \n );\n }\n);\n\nHoverCardGlassLegacy.displayName = 'HoverCardGlassLegacy';\n\n// ========================================\n// EXPORTS\n// ========================================\n\n// Compound API (shadcn/ui pattern)\nexport const HoverCardGlass = HoverCardGlassRoot;\nexport { HoverCardGlassTrigger, HoverCardGlassContent };\n\n// Legacy API (backward compatible)\nexport { HoverCardGlassLegacy };\n\n// shadcn/ui compatible aliases\nexport {\n HoverCardGlassRoot as HoverCard,\n HoverCardGlassTrigger as HoverCardTrigger,\n HoverCardGlassContent as HoverCardContent,\n};\n\n// Type exports\nexport type { HoverCardGlassRootProps, HoverCardGlassContentProps };\n" } ], "categories": [ "ui" ], "cssVars": { "light": { "--glass-bg": "rgba(255, 255, 255, 0.1)", "--glass-border": "rgba(255, 255, 255, 0.2)", "--blur-sm": "8px", "--blur-md": "16px", "--blur-lg": "24px" }, "dark": { "--glass-bg": "rgba(255, 255, 255, 0.05)", "--glass-border": "rgba(255, 255, 255, 0.1)", "--blur-sm": "8px", "--blur-md": "16px", "--blur-lg": "24px" } } }