Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,56 @@

Format: [Keep a Changelog](https://keepachangelog.com/) · [SemVer](https://semver.org/).

## [1.1.0] — 2026-07-28 — "Surfaces"

Twenty new components (31 → **51**) and a second primitive. The theme is surfaces you can
touch: light on a material, the pointer itself, and the page as it scrolls.

### Added
- **`useShader()` primitive** — a raw **WebGL2** runtime for full-screen fragment shaders in
~290 lines and **still zero runtime dependencies** (no `ogl`, no `three`). Draws a single
full-screen triangle from `gl_VertexID` (no buffers to allocate or leak) and owns the whole
lifecycle: DPR-clamped sizing via `ResizeObserver`, an `IntersectionObserver` that suspends the
loop off-screen, pause on tab blur, context-loss recovery, eased pointer input, uniform
declarations generated from the values you pass, and a single still frame for reduced-motion
users. Reports `supported: false` when WebGL2 is missing so components fall back to CSS
instead of a blank box.
- **Shaders & Light (6)** — `liquid-metal` (domain-warped FBM height field, normals from finite
differences, swept polish bands), `thin-film` (two-beam interference evaluated at three
wavelengths — real fringe order, not a hue rotation), `caustics` (folded coordinates
accumulating reciprocal distance), `halftone-gradient` (angled per-channel dot screens with
√-corrected dot area, or a computed 4×4 Bayer matrix), `volumetric-rays` (radial scattering
integral with decay normalised by sample count), `curl-flow` (FBM as a stream function; the
velocity is the perpendicular of its gradient, so the field is divergence-free by construction).
- **Cursor & Pointer (5)** — `inertia-cursor`, `elastic-cursor` (stretches along its velocity
vector with conserved area), `image-trail` (distance-thresholded emission, so spacing is even
at any speed), `pixel-trail` (sub-cell path walking, so a fast flick still lights a continuous
line), `crosshair` (point-to-rectangle snapping with a live coordinate readout).
- **Scroll-Driven (4)** — `scroll-stack`, `scroll-velocity`, `parallax-layers`, `scroll-scene`
(pins a section and exposes scrub progress via render prop, a CSS custom property, and a
per-frame callback).
- **Components (5)** — `card-swap`, `gooey-nav`, `bento-grid` (one pointer listener for the whole
grid, published to tiles as inherited custom properties), `elastic-slider` (exponentially damped
overshoot, full `role="slider"` keyboard contract), `circular-gallery` (drag converted through
arc length, so tracking is 1:1 at any radius).

### Changed
- `BentoGrid` gains a `rowHeight` prop; the row height was previously hardcoded at 140px, which
made the component unusable in any frame shorter than two rows.
- The reduced-motion test is now **transitive**: a component satisfies the contract either
directly or through a primitive that does, so the shaders inherit the guarantee from
`useShader` rather than restating it.
- The playground gives scroll-driven components a full-height section of their own — a 200px
preview tile can't demonstrate something driven by the page scroller.

### Fixed
- The CLI's `list` command iterated a hardcoded array of four categories, so components in any
newer category were silently omitted from its output. Both the CLI and the MCP server now derive
the category set from the registry.
- The MCP integration test asserted a literal component count, which fails on every addition and
trains you to bump the number instead of reading the failure. Expected counts now come from
`registry/meta.json`.

## [1.0.0] — 2026-06-18 — "Re-architecture"

A ground-up rebuild. ReactOmega is now an **AI-native React component registry** focused on
Expand Down
57 changes: 48 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
**motion & interaction** components you copy into your project — installable in one line by
**humans _and_ AI agents**.

![Version](https://img.shields.io/badge/version-1.0.0-7c5cff)
![Version](https://img.shields.io/badge/version-1.1.0-7c5cff)
![License](https://img.shields.io/badge/license-MIT-blue)
![Deps](https://img.shields.io/badge/runtime%20deps-none-3c873a)
![A11y](https://img.shields.io/badge/reduced--motion-safe-22d3ee)
Expand Down Expand Up @@ -60,7 +60,7 @@ npx -y github:Edwson/ReactOmega list --category text # filter by category

## Run the playground

**Live:** **https://edwson.github.io/ReactOmega/** — every one of the 31 components rendered live,
**Live:** **https://edwson.github.io/ReactOmega/** — every one of the 51 components rendered live,
with a copy-paste install command on each card. The playground source lives in [`web/`](web)
(Next.js + Tailwind). To run it locally:

Expand All @@ -70,23 +70,40 @@ npm install
npm run dev # → http://localhost:3000
```

## Components (v1.0) — 31
## Components (v1.1) — 51

**Text Animations** (novel + deeply customizable kinetic typography)
**Text Animations** (10) — novel + deeply customizable kinetic typography
`split-text` · `shiny-text` · `gradient-text` · `count-up` · `variable-proximity` (per-letter
variable-font axes by pointer distance) · `magnetic-text` (each letter springs to the pointer) ·
`gravity-text` (letters fall, bounce & reassemble with real gravity) · `elastic-text` (per-letter
jelly squash/stretch) · `scramble-text` (configurable decode) · `text-reveal` (scroll-linked
word-by-word brightening)

**Interaction & Motion**
**Interaction & Motion** (6)
`magnetic` · `spotlight-card` · `tilt-card` · `holographic-card` (iridescent foil + 3D tilt) ·
`click-spark` · `dot-grid`

**Components**
`star-border` · `dock` · `marquee`

**Physics & Art** (real physics — tactile, designed, never cosmic) — 12
**Cursor & Pointer** (5) — *new in 1.1*
`inertia-cursor` (exact dot + spring-lagged ring, difference-blended) · `elastic-cursor` (stretches
along its velocity vector, area conserved) · `image-trail` (distance-thresholded, so spacing is even
at any speed) · `pixel-trail` (sub-cell path walking — a fast flick still lights a continuous line) ·
`crosshair` (point-to-rectangle snapping + live coordinate readout)

**Scroll-Driven** (4) — *new in 1.1*
`scroll-stack` (sticky deck, continuous depth) · `scroll-velocity` (skews with scroll velocity,
frame-rate independent) · `parallax-layers` (progress normalised to the section's own centre) ·
`scroll-scene` (pins a section, exposes 0→1 scrub progress via render prop, CSS variable, or callback)

**Shaders & Light** (6) — *new in 1.1* — **hand-written GLSL on raw WebGL2, still zero deps**
`liquid-metal` (domain-warped FBM, normals from finite differences, swept polish bands) ·
`thin-film` (two-beam interference at three wavelengths — real fringe order, not a hue rotation) ·
`caustics` (folded coordinates accumulating reciprocal distance) · `halftone-gradient` (angled
per-channel dot screens with √-corrected dot area, or a computed 4×4 Bayer matrix) ·
`volumetric-rays` (radial scattering integral, decay normalised by sample count) · `curl-flow`
(FBM as a stream function; velocity is the perpendicular of its gradient, so the field is
divergence-free by construction)

**Physics & Art** (12) — real physics — tactile, designed, never cosmic
`spring-mesh` (press an elastic lattice, waves ripple & settle) · `cloth` (a verlet fabric you grab
& wave) · `metaballs` (gooey fluid that merges around the pointer) · `rope` (a verlet rope you grab
& swing) · `pendulum-wave` (staggered-length pendulums drift in & out of phase) · `newtons-cradle`
Expand All @@ -96,6 +113,28 @@ reflects) · `gravity-wells` (particles orbit the pointer with luminous trails)
`plucked-string` (pluck it, it vibrates with a decaying wave) · `falling-sand` (pour colored grains
that pile into mounds)

**Components** (8)
`star-border` · `dock` · `marquee` · `card-swap` (3D deck, every slot a pure function of depth) ·
`gooey-nav` (indicator stretches in flight, fused by an SVG goo filter) · `bento-grid` (one pointer
listener for the whole grid, shared with tiles as inherited custom properties) · `elastic-slider`
(exponentially damped overshoot, full `role="slider"` keyboard contract) · `circular-gallery`
(drag converted through arc length, so tracking is 1:1 at any radius)

### Shaders without a shader library

The six shader components share a `useShader()` primitive — a raw WebGL2 runtime in ~290 lines
with **no `ogl`, no `three`, and no new dependencies**. It draws one full-screen triangle from
`gl_VertexID` (nothing to allocate, nothing to leak) and owns DPR-clamped sizing, suspension while
off-screen, pause on tab blur, context-loss recovery, eased pointer input, and the single still
frame reduced-motion users get. When WebGL2 is unavailable it reports `supported: false` so the
component renders a CSS fallback rather than a blank box.

```tsx
import { LiquidMetal } from "@/components/reactomega/liquid-metal";

<div className="h-[60vh]"><LiquidMetal tint="#c9d4ff" /></div>;
```

Each ships a structured contract in the registry: description, tags, npm + primitive
dependencies, and the source. Browse [`registry.json`](registry.json) or any
[`public/r/<name>.json`](public/r).
Expand Down
10 changes: 7 additions & 3 deletions cli/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Copies a component (and its primitive dependencies) straight into your project,
* shadcn-style: you own the code. Zero runtime dependencies (Node 18+ built-ins).
*
* npx reactomega list [--category text|interaction|components]
* npx reactomega list [--category text|interaction|cursor|scroll|shader|physics|components]
* npx reactomega add split-text magnetic [--cwd .] [--registry <url|dir>] [--dry]
*
* --registry defaults to the published registry on jsDelivr; pass a local path
Expand Down Expand Up @@ -62,7 +62,11 @@ async function cmdList() {
const category = flag("category");
const comps = reg.items.filter((i) => i.type === "registry:component" && (!category || i.category === category));
console.log(color("bold", `\nReactOmega v${reg.version} — ${comps.length} components\n`));
const cats = ["text", "interaction", "components", "physics"];
// Preferred reading order, then anything else the registry knows about — a
// hardcoded list would silently hide whole categories as the registry grows.
const PREFERRED = ["text", "interaction", "cursor", "scroll", "shader", "physics", "components"];
const present = [...new Set(comps.map((i) => i.category))];
const cats = [...PREFERRED.filter((c) => present.includes(c)), ...present.filter((c) => !PREFERRED.includes(c))];
for (const cat of cats) {
const inCat = comps.filter((i) => i.category === cat);
if (!inCat.length) continue;
Expand Down Expand Up @@ -119,7 +123,7 @@ async function cmdAdd() {
else {
console.log(`reactomega — copy premium React components into your project

reactomega list [--category text|interaction|components]
reactomega list [--category text|interaction|cursor|scroll|shader|physics|components]
reactomega add <name...> [--cwd .] [--registry <url|dir>] [--dry]

Registry: ${SRC}
Expand Down
37 changes: 32 additions & 5 deletions llms.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ReactOmega

> AI-native React component registry — premium, accessible, reduced-motion-safe motion & interaction components. v1.0.0. Install any component in one line via the ReactOmega CLI, shadcn, or an MCP server. Source of truth: /registry.json.
> AI-native React component registry — premium, accessible, reduced-motion-safe motion & interaction components. v1.1.0. Install any component in one line via the ReactOmega CLI, shadcn, or an MCP server. Source of truth: /registry.json.

## Install a component
```
Expand Down Expand Up @@ -29,10 +29,26 @@ Every component is a self-contained file copied into your project (you own the c
- `dot-grid` — An interactive dot field that lights up and swells around the pointer. A modern, non-cosmic backdrop.
- `holographic-card` — An iridescent holo-foil card: a rainbow sheen and bright glare track the pointer with a color-dodge blend, over a subtle 3D tilt. Configurable tilt, intensity, and foil colors.

## Components
- `star-border` — Two soft glints travel continuously around the border of any element. Pure CSS.
- `dock` — A macOS-style magnifying dock; items swell based on pointer distance. Renders as a toolbar.
- `marquee` — A seamless infinite scroller (horizontal or vertical) with edge fade and pause-on-hover.
## Cursor & Pointer
- `inertia-cursor` — Replaces the native cursor with an exact dot plus a ring that lags on a spring, growing over anything matching a selector. Hover is delegated from the document so late-mounted elements work, and difference blending keeps it visible on any background.
- `elastic-cursor` — A gooey cursor that stretches along its own velocity vector and squashes perpendicular so its area is conserved exactly, rotating into the direction of travel and settling back to a circle at rest. Optional trailing blobs are welded together by an SVG goo filter.
- `image-trail` — Drops images along the pointer's path as it crosses a container, each fading and scaling out. Emission is thresholded by distance travelled rather than by event, with the remainder carried between events, so spacing stays even at any speed.
- `pixel-trail` — A canvas grid whose cells ignite under the pointer and decay exponentially into a dissolving comet trail. The path between the previous and current position is walked at sub-cell steps, so a fast flick still lights a continuous line.
- `crosshair` — A precision overlay: full-bleed hairlines, a centre reticle and a live monospace coordinate readout that snap to nearby targets. Distance is measured point-to-rectangle so hovering a target always locks, and one smoothstepped scalar drives the whole engage.

## Scroll-Driven
- `scroll-stack` — Cards that stack into a deck as you scroll, pinned with native sticky positioning. Each card's depth is the running sum of how far the later cards have travelled, so the scale, dim and blur are continuous rather than stepped, and the front card always stays clean.
- `scroll-velocity` — A seamless row that drifts at a base speed but is driven by scroll velocity, skewing as it lurches and easing back to baseline when you stop. Velocity is smoothed with a time-constant decay, so the feel is identical at 60Hz and 120Hz.
- `parallax-layers` — Depth layers that drift at different rates as a section crosses the viewport, with optional scale and blur on distant layers. Progress is normalised against the section's own centre, so the composition is neutral exactly when the section is centred.
- `scroll-scene` — Pins a section and exposes its scrub progress from 0 to 1 through a render prop, plus a live CSS custom property and a per-frame callback. Travel is derived from the measured spacer and pinned heights, so there is no viewport constant to get wrong.

## Shaders & Light (WebGL2)
- `liquid-metal` — A molten chrome surface that flows, catches light and dents away from the pointer. Two rounds of domain-warped FBM drive a height field; the normal is taken from finite differences each frame and lit with diffuse, specular and swept polish bands.
- `thin-film` — Iridescent soap-film sheen computed from real thin-film interference: phase is evaluated at three representative RGB wavelengths over a wobbling thickness field, so the fringe order is physical rather than a hue rotation. The pointer thins the film and shifts the bands.
- `caustics` — Underwater light caustics: a coordinate folded back on itself several times, each pass accumulating reciprocal distance, then gamma-crushed so only the focus filaments survive. The pointer disturbs the water above.
- `halftone-gradient` — A drifting multi-stop gradient rendered through a print screen — either angled per-channel dots with radius proportional to the square root of tone, or a computed 4x4 ordered Bayer matrix. The screen opens up under the pointer.
- `volumetric-rays` — God rays from a pointer-driven light source, integrated the classic way: march back toward the light sampling a drifting haze field and attenuating each step, with decay normalised by sample count so quality and brightness stay independent.
- `curl-flow` — Silk-like flowing bands from a curl-noise field. FBM acts as a stream function and the velocity is the perpendicular of its gradient, so the field is divergence-free by construction; coordinates advect along it and shade as anisotropic streamlines. The pointer injects a vortex.

## Physics & Art
- `spring-mesh` — An elastic lattice: every node is sprung to rest and coupled to its neighbors, so pressing the pointer sends real waves rippling outward that settle naturally.
Expand All @@ -48,9 +64,20 @@ Every component is a self-contained file copied into your project (you own the c
- `plucked-string` — A string pinned at both ends that you grab and pluck, then watch vibrate with a realistic decaying wave driven by neighbor-averaging physics.
- `falling-sand` — A falling-sand cellular automaton where dragging the pointer pours colored grains that fall and slide diagonally into realistic piling mounds.

## Components
- `star-border` — Two soft glints travel continuously around the border of any element. Pure CSS.
- `dock` — A macOS-style magnifying dock; items swell based on pointer distance. Renders as a toolbar.
- `marquee` — A seamless infinite scroller (horizontal or vertical) with edge fade and pause-on-hover.
- `card-swap` — A 3D deck where the front card peels away and the stack advances on an interval or on click. Every slot is a pure function of a card's distance from the front, so CSS transitions do all the interpolation; it pauses on hover and focus and announces changes politely.
- `gooey-nav` — A pill navigation whose liquid indicator stretches as it travels between items and settles into a single pill, fused by an SVG goo filter. Real buttons with roving tabindex and arrow-key movement; labels stay outside the filter so text remains crisp.
- `bento-grid` — A bento layout where the grid owns the only pointer listener and publishes shared coordinates as inherited custom properties, so the spotlight is pure CSS and continuous across gutters no matter how many tiles there are. Tiles add proximity glow and a subtle tilt.
- `elastic-slider` — A slider whose rail stretches like rubber past either end with exponentially diminishing overshoot, then springs back on release. Implements the full slider ARIA contract with arrow, page, home and end keys, pointer capture and touch support.
- `circular-gallery` — Items arranged around a horizontal cylinder that you drag to spin, with inertia on release and optional snapping to the nearest item. Drag is converted through arc length so tracking is one-to-one at any radius, and items past the horizon dim and stop taking pointer events.

## Primitives (added automatically as dependencies)
- `utils` — Tailwind class merge helper used by every component.
- `use-prefers-reduced-motion` — React hook that tracks the user's reduced-motion preference; motion components degrade gracefully when it is true.
- `use-shader` — A dependency-free raw WebGL2 runtime for full-screen fragment shaders: DPR-clamped sizing, suspension while off-screen, context-loss recovery, eased pointer input, auto-generated uniform declarations, and a single still frame for reduced-motion users.

## Machine-readable & MCP
- Registry index: [/registry.json](registry.json) — every component with deps + file targets.
Expand Down
Loading
Loading