{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "icon-button-glass", "type": "registry:component", "title": "Icon Button Glass", "description": "Icon-only button with glassmorphism styling and touch-friendly sizing.\n * Perfect for toolbar actions, header controls, and compact interfaces.\n *\n * ## Features", "dependencies": [ "class-variance-authority", "lucide-react", "react", "shadcn-glass-ui" ], "registryDependencies": [ "cn" ], "files": [ { "path": "components/glass/atomic/icon-button-glass.tsx", "type": "registry:component", "content": "/**\n * IconButtonGlass Component\n *\n * Icon-only button with glassmorphism styling and touch-friendly sizing.\n * Perfect for toolbar actions, header controls, and compact interfaces.\n *\n * ## Features\n * - Icon-only button with required aria-label for accessibility\n * - 4 size variants: `sm` (32px), `md` (40px), `lg` (48px), `touch` (44px mobile, 40px desktop)\n * - 3 visual variants: `gradient` (colorful gradient), `subtle` (glass card), `ghost` (transparent)\n * - Touch-friendly sizing with WCAG 2.1 AA compliance (44px minimum)\n * - Responsive touch variant adapts to screen size\n * - Built-in hover scale animation (105%)\n * - Focus ring for keyboard navigation\n * - Accepts any Lucide React icon component\n * - Customizable icon size independent of button size\n * - Theme-aware styling through CSS variables\n *\n * ## CSS Variables\n * Uses inline gradient styles (NOT CSS variables) for visual variants:\n * - `gradient` variant: `--icon-btn-from`, `--icon-btn-to`, `--icon-btn-shadow`, `--icon-btn-text`\n * - `subtle` variant: `--card-subtle-bg`, `--card-subtle-border`, `--icon-btn-text`\n * - `ghost` variant: No CSS variables (transparent background)\n *\n * @example Basic icon button\n * ```tsx\n * import { IconButtonGlass } from 'shadcn-glass-ui'\n * import { Search } from 'lucide-react'\n *\n * function Toolbar() {\n * return (\n * console.log('Search clicked')}\n * />\n * )\n * }\n * ```\n *\n * @example Touch-friendly size for mobile\n * ```tsx\n * import { Menu } from 'lucide-react'\n *\n * \n * ```\n *\n * @example Different variants\n * ```tsx\n * import { Settings, Bell, User } from 'lucide-react'\n *\n * // Gradient (colorful)\n * \n *\n * // Subtle (glass card)\n * \n *\n * // Ghost (transparent)\n * \n * ```\n *\n * @example Custom icon size\n * ```tsx\n * import { Trash2 } from 'lucide-react'\n *\n * \n * ```\n *\n * @accessibility\n * - `aria-label` prop is required for screen reader support\n * - Focus ring visible for keyboard navigation (2px ring with offset)\n * - Touch targets meet WCAG 2.1 AA minimum (44px) via `touch` size\n * - Hover and focus states provide clear interaction feedback\n * - Button type defaults to \"button\" to prevent form submission\n *\n * @since v1.0.0\n */\n\nimport { forwardRef, type ButtonHTMLAttributes, type CSSProperties } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { type LucideIcon } from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport '@/glass-theme.css';\n\n// ========================================\n// VARIANTS\n// ========================================\n\nconst iconButtonVariants = cva(\n 'rounded-xl flex items-center justify-center transition-all duration-300 hover:scale-105 focus:outline-none focus:ring-2 focus:ring-offset-2',\n {\n variants: {\n size: {\n sm: 'w-8 h-8',\n md: 'w-10 h-10',\n lg: 'w-12 h-12',\n // Touch target: 44px minimum for mobile (WCAG 2.1 AA)\n touch: 'w-11 h-11 md:w-10 md:h-10',\n },\n variant: {\n gradient: '',\n subtle: '',\n ghost: 'bg-transparent hover:bg-white/10',\n },\n },\n defaultVariants: {\n size: 'md',\n variant: 'gradient',\n },\n }\n);\n\n// ========================================\n// PROPS INTERFACE\n// ========================================\n\n/**\n * Props for IconButtonGlass component.\n *\n * Extends standard button attributes with icon-specific props and CVA variants.\n * The `aria-label` prop is required for accessibility since there is no visible text.\n *\n * @example\n * ```tsx\n * import { Settings } from 'lucide-react'\n *\n * const props: IconButtonGlassProps = {\n * icon: Settings,\n * 'aria-label': 'Open settings',\n * size: 'touch',\n * variant: 'gradient',\n * onClick: () => console.log('Clicked'),\n * };\n * ```\n */\nexport interface IconButtonGlassProps\n extends ButtonHTMLAttributes, VariantProps {\n /**\n * Lucide icon component to render inside the button.\n *\n * @example\n * ```tsx\n * import { Search, Menu, Settings } from 'lucide-react'\n *\n * \n * \n * \n * ```\n */\n readonly icon: LucideIcon;\n\n /**\n * Icon size in pixels.\n *\n * Independent of button size for flexible icon sizing.\n * Use smaller icons for compact buttons, larger for prominent actions.\n *\n * @default 20\n * @example\n * ```tsx\n * // Small icon in small button\n * \n *\n * // Large icon in large button\n * \n * ```\n */\n readonly iconSize?: number;\n\n /**\n * Accessible label for screen readers.\n *\n * REQUIRED since icon-only buttons have no visible text.\n * Describe the button's action clearly.\n *\n * @example\n * ```tsx\n * \n * \n * \n * ```\n */\n readonly 'aria-label': string;\n}\n\n// ========================================\n// COMPONENT\n// ========================================\n\nexport const IconButtonGlass = forwardRef(\n (\n { icon: Icon, iconSize = 20, size, variant, className, 'aria-label': ariaLabel, ...props },\n ref\n ) => {\n const gradientStyles: CSSProperties | undefined =\n variant === 'gradient'\n ? {\n background: 'linear-gradient(135deg, var(--icon-btn-from), var(--icon-btn-to))',\n boxShadow: 'var(--icon-btn-shadow)',\n }\n : undefined;\n\n const subtleStyles: CSSProperties | undefined =\n variant === 'subtle'\n ? {\n background: 'var(--card-subtle-bg)',\n border: '1px solid var(--card-subtle-border)',\n }\n : undefined;\n\n const iconStyles: CSSProperties = {\n color: 'var(--icon-btn-text)',\n };\n\n return (\n \n \n \n );\n }\n);\n\nIconButtonGlass.displayName = 'IconButtonGlass';\n" } ], "categories": [ "atomic" ] }