Ripple Grid
rivelle/ripple-gridFreeComponent
A field of cells that contracts and illuminates around the pointer.
Install it
npx shadcn@latest add https://rivelle.dev/r/ripple-grid.jsonSource
1"use client";23import * as React from "react";45import { cn } from "@/lib/utils";67type RippleGridProps = React.ComponentProps<"div"> & {8 columns?: number;9 rows?: number;10};1112function RippleGrid({13 className,14 columns = 12,15 onPointerLeave,16 onPointerMove,17 rows = 8,18 ...props19}: RippleGridProps) {20 const [active, setActive] = React.useState<number | null>(null);21 const cells = Array.from({ length: columns * rows });2223 return (24 <div25 className={cn(26 "grid overflow-hidden rounded-[2rem] border border-foreground/10 bg-background",27 className,28 )}29 data-active-index={active ?? undefined}30 data-slot="ripple-grid"31 onPointerLeave={(event) => {32 setActive(null);33 onPointerLeave?.(event);34 }}35 onPointerMove={(event) => {36 const bounds = event.currentTarget.getBoundingClientRect();37 const column = Math.min(38 columns - 1,39 Math.max(40 0,41 Math.floor(42 ((event.clientX - bounds.left) / bounds.width) * columns,43 ),44 ),45 );46 const row = Math.min(47 rows - 1,48 Math.max(49 0,50 Math.floor(((event.clientY - bounds.top) / bounds.height) * rows),51 ),52 );53 setActive(row * columns + column);54 onPointerMove?.(event);55 }}56 style={{ gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))` }}57 {...props}58 >59 {cells.map((_, index) => {60 const activeRow = active === null ? 0 : Math.floor(active / columns);61 const activeColumn = active === null ? 0 : active % columns;62 const row = Math.floor(index / columns);63 const column = index % columns;64 const distance =65 active === null66 ? 067 : Math.hypot(row - activeRow, column - activeColumn);6869 return (70 <span71 aria-hidden="true"72 className={cn(73 "aspect-square border-b border-r border-foreground/[.07] bg-transparent transition-[background-color,transform,box-shadow] duration-500 ease-out will-change-transform motion-reduce:transition-none",74 active !== null &&75 distance < 4.8 &&76 "scale-[.88] rounded-md bg-primary/[.22] shadow-[inset_0_0_28px_color-mix(in_oklch,var(--primary)_28%,transparent),0_0_24px_color-mix(in_oklch,var(--primary)_14%,transparent)]",77 active !== null &&78// … truncated
What it pulls in
Other registry items
Files it writes
More from rivelle
All 83 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | rivelle | Components | Free | 2 deps | |
| Alertalert | rivelle | Components | Free | 1 dep | |
| Alert Dialogalert-dialog | rivelle | Components | Free | 1 dep | |
| Aspect Ratioaspect-ratio | rivelle | Components | Free | 1 dep | |
| Avataravatar | rivelle | Components | Free | 1 dep | |
| Badgebadge | rivelle | Components | Free | 2 deps | |
| Breadcrumbbreadcrumb | rivelle | Components | Free | 2 deps | |
| Buttonbutton | rivelle | Components | Free | 2 deps |
