Social Float
atroui/social-floatFreeBlock
Fixed social FAB with expandable link tray.
Install it
npx shadcn@latest add https://atroui.com/r/social-float.jsonSource
1"use client"23import * as React from "react"4import Link from "next/link"5import { AnimatePresence, motion, useReducedMotion } from "motion/react"6import { Github, Mail, X } from "lucide-react"78import { cn } from "@/lib/utils"910const CONTENT = {11 links: [12 { label: "Email", href: "mailto:hello@example.com", external: false },13 { label: "GitHub", href: "https://github.com", external: true },14 { label: "X / Twitter", href: "https://x.com", external: true },15 { label: "Contact", href: "/contact", external: false },16 ] as Array<{17 label: string18 href: string19 external?: boolean20 icon?: "mail" | "github" | "x" | null21 }>,22}2324function XIcon({ className }: { className?: string }) {25 return (26 <svg27 viewBox="0 0 24 24"28 aria-hidden29 className={className}30 fill="currentColor"31 >32 <path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-4.714-6.231-5.401 6.231H2.744l7.727-8.835L1.254 2.25H8.08l4.259 5.672L18.244 2.25zm-1.161 17.52h1.833L7.084 4.126H5.117L17.083 19.77z" />33 </svg>34 )35}3637export function SocialFloat({38 links = CONTENT.links,39 className,40}: {41 links?: Array<{42 label: string43 href: string44 external?: boolean45 icon?: "mail" | "github" | "x" | null46 }>47 className?: string48} = {}) {49 const [open, setOpen] = React.useState(false)50 const reduceMotion = useReducedMotion()51 const rootRef = React.useRef<HTMLDivElement>(null)5253 React.useEffect(() => {54 if (!open) return55 const onKey = (e: KeyboardEvent) => {56 if (e.key === "Escape") setOpen(false)57 }58 const onPointer = (e: MouseEvent | TouchEvent) => {59 if (60 rootRef.current &&61 e.target instanceof Node &&62 !rootRef.current.contains(e.target)63 ) {64 setOpen(false)65 }66 }67 window.addEventListener("keydown", onKey)68 window.addEventListener("mousedown", onPointer)69 return () => {70 window.removeEventListener("keydown", onKey)71 window.removeEventListener("mousedown", onPointer)72 }73 }, [open])7475 return (76 <div77 ref={rootRef}78 className={cn(79 "pointer-events-none fixed right-4 bottom-5 z-40 sm:right-6 sm:bottom-7",80 className81 )}82 >83 <div className="pointer-events-auto flex flex-col items-end gap-2">84 <AnimatePresence>85 {open ? (86 <motion.div87 key="connect-panel"88 role="dialog"89 aria-label="Connect"90// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from atroui
All 81 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Analytics Provideranalytics-provider | atroui | Blocks | Free | 1 dep | |
| AR Portfolioar-portfolio | atroui | Blocks | Free | 1 dep | |
| Before / Afterbefore-after-slider | atroui | Blocks | Free | no deps | |
| Calendly Embedcalendly-embed | atroui | Blocks | Free | 1 dep | |
| Changelogchangelog | atroui | Blocks | Free | no deps | |
| Command Menucommand-menu | atroui | Blocks | Free | 4 deps | |
| Contact Formcontact-form | atroui | Blocks | Free | 2 deps | |
| Contextual CTAcontextual-cta | atroui | Blocks | Free | 2 deps |
