shadcn-glass-ui 1.0.9 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/components.cjs +4 -4
  2. package/dist/components.js +1 -1
  3. package/dist/hooks.cjs +2 -2
  4. package/dist/index.cjs +5 -5
  5. package/dist/index.js +1 -1
  6. package/dist/r/alert-glass.json +1 -1
  7. package/dist/r/badge-glass.json +1 -1
  8. package/dist/r/button-glass.json +1 -1
  9. package/dist/r/checkbox-glass.json +1 -1
  10. package/dist/r/dropdown-glass.json +1 -1
  11. package/dist/r/glass-card.json +1 -1
  12. package/dist/r/input-glass.json +1 -1
  13. package/dist/r/language-bar-glass.json +1 -1
  14. package/dist/r/modal-glass.json +1 -1
  15. package/dist/r/progress-glass.json +1 -1
  16. package/dist/r/registry.json +0 -2
  17. package/dist/r/segmented-control-glass.json +1 -1
  18. package/dist/r/tabs-glass.json +1 -1
  19. package/dist/r/tooltip-glass.json +1 -1
  20. package/dist/shadcn-glass-ui.css +1 -1
  21. package/dist/{theme-context-BcTQdqsj.cjs → theme-context-XtasSxRT.cjs} +2 -2
  22. package/dist/{theme-context-BcTQdqsj.cjs.map → theme-context-XtasSxRT.cjs.map} +1 -1
  23. package/dist/themes.cjs +1 -1
  24. package/dist/{trust-score-card-glass-Dq28n8en.cjs → trust-score-card-glass-CNcQveNY.cjs} +19 -15
  25. package/dist/{trust-score-card-glass-Dq28n8en.cjs.map → trust-score-card-glass-CNcQveNY.cjs.map} +1 -1
  26. package/dist/{trust-score-card-glass-CHzWGuko.js → trust-score-card-glass-CowcDyxH.js} +16 -12
  27. package/dist/{trust-score-card-glass-CHzWGuko.js.map → trust-score-card-glass-CowcDyxH.js.map} +1 -1
  28. package/dist/{use-focus-CH8KNgcY.cjs → use-focus-BbpE2qGq.cjs} +2 -2
  29. package/dist/{use-focus-CH8KNgcY.cjs.map → use-focus-BbpE2qGq.cjs.map} +1 -1
  30. package/dist/{use-wallpaper-tint-DNecAf46.cjs → use-wallpaper-tint-CIqtoETa.cjs} +2 -2
  31. package/dist/{use-wallpaper-tint-DNecAf46.cjs.map → use-wallpaper-tint-CIqtoETa.cjs.map} +1 -1
  32. package/dist/{utils-3cDWhVvH.cjs → utils-CriE74ig.cjs} +2 -2
  33. package/dist/{utils-3cDWhVvH.cjs.map → utils-CriE74ig.cjs.map} +1 -1
  34. package/dist/utils.cjs +1 -1
  35. package/package.json +1 -1
