@renge-ui/react
60+ component primitives.
All consuming Renge tokens via inline styles. Zero CSS-in-JS runtime, no class names, no specificity battles.
pnpm add @renge-ui/reactLayout
Container and grid components for page structure.
Stack
Flexbox container with configurable direction, gap, and alignment.
Horizontal / Vertical
<Stack direction="horizontal" gap="3">
<Badge>A</Badge>
<Badge>B</Badge>
</Stack>
<Stack direction="vertical" gap="2" align="flex-start">
<Button>Primary</Button>
<Button variant="outline">Secondary</Button>
</Stack>| Prop | Type | Default | Description |
|---|---|---|---|
| direction | "horizontal" | "vertical" | "vertical" | Flex direction |
| gap | "1"–"8" | "4" | Space between items (Renge space token) |
| align | string | "flex-start" | align-items value |
| justify | string | "flex-start" | justify-content value |
| wrap | boolean | false | Allow items to wrap |
Grid
CSS Grid layout with configurable columns and gap.
3-column grid
<Grid columns={3} gap="4">
<Card>One</Card>
<Card>Two</Card>
<Card>Three</Card>
</Grid>| Prop | Type | Default | Description |
|---|---|---|---|
| columns | number | string | 2 | Number of columns or a CSS grid-template-columns value |
| gap | "1"–"8" | "4" | Gap between cells |
AspectRatio
Constrains children to a fixed aspect ratio. Defaults to PHI (1.618).
PHI ratio / 16:9
<AspectRatio> {/* defaults to PHI = 1.618 */}
<img src="..." />
</AspectRatio>
<AspectRatio ratio={16/9}>
<video src="..." />
</AspectRatio>| Prop | Type | Default | Description |
|---|---|---|---|
| ratio | number | 1.618 | Width-to-height ratio. Defaults to PHI. |
Typography
Text, headings, links, and separators.
Heading
Semantic heading elements with token-driven sizes independent of level.
All sizes
Heading 4xl
Heading 3xl
Heading 2xl
Heading xl
Heading lg
<Heading level={1} size="4xl">Display heading</Heading>
<Heading level={2} size="xl">Section title</Heading>
<Heading level={3} size="lg">Subsection</Heading>| Prop | Type | Default | Description |
|---|---|---|---|
| level | 1 | 2 | 3 | 4 | 5 | 6 | 2 | HTML heading element level (h1–h6) |
| size | "lg" | "xl" | "2xl" | "3xl" | "4xl" | maps to level | Visual size — decoupled from semantic level |
| color | string | "fg" | Token color alias |
Text
Inline or block text with token-driven sizing and color.
Sizes & colors
<Text size="lg" color="fg">Primary text</Text>
<Text size="sm" color="fg-subtle">Secondary text</Text>
<Text as="p" size="base">Block paragraph</Text>| Prop | Type | Default | Description |
|---|---|---|---|
| as | ElementType | "span" | HTML element to render ("p", "span", "label", etc.) |
| size | "xs" | "sm" | "base" | "lg" | "xl" | "base" | Font size from the Renge type scale |
| color | string | "fg" | Token color alias: "fg", "fg-subtle", "fg-muted", "accent" |
| weight | string | — | Font weight override |
Anchor
Styled link with underline and color control.
<Anchor href="/docs">Read the docs</Anchor>
<Anchor href="https://..." target="_blank" rel="noopener noreferrer">Open in new tab</Anchor>
<Anchor href="#section" variant="subtle">Subtle</Anchor>| Prop | Type | Default | Description |
|---|---|---|---|
| href | string | — | Link destination |
| variant | "default" | "subtle" | "default" | Color and underline style |
| underline | boolean | false | Always show underline (default: underline on hover) |
Surfaces
Container components for grouping content.
Card
Content container with elevated, outlined, or filled appearance.
Variants
<Card variant="elevated" padding="4" radius="3">
<Heading level={3} size="lg">Title</Heading>
<Text color="fg-subtle">Description text here.</Text>
</Card>| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "elevated" | "outlined" | "filled" | "elevated" | Visual style of the card surface |
| padding | "1"–"8" | "4" | Inner padding (Renge space token) |
| radius | "1" | "2" | "3" | "full" | "2" | Border radius |
Interactive
Buttons and trigger controls.
Button
Primary action trigger with variant, size, and state options.
Variants
Sizes
Color schemes
<Button variant="solid" size="md" colorScheme="accent">
Save changes
</Button>
<Button variant="outline" size="sm">
Cancel
</Button>
<Button variant="solid" colorScheme="danger" onClick={handleDelete}>
Delete
</Button>| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "solid" | "outline" | "ghost" | "solid" | Visual style |
| size | "sm" | "md" | "lg" | "md" | Height and padding |
| colorScheme | "accent" | "danger" | "success" | "accent" | Color token set applied to the button |
| fullWidth | boolean | false | Stretch button to fill its container |
| disabled | boolean | false | Prevents interaction, reduces opacity |
Keyboard
| Key | Action |
|---|---|
EnterSpace | Activate the button |
Tab | Move focus to next focusable element |
ShiftTab | Move focus to previous focusable element |
IconButton
Square button for icon-only actions. Requires an aria-label.
Sizes
Variants
<IconButton aria-label="Close dialog" size="md" variant="ghost">
✕
</IconButton>| Prop | Type | Default | Description |
|---|---|---|---|
| aria-label | string | required | Accessible label (no visible text) |
| size | "sm" | "md" | "lg" | "md" | Square dimension |
| variant | "solid" | "outline" | "ghost" | "ghost" | Visual style |
Keyboard
| Key | Action |
|---|---|
EnterSpace | Activate the button |
CopyButton
Copies a value to clipboard. Briefly shows a confirmation state.
Example
<CopyButton
value="pnpm add @renge-ui/react"
label="Copy"
successLabel="Copied!"
timeout={2100}
/>| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | required | Text to copy to clipboard |
| label | string | "Copy" | Button label in default state |
| successLabel | string | "Copied!" | Label shown after successful copy |
| timeout | number | 2100 | ms before reverting to default label |
Keyboard
| Key | Action |
|---|---|
EnterSpace | Copy text to clipboard |
ButtonGroup
Groups related buttons with flush, attached borders.
Attached
Detached
<ButtonGroup attached>
<Button variant="outline">Day</Button>
<Button variant="outline">Week</Button>
<Button variant="solid">Month</Button>
</ButtonGroup>| Prop | Type | Default | Description |
|---|---|---|---|
| attached | boolean | true | When true, buttons share borders and have no gap |
| orientation | "horizontal" | "vertical" | "horizontal" | Layout direction |
Form Inputs
Text and value input controls.
Input
Text input with size, state, and type variants. Pair with FormField for labels.
Sizes
States
<FormField label="Email" htmlFor="email" required>
<Input id="email" type="email" placeholder="you@example.com" />
</FormField>
<FormField label="Username" htmlFor="user" errorText="Username is taken">
<Input id="user" state="error" value="taken_name" />
</FormField>| Prop | Type | Default | Description |
|---|---|---|---|
| size | "sm" | "md" | "lg" | "md" | Height and font size |
| state | "default" | "error" | "success" | "default" | Visual validation state |
| fullWidth | boolean | false | Stretches input to fill container |
| disabled | boolean | false | Prevents interaction |
Keyboard
| Key | Action |
|---|---|
Tab | Focus the input |
Enter | Submit enclosing form |
Select
Styled native select element.
Sizes
<FormField label="Country" htmlFor="country">
<Select id="country">
<option value="">Select a country</option>
<option value="us">United States</option>
<option value="uk">United Kingdom</option>
</Select>
</FormField>| Prop | Type | Default | Description |
|---|---|---|---|
| size | "sm" | "md" | "lg" | "md" | Height and font size |
| fullWidth | boolean | false | Stretches to fill container |
| disabled | boolean | false | Prevents interaction |
Keyboard
| Key | Action |
|---|---|
↑↓ | Navigate between options |
EnterSpace | Open dropdown / select focused option |
Escape | Close dropdown without selecting |
Textarea
Multi-line text input.
Example
<FormField label="Message" htmlFor="msg">
<Textarea id="msg" placeholder="Write something…" rows={4} />
</FormField>| Prop | Type | Default | Description |
|---|---|---|---|
| rows | number | 3 | Initial visible row count |
| resize | "none" | "vertical" | "both" | "vertical" | CSS resize direction |
| state | "default" | "error" | "default" | Validation state |
Checkbox
Binary toggle with label, checked, and indeterminate states.
States
const [agreed, setAgreed] = useState(false);
<Checkbox
label="I agree to the terms"
checked={agreed}
onChange={() => setAgreed(p => !p)}
/>
{/* Indeterminate (partial selection) */}
<Checkbox
label="Select all"
checked={false}
indeterminate
onChange={handleSelectAll}
/>| Prop | Type | Default | Description |
|---|---|---|---|
| label | string | — | Visible label text |
| checked | boolean | false | Controlled checked state |
| indeterminate | boolean | false | Partial-selection state (renders a dash) |
| disabled | boolean | false | Prevents interaction |
| onChange | () => void | — | Called on user toggle |
Keyboard
| Key | Action |
|---|---|
Space | Toggle checked / unchecked |
Switch
Toggle switch with golden-ratio track proportions.
States
const [enabled, setEnabled] = useState(false);
<Switch
label="Enable notifications"
checked={enabled}
onChange={() => setEnabled(p => !p)}
/>| Prop | Type | Default | Description |
|---|---|---|---|
| label | string | — | Visible label text |
| checked | boolean | false | Controlled on/off state |
| disabled | boolean | false | Prevents interaction |
| onChange | () => void | — | Called on user toggle |
Keyboard
| Key | Action |
|---|---|
Space | Toggle on / off |
RadioGroup / Radio
Single-choice selection group. Inner dot sized at outer/PHI.
Vertical group
const [plan, setPlan] = useState("starter");
<RadioGroup value={plan} onChange={setPlan} name="plan">
<Radio value="starter" label="Starter — Free" />
<Radio value="pro" label="Pro — $12/mo" />
<Radio value="enterprise" label="Enterprise — Custom" />
</RadioGroup>| Prop | Type | Default | Description |
|---|---|---|---|
| name | string | required | HTML name attribute shared by all radios in the group |
| value | string | — | Currently selected value (controlled) |
| defaultValue | string | — | Initial value (uncontrolled) |
| onChange | (value: string) => void | — | Called when selection changes |
| direction | "vertical" | "horizontal" | "vertical" | Layout direction |
Keyboard
| Key | Action |
|---|---|
↑↓←→ | Move selection through radio options |
Space | Select the focused radio |
Slider
Range input. Current value: 50
Controlled
const [value, setValue] = useState(50);
<Slider
min={0}
max={100}
step={1}
value={value}
onChange={(e) => setValue(Number(e.target.value))}
/>| Prop | Type | Default | Description |
|---|---|---|---|
| value | number | — | Controlled value |
| min | number | 0 | Minimum value |
| max | number | 100 | Maximum value |
| step | number | 1 | Increment step |
| onChange | (value: number) => void | — | Called on change |
Keyboard
| Key | Action |
|---|---|
←↓ | Decrease value by one step |
→↑ | Increase value by one step |
Home | Jump to minimum |
End | Jump to maximum |
FormField
Wrapper that adds a label, helper text, and error message to any input.
With helper / error
<FormField
label="Email"
htmlFor="email"
helperText="We'll never share this."
required
>
<Input id="email" type="email" />
</FormField>
<FormField label="Username" htmlFor="user" errorText="Already taken">
<Input id="user" state="error" />
</FormField>| Prop | Type | Default | Description |
|---|---|---|---|
| label | string | required | Visible label text |
| htmlFor | string | — | Links label to an input id |
| helperText | string | — | Shown below input in muted color |
| errorText | string | — | Shown below input in danger color; overrides helperText |
| required | boolean | false | Appends a * marker to the label |
Advanced Inputs
Complex multi-value input components.
NumberInput
Number input with − / + stepper buttons. Current value: 5
Controlled
const [qty, setQty] = useState(1);
<NumberInput
value={qty}
min={1}
max={99}
step={1}
onChange={setQty}
/>| Prop | Type | Default | Description |
|---|---|---|---|
| value | number | — | Controlled value |
| min | number | — | Lower bound (decrement button disables at min) |
| max | number | — | Upper bound |
| step | number | 1 | Increment amount |
| onChange | (value: number) => void | — | Called on change |
Keyboard
| Key | Action |
|---|---|
↑ | Increment by step |
↓ | Decrement by step |
TagInput
Controlled tag entry. Press Enter or comma to add; Backspace to remove last.
Controlled
const [tags, setTags] = useState(["design", "system"]);
<TagInput
tags={tags}
onChange={setTags}
placeholder="Add a tag…"
/>| Prop | Type | Default | Description |
|---|---|---|---|
| tags | string[] | [] | Controlled array of tag strings |
| onChange | (tags: string[]) => void | — | Called on add or remove |
| placeholder | string | "Add tags…" | Input placeholder text |
Keyboard
| Key | Action |
|---|---|
Enter, | Add current input text as a tag |
Backspace | Remove last tag when input is empty |
Rating
Star rating input. Current: 3 / 5
Controlled / Readonly
const [stars, setStars] = useState(0);
<Rating value={stars} max={5} onChange={setStars} />
{/* Read-only display */}
<Rating value={4.0} max={5} readonly />| Prop | Type | Default | Description |
|---|---|---|---|
| value | number | 0 | Number of filled stars |
| max | number | 5 | Total number of stars |
| readonly | boolean | false | Disables interaction when true |
| onChange | (value: number) => void | — | Called on star click |
Keyboard
| Key | Action |
|---|---|
← | Decrease rating |
→ | Increase rating |
Home | Set to minimum |
End | Set to maximum |
Data Display
Components for displaying structured information.
Badge
Label badge with semantic color schemes.
Variants (color)
Sizes
<Badge variant="success">Verified</Badge>
<Badge variant="warning">Pending review</Badge>
<Badge variant="danger">Rejected</Badge>
<Badge variant="neutral" size="sm">Draft</Badge>| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "accent" | "neutral" | "success" | "warning" | "danger" | "info" | "neutral" | Semantic color scheme |
| size | "sm" | "md" | "lg" | "md" | Badge size |
Avatar
User avatar with image support and initials fallback.
Sizes & fallback
{/* Initials fallback */}
<Avatar initials="VM" size="3" />
{/* With image */}
<Avatar src="/avatar.png" alt="Vanessa Martin" size="4" />
{/* Square shape */}
<Avatar initials="VM" size="3" shape="square" />| Prop | Type | Default | Description |
|---|---|---|---|
| initials | string | — | Text rendered as initials (max 2 chars); shown when no src |
| src | string | — | Image URL; falls back to initials if omitted or fails |
| alt | string | — | Alt text for image |
| size | "1" | "2" | "3" | "4" | "5" | "3" | Diameter — Fibonacci steps (1=smallest, 5=largest) |
| shape | "circle" | "square" | "circle" | Border radius shape |
Stat
Metric display with optional label and trend indicator.
Examples
<Stat
label="Monthly Revenue"
value="$84,240"
trend="up"
trendValue="+12% this month"
/>| Prop | Type | Default | Description |
|---|---|---|---|
| label | string | — | Metric label above the value |
| value | string | — | Primary metric value |
| trend | "up" | "down" | — | Arrow direction for trend indicator |
| trendValue | string | — | Trend description text |
Alert
Status message with semantic color and optional title.
Status variants
<Alert status="success" title="Published">
Your post is now live.
</Alert>
<Alert status="danger" title="Failed to save">
Please check your connection and try again.
</Alert>| Prop | Type | Default | Description |
|---|---|---|---|
| status | "info" | "success" | "warning" | "error" | "info" | Semantic status; controls icon and color |
| title | string | — | Bold heading above the message |
| onClose | () => void | — | If provided, renders a close button |
Tables & Lists
Structured data display and expandable content.
Table
Data table with bordered and striped variants.
Example
| Package | Version | Status |
|---|---|---|
@renge-ui/tokens | 2.6.1 | stable |
@renge-ui/react | 3.7.0 | stable |
@renge-ui/tailwind | 2.9.0 | stable |
@renge-ui/petals | 1.1.0 | stable |
@renge-ui/vue | 1.1.0 | stable |
@renge-ui/svelte | 1.1.0 | stable |
@renge-ui/test-utils | 1.0.2 | stable |
<Table bordered striped>
<TableHead>
<TableRow>
<TableHeader>Name</TableHeader>
<TableHeader>Status</TableHeader>
</TableRow>
</TableHead>
<TableBody>
<TableRow index={0}>
<TableCell>Alpha</TableCell>
<TableCell><Badge variant="success">Active</Badge></TableCell>
</TableRow>
</TableBody>
</Table>| Prop | Type | Default | Description |
|---|---|---|---|
| striped | boolean | false | Alternates row backgrounds |
| bordered | boolean | false | Adds outer border and radius |
Accordion
Collapsible sections. By default only one item can be open at a time.
Example
<Accordion multiple>
<AccordionItem id="q1" title="What is Renge?">
A design system built on natural mathematics.
</AccordionItem>
<AccordionItem id="q2" title="How do I install?">
pnpm add @renge-ui/react
</AccordionItem>
</Accordion>| Prop | Type | Default | Description |
|---|---|---|---|
| multiple | boolean | false | Allow multiple items open simultaneously |
| value | string | string[] | — | Controlled open item id(s) |
Keyboard
| Key | Action |
|---|---|
Tab | Move focus between accordion headers |
EnterSpace | Toggle the focused item open/closed |
Skeleton
Animated loading placeholder. Use in place of content while data is fetching.
Shapes
{/* Text placeholder */}
<Skeleton variant="text" lines={3} />
{/* Avatar placeholder (circular) */}
<Skeleton variant="circular" height="48px" width="48px" />
{/* Card / image placeholder */}
<Skeleton variant="rectangular" height="200px" />| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "text" | "circular" | "rectangular" | "rectangular" | Shape variant |
| width | string | "100%" | CSS width value |
| height | string | "1rem" | CSS height value |
| lines | number | 3 | Line count when variant='text' |
Feedback & Status
Loading states, progress, and overlays.
Spinner
Animated loading indicator.
Sizes
<Spinner size="md" />
{/* With loading state */}
<Button disabled={isLoading}>
{isLoading ? <Spinner size="sm" /> : "Submit"}
</Button>| Prop | Type | Default | Description |
|---|---|---|---|
| size | "sm" | "md" | "lg" | "md" | Spinner diameter |
| color | string | "accent" | Token color |
Progress
Horizontal progress bar with value and color scheme options.
Values
<Progress value={61.8} color="accent" />
<Progress value={100} color="success" aria-label="Upload complete" />| Prop | Type | Default | Description |
|---|---|---|---|
| value | number | 0 | Progress percentage (0–100) |
| color | "accent" | "success" | "warning" | "danger" | "accent" | Fill color |
Modal
Accessible dialog rendered into a portal. Traps focus and locks scroll.
Example
const [open, setOpen] = useState(false);
<Button onClick={() => setOpen(true)}>Open modal</Button>
<Modal open={open} onClose={() => setOpen(false)} size="md">
<ModalHeader>
<Heading level={2} size="lg">Confirm deletion</Heading>
</ModalHeader>
<ModalBody>
<Text>This action cannot be undone.</Text>
</ModalBody>
<ModalFooter>
<Button variant="outline" onClick={() => setOpen(false)}>Cancel</Button>
<Button colorScheme="danger" onClick={handleDelete}>Delete</Button>
</ModalFooter>
</Modal>| Prop | Type | Default | Description |
|---|---|---|---|
| open | boolean | false | Controls visibility |
| onClose | () => void | — | Called when backdrop clicked or Escape pressed |
| size | "sm" | "md" | "lg" | "md" | Max-width of the dialog |
Keyboard
| Key | Action |
|---|---|
Tab | Move focus forward through dialog elements (trapped inside modal) |
ShiftTab | Move focus backward through dialog elements |
Escape | Close the modal |
Progress & Steps
Multi-step flows and process indicators.
Stepper
Horizontal step indicator for multi-step flows. Current step: 2 / 4
Controlled
const [step, setStep] = useState(0);
const steps = [
{ label: "Install", description: "Add the package" },
{ label: "Configure", description: "Set up tokens" },
{ label: "Build", description: "Use components" },
{ label: "Ship", description: "Deploy" },
];
<Stepper
steps={steps}
currentStep={step}
onStepChange={setStep}
/>| Prop | Type | Default | Description |
|---|---|---|---|
| steps | { label: string; description?: string }[] | required | Array of step objects |
| currentStep | number | 0 | Zero-indexed active step |
| onStepChange | (step: number) => void | — | Called when a step is clicked |
Display & Content
Utility display components.
KBD
Keyboard shortcut indicator with monospace styling.
Examples
Press <KBD>⌘</KBD> + <KBD>K</KBD> to open search.Chip
Small inline tag — dismissible or selectable.
Variants
<Chip variant="accent">React</Chip>
<Chip variant="neutral" onDismiss={() => removeTag("design")}>Design</Chip>| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "neutral" | "accent" | "success" | "warning" | "danger" | "info" | "neutral" | Semantic color scheme |
| onDismiss | () => void | — | If provided, renders a × dismiss button |
Accessibility Utilities
Components for building inclusive interfaces.
VisuallyHidden
Renders content visually hidden but accessible to screen readers.
<button aria-label="Close">
<VisuallyHidden>Close dialog</VisuallyHidden>
✕
</button>SkipLink
Keyboard-accessible link that appears on focus, allowing users to skip to main content.
{/* Place at the very top of your layout */}
<SkipLink href="#main">Skip to main content</SkipLink>
<Navbar>…</Navbar>
<main id="main">…</main>Full Reference
All 60+ components are fully typed with TypeScript, accept standard HTML props via spread, and use Renge tokens exclusively for styling. See @renge-ui/react on npm or the GitHub README for the complete API.
