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.
Pane
Network
Tempo
Fee
EmailValidator
Limited
DomainIntel
Unlimited
Surface
Tempo WalletSession restored
NowGrouping
Use Rows.Group for nested rows and Rows.Panel for expanded content. The trigger row only owns the chevron state with action={{ type: "expand", expanded }}.
Usage
import { useEffect, useState } from 'react'
import { Rows } from 'regen-ui'
export function TransactionRows() {
const [loadingOpen, setLoadingOpen] = useState(false)
const [reviewOpen, setReviewOpen] = useState(false)
return (
<Rows>
<Rows.Row label="Network">Tempo</Rows.Row>
<Rows.Row action={{ type: 'navigation' }} label="Recipient" onClick={() => {}}>
0xd8dA…6045
</Rows.Row>
<Rows.Row
action={{
expanded: reviewOpen,
type: 'expand',
}}
label="Details"
onClick={() => setReviewOpen((open) => !open)}
>
Sponsored
</Rows.Row>
{reviewOpen && (
<Rows.Panel>
<div className="grid gap-[8px] py-[10px] label-13">
<div className="flex items-center justify-between gap-[12px]">
<span className="text-foreground-secondary">Chain ID</span>
<span className="tabular-nums">42431</span>
</div>
<div className="flex items-center justify-between gap-[12px]">
<span className="text-foreground-secondary">Fees</span>
<span>Sponsored</span>
</div>
</div>
</Rows.Panel>
)}
<Rows.Row
action={{
expanded: loadingOpen,
type: 'expand',
}}
label="Loading"
onClick={() => setLoadingOpen((open) => !open)}
>
Pending
</Rows.Row>
{loadingOpen && (
<Rows.Panel>
<Rows.PanelLoader />
</Rows.Panel>
)}
</Rows>
)
}
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 (
<Rows dividers="full" variant="surface">
<Rows.Row
action={{
expanded: activityOpen,
type: 'expand',
}}
onClick={() => setActivityOpen((open) => !open)}
>
<div className="flex flex-1 flex-col truncate">
<span>Access key activity</span>
<span className="text-foreground-secondary">2 transactions</span>
</div>
</Rows.Row>
{activityOpen && (
<Rows.Group>
<Rows.Row
render={<a href="https://example.org" rel="noopener noreferrer" target="_blank" />}
>
<div className="flex flex-1 flex-col truncate">
<span>Access key spend</span>
<span className="text-foreground-secondary">EmailValidator</span>
</div>
<span className="text-foreground-secondary">Now</span>
</Rows.Row>
<Rows.Row
render={<a href="https://example.org" rel="noopener noreferrer" target="_blank" />}
>
<div className="flex flex-1 flex-col truncate">
<span>Session closed</span>
<span className="text-foreground-secondary">DomainIntel</span>
</div>
<span className="text-foreground-secondary">1m</span>
</Rows.Row>
</Rows.Group>
)}
<Rows.Row
action={{
expanded: syncOpen,
type: 'expand',
}}
onClick={() => onSyncOpenChange(!syncOpen)}
>
<div className="flex flex-1 flex-col truncate">
<span>Syncing activity</span>
<span className="text-foreground-secondary">
{syncLoading ? 'Loading rows' : syncLoaded ? '2 rows loaded' : 'Loads on open'}
</span>
</div>
</Rows.Row>
{syncOpen && (syncLoading || syncLoaded) && (
<Rows.Group>
{syncLoading ? (
<Rows.RowGroupLoader />
) : (
<>
<Rows.Row
render={
<a href="https://example.org" rel="noopener noreferrer" target="_blank" />
}
>
<div className="flex flex-1 flex-col truncate">
<span>Recipient checked</span>
<span className="text-foreground-secondary">0xd8dA…6045</span>
</div>
<span className="text-foreground-secondary">Now</span>
</Rows.Row>
<Rows.Row
render={
<a href="https://example.org" rel="noopener noreferrer" target="_blank" />
}
>
<div className="flex flex-1 flex-col truncate">
<span>Policy refreshed</span>
<span className="text-foreground-secondary">DomainIntel</span>
</div>
<span className="text-foreground-secondary">Now</span>
</Rows.Row>
</>
)}
</Rows.Group>
)}
</Rows>
)
}API Reference
Rows.Props
| Name | Type | Default | Description |
|---|---|---|---|
children | ReactNode | None | Row items. |
dividers | 'full' | 'inset' | Rows.defaultDividers[variant] | Horizontal row divider length. Defaults to `'inset'` for pane rows and `'full'` for surface rows. |
variant | 'pane' | 'surface' | 'pane' | Visual row group surface. |
Inherits HTMLAttributes<HTMLDivElement>. | |||
childrenType
ReactNodeDefaultNone
Row items.dividersType
'full' | 'inset'Default
Horizontal row divider length. Defaults to `'inset'` for pane rows and `'full'` for surface rows.Rows.defaultDividers[variant]variantType
'pane' | 'surface'Default
Visual row group surface.'pane'Inherits
HTMLAttributes<HTMLDivElement>.Rows.Group.Props
Props for nested rows rendered with `Rows.Group`.
| Name | Type | Default | Description |
|---|---|---|---|
children | ReactNode | None | Nested row items. |
Inherits HTMLAttributes<HTMLDivElement>. | |||
childrenType
ReactNodeDefaultNone
Nested row items.Inherits
HTMLAttributes<HTMLDivElement>.Rows.Panel.Props
Props for expanded content rendered with `Rows.Panel`.
| Name | Type | Default | Description |
|---|---|---|---|
children | ReactNode | None | Panel content. |
Inherits HTMLAttributes<HTMLDivElement>. | |||
childrenType
ReactNodeDefaultNone
Panel content.Inherits
HTMLAttributes<HTMLDivElement>.Rows.Row.Props
| Name | Type | Default | Description |
|---|---|---|---|
action | ActionExpand | ActionNavigation | ActionNone | 'none' | Row action affordance. |
onClick | OnClick | 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 | None | Row content. |
disabled | boolean | None | Disable interaction when the row is interactive. |
height | number | None | Row height in px. Defaults to the variant height. |
label | ReactNode | None | Left-side label for key-value rows. |
render | ReactElement | None | Element to render as instead of a div or button. |
spacing | 'both' | 'end' | 'none' | 'start' | 'both' | Which sides keep the parent `<Rows>` padding. Only applies to pane rows. |
Inherits HTMLAttributes<HTMLElement>, except action, onClick. | |||
actionType
ActionExpand | ActionNavigation | ActionNoneDefault
Row action affordance.'none'onClickType
OnClickDefaultNone
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.childrenType
ReactNodeDefaultNone
Row content.disabledType
booleanDefaultNone
Disable interaction when the row is interactive.heightType
numberDefaultNone
Row height in px. Defaults to the variant height.labelType
ReactNodeDefaultNone
Left-side label for key-value rows.renderType
ReactElementDefaultNone
Element to render as instead of a div or button.spacingType
'both' | 'end' | 'none' | 'start'Default
Which sides keep the parent `<Rows>` padding. Only applies to pane rows.'both'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`.
| Name | Type | Default | Description |
|---|---|---|---|
expanded | boolean | None | Whether the adjacent content is currently open. |
type | 'expand' | None | Action type. |
expandedType
booleanDefaultNone
Whether the adjacent content is currently open.typeType
'expand'DefaultNone
Action type.Rows.Row.ActionNavigation
Navigation row action.
| Name | Type | Default | Description |
|---|---|---|---|
type | 'navigation' | None | Action type. |
typeType
'navigation'DefaultNone
Action type.Rows.Row.ActionNone
No visual row action.
| Name | Type | Default | Description |
|---|---|---|---|
type | 'none' | None | Action type. |
typeType
'none'DefaultNone
Action type.