Changelog
Every change to the registry, newest first — one entry per merged PR, tagged with the items it touched.
Machine-readable copies: llms-changelog.txt (full history) and r/versions.json (per-item content hashes for drift detection — see For agents).
- ChangedBreaking
`sidebar-nav` no longer imports `next/link` — the only Next dependency left anywhere in the registry, and the reason the build failed outright for every non-Next consumer. Items with an `href` now render a plain `<a href>`, and a new optional `renderLink` prop supplies a router link instead, forwarded by `scoped-nav` to both of its levels. **Migration for Next.js (and any router-driven) consumers: pass `renderLink={({ href }) => <Link href={href} />}` to `SidebarNav`/`ScopedNav` — it typechecks and looks identical without it, but every nav click becomes a full document load, losing prefetch, scroll restoration and in-memory SPA state.** React Router is `({ href }) => <Link to={href} />`. `href` and `onSelect` are also no longer mutually exclusive, so an item can keep real link semantics — Cmd/Ctrl-click, middle-click, open-in-new-tab — instead of degrading to a button. Where the two are combined, `onSelect` is skipped for modifier and non-primary clicks, which previously navigated the current tab as well as opening the new one; on an ordinary click the link still navigates itself, so a combined `onSelect` is a side-effect hook (close the mobile sidebar, telemetry) rather than a routing hook — **if you previously combined `href` with an `onSelect` that routed, move the routing to `renderLink` or drop the `href`**. An item with neither `href` nor `onSelect` used to render `<a href="#">`; items with no `href` now render a real `<button>`, which also fixes sub-items whose `onSelect`-only rows were anchors with no `href` — unfocusable, and inert to keyboard users.
- Fixed
A round of fixes found by migrating a real non-Next consumer (a Vite + React 19 SPA) onto nx-ui — every one of them affects any consumer. (The `sidebar-nav`/`scoped-nav` half of that round is a separate, breaking entry.) `app-breadcrumbs` and `scope-breadcrumbs` skip a crumb's `onSelect` on modifier and non-primary clicks: an anchor paired with an `onSelect` previously navigated the current tab as well as opening the new one. `sidebar` closes an accessibility hole and three layout defects: an offcanvas-collapsed sidebar is now `visibility: hidden` rather than merely parked off-screen (its nav controls stayed focusable and in the accessibility tree, with `SidebarRail` opting back in so the sidebar can still be reopened); `SidebarContent` drops its hard-coded `no-scrollbar`, which left an over-tall nav scrollable with no affordance at all; `SidebarMenuAction` and `SidebarGroupAction` grow to 24x24 to meet WCAG 2.5.8 on pointer devices, where their touch halo is deliberately disabled; the menu-button's padding is split into `px-2 py-1.5` so it no longer dictates row height; and `SidebarGroupLabel` drops from `h-8` to `h-6` around its 16px line box. `avatar` fixes a contrast failure that showed on every screen of a consumer app: fallback initials were 2.18:1 in light and 1.36:1 in dark against WCAG AA's 4.5:1, and now use `text-fg-secondary` (8.84:1 / 7.10:1); the avatar-group "+N" chip took the same token. `sonner` restores the `next-themes` fallback (`resolvedTheme ?? theme ?? "system"`) that stopped a light-themed toast flash before hydration, and `data-table`, `progress` and `tags-input` shed unused declarations that failed to typecheck in consumers running `noUnusedLocals` — sixteen other shipped files still trip that flag and are listed under Troubleshooting in `docs/registry.md` pending a follow-up. `nx-ui-doctor` finally works outside a repo-root layout: it reads `aliases` from `components.json` and resolves them through the project's `tsconfig`/`jsconfig` path mapping (following `extends` and project references, so Vite's split config resolves), so `wrap-audit` no longer reports every vendored file as missing in a `src/`-layout repo — local-edit detection had never once run there.
- Added
nx-ui now officially supports `lucide-react` alongside `@untitledui/icons` in consumer app code. Both sets draw on a 24 viewBox at stroke-width 2 with round caps and joins, so they interoperate without adjustment. The new `lucide-provider` item pins that weight against a future change to lucide's default, and any individual icon can still override it with a `strokeWidth` prop or a `stroke-[…]` utility.
- Fixed
`featured-icon` no longer crashes when given a `lucide-react` icon — and nor do `metric-card` and `empty-state`, which pass their `icon` prop straight through to it. lucide icons are `forwardRef` objects rather than functions, so the old component-vs-element check misread them as a React child and React threw "Objects are not valid as a React child". Reinstall `featured-icon` if you pass icons from any set other than `@untitledui/icons`.
- Fixed#57
Tidied the layout and alignment across the auth and account surfaces. `account-settings` no longer renders an empty padded band above the first row when there is no action notice, its list sections use a single full-width row idiom (leading mark, title/meta, actions pinned right) instead of the label-left settings grid, and the success notice uses the utility palette rather than undefined `success` classes. `auth-signup`'s terms checkbox label no longer breaks apart onto four lines (the shared `Label` is a flex container), and the strength meter shows a visible track with an inline strength label and neutral, non-alarming markers for unmet requirements. `auth-login` link buttons drop the `sm` size that was inflating the password-label row, icon-only social buttons gained accessible names, the brand panel pins its logo to the top, and `AuthCenteredLayout` recolours the field-separator chip so it matches the card in dark mode. `auth-recovery` gives every step the same header mark, centres the OTP group, and generates unique field ids. `credentials` cards align their empty states with the account blocks, stop wrapping the `x-api-key` code span, and generate unique create-form ids. The `/view/sign-in`, `/view/sign-up` and `/view/forgot-password` examples now compose these blocks instead of duplicating the forms.
- Added
Added `pdf-templates`, an installable set of renderer-native, monochrome A4 documents powered by the Takumi renderer used by PDFCN: an invoice, an operations report, and an evidence-led compliance certificate. The block exports serialisable data contracts, printable document components, deterministic samples, and `renderPdfTemplate()` for use in a consumer’s server route, worker, or job.
- Added
Nexus Account now appears in the canonical app directory as a live customer portal at myaccount.nexusregen.com, with a profile/security-focused descriptor and search terms. The app-icon family gains a dedicated user mark so account surfaces are recognisable in every shared app switcher.
nx-app-iconnx-apps - Added
Add account-management sections for identity consumers: profile presentation, linked sign-in methods, passkeys, sessions and organisation memberships, including reusable loading, empty, feedback and destructive-confirmation states. Every component takes display data and callbacks only, so applications retain their own nx-id integration, authorization and lifecycle policy.
- Added
New **`credentials`** block: the account-credentials kit for self-serve portals (NX-776). `ApiKeysCard` manages a user's central API keys — create form (name + expiry in days, bounded to the server's policy), a shown-once secret panel with copy button and warning copy, a list with `start` prefix/created/expiry/last-used, and revoke behind a destructive confirm. `ConnectedAppsCard` lists OAuth consents (client name/host, scope badges, grant date) with the same revoke-with-confirm idiom. Both are data-driven like every nx-ui block: the consumer owns the data and supplies async callbacks (Better Auth `apiKeyClient` create/list/delete and the oauth-provider consent endpoints — wired in nx-myaccount); the blocks own only the interaction states and render thrown callback errors inline.
- Changed
Geo joins the family: the `nx-apps` directory gains Nexus Geo (geo.nexusregen.com — internal geo-services and HGV routing platform), and `NxAppIcon` gains the `pin` mark for it — a map pin with the hole knocked out, on the graphite tile. The switcher grid is now six apps in two rows; Nexus Geo itself adopts the AppSwitcher in its shell this round, so the family is fully linked across agent-services, emailhub and geo.
nx-app-iconnx-apps - Changed
AppSwitcher v2, built for the unified cross-app shell rolling out across the Nexus family (Agent Services and Email Hub first). The popover grid is now choreographed — tiles stagger in on springs, hover lifts and press sinks, the active app's tick pops in and the trigger chevron flips (all instant under `prefers-reduced-motion`). Past six apps the popover gains a filter matching name/description/keywords with ArrowDown into the grid; a `statusBadge` field marks beta apps; a `footer` slot takes an environment hint or directory link; and an `onSelect` callback fires before cross-app navigation (telemetry hook). New `enabled: false` app state renders a locked, non-followable tile ("No access") — the visible-but-disabled shape entitlement gating needs. New **`nx-apps`** module: the canonical directory of Nexus apps (`NX_APPS`) plus `resolveNxApps({ activeId, user })`, which applies the access policy ahead of the billing/entitlements work — `audience: "staff"` apps hide from known non-staff users, `entitlement`-gated apps render locked without the entitlement (staff bypass), and with no user passed everything fails open since apps gate their own auth. Adding an app to the family is now one directory entry and a re-vendor, instead of editing every consumer's shell. Also in this round: standalone `lib/*` registry items no longer pin an explicit install `target`, so they land through each consumer's `lib` alias (repo-root `lib/` or `src/lib/`) like `utils` always has — an explicit target bypassed the alias and stranded the file where `@/lib/<name>` couldn't resolve it. Consumers with a previously-installed lib item (mapbox, nx-ui-doctor, …) may see one drift flag; content is unchanged, so `--overwrite` or re-`lock` clears it.
app-switchernx-apps - Changed
Per-app identities: `NxAppIcon` gains a `mark` prop — named identity glyphs (`shield`, `bolt`, `mail`, `exchange`, `sliders`) drawn as single-colour fills in the tile canvas, replacing the one-arrow-fits-all emblem in the app switcher grid. The Nexus arrow stays the default (`mark="emblem"`), so existing tiles are unchanged; `AppSwitcherApp.mark` carries it through the switcher trigger and tiles. Directory refresh in `nx-apps`: Materials Exchange is live at use.nexusregen.com, Manage (the MEP admin panel) joins at manage.nexusregen.com, Agent Services now lands on `/admin` (its apex is the public docs surface), and Procurement drops off until it's real. Access-policy default flip: `resolveNxApps` now renders the **same directory everywhere by default** — every app visible and enabled — because per-instance nx-id role differences made the switcher inconsistent between apps for the same user. The staff-audience / entitlement policy is unchanged but moves behind `enforceAccessPolicy: true`, to be switched on once roles and billing entitlements are reliably populated (ADR-016's billing-prep shape stands).
- Internal
Tooling & docs: a keyboard-interaction smoke test (`bun run smoke:keyboard`) drives arrow-key widgets (menubar, combobox, tabs, radiogroups, sliders…) and runs in PR CI; the a11y audit gains a warning budget (`A11Y_WARN_BUDGET`, ratcheted at the current 58 baseline in CI); a weekly `loop-consumer-drift` workflow runs `nx-ui-doctor check` in consumer repos and files drift issues (inert until `AGENT_LOOPS_ENABLED` + a `CONSUMER_REPOS_TOKEN` secret exist); the charts gallery gains a per-theme colours demo exercising `theme: { light, dark }`; and a small contrast sweep moves content-bearing text off `text-fg-quaternary` in the showcase chrome and example pages.
- Internal
Showcase & tooling: new gallery pages for data-table, scope, scope-breadcrumbs, nx-app-icon and nx-emblem; the API-reference extractor now covers all `ai-*` items and the nested block families (113 → 192 documented items); dependency chips link correctly for AI items; `[`/`]` keyboard paging through the gallery; the repo gains its first test suite (127 vitest tests over the lib modules and build-script parsers, `bun run test`); and PR CI now runs the interaction smoke test and a11y audit against a production build.
- Fixed
Item type corrections: `use-marketplace` and `use-listings-clusters` are now declared as `registry:hook`, and the types-only `marketplace-types` contract as `registry:lib` (all three were previously mislabeled `registry:block`). Install paths are unchanged.
marketplace-typesuse-marketplaceuse-listings-clusters - Added
Four new domain/marketplace atoms: `ewc-badge` (a compact EWC code chip with hazard asterisk and dot), `price-range` (the marketplace gate-fee range formatting as a standalone atom), `movement-status-badge` (per-status pills for the waste-movement lifecycle) and `movement-timeline` (the lifecycle as a stepper built on the ui Stepper, with timestamps, notes and clickable steps).
- Added
Two new domain components: `mass-input`, a weight/volume control (t / kg / m³) with a live density-converted equivalent readout when a material or density is given (built on `number-input` + `native-select`, densities from `data-material-terms`); and `transfer-document`, a duty-of-care waste transfer note preview surface (paper sheet, parties grid, EWC/quantity block, signature slots with an `onSign` callback) fed by the same values shape as `transfer-note`.
- Changed
The UUI component tokens are now actually consumed: Switch gains an optional `slim` variant (the UUI slim-toggle treatment, `slim` prop + `data-slim`), and the default Switch border, Slider handle and Avatar fallback now use their dedicated theme tokens (`toggle-border`, `slider-handle-*`, `avatar-styles-bg-neutral`) instead of generic shadcn classes. Also fixes the dark-mode value of `--color-avatar-styles-bg-neutral`, which stayed light-gray and produced light-on-light initials (now neutral-700). Light-mode visuals are unchanged except a hairline switch border and a slightly darker avatar fallback — both per the UUI spec; dark-mode slider handles invert to the spec's accent fill.
- Fixed
Three silently-broken styles fixed: the missing `--color-bg-secondary_subtle` token is defined again (data-table header/footer/pinned-column backgrounds were rendering transparent), the signup password-strength meter and requirement ticks now use real theme colours (the `success-*`/`warning-*` classes it referenced never existed), and per-theme chart colours (`theme: { light, dark }` in a chart config) now actually apply in dark mode — the emitted selector targeted `.dark` instead of `.dark-mode`.
- Internal
Brand variants now alias base ramps with `var(--color-*)` instead of duplicating hex literals (ocean brand → blue ramp, graphite accent → neutral ramp, accent = brand for ocean/ultraviolet/ember). Computed colours are identical — no visual change — and the variant-authoring rules (alias, don't copy; the five-variable dark-flip contract) are now documented in `docs/architecture.md`.
theme-oceantheme-ultraviolettheme-embertheme-graphite - Fixed
Accessibility round: the number-input steppers now show a visible focus ring; the interactive Rating is a real radiogroup (roving tabindex, arrow/Home/End keys); the settings nav marks its active section with `aria-current`; MenubarItem shows a pointer cursor; the toaster follows the app's resolved theme instead of the raw `system` setting; and every focus ring in the library now uses the same 24% ring tint (ring-4 for controls, ring-2 for small inline targets — the rule is documented in `docs/architecture.md`). The base theme also gains a blanket reduced-motion guard and a forced-colours (Windows High Contrast) block so focus stays visible when box-shadow rings are stripped.
- Added
Version management and agent ops landed: every registry item now has a published content hash in `/r/versions.json` (compare against your `nx-ui.lock` to detect drift), this changelog (one entry per PR, browsable at `/changelog`, machine-readable at `/llms-changelog.txt`), the `@nx-ui/nx-ui-doctor` script for consumer-side `lock`/`check`/`wrap-audit`, an agent onboarding page at `/agents`, CI, and scheduled maintenance loops.
nx-ui-doctor - Added#39
The `stockpile-visualiser` domain block: an interactive 3D soil-stockpile visualisation on a dependency-free canvas engine — a rotatable surveyed heightfield with test-location pins, live morph-animated stock levels, and geotechnical overlays for angle-of-repose stability, height compliance, test coverage, cut/fill deltas and cross-sections.
- Added#40
The haulage kit: `haulage-vehicle-select` (a UK construction/waste vehicle picker with drawn side-profile artwork, payload/volume/CO2e details and loads-required estimates, backed by the `data-haulage-vehicles` dataset) and `vehicle-registration-input` (a UK number-plate field that auto-formats all five registration formats, with a plate visual variant and live format/age/region decoding via the `vehicle-registration` lib module).
- Docs#35
The docs engine: view-code toggles on every demo, generated API/props tables, cross-link chips between related items, per-item markdown cards at `/llms/<name>.md`, a table-of-contents rail and dual-mode preview canvases.
- Docs
Docs-drift audit fixes: updated brand-variant docs to list all eight drop-in themes (added nexus-midnight, nexus-sand, nexus-slate which shipped without docs); corrected block install-path docs to reflect that all blocks install under `components/blocks/` (no flatten-to-root); filled out AGENTS.md structure table with three missing block subdirs (calendar-view, kanban, settings) and geo-fixtures dataset; fixed `registry.json` homepage to `https://ui.nexusregen.com` per architecture.md; added an icon name quick-reference table to the consumer skill.
- Fixed
Accessibility wave: all 111 serious findings from the a11y audit cleared across the component suite and showcase — missing accessible names and labels, aria reference integrity, duplicate ids, landmarks and contrast.
- Internal#34
Showcase wayfinding: collapsible nav groups, command-palette upgrades (including recents), a top bar dogfooding ScopeBreadcrumbs, a keyboard-shortcuts dialog, and the first changelog page.
- Fixed#30
Bare `text-tertiary`/`text-quaternary` utilities (which don't exist in the theme) replaced with the correct full-token forms `text-text-tertiary`/`text-text-quaternary` wherever they had crept in.
- Docs#12
Consumer skill bumped to 1.2.0: theme-variant wiring, block install paths and refreshed inventories.
- Added#27
Sidebar-nav scroll affordances via the new `scroll-fade` block, a user-menu organisation section, and breadcrumb Untitled UI parity.
- Fixed#18
Restored the shadcn custom variants and utilities the theme had dropped — `styles/shadcn-compat.css` now ships with the theme item, carrying the `data-*` variants and scroll/shimmer utilities the base-vega components rely on.
theme - Added#19
The scoped app shell for core nx products: optional top bar, org ▸ project scope breadcrumbs with switchers, the two-level sliding sidebar nav, and the app-switcher launcher. `app-shell` gained the top-bar slot (additive).
- Internal#32
Showcase QA tooling: live-preview viewport presets, the `/foundations/theme-matrix` page for eyeballing every brand x mode combination, and a generated design-token reference (`build-token-docs.ts`).
- Internal#14
Showcase preview UX: nav affordances, pointer cursors, and full-width + windowed preview modes.
- Added#31
Three visual-first opportunity surfaces: the proximity map, the cost-proportional flow canvas and the cost-vs-readiness decision grid.
- Added#29
The opportunity matrix family: pathway comparison cards, the options matrix and AI viability surfaces for material-routing decisions.
- Fixed#16
Notification centre rebuilt on the nexus4 anatomy: unread edge bars, severity tiles, date-grouped rows under sticky headers, inline decisions and hover quick actions.
- Internal#11
Motion and polish pass across the showcase — scroll reveals, transitions and consistency fixes.
- Added#24
The componentised marketplace map experience: supercluster bubbles with type-mix rings, the virtualised listings panel, the faceted filter panel, shared listing cards, and the headless orchestrator hooks.
marketplace-maplistings-panellistings-filterslisting-cardmarketplace-typesuse-marketplaceuse-listings-clusters - Added#6
The marketing pattern family: config-driven backdrops, heroes, section primitives, feature rows and cards, CTA band, logo cloud, testimonials, stats band, how-it-works, FAQ, and the site header/footer.
- Added#20
Map tooling: the glass-pill map toolbar, travel-time isochrone overlays, click-to-add waypoint routing (both against the nx-geo contracts), and the cinematic transfer-preview choreography.
- Internal#15
Site header/footer demos now use the real Nexus lockup; the footer watermark reuses `nx-emblem`.
- Docs#33
Home page redesigned (hero band, live registry stats, curated highlights) and a `/docs` section added to the showcase: getting-started, theming, components-and-blocks, app-shell-pattern and contributing guides.
- Internal#10
The examples gallery: full-page compositions served full-bleed at `/view/<slug>` — auth screens, dashboards, settings, error states and the live Movement Control Room.
- Added
DX wave: visual regression (`bun run visual`) and accessibility audit (`bun run a11y`) suites, generated per-component API docs on showcase pages, the `llms.txt`/`llms-full.txt` agent manifests, and the compact density mode (showcase-only theme capability).
- Added#17
Domain modal selector flows: the full EWC List of Wastes lookup modal, the grouped material picker modal with cascading suggestions, and the location field flow with directory search and a map escape hatch.
- Added#9
The TanStack Table data-table kit in the shadcn idiom: sorting, faceted and multi-column filters, global search, row selection with a bulk-action bar, pagination, column visibility and pinning, expandable sub-rows, loading skeletons and empty states — plus tables and charts showcase sections.
- Added
21 new components and blocks in one wave, a brand refresh, and the surface brand-variant themes (ultraviolet, evergreen, ocean, ember, graphite) switched by `data-brand`.
- Added#28
Collapsible open/close motion, the checkbox-card and checkbox-group components, and an accordion badge-gap fix.
- Added#13
The brand icon system: `nx-emblem` weights (regular keyline through solid), the Google-style `nx-app-icon` product family, and the yellow-on-dark logo treatment.
- Fixed#26
Glow variants, a brand-fill contrast audit across both modes, and the background-pattern stacking contract.
- Added#8
31 AI Elements ports (`ai-*` items: conversation, message, reasoning, tool, prompt-input, workflow canvas and friends), restyled to the nx look and installing to `components/ai/`.
- Added#4
The Mapbox map suite: a theme-aware `map-view` wrapper plus branded markers, clustered site maps, route maps with progress overlays, boundary polygons and glass stat overlays.
- Added#3
Untitled UI parity wave for forms: date picker, filters, tags, file upload, stepper and friends joined the suite.
- Added#7
The Nexus domain family: EWC (European Waste Catalogue) selector, construction material selector, UK location selector, project-scope selector and compliance checklist, with their reference datasets shipped as `data-*` items.
- Added#5
Untitled UI parity wave for display components, plus the design-flare utilities (`flare-styles`).
- Added
The two-layer design-token foundation landed: the full Untitled UI colour/type/shadow/radius system carrying Nexus navy and Aureolin yellow, mapped onto shadcn's semantic CSS variables, with light and dark driven by `light-mode`/`dark-mode` classes (primary flips navy→yellow in dark).
theme - Internal
Showcase gallery infrastructure and 69 demo pages (59 components + 10 blocks), dogfooding the app-shell blocks as the gallery's own chrome.
- Added
All 60 base components restyled to the Untitled UI look under the minimal-diff doctrine (tokens first, class deltas second, APIs untouched), plus the first 10 app-shell blocks and the registry build system that derives dependencies by parsing imports.
- Internal#2
Showcase preview UX: ⌘K search, brand theme variations behind a picker, and the generated navigation manifest.
- Fixed
Base UI menu labels must sit inside a Group — fixed everywhere and guarded by a new headless interaction smoke test (`bun run smoke`) that clicks every control on every showcase page.
- Internal
Repo scaffolded: Next.js 16 App Router showcase app with the full shadcn base-vega baseline (60 unmodified components) on Base UI primitives, Bun and Tailwind CSS v4.
- Fixed
Removed stale per-component `dark:` overrides that fought the theme's token flip — dark mode now comes entirely from CSS variables.
- Fixed
First consumption-test findings fixed: `shadcn init` guidance, removal of conflicting globals.css scaffolding, and correct consumer install paths for blocks.
- Docs
The two canonical agent skills shipped: `nx-ui-components` (consuming — discovery, install, theme wiring, troubleshooting) and `nx-ui-contribute` (maintaining — the minimal-diff doctrine and registry regeneration).