Versioned changes for every UniqueUI component, newest first. Each entry corresponds to a semver bump on the component manifest (registry/components/<slug>.json → changelog).
BREAKING: columns are now typed definitions ({ id, header, accessor, cell?, ... }) and rows are your own typed objects — Record<string, ReactNode> cells and { key, label, sortKey } columns are gone.
BREAKING: getRowId is required; freezeColumns/freezeCount/freezeLeftCount/freezeRightCount are replaced by per-column freeze: "left" | "right"; initialPage/onPageChange/getRowKey/paginationPreviousLabel/paginationNextLabel were removed.
Hand-rolled row virtualization (windowing) handles up to 100,000 rows; the engine auto-switches to a standard renderer when groupBy or rowSpan is used.
New: global debounced search, typed multi-sort with shift-click, multi-select with filtered-aware select-all, row expansion, row grouping with collapsible headers, rowspan merging, column groups (multi-level headers), pinned rows, sticky header, and basic/advanced/enterprise presets.
Accessibility: aria-sort, aria-selected, aria-expanded, labelled controls, and true aria-rowcount/aria-rowindex under windowing.
Accessibility: multi-sort priority is now announced to assistive tech via an sr-only label instead of being hidden.
The root element forwards arbitrary div props (id, style, role, aria-*, data-*).
Fixed virtual spacer math and select-all to stay correct when pinned rows, expansion, or active search are combined, and row spans now align with grouped render order.
Theme switcher now uses a plain button-menu pattern (disclosure button + `aria-current` on the active theme) instead of `role="listbox"`/`role="option"`, which had promised listbox keyboard semantics the widget did not implement.
Rewrote the burst as a continuous, seamlessly looping fiber-optic engine: rays grow, over-extend, fade, and respawn with fresh angle/length/speed/opacity instead of a one-time reveal.
Added pointer reactivity — fibers near the cursor (middle→tip only) brighten, stretch, and bend toward it, then ease back; the dense zone near the origin stays calm.
Each fiber now carries a single glowing dot fixed at its tip instead of dots travelling along it.
Softened the origin: fibers fade to near-zero through the dense convergence zone and peak only after fanning apart, plus a diffuser core bloom, so the bottom-center no longer blows out to white.
Raised the fiber count for a fuller, more balanced spread.
Increased overall fiber count and shortened the burst (~100px), with the origin touching the bottom edge.
Widened the fan horizontally and lengthened the side fibers so it spreads to the full width along the bottom (height unchanged).
Constrained the burst to a masked lower band so it no longer reaches the headline.
Removed the count-up stat row; the hero now shows the headline only.
Added a `burstProps.interactive` flag to toggle pointer reactivity.
Simplified the backdrop to a single continuous diagonal gradient drift. Removed: the radial center mask (was creating a visible dark void behind the headline), the diagonal aurora-sweep band (read as a stray light slash), and the filament hairline (read as a stray diagonal line). Kept: three large blurred gradient orbs (teal, magenta, amber) each drifting along the top-left ↔ bottom-right diagonal axis on its own slow loop (38s, 46s, 42s) with phase offsets so they pass through each other smoothly. Film grain opacity dropped to 0.10 (subtler). `mix-blend: screen` still produces the tertiary blooms where orbs overlap.
Rewrote the backdrop entirely with `motion/react` — every layer is now a `motion.div` with explicit `animate` keyframe arrays and `repeat: Infinity` (no CSS keyframes, no rAF). Three drifting gradient orbs (teal 14s, amber 18s, magenta 22s) on `mix-blend: screen` create tertiary colors where they overlap (lavender from teal+magenta, gold from amber+magenta). Added an aurora-sweep band translating diagonally every 12s and increased orb alphas so the motion actually reads. Filament breathing tightened to 6s. `useReducedMotion()` freezes every layer at its initial frame.
Replaced the rotating conic backdrop with a four-layer silver-vapor composition: cool-teal + warm-amber blurred blobs drifting on asymmetric paths (mix-blend: screen, lavender bloom at overlap, radially masked away from the central headline region), a subtle drifting dot-grid foundation, an SVG film-grain overlay, and a single diagonal filament hairline whose opacity breathes over 12s. All layers freeze under prefers-reduced-motion. Base color shifted from `#08080a` to a cooler `#06080c`.
Initial release: per-letter cursor-tracking springs on a dark conic-backdrop hero. Letters stagger in with spring physics, then track the pointer within a configurable radius. Reduced-motion disables magnetic follow and collapses entrance to opacity-only.
Initial release: standalone per-letter cursor-tracking text component. Wraps any string with springs that lean toward the pointer; falloff is linear inside `radius`, zero outside; capped at `strength`. Optional `animateEntry` staggers letters in on mount. `as` prop lets it render as h1/h2/p/span. aria-label on the wrapper + aria-hidden on every glyph keep screen readers from spelling out the word.
Anchored the rotating halo's start frame so motion v12's `repeat: Infinity` loop runs after hydration (previously froze in production where SSR baked in the target rotation).
Anchored the conic foil's start rotation so motion v12's `repeat: Infinity` loop runs after hydration (previously froze in production where SSR baked in the target rotation).
Anchored the aurora ribbons' start frames so motion v12's `repeat: Infinity` loop runs after hydration (previously froze in production where SSR baked in the target keyframes).
Anchored each row's start frame so motion v12's `repeat: Infinity` loop runs after hydration (previously froze in production where SSR baked in the target translation).