@zero.sc/ui
v0.1.5
Published
React components that encode an application shell — 144 components, light and dark, 375px first, accessibility to the ARIA Authoring Practices.
Maintainers
Readme
The problem this solves
There is no shortage of component libraries. What this package is actually about is not the components — it is the shell.
Ship ten products and you get ten headers at ten different heights, an account menu in a different corner each time, and a sign-out link nobody can find twice. Users moving between products from the same organisation relearn the furniture at every door.
@zero.sc/ui is that shell written down as code: nav height, control sizing, what the
account menu contains, where the language and theme switches live, what collapses on a
narrow screen. The components exist to keep that contract, not the other way round.
Install
npm install @zero.sc/uiimport '@zero.sc/ui/styles.css';react and react-dom 19 are peers. The only runtime dependencies are clsx,
tailwind-merge and @zero.sc/motion —
this is not a wrapper over radix, shadcn or headlessui. It was written from scratch.
Sixty seconds
import { Button, Card, CardHeader, Input } from '@zero.sc/ui';
export function SignIn() {
return (
<Card>
<CardHeader title="Sign in" description="Use your work email." />
<Input label="Email" type="email" />
<Input label="Password" type="password" />
<Button variant="primary">Continue</Button>
</Card>
);
}What's inside
144 components across twenty-one groups.
| Group | Count | What |
|-------|-------|------|
| components | 64 | Buttons, inputs, selects, tabs, modals, toasts — the floor |
| media | 12 | Image, video and audio surfaces |
| ai | 8 | Assistant panel, streaming bubbles, pipeline readouts |
| data | 7 | Tables, charts, pagination |
| layout | 6 | Shell, grid, stack |
| feedback | 5 | Empty states, errors, loading |
| canvas · editor · immersive · realtime · social | 4 each | Drawing, document editing, 3D, realtime, social |
| commerce · form · nav · overlay · structure | 3 each | Checkout, forms, navigation, overlays, skeleton |
| action · display | 2 each | Doing, showing |
| docs · i18n · lib | 1 each | Docs, locale, utilities |
The hooks are usable on their own: use-controllable (controlled and uncontrolled in one),
use-focus-trap, use-roving-tabindex, use-typeahead, use-dismiss, use-anchor,
use-position, use-scroll-lock, use-presence.
The contract it keeps
- 375px is the floor, not an afterthought. Desktop is layered on top, never the reverse. Touch targets 44px, input text 16px (iOS refuses to zoom below that), header 56px.
- Two palettes. Colour is declared as OKLCH tokens and light/dark is a token redefinition — no light/dark branching inside components.
- Accessibility follows the spec. Roving tabindex, focus trap, typeahead and inert backgrounds implement the behaviour defined by the W3C ARIA Authoring Practices. We did not invent it; screen readers already know it.
"use client"sits on file boundaries. 133 files carry the directive, so inside a server component tree only what needs to be a client becomes one. That is why this ships file-by-file instead of bundled.- English defaults, overridable. Component copy ships in English. Strings that appear on screen are props, so an app supplies its own language rather than inheriting ours.
Honest limits
- 77 of 144 components let a
refthrough. React 19 treatsrefas an ordinary prop, so a plain{...props}spread forwards it — but 67 components still handle it in no form at all. - There are zero render tests. The current suite exercises pure logic only. Whether focus trap or roving tabindex actually behaves has to be checked by eye in the live gallery; there is no automated check yet.
asChildcomposition exists on 6 components, the trigger-shaped ones.- This is 0.x. No line has been drawn yet between which of the 685 exports are public contract and which are internal. The surface may shrink before 1.0.
- The license text shipped with this version is still an unreviewed draft — see below.
Around it
| | |
|---|---|
| Docs and playground | kit.zero.sc |
| Motion | @zero.sc/motion — used by this package |
| A whole app | @zero.sc/create — landing, console, sign-in and ten locales already wired |
| Everything | @zero.sc |
License
MIT OR Zero License v1.0 — take whichever you prefer. Choosing MIT is enough; nothing further is required of you.
The Zero name, marks and logos are not covered — build anything you like with this code, just don't present it as a Zero product.
Copyright (c) 2026 Zero. Source Code begins at Zero.
