@arun-dev/ui
v3.0.0
Published
Brand-agnostic React component library styled entirely via @arun-dev/tokens semantic CSS custom properties
Maintainers
Readme
@arun-dev/ui
Brand-agnostic React component library. Components carry no colors of their own — all visual
styling resolves through semantic CSS custom properties from
@arun-dev/tokens.
Installation
npm install @arun-dev/ui @arun-dev/tokensPeer dependencies: react >= 19, react-dom >= 19.
Setup — tokens are required
Components read semantic tokens (--color-bg-*, --color-text-*, --color-border-*, …) at
render time. Load the tokens and the component styles once, before any component renders:
import '@arun-dev/tokens/base'; // primitives + default brand
import '@arun-dev/ui/components.css'; // all component stylesTo use a custom brand instead of the default, replace the brand layer with your own stylesheet —
either generated by createBrand() from @arun-dev/tokens/createBrand, or hand-written. Any
brand CSS must define every variable in the BrandSemanticContract type.
Individual stylesheets are also exported if you prefer à la carte loading:
@arun-dev/ui/css/reset, …/css/btn, …/css/card, …/css/chip, …/css/badge,
…/css/metric, …/css/utilities.
Components
import { Button, Card, Chip, Badge } from '@arun-dev/ui';| Component | Props |
| --------- | --------------------------------------------------------------------------------------------------- |
| Button | variant: 'ghost' \| 'primary', href (renders <a>), type, disabled, onClick |
| Card | as (tag name, default div), lift (hover elevation) |
| Chip | variant: 'default' \| 'accent' |
| Badge | tone: 'neutral' \| 'success' \| 'warning' \| 'error' \| 'info' |
| Switch | Switch.Root / Switch.Thumb — checked, defaultChecked, onCheckedChange, disabled, name |
Props types are exported for the components this package defines — ButtonProps,
CardProps, ChipProps, BadgeProps — along with the ButtonVariant, ChipVariant and
BadgeTone value unions. Switch's types belong to
@arun-dev/headless; derive them with
ComponentProps<typeof Switch.Root>.
Every component also accepts:
className— concatenated with the component's own classes, never replacing them.render— an element or component to render instead of the default. Props,className, event handlers andrefare merged onto it. Its own props win,childrenincluded: an element with no children of its own takes the component's, one that declares children keeps them.ref— merged with any ref on therenderelement.- any other prop — spread onto the rendered element, so
id,aria-*,data-*and event handlers all reach the DOM.
<Chip render={<li />}>React</Chip>
<Button render={<NextLink href="/docs" />}>Docs</Button>
<Card render={<article />} lift>…</Card>Theming
Light and dark mode come from the token layer — system preference by default, explicit override
via data-theme="dark" / data-theme="light" on the root element. Components need no changes.
