# Introduction Tempo UI primitives for React and Vite apps. HTML: / Markdown: /index.md Regen collects Tempo UI primitives for React and Vite apps. Start with the [installation instructions](/installation.md), or use the project links below. ## Project Links - [GitHub repository](https://github.com/tempoxyz/regen): Source, releases, issues, and pull requests for the package. - [DESIGN.md](https://github.com/tempoxyz/regen/blob/main/DESIGN.md): Design-system conventions for tokens, component APIs, interaction, and review. - [AGENTS.md](https://github.com/tempoxyz/regen/blob/main/AGENTS.md): Project conventions for agents working in this repository. - [llms.txt](/llms.txt): Markdown index for agents and other non-browser clients. --- # Installation Install and configure Regen UI in a React app running through Vite. HTML: /installation Markdown: /installation.md ## Requirements Regen expects a React app running through Vite. Add Vite and the React plugin if the parent app does not already have them. ```bash pnpm add -D vite @vitejs/plugin-react ``` ## Install from the registry ```bash pnpm add regen-ui lucide-react ``` ## Or install as a submodule Add Regen under the parent repo, register it in pnpm-workspace.yaml, then install the workspace package from the consuming app. ```bash git submodule add ref/regen ``` ```yaml packages: - app - ref/regen ``` ```bash pnpm --filter app add regen-ui@workspace:* lucide-react ``` ## Enable the Vite plugin The plugin is used in both Tailwind and non-Tailwind apps. It wires source imports, local package reloads, Tailwind processing, and theme isolation when requested. ```tsx import react from '@vitejs/plugin-react' import regen from 'regen-ui/vite' import { defineConfig } from 'vite' export default defineConfig({ plugins: [regen(), react()], }) ``` ## No Tailwind parent app Import the compiled Regen stylesheet once from the app entrypoint. ```tsx import 'regen-ui/styles.css' ``` ## Tailwind parent app Import Regen from the app stylesheet so Tailwind extracts the app and Regen together. Regen exposes semantic utilities such as bg-accent, text-foreground, and rounded-button. ```css @import 'tailwindcss'; @import 'regen-ui/tailwind.css'; ``` ## Theme scope Use the default non-isolated mode when Regen should share the parent app semantic tokens. ```tsx regen() ``` Use isolated mode when the parent app owns names like bg-accent and Regen should keep its generated utilities under rgn-*. ```tsx regen({ theme: 'isolated' }) ``` ## Use a component ```tsx import { Button } from 'regen-ui' export function SubmitButton() { return } ``` ## Pages - [Introduction](/index.md): Tempo UI primitives for React and Vite apps. - [Installation](/installation.md): Install and configure Regen UI in a React app running through Vite. - [Examples](/examples.md): Reference wallet surfaces built from Regen components. - [Colors](/colors.md): Color values used by Regen components. - [Typography](/typography.md): Text styles exposed by Regen Tailwind utilities. - [Amount](/amount.md): Formatted token amounts with signs and emphasis variants. - [Box](/box.md): Standard surface container for cards, panels, and linked boxes. - [Button](/button.md): Primary action, secondary action, negative action, text action, icon action, loading, and disabled states. - [Choices](/choices.md): Button-style radio group for choosing one value from a short list. - [Copy](/copy.md): Clipboard action for addresses and other copyable values. - [Empty](/empty.md): Centered state for empty lists, blocked screens, and recoverable errors. - [Fields](/fields.md): Field layout and shared defaults for form controls. - [Frame](/frame.md): Dialog shell for review and confirmation surfaces. - [Hash](/hash.md): Compact middle-truncated display for addresses and hashes. - [Identicon](/identicon.md): Deterministic account avatars derived from addresses. - [Info](/info.md): Inline status callouts with optional action links. - [Input](/input.md): Labeled text fields and specialized amount entry. - [Otp](/otp.md): One-time passcode entry fields. - [Qr](/qr.md): Scannable QR codes for wallet addresses, payment URIs, and setup codes. - [Rows](/rows.md): Compact key-value and surface rows. Expanded content renders as explicit Rows.Group or Rows.Panel siblings so regular and virtualized lists share the same model. - [Select](/select.md): Composable select primitives for custom option rows. - [Status](/status.md): Centered status block for loading, success, error, and informational states. - [Tabs](/tabs.md): Controlled tab list with keyboard navigation and an active indicator. - [Tag](/tag.md): Compact inline label for status, category, and metadata chips. - [Tooltip](/tooltip.md): Short hover and focus labels for compact controls. - [Token](/token.md): Network token icon rendering. --- # Examples Reference wallet surfaces built from Regen components. HTML: /examples Markdown: /examples.md --- # Colors Color values used by Regen components. HTML: /colors Markdown: /colors.md ## Semantic Utilities ### Background Utilities | Class | Role | Description | | --- | --- | --- | | `bg-background` | background | Page background | | `bg-surface` | background | Default surface | | `bg-surface-hover` | background | Hover on default surface | | `bg-surface-active` | background | Active default surface | | `bg-secondary` | background | Secondary controls | | `bg-secondary-hover` | background | Hover on secondary controls | | `bg-secondary-active` | background | Active secondary controls | | `bg-pane` | background | Grouped pane | | `bg-accent` | background | Solid accent | | `bg-accent-hover` | background | Hover on solid accent | | `bg-accent-active` | background | Active solid accent | | `bg-negative` | background | Solid negative | | `bg-negative-hover` | background | Hover on solid negative | | `bg-negative-active` | background | Active solid negative | | `bg-negative-subtle` | background | Negative callout background | | `bg-positive-subtle` | background | Positive callout background | | `bg-info-subtle` | background | Info callout background | | `bg-warning-subtle` | background | Warning callout background | ### Text Utilities | Class | Role | Description | | --- | --- | --- | | `text-foreground` | text | Primary text | | `text-foreground-secondary` | text | Secondary text | | `text-foreground-secondary-hover` | text | Hover on secondary text | | `text-on-accent` | text | Text on solid accent | | `text-on-negative` | text | Text on solid negative | | `text-negative` | text | Negative text | | `text-info` | text | Info text | | `text-warning` | text | Warning text | | `text-positive` | text | Positive text | ### Border Utilities | Class | Role | Description | | --- | --- | --- | | `border-border` | border | Default border | | `border-border-hover` | border | Hover border | | `border-border-pane` | border | Pane border | | `border-focus` | border | Focus border | | `border-negative` | border | Negative border | | `border-info` | border | Info border | | `border-warning` | border | Warning border | ### Outline Utilities | Class | Role | Description | | --- | --- | --- | | `outline-focus` | outline | Keyboard focus ring | ## Palette Utilities - `--color-gray-{1..10}`: Gray - `--color-red-{1..10}`: Red - `--color-amber-{1..10}`: Amber - `--color-green-{1..10}`: Green - `--color-blue-{1..10}`: Blue - `--color-purple-{1..10}`: Purple - `--color-gray-dark-{1..10}`: Gray Dark - `--color-red-dark-{1..10}`: Red Dark - `--color-amber-dark-{1..10}`: Amber Dark - `--color-green-dark-{1..10}`: Green Dark - `--color-blue-dark-{1..10}`: Blue Dark - `--color-purple-dark-{1..10}`: Purple Dark --- # Typography Text styles exposed by Regen Tailwind utilities. HTML: /typography Markdown: /typography.md ## Text Styles ### Headings - `heading-64` - `heading-48` - `heading-40` - `heading-32` - `heading-24` - `heading-20` - `heading-16` ### Copy - `copy-16` - `copy-15` - `copy-14` - `copy-13` ### Labels - `label-16` - `label-15` - `label-14` - `label-13` - `label-12` ### Buttons - `button-16` - `button-14` - `button-12` --- # Amount Formatted token amounts with signs and emphasis variants. HTML: /amount Markdown: /amount.md ## Usage ```tsx import type { Hex } from 'ox' import { Amount } from 'regen-ui' const amount: Amount.Amount = { amount: '0x6f05b59d3b20000' as Hex.Hex, decimals: 18, formatted: '50.00', symbol: 'PathUSD', } export function FeeAmount() { return } ``` ## API Reference ### Amount.Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | align | 'center' \| 'left' \| 'right' | No | 'left' | Horizontal alignment of the value. | | amount | Amount | Yes | None | Amount object — fiat/crypto formatting is derived automatically. | | className | string | No | None | Additional class names. | | maxDecimals | number | No | None | Maximum fractional digits to show. | | precise | boolean | No | None | Whether to show nonzero sub-cent fiat values with significant digits. | | sign | string | No | '' | Prefix character displayed before formatted values (e.g. `"−"` or `"+"`). | | size | 'lg' \| 'md' \| 'sm' | No | 'sm' | Size variant. | | strikethrough | boolean | No | None | Whether to strike through the values (e.g. sponsored fees). Also applies `text-foreground-secondary`. | ### Amount.Amount | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | decimals | number | Yes | None | Token decimals used to format the raw hex amount. | | formatted | string | Yes | None | Human-readable token amount. | | symbol | string | Yes | None | Token symbol used for fiat or crypto display. | | amount | `0x${string}` | Conditional | None | Raw token amount as a hex quantity. | | value | `0x${string}` | Conditional | None | Raw token amount as a hex quantity. | --- # Box Standard surface container for cards, panels, and linked boxes. HTML: /box Markdown: /box.md ## Usage ```tsx import { Box } from 'regen-ui' export function ActionCard() { return ( <> console.log('clicked')}> Open console.log('clicked')}> Disabled ) } ``` ## API Reference ### Box.Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | disabled | boolean | No | None | Disable interaction when Box renders as an interactive element. | | padding | number | No | 16 | Padding in px. | | render | ReactElement | No | None | Element to render as instead of `
` or ` ) } ``` ### Button.Text ```tsx import { Button } from 'regen-ui' export function InlineAction() { return View details } ``` ### Button.Icon ```tsx import { Button } from 'regen-ui' import { MoreHorizontal } from 'lucide-react' export function MenuButton() { return ( ) } ``` ## API Reference ### Button.Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | icon | ReactNode | No | None | Icon or element before the label. | | loading | boolean | No | false | Show a loading spinner and disable the button. | | render | ReactElement | No | None | Element to render as instead of ` } icon={} title="No activity yet" > Transactions and authorizations will appear here. ) } ``` ## API Reference ### Empty.Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | action | ReactNode | No | None | Optional action rendered below the message. | | children | ReactNode | No | None | Supporting copy. | | className | string | No | None | Additional class names for layout-specific sizing. | | icon | ReactNode | No | None | Decorative icon shown above the title. | | title | ReactNode | Yes | None | Primary empty-state message. | --- # Fields Field layout and shared defaults for form controls. HTML: /fields Markdown: /fields.md ## Usage ### Stacked ```tsx import { Calendar } from 'lucide-react' import { Button, Fields, Input } from 'regen-ui' export function IdentityFields() { return ( } /> ) } ``` ### Inline ```tsx import { Fields, Input } from 'regen-ui' export function AddressFields() { return ( ) } ``` ## API Reference ### Fields.Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | children | ReactNode | Yes | None | Field controls rendered in the group. | | variant | 'default' \| 'stacked' | No | 'stacked' | Field variant applied to child controls unless they override it: 'default' for external labels or 'stacked' for internal labels. | | Inherits | HTMLAttributes<HTMLDivElement> | | | Inherited props. | ### Fields.Inline.Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | children | ReactNode | Yes | None | Field controls rendered in the inline layout. | | Inherits | HTMLAttributes<HTMLDivElement> | | | Inherited props. | --- # Frame Dialog shell for review and confirmation surfaces. HTML: /frame Markdown: /frame.md ## Usage ```tsx import { Button, Frame } from 'regen-ui' export function ReviewFrame(props: { onDismiss: () => void }) { return ( } onDismiss={props.onDismiss} subtitle="Review the details before continuing." title="Review request" > Request details ) } ``` ### Inherited dismiss ```tsx import { Frame } from 'regen-ui' export function FramedRoute(props: { children: React.ReactNode; onDismiss: () => void }) { return ( {props.children} ) } ``` ## API Reference ### Frame.Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | bodyClassName | string | No | None | Additional class names for uncommon body wrapper overrides. | | footer | ReactNode | No | None | Footer content anchored to the bottom. | | footerClassName | string | No | None | Additional class names for uncommon footer wrapper overrides. | | onDismiss | () => void \| null | No | None | Dismiss handler. Pass null to opt out of inherited dismiss behavior. | | subtitle | ReactNode | No | None | Secondary text below the title. | | title | ReactNode | No | None | Primary heading text. | | variant | 'card' \| 'page' \| 'plain' \| 'sheet' | No | 'card' | Visual shell variant. | | Inherits | HTMLAttributes<HTMLDivElement> | | | Except title. | ### Frame.Actions.Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | children | ReactNode | Yes | None | Action buttons. | ### Frame.Provider.Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | children | ReactNode | Yes | None | Nested frame content. | | onDismiss | () => void | No | None | Dismiss handler inherited by nested frames. | --- # Hash Compact middle-truncated display for addresses and hashes. HTML: /hash Markdown: /hash.md ## Format Helper ```tsx import { formatHash } from 'regen-ui' formatHash('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045') // "0xd8dA…6045" ``` ## Usage ```tsx import { Hash } from 'regen-ui' export function AddressLabel() { return } ``` ## API Reference ### Hash.Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | copy | boolean | No | false | Show an inline copy button after the hash. | | min | number | No | 4 | Minimum number of body characters to keep visible on each side. | | value | string | Yes | None | Hash or address value to display. | | Inherits | HTMLAttributes<HTMLSpanElement> | | | Except children. | --- # Identicon Deterministic account avatars derived from addresses. HTML: /identicon Markdown: /identicon.md ## Usage ```tsx import type { Address } from 'ox' import { Identicon } from 'regen-ui' const address = '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045' as Address.Address export function AccountAvatar() { return } ``` ## API Reference ### Identicon.Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | address | `0x${string}` | Yes | None | Tempo address. | | className | string | No | None | Additional CSS classes. | | size | number | No | 64 | Size in px. | --- # Info Inline status callouts with optional action links. HTML: /info Markdown: /info.md ## Usage ```tsx import { Info } from 'regen-ui' export function BalanceWarning() { return ( ) } ``` ## API Reference ### Info.Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | action | Action | No | None | Optional trailing action rendered inline. | | className | string | No | None | Additional class names. | | message | ReactNode | Yes | None | Message body. | | type | 'error' \| 'info' \| 'warning' | No | 'info' | Visual variant. | ### Info.Action Optional trailing action rendered inline on an info callout. | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | external | boolean | No | true | Whether the link opens in a new tab. | | href | string | Conditional | None | Link target. | | label | ReactNode | Yes | None | Link text.
Button text. | | onClick | () => void | Conditional | None | Called when the link is clicked.
Called when the button is clicked. | --- # Input Labeled text fields and specialized amount entry. HTML: /input Markdown: /input.md ## Usage ```tsx import { Input } from 'regen-ui' export function EmailField() { return ( ) } ``` ### Inline fields ```tsx import { Fields, Input } from 'regen-ui' export function NameFields() { return ( ) } ``` ### Stacked fields ```tsx import { Calendar, Eye } from 'lucide-react' import { Button, Fields, Input } from 'regen-ui' export function IdentityForm() { return ( } /> } /> ) } ``` ### Input.Amount ```tsx import { useState } from 'react' import { Input } from 'regen-ui' export function PaymentAmount() { const [value, setValue] = useState('') return ( 250 ? 'Amount exceeds available balance.' : undefined} onChange={setValue} onMax={() => setValue('250')} prefix="$" value={value} /> ) } ``` ## API Reference ### Input.Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | error | string \| boolean | No | None | Error message or boolean error state. | | label | ReactNode | No | None | Label displayed for the input. | | prefix | ReactNode | No | None | Element rendered before the input (e.g. "https://"). | | suffix | ReactNode | No | None | Element rendered after the input (e.g. ".com"). | | variant | 'default' \| 'stacked' | No | 'default' | Visual layout variant: 'default' for an external label or 'stacked' for an internal label. | | Inherits | InputHTMLAttributes<HTMLInputElement> | | | Except prefix, size. | ### Input.Amount.Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | error | string \| boolean | No | None | Error message or boolean error state. Error takes precedence over the Max shortcut. | | onChange | (value: string) => void | Yes | None | Called with the raw comma-free decimal value. | | onMax | () => void | No | None | Called when the Max shortcut is pressed. | | prefix | ReactNode | No | None | Element rendered before the amount input. | | suffix | ReactNode | No | None | Element rendered after the amount input. | | value | string | Yes | None | Raw comma-free decimal value. | | Inherits | InputHTMLAttributes<HTMLInputElement> | | | Except children, onChange, type, value. | --- # Otp One-time passcode entry fields. HTML: /otp Markdown: /otp.md ## Usage ```tsx import { useState } from 'react' import { Otp } from 'regen-ui' export function VerificationCode() { const [value, setValue] = useState('') return } ``` ## API Reference ### Otp.Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | className | string | No | None | Additional class names for the slot group. | | disabled | boolean | No | None | Disable all inputs. | | error | string \| boolean | No | None | Error message or boolean error state. | | length | number | No | 6 | Number of digits. | | onChange | (value: string) => void | No | None | Called with the current value string. | | size | 'large' \| 'medium' \| 'small' | No | 'medium' | Input size. | | value | string | No | None | Current value string. | --- # Qr Scannable QR codes for wallet addresses, payment URIs, and setup codes. HTML: /qr Markdown: /qr.md ## Usage ```tsx import { Qr } from 'regen-ui' export function WalletQr() { return } ``` ## API Reference ### Qr.Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | className | string | No | None | Additional class names for the SVG root. | | size | 'large' \| 'medium' \| 'small' | No | 'medium' | Visual size preset. | | value | string | Yes | None | Encoded QR value. | --- # Rows Compact key-value and surface rows. Expanded content renders as explicit Rows.Group or Rows.Panel siblings so regular and virtualized lists share the same model. HTML: /rows Markdown: /rows.md ## Usage ```tsx import { useEffect, useState } from 'react' import { Rows } from 'regen-ui' export function TransactionRows() { const [loadingOpen, setLoadingOpen] = useState(false) const [reviewOpen, setReviewOpen] = useState(false) return ( Tempo {}}> 0xd8dA…6045 setReviewOpen((open) => !open)} > Sponsored {reviewOpen && (
Chain ID 42431
Fees Sponsored
)} setLoadingOpen((open) => !open)} > Pending {loadingOpen && ( )}
) } export function SurfaceRows() { const [activityOpen, setActivityOpen] = useState(true) const [syncLoaded, setSyncLoaded] = useState(false) const [syncLoading, setSyncLoading] = useState(false) const [syncOpen, setSyncOpen] = useState(false) useEffect(() => { if (!syncLoading) return const timeout = setTimeout(() => { setSyncLoaded(true) setSyncLoading(false) }, 700) return () => clearTimeout(timeout) }, [syncLoading]) const onSyncOpenChange = (open: boolean) => { setSyncOpen(open) if (open && !syncLoaded) setSyncLoading(true) if (!open) { setSyncLoaded(false) setSyncLoading(false) } } return ( setActivityOpen((open) => !open)} >
Access key activity 2 transactions
{activityOpen && ( } >
Access key spend EmailValidator
Now
} >
Session closed DomainIntel
1m
)} onSyncOpenChange(!syncOpen)} >
Syncing activity {syncLoading ? 'Loading rows' : syncLoaded ? '2 rows loaded' : 'Loads on open'}
{syncOpen && (syncLoading || syncLoaded) && ( {syncLoading ? ( ) : ( <> } >
Recipient checked 0xd8dA…6045
Now
} >
Policy refreshed DomainIntel
Now
)}
)}
) } ``` ## API Reference ### Rows.Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | children | ReactNode | Yes | None | Row items. | | dividers | 'full' \| 'inset' | No | Rows.defaultDividers[variant] | Horizontal row divider length. Defaults to `'inset'` for pane rows and `'full'` for surface rows. | | variant | 'pane' \| 'surface' | No | 'pane' | Visual row group surface. | | Inherits | HTMLAttributes<HTMLDivElement> | | | Inherited props. | ### Rows.Group.Props Props for nested rows rendered with `Rows.Group`. | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | children | ReactNode | Yes | None | Nested row items. | | Inherits | HTMLAttributes<HTMLDivElement> | | | Inherited props. | ### Rows.Panel.Props Props for expanded content rendered with `Rows.Panel`. | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | children | ReactNode | Yes | None | Panel content. | | Inherits | HTMLAttributes<HTMLDivElement> | | | Inherited props. | ### Rows.Row.Props | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | action | ActionExpand \| ActionNavigation \| ActionNone | Conditional | 'none' | Row action affordance. | | onClick | OnClick | Conditional | None | Press handler. Update `action.expanded` and render adjacent content from here.
Press handler.
Press handler. When provided without `render` or a visual action, the row renders as a button. | | children | ReactNode | Yes | None | Row content. | | disabled | boolean | No | None | Disable interaction when the row is interactive. | | height | number | No | None | Row height in px. Defaults to the variant height. | | label | ReactNode | No | None | Left-side label for key-value rows. | | render | ReactElement | No | None | Element to render as instead of a div or button. | | spacing | 'both' \| 'end' \| 'none' \| 'start' | No | 'both' | Which sides keep the parent `` padding. Only applies to pane rows. | | Inherits | HTMLAttributes<HTMLElement> | | | Except action, onClick. | ### Rows.Row.ActionExpand Expand row action. Shows a chevron for rows that open adjacent content such as `Rows.Group`. | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | expanded | boolean | Yes | None | Whether the adjacent content is currently open. | | type | 'expand' | Yes | None | Action type. | ### Rows.Row.ActionNavigation Navigation row action. | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | type | 'navigation' | Yes | None | Action type. | ### Rows.Row.ActionNone No visual row action. | Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | type | 'none' | Yes | None | Action type. | --- # Select Composable select primitives for custom option rows. HTML: /select Markdown: /select.md ## Usage ```tsx import { useState } from 'react' import { Select, Token } from 'regen-ui' const assetItems = [ { label: 'pathUSD', prefix: ( ), suffix: '1,240.50', value: 'pathusd', }, { label: 'USDC.e', prefix: ( ), suffix: '845.00', value: 'usdce', }, ] export function AssetSelect() { const [value, setValue] = useState('pathusd') return