caliper uidocs

Roadmap block

Block

A public roadmap in now, next and later. Votes roll the count and move the card to its place in the column, so readers see their vote count.

Installs components/ui/roadmap-block.tsxDepends on lucide-reactMotion none in component source
pnpm dlx shadcn@latest add https://caliperui.site/r/roadmap-block.json

Roadmap

What we're building

Vote for what matters to you. We read every vote and post updates in the changelog.

Now2

Shipping this quarter
  1. Multi-currency invoices

    Send and reconcile in 30 currencies.

    Billing
  2. Two-way Xero sync

    Integrations

Next3

Designing
  1. Approve from your phone

    Approvals
  2. Budgets by department

    Set a budget and see spend against it daily.

    Planning
  3. Exportable audit log

    Security

Later2

Exploring
  1. Payroll journal import

    Integrations
  2. Webhooks for every event

    Developers

When to use #

Use it for

  • Public roadmaps and feature request boards.
  • Showing direction without promising dates.

Skip it when

  • Internal planning with owners and dates; use the project board.
  • Votes you will not act on.

Installation #

terminal
pnpm dlx shadcn@latest add https://caliperui.site/r/roadmap-block.json

Adds its 8 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.

Usage #

This is the code behind the preview above.

example.tsx
import { RoadmapBlock } from "@/components/ui/roadmap-block"

export function RoadmapBlockDemo() {
  return (
    <RoadmapBlock
      eyebrow="Roadmap"
      title="What we're building"
      lead="Vote for what matters to you. We read every vote and post updates in the changelog."
      columns={[
        { id: "now", title: "Now", note: "Shipping this quarter", items: [
          { id: "multi", title: "Multi-currency invoices", body: "Send and reconcile in 30 currencies.", votes: 412, tag: "Billing" },
          { id: "xero", title: "Two-way Xero sync", votes: 288, voted: true, tag: "Integrations" },
        ] },
        { id: "next", title: "Next", note: "Designing", items: [
          { id: "budget", title: "Budgets by department", body: "Set a budget and see spend against it daily.", votes: 196, tag: "Planning" },
          { id: "mobile", title: "Approve from your phone", votes: 201, tag: "Approvals" },
          { id: "audit", title: "Exportable audit log", votes: 74, tag: "Security" },
        ] },
        { id: "later", title: "Later", note: "Exploring", items: [
          { id: "payroll", title: "Payroll journal import", votes: 133, tag: "Integrations" },
          { id: "api", title: "Webhooks for every event", votes: 98, tag: "Developers" },
        ] },
      ]}
    />
  );
}

API reference #

RoadmapBlock

component
PropTypeDefault
eyebrowstring—
title *string—
leadstring—
columns *readonly RoadmapColumn[]—
onVote((itemId: string, voted: boolean) => void)—
classNamestring—

Accessibility #

It is built on native elements and keeps aria-pressed, aria-label, aria-hidden and aria-labelledby in step with state.

No custom key handling; Tab and the native activation keys do the work.

Motion #

It declares no animation in its component source. Any transition comes from its stylesheet, which uses the duration tokens that collapse to instant under prefers-reduced-motion.