LLabanaat
React 19TypeScriptTailwind CSSRadix Primitives

Building blocks for
modern React interfaces.

Labanaat UI is a modern, accessible React component library designed for building production-ready interfaces — 47 components, one consistent way to use them, and a token system that makes it genuinely yours.

$ npm install @labanaat/ui

Workspace settings

Live components rendered on this page — not a screenshot.

Ada Lovelace
Ada Lovelace
ada@example.com
Owner
Default role for new members

Numbers you can check against the repository yourself — nothing here is a marketing estimate.

47
components
16
built on Radix primitives
31
composed from scratch or a purpose-fit library
0
required config to start

The parts of every project nobody wants to rebuild.

None of this is glamorous work, which is exactly why it keeps getting skipped, rushed, or copy-pasted from the last project. Labanaat exists so your team spends its time on the product, not on reinventing a dropdown.

Rebuilding the same 30 components

Every new product starts with a button, a dialog, a dropdown — built from scratch, styled by hand, accessibility bolted on later if at all. Labanaat starts you past that point, with the boring 80% already solved correctly.

A design system that fights your brand

Most libraries hardcode their look and dare you to override it with !important. Labanaat has no opinion about your brand — every color, radius, and shadow is a variable you own, from day one, not after a painful migration.

Accessibility as an afterthought

Keyboard traps, missing focus states, unlabeled icon buttons — the usual result of bolting a11y on at the end. Here it's part of the component's definition of done, with a CI pipeline that runs the full axe-core sweep on every change, not audited once a year.

Documentation that lies about the API

Docs that drift from the real props the moment someone ships a fix. Every component page here renders the actual, currently-published component — if the docs show it, that's what you get when you install it.

47 components. One consistent way to use them.

A sample of what's in the box — every piece below is a real, live instance of the library, sharing the same accent color you pick in the header, not a static mockup or screenshot.

Table
MemberStatus
Ada LovelaceAda LovelaceActive
Grace HopperGrace HopperInvited
Seats used70%
Button
Badge
PrimarySuccessWarningDanger
Accordion

Within 30 days, no questions asked.
Tabs

Manage your account settings.

Form controls
This is one page.
Every component on this section — table, buttons, badges, accordion, tabs, form controls — is imported straight from @labanaat/ui.

It's not just buttons and badges.

Drag-and-drop boards, charts, query builders, activity feeds — the same design system, the same tokens, the same accessibility bar. Drag a card below; it's a real board, not a screenshot.

Kanban
To do2
Design review
Write tests
Done1
Set up repo
Chart
FilterBuilder
Where
Field
Operator
ActivityFeed
Ada Lovelace

Ada Lovelace invited Grace Hopper

Alan Turing

Alan Turing created project Enigma

Same rules apply.
Kanban ships real keyboard drag support via dnd-kit's keyboard sensor, DataGrid and Chart aren't shown here but follow the exact same pattern — see the full component catalog.

Every value is a design token.

Color, spacing, radius, typography, shadow, and motion all resolve to a CSS variable defined once. Rebrand a whole app by overriding a handful of variables — no component code changes, no rebuild.

The color picker in the header above isn't decoration — it calls the exact same applyTokenOverrides() function you'd call in your own app. Twelve presets ship built in, and nothing stops you from passing your own hex values instead.

Even the neutral surfaces — card backgrounds, dividers, subtle fills — pick up a faint wash of whatever accent is active, via color-mix(), so a theme change feels coherent instead of like one button changed color on an otherwise gray page.

:root {
--ui-primary: #7c3aed;
--ui-radius-md: 0.375rem;
}

// every component picks this up automatically
<Button>Continue</Button>

Accessible by default, verified automatically.

Keyboard navigation, focus trapping, and correct ARIA roles are built into every interactive component — not bolted on. Every component ships with axe-core assertions, not just a claim in the docs.

Complex patterns — Dialog, Select, Combobox, Tabs — use Radix Primitives internally for behavior that's been battle-tested across thousands of production apps, wrapped in the library's own styling and API.

Where no accessible primitive existed — Combobox has none in Radix today — it's implemented directly against the WAI-ARIA 1.2 pattern rather than reaching for an unmaintained dependency just to check a box.

import { axe } from "vitest-axe";

it("has no violations", async () => {
const { container } = render(<Combobox />);
expect(await axe(container)).toHaveNoViolations();
});

Not "should work." Verified on every change.

36 of 47 components have a dedicated behavior test file, and the full library runs through a cross-component accessibility sweep against axe-core covering 40 — the same commands wired into a CI pipeline that runs on every pull request, not just before a release. Every component has at least one of the two; closing the remaining gap between the two sets is the next priority.

Interaction-heavy components get interaction-heavy tests — the Slider suite, for example, simulates real keyboard drags and asserts the displayed value actually updates live, for both single and range selection.

Test files
38
Assertions
189
a11y-swept components
40
Type coverage
100%
$ pnpm test

✓ src/components/button/Button.test.tsx (5 tests)
✓ src/components/slider/Slider.test.tsx (4 tests)
✓ src/components/combobox/Combobox.test.tsx (3 tests)
✓ src/components/calendar/Calendar.test.tsx (11 tests)
✓ src/test/accessibility.a11y.test.tsx (27 tests)

Test Files 38 passed (38)
Tests 189 passed (189)

One component. Both themes. No extra work.

Both cards below render simultaneously, independent of the toggle in the header, using the exact hex values the current accent resolves to in each theme — including the swatches underneath, so there's nothing to take on faith.

Light theme
GH
Grace Hopper
Deploy completed
Live
#ffffff
#f8fafc
#e2e8f0
#0f172a
#4F46E5
Dark theme
GH
Grace Hopper
Deploy completed
Live
#020617
#0f172a
#1e293b
#f8fafc
#6366F1

Compose the parts you need.

Card, Dialog, Drawer, and Accordion expose subcomponents instead of a wall of configuration props. Read the JSX, know the layout — no prop-hunting through documentation to find the one flag that changes the footer alignment.

It's the same philosophy end to end: components describe structure, tokens describe appearance, and neither one leaks into deciding things the other should own.

<Card>
<Card.Header>
<Card.Title>Plan</Card.Title>
</Card.Header>
<Card.Content>
<ProgressBar value={7} max={10} />
</Card.Content>
</Card>

From install to themed, in three steps.

1. Install

One package, scoped entry points per component so your bundler only ships what you import.

$ npm install @labanaat/ui

2. Import

No provider soup, no config file. Import the stylesheet once, then components as you need them.

import { Button } from "@labanaat/ui/button";

3. Theme it

Override the tokens that matter to you. Everything else — hover states, focus rings, dark mode — follows automatically.

--ui-primary: #e11d48;

Start with the components you need today.

Every component ships its own entry point, so you only bundle what you import — 47 components, one consistent way to reach for any of them, from a Button to a full DataGrid.

No config file to write before your first component renders, no design tokens to define from scratch — pick an accent color and start building.

$ npm install @labanaat/ui

import { Button } from "@labanaat/ui/button";
import "@labanaat/ui/styles.css";

// that's it — no provider, no config
<Button>Get started</Button>