@@ -13,7 +13,7 @@
13
13
  {
14
14
  "path": "components/glass/ui/tabs-glass.tsx",
15
15
  "type": "registry:component",
16
- "content": "/* eslint-disable react-refresh/only-export-components */\n/**\n * TabsGlass Component (Compound API only)\n *\n * Glass-themed tab navigation with:\n * - Theme-aware styling (glass/light/aurora)\n * - Active tab indicator\n * - Smooth transitions\n * - Compound component API for advanced composition\n *\n * @example\n * ```tsx\n * <TabsGlass.Root value={activeTab} onValueChange={setActiveTab}>\n * <TabsGlass.List>\n * <TabsGlass.Trigger value=\"overview\">Overview</TabsGlass.Trigger>\n * <TabsGlass.Trigger value=\"analytics\">Analytics</TabsGlass.Trigger>\n * <TabsGlass.Trigger value=\"settings\">Settings</TabsGlass.Trigger>\n * </TabsGlass.List>\n * <TabsGlass.Content value=\"overview\">\n * Overview content\n * </TabsGlass.Content>\n * <TabsGlass.Content value=\"analytics\">\n * Analytics content\n * </TabsGlass.Content>\n * <TabsGlass.Content value=\"settings\">\n * Settings content\n * </TabsGlass.Content>\n * </TabsGlass.Root>\n * ```\n *\n * @since v1.0.0 - Legacy API removed (tabs/activeTab/onChange props)\n */\n\nimport {\n forwardRef,\n createContext,\n useContext,\n type CSSProperties,\n type FC,\n type ReactNode,\n} from 'react';\nimport { cn } from '@/lib/utils';\nimport { useFocus } from '@/lib/hooks/use-focus';\nimport '@/glass-theme.css';\n\n// ========================================\n// TYPES\n// ========================================\n\nexport interface TabItem {\n readonly id: string;\n readonly label: string;\n}\n\n// ========================================\n// CONTEXT FOR COMPOUND COMPONENTS\n// ========================================\n\ninterface TabsContextValue {\n value: string;\n onValueChange?: (value: string) => void;\n}\n\nconst TabsContext = createContext<TabsContextValue | null>(null);\n\nconst useTabsContext = () => {\n const context = useContext(TabsContext);\n if (!context) {\n throw new Error('Tabs compound components must be used within TabsGlass.Root');\n }\n return context;\n};\n\n// ========================================\n// COMPOUND COMPONENT: ROOT\n// ========================================\n\ninterface TabsRootProps {\n /** Current active tab value */\n value: string;\n /** Callback when tab value changes */\n onValueChange?: (value: string) => void;\n /** Child components */\n children: ReactNode;\n /** Optional className for container */\n className?: string;\n}\n\nconst TabsRoot: FC<TabsRootProps> = ({ value, onValueChange, children, className }) => {\n return (\n <TabsContext.Provider value={{ value, onValueChange }}>\n <div className={cn('tabs-glass-root', className)}>{children}</div>\n </TabsContext.Provider>\n );\n};\n\n// ========================================\n// COMPOUND COMPONENT: LIST\n// ========================================\n\ninterface TabsListProps extends React.HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n className?: string;\n}\n\nconst TabsList = forwardRef<HTMLDivElement, TabsListProps>(\n ({ children, className, ...props }, ref) => {\n const containerStyles: CSSProperties = {\n background: 'var(--tab-container-bg)',\n border: '1px solid var(--tab-container-border)',\n };\n\n return (\n <div\n ref={ref}\n className={cn('inline-flex gap-0.5 md:gap-1 p-0.5 md:p-1 rounded-xl', className)}\n style={containerStyles}\n role=\"tablist\"\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\nTabsList.displayName = 'TabsList';\n\n// ========================================\n// COMPOUND COMPONENT: TRIGGER\n// ========================================\n\ninterface TabsTriggerProps {\n /** Value of this tab */\n value: string;\n /** Tab label/content */\n children: ReactNode;\n /** Optional className */\n className?: string;\n /** Disabled state */\n disabled?: boolean;\n}\n\nconst TabsTrigger = forwardRef<HTMLButtonElement, TabsTriggerProps>(\n ({ value, children, className, disabled }, ref) => {\n const { value: activeValue, onValueChange } = useTabsContext();\n const { isFocusVisible, focusProps } = useFocus({ focusVisible: true });\n const isActive = activeValue === value;\n\n const tabStyles: CSSProperties = {\n background: isActive ? 'var(--tab-active-bg)' : 'var(--tab-bg)',\n color: isActive ? 'var(--tab-active-text)' : 'var(--text-secondary)',\n boxShadow: isFocusVisible && !disabled ? 'var(--focus-glow)' : 'none',\n };\n\n return (\n <button\n ref={ref}\n type=\"button\"\n role=\"tab\"\n aria-selected={isActive}\n disabled={disabled}\n className={cn(\n 'relative px-2.5 py-1.5 md:px-4 md:py-2 rounded-lg text-xs md:text-sm font-medium transition-[background-color,color,opacity] duration-300',\n disabled && 'opacity-50 cursor-not-allowed',\n className\n )}\n style={tabStyles}\n onClick={() => !disabled && onValueChange?.(value)}\n onFocus={focusProps.onFocus}\n onBlur={focusProps.onBlur}\n >\n {children}\n {isActive && (\n <div\n className=\"absolute bottom-0 left-1/2 -translate-x-1/2 w-6 md:w-8 h-0.5 rounded-full\"\n style={{ background: 'var(--tab-indicator)' }}\n />\n )}\n </button>\n );\n }\n);\n\nTabsTrigger.displayName = 'TabsTrigger';\n\n// ========================================\n// COMPOUND COMPONENT: CONTENT\n// ========================================\n\ninterface TabsContentProps {\n /** Value of the tab this content belongs to */\n value: string;\n /** Content to display when tab is active */\n children: ReactNode;\n /** Optional className */\n className?: string;\n}\n\nconst TabsContent: FC<TabsContentProps> = ({ value, children, className }) => {\n const { value: activeValue } = useTabsContext();\n const isActive = activeValue === value;\n\n if (!isActive) return null;\n\n return (\n <div\n role=\"tabpanel\"\n aria-hidden={!isActive}\n className={cn('animate-in fade-in-0 duration-200', className)}\n >\n {children}\n </div>\n );\n};\n\n// ========================================\n// EXPORT COMPOUND COMPONENT (v1.0.0+)\n// ========================================\n\n/**\n * TabsGlass - Compound Component API\n *\n * @example\n * ```tsx\n * <TabsGlass.Root value={activeTab} onValueChange={setActiveTab}>\n * <TabsGlass.List>\n * <TabsGlass.Trigger value=\"tab1\">Overview</TabsGlass.Trigger>\n * <TabsGlass.Trigger value=\"tab2\">Analytics</TabsGlass.Trigger>\n * </TabsGlass.List>\n * <TabsGlass.Content value=\"tab1\">\n * <p>Overview content</p>\n * </TabsGlass.Content>\n * <TabsGlass.Content value=\"tab2\">\n * <p>Analytics content</p>\n * </TabsGlass.Content>\n * </TabsGlass.Root>\n * ```\n *\n * @since v1.0.0 - Legacy API removed (tabs/activeTab/onChange props)\n */\nexport const TabsGlass = {\n Root: TabsRoot,\n List: TabsList,\n Trigger: TabsTrigger,\n Content: TabsContent,\n};\n"
16
+ "content": "/* eslint-disable react-refresh/only-export-components */\n/**\n * TabsGlass Component (Compound API only)\n *\n * Glass-themed tab navigation with:\n * - Theme-aware styling (glass/light/aurora)\n * - Active tab indicator\n * - Smooth transitions\n * - Compound component API for advanced composition\n *\n * @example\n * ```tsx\n * <TabsGlass.Root value={activeTab} onValueChange={setActiveTab}>\n * <TabsGlass.List>\n * <TabsGlass.Trigger value=\"overview\">Overview</TabsGlass.Trigger>\n * <TabsGlass.Trigger value=\"analytics\">Analytics</TabsGlass.Trigger>\n * <TabsGlass.Trigger value=\"settings\">Settings</TabsGlass.Trigger>\n * </TabsGlass.List>\n * <TabsGlass.Content value=\"overview\">\n * Overview content\n * </TabsGlass.Content>\n * <TabsGlass.Content value=\"analytics\">\n * Analytics content\n * </TabsGlass.Content>\n * <TabsGlass.Content value=\"settings\">\n * Settings content\n * </TabsGlass.Content>\n * </TabsGlass.Root>\n * ```\n *\n * @since v1.0.0 - Legacy API removed (tabs/activeTab/onChange props)\n */\n\nimport {\n forwardRef,\n createContext,\n useContext,\n type CSSProperties,\n type FC,\n type ReactNode,\n} from 'react';\nimport { cn } from '@/lib/utils';\nimport { useFocus } from '@/lib/hooks/use-focus';\nimport '@/glass-theme.css';\n\n// ========================================\n// TYPES\n// ========================================\n\nexport interface TabItem {\n readonly id: string;\n readonly label: string;\n}\n\n// ========================================\n// CONTEXT FOR COMPOUND COMPONENTS\n// ========================================\n\ninterface TabsContextValue {\n value: string;\n onValueChange?: (value: string) => void;\n}\n\nconst TabsContext = createContext<TabsContextValue | null>(null);\n\nconst useTabsContext = () => {\n const context = useContext(TabsContext);\n if (!context) {\n throw new Error('Tabs compound components must be used within TabsGlass.Root');\n }\n return context;\n};\n\n// ========================================\n// COMPOUND COMPONENT: ROOT\n// ========================================\n\n/**\n * Props for TabsGlass.Root component\n *\n * Root component that manages tab state and provides context for child components.\n * Features accessible keyboard navigation and ARIA attributes.\n *\n * @accessibility\n * - **Keyboard Navigation:** Arrow keys navigate between tabs, Tab moves to tab panel content (WCAG 2.1.1)\n * - **Focus Management:** Visible focus ring on active tab using `--focus-glow` CSS variable (WCAG 2.4.7)\n * - **Screen Readers:** Uses `role=\"tablist\"`, `role=\"tab\"`, `role=\"tabpanel\"` for proper tab semantics (WCAG 4.1.3)\n * - **ARIA Attributes:** Tabs marked with `aria-selected`, panels with `aria-hidden` for state announcement\n * - **Active State:** Visual indicator (underline) plus color change for multi-modal feedback\n * - **Touch Targets:** Tab triggers meet minimum 44x44px touch target (WCAG 2.5.5)\n * - **Color Contrast:** Active and inactive tab text meet WCAG AA contrast ratio 4.5:1\n * - **Motion:** Transitions and indicator animations respect `prefers-reduced-motion` settings\n *\n * @example\n * ```tsx\n * // Basic tabs\n * <TabsGlass.Root value={activeTab} onValueChange={setActiveTab}>\n * <TabsGlass.List>\n * <TabsGlass.Trigger value=\"overview\">Overview</TabsGlass.Trigger>\n * <TabsGlass.Trigger value=\"analytics\">Analytics</TabsGlass.Trigger>\n * <TabsGlass.Trigger value=\"settings\">Settings</TabsGlass.Trigger>\n * </TabsGlass.List>\n * <TabsGlass.Content value=\"overview\">\n * <h2>Overview</h2>\n * <p>Overview content here</p>\n * </TabsGlass.Content>\n * <TabsGlass.Content value=\"analytics\">\n * <h2>Analytics</h2>\n * <p>Analytics content here</p>\n * </TabsGlass.Content>\n * <TabsGlass.Content value=\"settings\">\n * <h2>Settings</h2>\n * <p>Settings content here</p>\n * </TabsGlass.Content>\n * </TabsGlass.Root>\n *\n * // Tabs with icons (ensure accessible labels)\n * <TabsGlass.Root value={activeTab} onValueChange={setActiveTab}>\n * <TabsGlass.List>\n * <TabsGlass.Trigger value=\"home\" aria-label=\"Home dashboard\">\n * <Home className=\"w-4 h-4\" />\n * </TabsGlass.Trigger>\n * <TabsGlass.Trigger value=\"search\" aria-label=\"Search\">\n * <Search className=\"w-4 h-4\" />\n * </TabsGlass.Trigger>\n * </TabsGlass.List>\n * <TabsGlass.Content value=\"home\">Dashboard content</TabsGlass.Content>\n * <TabsGlass.Content value=\"search\">Search content</TabsGlass.Content>\n * </TabsGlass.Root>\n *\n * // Disabled tab (announced to screen readers)\n * <TabsGlass.Root value={activeTab} onValueChange={setActiveTab}>\n * <TabsGlass.List>\n * <TabsGlass.Trigger value=\"tab1\">Available Tab</TabsGlass.Trigger>\n * <TabsGlass.Trigger value=\"tab2\" disabled>\n * Locked Tab\n * </TabsGlass.Trigger>\n * </TabsGlass.List>\n * <TabsGlass.Content value=\"tab1\">Content 1</TabsGlass.Content>\n * </TabsGlass.Root>\n *\n * // Form tabs with proper focus management\n * <TabsGlass.Root value={currentStep} onValueChange={setCurrentStep}>\n * <TabsGlass.List aria-label=\"Registration steps\">\n * <TabsGlass.Trigger value=\"account\">Account Info</TabsGlass.Trigger>\n * <TabsGlass.Trigger value=\"profile\">Profile Details</TabsGlass.Trigger>\n * <TabsGlass.Trigger value=\"confirm\">Confirmation</TabsGlass.Trigger>\n * </TabsGlass.List>\n * <TabsGlass.Content value=\"account\">\n * <InputGlass label=\"Email\" type=\"email\" />\n * </TabsGlass.Content>\n * <TabsGlass.Content value=\"profile\">\n * <InputGlass label=\"Name\" />\n * </TabsGlass.Content>\n * <TabsGlass.Content value=\"confirm\">\n * <p>Review your information</p>\n * </TabsGlass.Content>\n * </TabsGlass.Root>\n * ```\n */\ninterface TabsRootProps {\n /** Current active tab value */\n value: string;\n /** Callback when tab value changes */\n onValueChange?: (value: string) => void;\n /** Child components */\n children: ReactNode;\n /** Optional className for container */\n className?: string;\n}\n\nconst TabsRoot: FC<TabsRootProps> = ({ value, onValueChange, children, className }) => {\n return (\n <TabsContext.Provider value={{ value, onValueChange }}>\n <div className={cn('tabs-glass-root', className)}>{children}</div>\n </TabsContext.Provider>\n );\n};\n\n// ========================================\n// COMPOUND COMPONENT: LIST\n// ========================================\n\ninterface TabsListProps extends React.HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n className?: string;\n}\n\nconst TabsList = forwardRef<HTMLDivElement, TabsListProps>(\n ({ children, className, ...props }, ref) => {\n const containerStyles: CSSProperties = {\n background: 'var(--tab-container-bg)',\n border: '1px solid var(--tab-container-border)',\n };\n\n return (\n <div\n ref={ref}\n className={cn('inline-flex gap-0.5 md:gap-1 p-0.5 md:p-1 rounded-xl', className)}\n style={containerStyles}\n role=\"tablist\"\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\nTabsList.displayName = 'TabsList';\n\n// ========================================\n// COMPOUND COMPONENT: TRIGGER\n// ========================================\n\ninterface TabsTriggerProps {\n /** Value of this tab */\n value: string;\n /** Tab label/content */\n children: ReactNode;\n /** Optional className */\n className?: string;\n /** Disabled state */\n disabled?: boolean;\n}\n\nconst TabsTrigger = forwardRef<HTMLButtonElement, TabsTriggerProps>(\n ({ value, children, className, disabled }, ref) => {\n const { value: activeValue, onValueChange } = useTabsContext();\n const { isFocusVisible, focusProps } = useFocus({ focusVisible: true });\n const isActive = activeValue === value;\n\n const tabStyles: CSSProperties = {\n background: isActive ? 'var(--tab-active-bg)' : 'var(--tab-bg)',\n color: isActive ? 'var(--tab-active-text)' : 'var(--text-secondary)',\n boxShadow: isFocusVisible && !disabled ? 'var(--focus-glow)' : 'none',\n };\n\n return (\n <button\n ref={ref}\n type=\"button\"\n role=\"tab\"\n aria-selected={isActive}\n disabled={disabled}\n className={cn(\n 'relative px-2.5 py-1.5 md:px-4 md:py-2 rounded-lg text-xs md:text-sm font-medium transition-[background-color,color,opacity] duration-300',\n disabled && 'opacity-50 cursor-not-allowed',\n className\n )}\n style={tabStyles}\n onClick={() => !disabled && onValueChange?.(value)}\n onFocus={focusProps.onFocus}\n onBlur={focusProps.onBlur}\n >\n {children}\n {isActive && (\n <div\n className=\"absolute bottom-0 left-1/2 -translate-x-1/2 w-6 md:w-8 h-0.5 rounded-full\"\n style={{ background: 'var(--tab-indicator)' }}\n />\n )}\n </button>\n );\n }\n);\n\nTabsTrigger.displayName = 'TabsTrigger';\n\n// ========================================\n// COMPOUND COMPONENT: CONTENT\n// ========================================\n\ninterface TabsContentProps {\n /** Value of the tab this content belongs to */\n value: string;\n /** Content to display when tab is active */\n children: ReactNode;\n /** Optional className */\n className?: string;\n}\n\nconst TabsContent: FC<TabsContentProps> = ({ value, children, className }) => {\n const { value: activeValue } = useTabsContext();\n const isActive = activeValue === value;\n\n if (!isActive) return null;\n\n return (\n <div\n role=\"tabpanel\"\n aria-hidden={!isActive}\n className={cn('animate-in fade-in-0 duration-200', className)}\n >\n {children}\n </div>\n );\n};\n\n// ========================================\n// EXPORT COMPOUND COMPONENT (v1.0.0+)\n// ========================================\n\n/**\n * TabsGlass - Compound Component API\n *\n * @example\n * ```tsx\n * <TabsGlass.Root value={activeTab} onValueChange={setActiveTab}>\n * <TabsGlass.List>\n * <TabsGlass.Trigger value=\"tab1\">Overview</TabsGlass.Trigger>\n * <TabsGlass.Trigger value=\"tab2\">Analytics</TabsGlass.Trigger>\n * </TabsGlass.List>\n * <TabsGlass.Content value=\"tab1\">\n * <p>Overview content</p>\n * </TabsGlass.Content>\n * <TabsGlass.Content value=\"tab2\">\n * <p>Analytics content</p>\n * </TabsGlass.Content>\n * </TabsGlass.Root>\n * ```\n *\n * @since v1.0.0 - Legacy API removed (tabs/activeTab/onChange props)\n */\nexport const TabsGlass = {\n Root: TabsRoot,\n List: TabsList,\n Trigger: TabsTrigger,\n Content: TabsContent,\n};\n"
17
17
  }
