crispmeasured from Attio

People page

A second object list — People — over the same AppShell + Sidebar + table composition, proving the CRUD surface generalises.

The Companies page rebuilt for a different object — People — with nothing changed but the columns and rows. Same App Shell, same Sidebar, same view bar and Records Table; the table is schema-driven, so a new object is just a new columns + rows pair. Open a row's ↗ to peek it, or its name to see the full Record Page.

Composition

8 records
Ssundar@google.comGoogleChief Executive OfficerMountain View, CA+1 650-253-0000
Ssatya@microsoft.comMicrosoftChairman & CEORedmond, WA+1 425-882-8080
Ddylan@figma.comFigmaCo-founder & CEOSan Francisco, CA+1 415-895-9000
Iivan@notion.soNotionCo-founder & CEOSan Francisco, CA+1 415-555-0142
Kkarri@linear.appLinearCo-founder & CEOSan Francisco, CA+1 415-555-0177
Grauchg@vercel.comVercelFounder & CEOSan Francisco, CA+1 415-555-0193
Ssam@openai.comOpenAIChief Executive OfficerSan Francisco, CA+1 415-555-0128
Ddario@anthropic.comAnthropicCo-founder & CEOSan Francisco, CA+1 415-555-0164

The only difference from the Companies example is the data:

const peopleColumns: Column[] = [
  { key: "person", label: "Name", type: "entity", icon: User },
  { key: "email", label: "Email", type: "url", icon: Mail },
  { key: "company", label: "Company", type: "text", icon: Building2 },
  { key: "title", label: "Title", type: "text", icon: Briefcase },
  { key: "location", label: "Location", type: "text", icon: MapPin },
  { key: "phone", label: "Phone", type: "text", icon: Phone },
];

<RecordsTable columns={peopleColumns} rows={peopleRows} />;

Everything else — sort, filter, inline edit, selection, the create modal, the peek panel — comes for free because it's driven by the column types, not the object.

On this page