caliper uidocs

Repo city

Pro

A repository as a city: districts are folders, buildings are files. Footprint is size and height is how much a file changed lately, so a big quiet file and a small busy one are different at a glance. The three busiest are ember. A switch makes height size too, for the plain treemap.

Installs components/ui/repo-city.tsxDepends on @radix-ui/react-slot, lucide-reactMotion none in component source
pnpm dlx shadcn@latest add @caliper/repo-city

Footprint is size. Height is changes in 90 days.

Choose a building, or a file from the list.

When to use #

Use it for

  • Finding hotspots: where a codebase changes most and where that overlaps with size.
  • Reviews and handovers that need a picture of a repository before the details.

Skip it when

  • Comparing exact values across many files; use the ranked list or a table.
  • Repositories with thousands of files; roll them up into folders first.

Decisions #

Why it is built this way, so you know what to keep when you change your copy.

Behaviour

Every building is a button with its facts
Each one is named with its path, size, changes and whether it is a hotspot. The ranked list beside it holds the same files and is the quick way in by keyboard.
Height has a plain mode
Switching to size makes the city an ordinary treemap with extrusion, so the second measure can be turned off without losing the layout.

Styling

Ember marks only the hottest
Everything else shades from the surface to the ink by changes, so colour repeats what height says.

Installation #

terminal
pnpm dlx shadcn@latest add @caliper/repo-city

Adds its 6 files to components/ui/, each with its own stylesheet, and installs their packages. Pro installs with your access token, set up once per project. See Pro access. The first part also adds Caliper UI’s tokens; import them once as in Installation.

Usage #

Import it from your copy of the source. The example behind the preview comes with the source.

example.tsx
import { RepoCity } from "@/components/ui/repo-city"

The worked example comes with Pro

The 23-line example behind the preview opens here with a Pro or Team licence.

Checking your licence…

API reference #

RepoCity

component
PropTypeDefaultDescription
label *string—Names the city for screen readers, for example "Repository activity".
files *readonly RepoFile[]—
heightRepoHeight—What the height shows. Controlled when set.
defaultHeightRepoHeight"changes"
onHeightChange((height: RepoHeight) => void)—
selectedstring | null—The selected file path, or null. Controlled when set.
defaultSelectedstring | nullnull
onSelect((path: string | null) => void)—
hotspotsnumber3How many of the busiest files are ember and called hotspots.
sizeUnitstring"lines"
changeUnitstring"changes"
periodstring"in 90 days"Said after the change count, for example "in 90 days".
statusDepthStatus"ready"
messagesDepthMessages—
onRetry(() => void)—
disabledboolean—
classNamestring—

Accessibility #

It exposes group semantics, with aria-label, aria-hidden, aria-pressed and aria-live kept in step with state. Changes that matter are announced through a live region.

KeyBehaviour
←Moves to the previous item or value.
→Moves to the next item or value.
↑Moves to the previous item or value.
↓Moves to the next item or value.

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.