Row

Flexible interactive row primitive with leading slot, middle title, trailing actions, active state, and drag handle icon.

// Plain markup
import { Row, RowDragHandle } from "@shavin/ui";

Side-menu nav (icon leading, active state) — this is what NavItem is built on

const [active, setActive] = useState("due");

<div className="w-64 space-y-0.5 rounded-[var(--radius-panel)] border border-hairline bg-surface p-2">
  <Row leading={<BellIcon />} active={active === "due"} onClick={() => setActive("due")}>
    Due & renewals
  </Row>
  <Row leading={<BellIcon />} active={active === "money"} onClick={() => setActive("money")}>
    Money
  </Row>
</div>

Trailing content — badge, chevron, secondary text

<div className="w-72 space-y-0.5">
  <Row trailing={<Badge color="accent">3</Badge>}>Inbox</Row>
  <Row trailing={<ChevronRight />}>Settings</Row>
  <Row trailing={<span className="text-xs text-fg-subtle">⌘K</span>}>Search</Row>
</div>

Checkbox / Radio instead of an icon — selectable list rows

Checkbox list
emi
subs
bills
Radio list
weekly
monthly
yearly
{/* Checkbox list */}
{["emi", "subs", "bills"].map((k) => {
  const isChecked = checked.includes(k);
  return (
    <Row
      key={k}
      as="div"
      onClick={toggle}
      leading={<Checkbox checked={isChecked} onCheckedChange={toggle} />}
      className="cursor-pointer capitalize"
    >
      {k}
    </Row>
  );
})}

{/* Radio list */}
<RadioGroup value={radio} onValueChange={setRadio}>
  {["weekly", "monthly", "yearly"].map((k) => (
    <Row
      key={k}
      as="div"
      onClick={() => setRadio(k)}
      leading={<Radio value={k} />}
      className="cursor-pointer capitalize"
    >
      {k}
    </Row>
  ))}
</RadioGroup>

Draggable list card — drag handle leading, hover-revealed remove action trailing

Netflix
Car EMI
Electricity
<Row
  as="div"
  className="border border-hairline bg-surface"
  leading={<RowDragHandle />}
  trailing={<button aria-label="Remove"></button>}
>
  Netflix
</Row>

Multiple independent click targets — as="div" (no outer button)

<Row
  as="div"
  leading={<button aria-label="Toggle visibility" className="border-danger h-4 w-4 rounded-[3px] border-2" />}
  trailing={<button aria-label="Info"></button>}
>
  <button className="text-left hover:underline">Subscriptions</button>
</Row>

Props

PropTypeDefault
asElementType
leadingReactNode
trailingReactNode
childrenReactNode
classNamestring
active"true" | "false" | "hover""false"
Configure Theme
Theme
Accent Color
Custom
Gray Family
Appearance
Radius
Scaling
Panel Style
Heading Font
Body Font