Skip to main content
Exemplar page — first pass, entirely proposal. No audited Invoca screen backs this page — Titan’s design library was not available while writing it. It is built from general interaction-design practice and from the constraints Views overview, Loading & skeletons, Empty & zero states, and Error handling already establish. Treat every constraint below as a starting point to check against real product screens, not as a rule already enforced.

What it is

A page whose job is giving the shape of something, not enumerating its members. List view states the boundary from the other side: a list page that accumulates a summary strip, a chart, and a panel of recent activity has stopped being a list and become a dashboard with a table on it (TITAN-LSTVIEW-01). That is the test this archetype exists on the far side of — a Dashboard is what that accumulation was reaching for all along. You are building one if the page answers “what’s the shape of this?” — an account’s health, a campaign’s performance this month, an integration’s recent activity — rather than “which of these?” (List view) or “what about this one?” (Detail view). Its subject is typically an account, a time range, or a product area — not a single record.

Region vocabulary

This archetype adds no regions to the page frame. What it adds is a name for what fills Contents: a widget — one self-contained summary that answers a single question at a glance. A widget is not a frame region and not a named export in this system; it is this archetype’s own word for one grid cell.

Choose this view when

  • The page’s subject is a whole, not a member of a collection — an account, a time range, a product area — and the reader’s job is reading its shape, not finding one item inside it.
  • What answers the reader’s question is several independent summaries, each readable at a glance, rather than one continuous body of rows or one record’s own attributes.
  • Acting further means navigating away to a list or detail view. The dashboard itself commits to nothing.

Choose something else when

Regions

What fills each region

Header — Right, or Controls

A time-range or scope selector changes what the widgets display — it reshapes what’s rendered without changing any underlying data. That is the job Views overview assigns to Controls: Controls changes what the body shows, never what the data is.” Switching a dashboard from “last 7 days” to “last 30 days” doesn’t touch the data; it changes which slice of it the widgets summarize. That puts the selector in Controls, not RightRight is reserved for an action on the page itself (export the current view, customize which widgets show), never for something that reshapes what the widgets are summarizing.

Contents — the widget grid

A responsive grid of summary widgets — stat tiles, charts, small tables — each answering one question at a glance. Card is the system’s container for a self-contained unit of content and is the natural widget shell; a widget’s own content might be a number and a trend, a small Table, or a chart. Charting itself isn’t a documented component in this system yet, so a chart widget’s internal rendering is out of this page’s scope.
Whether widgets can be individually configured or rearranged by the reader is an open question this page does not resolve. Nothing already documented gives grounds to assert either answer. Treat a fixed, page-defined widget set as the default until a real case forces the question.

Contents — loading

A dashboard’s widgets load independently and at different speeds — a stat tile might resolve in 200ms while a chart’s query takes three seconds. Each widget gets its own Skeleton matching its own eventual shape — a chart-shaped skeleton, a stat-tile-shaped skeleton — per Loading & skeletons, rather than one page-level spinner blocking the whole grid until every widget resolves. A reader who wants one number should not wait on the slowest chart to see it.

Contents — empty widget vs. failed widget

A widget with nothing to show and a widget that failed to load are different states, and the distinction is made at the widget level, not the page’s:
  • Nothing to show. The underlying query succeeded and returned nothing to summarize — no calls in the selected range. Follows Empty & zero states, scoped to that one widget.
  • Failed to load. The widget’s own request errored. Follows Error handling, scoped to that one widget, with its own retry.
One widget’s failure must not block the others from rendering. Each widget owns its own load, its own empty case, and its own failure independently — see Constraints.

Responsive and density behavior

Titan is desktop-first — most surfaces live at lg and xl, and xs/sm are rarely exercised (see Layout & grid). What follows is proposed with that in mind: it answers “does it still work at all” below md rather than describing a deliberate phone-first behavior.
Widget order at narrow widths is the page’s decision, not the reader’s, until the open question above about rearrangement is resolved. Absent that, the most important widget renders first in source order, since a single column reads top to bottom.

Accessibility

The page-level decisions are the frame’s, and they apply unchanged — see Views overview → Accessibility. One main, one h1 on Title, region order matching visual order. What is specific to this archetype:
  • Each widget has its own heading, descending from Title’s h1 without skipping a level, so a screen-reader user outlining the page can tell the widgets apart and jump between them. A dashboard built from a dozen unlabeled Cards is a dozen indistinguishable regions.
  • Each widget’s loading state carries its own aria-busy, per Loading & skeletons → Accessibility — a dozen simultaneous, independent loads should announce as a dozen independent completions, not one.
  • A failed widget’s retry action has an accessible name naming what it retries — “Retry call volume,” not “Retry” — the same reasoning List view applies to a row action among several identical ones.
  • An empty or failed widget does not disappear. The region stays, with its own EmptyState or error message in place, so a screen-reader user tabbing through the grid encounters a stated reason rather than a missing widget.

Constraints

Composed example

No live embed exists yet. Per this page’s own rule, a composed example should be a real screen or a live embed rather than a static image — the diagram below is structural (region names and what’s in them, no measurements or visual styling) for exactly that reason, the same way every Structure diagram in Patterns is. Replace it with a live embed the first time this archetype is built.

Why it works this way

A widget’s independence is the point, not an implementation detail. The reason to load, empty, and fail each widget on its own, rather than gating the grid on the slowest widget or the first one to error, is the same reason the page exists at all: a dashboard’s value is that several different questions can each get answered the moment their own answer is ready, without waiting on each other. A page-level spinner or a page-level error state would make every widget only as fast, or as reliable, as the worst one on the page — which throws away the one advantage a grid of independent summaries has over a single query that has to succeed all at once. The cap on widget count exists because “at a glance” is a real claim, not a slogan. List view names the failure mode from the other side — a list that keeps gaining widgets has stopped being a list. The matching failure here is a dashboard that keeps gaining widgets until reading it takes as long as reading the underlying data would have. A stated ceiling forces that overflow into a decision — split the dashboard, or promote a widget to its own page — instead of letting the grid grow until it quietly stops working.
Last modified on September 2, 2026