{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "glow-link-button",
"type": "registry:ui",
"title": "Glow Link Button",
"description": "iOS 26 liquid-glass link pill with cursor-following radial glow and spring arrow.",
"dependencies": [
"motion"
],
"files": [
{
"path": "registry/ruixenui/glow-link-button.tsx",
"content": "\"use client\";\n\nimport * as React from \"react\";\nimport { motion } from \"motion/react\";\n\n/* ── sound ── */\nlet _a: AudioContext, _b: AudioBuffer;\nconst tick = () => {\n if (typeof window === \"undefined\") return;\n if (!_a) {\n _a = new AudioContext();\n _b = _a.createBuffer(1, (_a.sampleRate * 0.003) | 0, _a.sampleRate);\n const d = _b.getChannelData(0);\n for (let i = 0; i < d.length; i++)\n d[i] = (Math.random() * 2 - 1) * (1 - i / d.length) ** 4;\n }\n const s = _a.createBufferSource();\n s.buffer = _b;\n const g = _a.createGain();\n g.gain.value = 0.08;\n s.connect(g).connect(_a.destination);\n s.start();\n};\n\n/* ── theme ── */\nconst CSS = `\n.gl{\n --gl-glass:linear-gradient(180deg,rgba(255,255,255,0.78),rgba(255,255,255,0.62));\n --gl-border:rgba(0,0,0,0.06);\n --gl-shadow:0 0 1px rgba(0,0,0,0.04),0 2px 8px rgba(0,0,0,0.04),inset 0 1px 0 rgba(255,255,255,0.8);\n --gl-hi:rgba(0,0,0,0.88);\n --gl-dim:rgba(0,0,0,0.42);\n --gl-glow:rgba(0,0,0,0.03)\n}\n.dark .gl,[data-theme=\"dark\"] .gl{\n --gl-glass:linear-gradient(180deg,rgba(255,255,255,0.05),rgba(255,255,255,0.02));\n --gl-border:rgba(255,255,255,0.07);\n --gl-shadow:0 1px 3px rgba(0,0,0,0.08),inset 0 1px 0 rgba(255,255,255,0.04);\n --gl-hi:rgba(255,255,255,0.88);\n --gl-dim:rgba(255,255,255,0.28);\n --gl-glow:rgba(255,255,255,0.04)\n}`;\n\n/* ── component ── */\nexport interface GlowLinkButtonProps {\n label?: string;\n href?: string;\n sound?: boolean;\n style?: React.CSSProperties;\n}\n\nexport default function GlowLinkButton({\n label = \"Explore on GitHub\",\n href = \"#\",\n sound = true,\n style,\n}: GlowLinkButtonProps) {\n const [hovered, setHovered] = React.useState(false);\n const [glowX, setGlowX] = React.useState(0);\n\n return (\n <>\n \n sound && tick()}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n onMouseMove={(e) => {\n const r = e.currentTarget.getBoundingClientRect();\n setGlowX(e.clientX - r.left);\n }}\n whileHover={{ scale: 1.03 }}\n whileTap={{ scale: 0.97 }}\n transition={{ type: \"spring\", stiffness: 500, damping: 30 }}\n style={{\n position: \"relative\",\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 8,\n padding: \"10px 18px\",\n borderRadius: 24,\n border: \"1px solid var(--gl-border)\",\n background: \"var(--gl-glass)\",\n boxShadow: \"var(--gl-shadow)\",\n backdropFilter: \"blur(24px)\",\n WebkitBackdropFilter: \"blur(24px)\",\n color: \"var(--gl-hi)\",\n fontSize: 14,\n fontWeight: 500,\n textDecoration: \"none\",\n cursor: \"pointer\",\n outline: \"none\",\n userSelect: \"none\",\n overflow: \"hidden\",\n ...style,\n }}\n >\n {/* cursor glow */}\n \n {label}\n \n \n \n \n \n >\n );\n}\n",
"type": "registry:ui",
"target": "components/ruixen/glow-link-button.tsx"
}
]
}