Skip to content

Interactive Grid Pattern

A grid whose cells light up under the mouse or pen. Decoration only: it does nothing on touch or for reduced motion and never takes focus.

Motionv0.1.0experimentalWCAG 2.2 AAView spec

Optional, and kept apart.

Nothing here is included in a project unless you add it, and the plain component it builds on is unchanged. This effect is decoration: it is hidden from screen readers, stands still for visitors who prefer reduced motion, and can be paused. Use Still on a preview to see that version.

Move the mouse here

Cells light up under a mouse or pen, not on touch

import { InteractiveGridPattern } from "@rdloom/react";

export default function InteractiveGridPatternExample() {
  return (
    <div className="flex w-full justify-center">
      <div className="relative flex h-96 w-full items-center justify-center overflow-hidden rounded-xl border border-[var(--rd-color-border-default)] bg-[var(--rd-color-surface-default)]">
        <InteractiveGridPattern />
        <div className="relative text-center">
          <p className="text-4xl font-semibold tracking-tight text-[var(--rd-color-text-default)]">Move the mouse here</p>
          <p className="text-base text-[var(--rd-color-text-muted)]">Cells light up under a mouse or pen, not on touch</p>
        </div>
      </div>
    </div>
  );
}

Installation

npx rdloom add interactive-grid-pattern

Copies the source into src/components/rdloom. Edit it freely: rdloom upgrade merges later versions into your changes.

It also adds rdloom-motion.css next to your tokens and imports it from the tokens file, once: no setup, and no inline styles. The plain components you already use are untouched.

Use another registry client
npx shadcn@latest add https://rdloom.vimalbhatt.com/r/interactive-grid-pattern.json

Works, but without upgrade tracking, and you import the motion CSS yourself.

Usage

import { InteractiveGridPattern } from "@rdloom/react";

<div className="flex w-full justify-center">
  <div className="relative flex h-96 w-full items-center justify-center overflow-hidden rounded-xl border border-[var(--rd-color-border-default)] bg-[var(--rd-color-surface-default)]">
    <InteractiveGridPattern />
    <div className="relative text-center">
      <p className="text-4xl font-semibold tracking-tight text-[var(--rd-color-text-default)]">Move the mouse here</p>
      <p className="text-base text-[var(--rd-color-text-muted)]">Cells light up under a mouse or pen, not on touch</p>
    </div>
  </div>
</div>

Trail

A short fading trail

Cells light up under a mouse or pen, not on touch

import { InteractiveGridPattern } from "@rdloom/react";

export default function InteractiveGridPatternExample() {
  return (
    <div className="flex w-full justify-center">
      <div className="relative flex h-96 w-full items-center justify-center overflow-hidden rounded-xl border border-[var(--rd-color-border-default)] bg-[var(--rd-color-surface-default)]">
        <InteractiveGridPattern variant="trail" size={32} />
        <div className="relative text-center">
          <p className="text-4xl font-semibold tracking-tight text-[var(--rd-color-text-default)]">A short fading trail</p>
          <p className="text-base text-[var(--rd-color-text-muted)]">Cells light up under a mouse or pen, not on touch</p>
        </div>
      </div>
    </div>
  );
}

API Reference

Defined by the spec. Components also accept the props of the React Aria component they wrap.

PropTypeDefault
size

Cell size in pixels.

number40
strokeWidth

Line thickness in pixels.

number1
color

Colour of the grid lines.

string"color-mix(in srgb, var(--rd-color-text-default) 16%, transparent)"
activeColor

Colour of the lit cells.

string"var(--rd-color-action-primary)"
variant

fill lights the cell under the pointer; trail leaves a short fading trail of cells.

"fill" | "trail""fill"
fade

Fades the grid out toward its edges.

booleantrue
isStill

Turns the lighting off.

booleanfalse

Accessibility

Role presentation, WCAG 2.2 AA. Tested with axe and keyboard tests; screen reader checks are in the audit checklist.

Keyboard

Not interactive.

Screen readers announce

  • Ignored: it is not announced

What your code must do

  • Pure decoration: aria-hidden, never focusable, and pointer-events none so content on top stays usable
  • It is drawn with CSS only, so it needs no JavaScript and is safe in server HTML
  • Stands still for visitors who ask for less motion (prefers-reduced-motion), with isStill, and inside an rdm-still container
  • Drift is slow and never flashes (WCAG 2.2.2, 2.3.1)
  • Hidden in forced-colors (high contrast) mode so it never fights system colours
  • Keep text on top at 4.5:1 against the lines: use a low-contrast token for the pattern
  • The pointer is read from the parent element only for mouse and pen; touch does nothing
  • It never takes the pointer or focus and never replaces a focus ring

Guidelines

Use it when

  • A hero or empty state where a little pointer feedback adds life

Avoid it when

  • Anything people must click: the effect is never a control
  • Touch-first screens, where it does nothing

Don't

  • Using it as the only hover feedback
  • Putting several on one screen

Design tokens

The semantic tokens this component uses. Change them once and every component follows; see Design tokens.

  • --rd-color-border-default