expandable-bento-grid
vengenceui/expandable-bento-gridFreeComponent
vengenceui publishes no description for this item.
Live preview
live · rendered by the registry
Rendered by vengenceui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://www.vengenceui.com/r/expandable-bento-grid.jsonSource
1'use client'23import React, { useEffect, useId, useRef, useState } from 'react'4import { AnimatePresence, motion } from 'framer-motion'5import { useOutsideClick } from '@/hooks/use-outside-click'6import { X } from 'lucide-react'78export interface BentoGridProps {9 items: {10 id: string | number11 title: string12 subtitle?: string13 description?: string14 content: React.ReactNode15 icon?: React.ReactNode16 className?: string17 }[]18}1920export default function ExpandableBentoGrid({ items }: BentoGridProps) {21 const [active, setActive] = useState<(typeof items)[number] | boolean | null>(null)22 const ref = useRef<HTMLDivElement>(null)23 const id = useId()2425 useEffect(() => {26 function onKeyDown(event: KeyboardEvent) {27 if (event.key === 'Escape') {28 setActive(false)29 }30 }3132 if (active && typeof active === 'object') {33 document.body.style.overflow = 'hidden'34 } else {35 document.body.style.overflow = 'auto'36 }3738 window.addEventListener('keydown', onKeyDown)39 return () => window.removeEventListener('keydown', onKeyDown)40 }, [active])4142 useOutsideClick(ref, () => setActive(null))4344 return (45 <>46 <AnimatePresence>47 {active && typeof active === 'object' && (48 <motion.div49 initial={{ opacity: 0 }}50 animate={{ opacity: 1 }}51 exit={{ opacity: 0 }}52 className="fixed inset-0 bg-black/20 h-full w-full z-[10000]"53 />54 )}55 </AnimatePresence>56 <AnimatePresence>57 {active && typeof active === 'object' ? (58 <div className=" fixed inset-0 top-16 grid place-items-center z-[10001] ">59 <motion.button60 key={`button-${active.title}-${id}`}61 layout62 initial={{ opacity: 0 }}63 animate={{ opacity: 1 }}64 exit={{ opacity: 0, transition: { duration: 0.05 } }}65 className="flex absolute top-2 right-2 md:right-10 lg:hidden items-center justify-center bg-white rounded-full h-6 w-6"66 onClick={() => setActive(null)}67 >68// … truncated
What it pulls in
npm packages
Files it writes
More from vengenceui
All 131 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| accordionaccordion | vengenceui | Components | Free | 2 deps | |
| agent-bento-gridagent-bento-grid | vengenceui | Components | Free | 1 dep | |
| alertalert | vengenceui | Components | Free | no deps | |
| animated-buttonanimated-button | vengenceui | Components | Free | 1 dep | |
| animated-footeranimated-footer | vengenceui | Components | Free | 2 deps | |
| animated-numberanimated-number | vengenceui | Components | Free | 1 dep | |
| animated-raysanimated-rays | vengenceui | Components | Free | no deps | |
| animated-tooltipanimated-tooltip | vengenceui | Components | Free | 1 dep |
