⚠️ Mobile is not supported yet.
Search for a command to run...
An open source collection of accessible, contrast-gated React components on a warm neutral palette and a two-tier glass material — the VeloBits design system, authored once and shipped both as an npm package and as this registry.
The one sanctioned height animation: Radix measures --radix-accordion-content-height, so it does not thrash layout the way an unbounded height:auto transition would.
Status panel. Defaults to polite role="status"; escalate to "alert" deliberately. Tier-S glass on the neutral variant only — the four soft washes would replace the tint.
The authenticated chrome. `sidebar` is a prop rather than a child because it is rendered TWICE — as a rail at md and up, and inside a drawer below it — so a nav item cannot exist in one and not the other. Ships the skip link, which is the most-skipped WCAG requirement in an admin UI.
(No description)
Soft washes pair with the matching text token, never with the solid fill.
A named nav landmark around an ordered list. The leaf is a plain span with aria-current="page" — NOT shadcn’s role="link" aria-disabled, which announces static text as a broken link.
Controls are radius-md. No variant paints --primary as text; `link` uses --primary-text.
Tier-S glass by default; surface="panel" for the opaque original, which writes border-border explicitly so it survives an app that skipped the base layer.
Includes the indeterminate state bulk-selection headers need.
Tailwind-aware class merger. Signature must stay twMerge(clsx(...)) — the dashboard app points components.json `utils` at it.
Preformatted code, with a copy button that survives an insecure origin (navigator.clipboard is absent over plain http). The `terminal` variant is the theme-invariant --code/--on-code pair, which is what a one-time secret is revealed on.
cmdk inside a Radix Dialog. The ⌘K listener is opt-in via `shortcut` — a design system must not bind a global key by merely being imported.
Sorting, selection and row activation over a column registry — deliberately not TanStack, whose grouping and pivoting nothing here uses. aria-sort goes on the th, not the sort button, and an activatable row needs tabIndex + Enter/Space + a target check or it is mouse-only.
The centred form modal. `focusFirstField` exists because autoFocus is silently swallowed by Radix FocusScope.
A unified line diff. The +/− gutter is the primary channel and the green/red wash the secondary — colour alone fails 1.4.1, and the gutter is also the only channel that survives greyscale. Ships `diffLines`, with a guard: LCS is O(n·m) in MEMORY.
Highlight is data-[highlighted], never :hover — Radix drives keyboard focus through it. Cannot host a text input; use Dialog or Popover.
First-run, filtered-to-nothing and failed-to-load are three different states; this covers the first two and an Alert covers the third. The title is a <p> unless headingLevel is set, because an empty state usually sits inside a container that already has the heading.
Label/description/error wiring. Keeps BOTH ids in aria-describedby when a field has an error and a hint.
react-hook-form bound to Field’s ARIA wiring. label and description are PROPS, not children, because aria-describedby is assembled before children render — a description left out while its id is still listed is a dangling reference. NOT exported from the npm barrel: react-hook-form is an optional peer.
All three glass tiers behind one prop: surface (Tier S, no blur by default) · overlay · elevated. Never for page backgrounds, table rows, or nested glass.
border-input maps to --field-border, the half WCAG 1.4.11 gates.
A real <label>, so htmlFor resolves. Non-control roots need aria-labelledby instead.
Page transitions and capped list staggers on framer-motion, which was already a required peer for VelobitsProvider’s MotionConfig and until now bought nothing else. Subpath-only in the npm package (@velobitsio/ui/motion), like form, because the barrel’s own-code budget has ~4 kB left and nobody should pay for Framer to import a Button. Reduced motion is handled by MotionConfig and the token layer — do NOT add a third path. Stagger caps at STAGGER_LIMIT items so a 200-row list does not take eight seconds to arrive.
A cva-styled native <select>. Deliberately NOT Radix Select, which is undriveable under happy-dom.
Numbers are links, previous/next are buttons: an <a> cannot express "unavailable" without ceasing to be focusable. Unavailability is aria-disabled plus a guard, so focus is not lost at the ends of the range. `paginationRange` returns a CONSTANT number of slots so the control never reflows as you page.
The elevated tier, for glass stacked on glass. PopoverTitle wires aria-labelledby — Radix content is role="dialog" with no Title part, so it is otherwise unnamed.
Radix ToggleGroup with a REAL disabled and a working accessible name — a div root makes an external htmlFor dangle, and pointer-events-none leaves the control focusable and unannounced.
Decorative, so it uses --border and is exempt from 1.4.11.
The anchored reading sheet. Deliberately NOT Dialog and deliberately does NOT redirect focus — the two focus policies are opposites, so do not merge them behind a `side` variant. The bottom variant needs a definite 75dvh.
aria-hidden; pair with ONE sr-only live region rather than announcing each block.
On/off/partial/pending/archived as one chip. Every status ships a DISTINCT glyph, because colour alone fails 1.4.1 and on-versus-off is the distinction a control plane exists to make unambiguous. Composes Badge rather than re-deriving the soft-wash pairs.
Applies immediately. Thumb translation is mirrored explicitly for RTL.
Rows are never glass — one backdrop-filter per row repaints its own backdrop region on every scroll. Surface treatment belongs on the container.
React-free light/dark resolution, storage and the blocking init script. Storage key is required, never defaulted.
Variants use a logical border stripe, not a soft wash: bg-*-soft is a utility and beats --glass-bg from the components layer, flattening the tier.
TooltipProvider is required — Radix throws without it, and under Module Federation it must be a singleton.
Media query subscription plus usePrefersReducedMotion. Import breakpoints from @velobitsio/tokens rather than re-typing the pixel value, so the JS and CSS breakpoints cannot drift apart.
Row selection for DataTable. The selection is DERIVED — the stored set intersected with the rows on screen — so a bulk action can never point at a row the filter has hidden. Returns a stable object identity, which is what keeps DataTable’s memoised rows from re-rendering per keystroke.
ThemeProvider + useTheme. Honours the existing fmx_theme_mode and tf.theme keys.
The base style: tokens, the cn util, the provider stack, and every Tier-1 primitive, Tier-2 overlay and Tier-3 composite. Start here.
Mount once at the shell root: ThemeProvider + TooltipProvider + MotionConfig reducedMotion="user".
The full token layer as CSS variables. Every colour pair here is contrast-verified in both themes by the @velobitsio/tokens test suite.