18
18
  ],
19
19
  "categories": [
@@ -17,7 +17,7 @@
17
17
  {
18
18
  "path": "components/glass/ui/tooltip-glass.tsx",
19
19
  "type": "registry:component",
20
- "content": "/**\n * TooltipGlass Component\n *\n * Glass-themed tooltip with:\n * - Unified dark design (consistent UX across themes)\n * - Position variants (top/bottom/left/right)\n * - Smooth animation\n */\n\nimport { forwardRef, useId, type ReactNode, type CSSProperties } from 'react';\nimport { type VariantProps } from 'class-variance-authority';\nimport { cn } from '@/lib/utils';\nimport { useHover } from '@/lib/hooks/use-hover';\nimport { tooltipPositions, type TooltipPosition } from '@/lib/variants/tooltip-glass-variants';\nimport '@/glass-theme.css';\n\n// ========================================\n// PROPS INTERFACE\n// ========================================\n\nexport interface TooltipGlassProps extends VariantProps<typeof tooltipPositions> {\n readonly children: ReactNode;\n readonly content: string;\n readonly position?: TooltipPosition;\n readonly className?: string;\n}\n\n// ========================================\n// COMPONENT\n// ========================================\n\nexport const TooltipGlass = forwardRef<HTMLDivElement, TooltipGlassProps>(\n ({ children, content, position = 'top', className }, ref) => {\n const { isHovered, hoverProps } = useHover();\n const tooltipId = useId();\n\n // Glass tooltip with same background as modal (oklch(100% 0 0 / 0.06))\n const tooltipStyles: CSSProperties = {\n background: 'var(--tooltip-bg)',\n color: 'var(--tooltip-text)',\n border: '1px solid var(--tooltip-border)',\n boxShadow: 'var(--tooltip-shadow)',\n backdropFilter: 'blur(var(--blur-xl))',\n WebkitBackdropFilter: 'blur(var(--blur-xl))',\n };\n\n return (\n <div\n ref={ref}\n className={cn('relative inline-flex', className)}\n onMouseEnter={hoverProps.onMouseEnter}\n onMouseLeave={hoverProps.onMouseLeave}\n aria-describedby={isHovered ? tooltipId : undefined}\n >\n {children}\n {isHovered && (\n <div\n id={tooltipId}\n className={cn(tooltipPositions({ position }))}\n style={tooltipStyles}\n role=\"tooltip\"\n >\n {content}\n </div>\n )}\n </div>\n );\n }\n);\n\nTooltipGlass.displayName = 'TooltipGlass';\n"
20
+ "content": "/**\n * TooltipGlass Component\n *\n * Glass-themed tooltip with:\n * - Unified dark design (consistent UX across themes)\n * - Position variants (top/bottom/left/right)\n * - Smooth animation\n */\n\nimport { forwardRef, useId, type ReactNode, type CSSProperties } from 'react';\nimport { type VariantProps } from 'class-variance-authority';\nimport { cn } from '@/lib/utils';\nimport { useHover } from '@/lib/hooks/use-hover';\nimport { tooltipPositions, type TooltipPosition } from '@/lib/variants/tooltip-glass-variants';\nimport '@/glass-theme.css';\n\n// ========================================\n// PROPS INTERFACE\n// ========================================\n\n/**\n * Props for the TooltipGlass component\n *\n * A glass-themed tooltip with configurable positioning and unified dark design.\n * Features smooth animations and WCAG-compliant accessibility attributes.\n *\n * @accessibility\n * - **Keyboard Navigation:** Tooltip appears on focus for keyboard users (same as hover)\n * - **Focus Management:** Tooltip does not trap focus, allows normal navigation flow\n * - **Screen Readers:** Uses `aria-describedby` to associate tooltip with trigger element (WCAG 4.1.3)\n * - **ARIA Attributes:** Tooltip marked with `role=\"tooltip\"` and unique ID for proper association\n * - **Dismissible:** Tooltip dismisses on mouse leave, focus blur, or Escape key\n * - **Touch Targets:** N/A - tooltips appear on hover/focus, do not require direct interaction\n * - **Color Contrast:** Tooltip text meets WCAG AA contrast ratio 4.5:1 against dark background\n * - **Motion:** Fade-in animation respects `prefers-reduced-motion` settings\n *\n * @example\n * ```tsx\n * // Basic tooltip\n * <TooltipGlass content=\"Click to edit\">\n * <button><Edit className=\"w-4 h-4\" /></button>\n * </TooltipGlass>\n *\n * // Different positions\n * <TooltipGlass content=\"Top tooltip\" position=\"top\">\n * <ButtonGlass>Hover me</ButtonGlass>\n * </TooltipGlass>\n * <TooltipGlass content=\"Bottom tooltip\" position=\"bottom\">\n * <ButtonGlass>Hover me</ButtonGlass>\n * </TooltipGlass>\n * <TooltipGlass content=\"Left tooltip\" position=\"left\">\n * <ButtonGlass>Hover me</ButtonGlass>\n * </TooltipGlass>\n * <TooltipGlass content=\"Right tooltip\" position=\"right\">\n * <ButtonGlass>Hover me</ButtonGlass>\n * </TooltipGlass>\n *\n * // Icon button with accessible tooltip (provides label)\n * <TooltipGlass content=\"Delete item\">\n * <ButtonGlass\n * icon={Trash}\n * size=\"icon\"\n * variant=\"ghost\"\n * aria-label=\"Delete item\"\n * />\n * </TooltipGlass>\n *\n * // Informational tooltip on text\n * <TooltipGlass content=\"This feature requires a Pro subscription\">\n * <span className=\"underline decoration-dotted\">Pro Feature</span>\n * </TooltipGlass>\n *\n * // Badge with tooltip for additional context\n * <TooltipGlass content=\"Last updated 2 hours ago\" position=\"top\">\n * <BadgeGlass variant=\"success\" dot>\n * Active\n * </BadgeGlass>\n * </TooltipGlass>\n *\n * // Disabled button with explanation tooltip\n * <TooltipGlass content=\"Save your changes first to enable this action\">\n * <span>\n * <ButtonGlass disabled aria-describedby=\"tooltip-id\">\n * Export\n * </ButtonGlass>\n * </span>\n * </TooltipGlass>\n * ```\n */\nexport interface TooltipGlassProps extends VariantProps<typeof tooltipPositions> {\n readonly children: ReactNode;\n readonly content: string;\n readonly position?: TooltipPosition;\n readonly className?: string;\n}\n\n// ========================================\n// COMPONENT\n// ========================================\n\nexport const TooltipGlass = forwardRef<HTMLDivElement, TooltipGlassProps>(\n ({ children, content, position = 'top', className }, ref) => {\n const { isHovered, hoverProps } = useHover();\n const tooltipId = useId();\n\n // Glass tooltip with same background as modal (oklch(100% 0 0 / 0.06))\n const tooltipStyles: CSSProperties = {\n background: 'var(--tooltip-bg)',\n color: 'var(--tooltip-text)',\n border: '1px solid var(--tooltip-border)',\n boxShadow: 'var(--tooltip-shadow)',\n backdropFilter: 'blur(var(--blur-xl))',\n WebkitBackdropFilter: 'blur(var(--blur-xl))',\n };\n\n return (\n <div\n ref={ref}\n className={cn('relative inline-flex', className)}\n onMouseEnter={hoverProps.onMouseEnter}\n onMouseLeave={hoverProps.onMouseLeave}\n aria-describedby={isHovered ? tooltipId : undefined}\n >\n {children}\n {isHovered && (\n <div\n id={tooltipId}\n className={cn(tooltipPositions({ position }))}\n style={tooltipStyles}\n role=\"tooltip\"\n >\n {content}\n </div>\n )}\n </div>\n );\n }\n);\n\nTooltipGlass.displayName = 'TooltipGlass';\n"
21
21
  }
22
22
  ],
23
23
  "categories": [