Generated from `@cosmoops/connect-sdk/ui`'s TypeScript source and its own doc comments - see [Reference](/docs/reference) for the other entry points. Regenerated on every deploy; don't hand-edit.

## Interfaces

### Interface: ConnectEmptyStateProps [#interface-connectemptystateprops]

#### Properties

| Property | Type | Description |
| ------ | ------ | ------ |
| `icon?` | `ReactNode` | Rendered at `size-8`. Any icon element - lucide, an SVG, a glyph. |
| `title` | `ReactNode` | What is absent, in the user's words. One line. |
| `description?` | `ReactNode` | - |
| `action?` | `ReactNode` | The one control that resolves the emptiness - "New contact" for a list that has never had anything in it, "Clear filter" for one whose contents are merely hidden. |
| `variant?` | `"card"` \| `"dashed"` \| `"plain"` | - |
| `className?` | `string` | - |

***

### Interface: ConnectMetricChartProps [#interface-connectmetricchartprops]

#### Properties

| Property | Type | Description |
| ------ | ------ | ------ |
| `series` | `Pick`\<[`ApplicationMetricSeries`](/docs/reference/core#interface-applicationmetricseries), `"unit"` \| `"label"` \| `"points"`\> & `Partial`\<[`ApplicationMetricSeries`](/docs/reference/core#interface-applicationmetricseries)\> | One series from `analytics.metrics()`. Pass the whole series; the chart reads its `points`, `unit` and `label`. |
| `variant?` | `"line"` \| `"column"` | `column` (default) for a flow - deals won *in* a day - and `line` for a level a gauge reports. A line between two flow buckets invents the values in between; a column per level reads as a sum nobody took. Defaults to `line` for a `gauge` series and `column` for everything else. |
| `formatValue?` | (`value`: `number`) => `string` | How a value is written - on the scale and in each hover. Defaults to `formatMetricValue` by the series' unit. |
| `formatBucket?` | (`bucket`: `string`) => `string` | How a bucket is written on the axis and in each hover. Defaults to the bucket key (`2026-10-01`). |
| `summary?` | `string` | Announced to a screen reader in place of the drawing. Defaults to the label and the range. |
| `className?` | `string` | - |

***

### Interface: ConnectPageHeaderProps [#interface-connectpageheaderprops]

#### Properties

| Property | Type | Description |
| ------ | ------ | ------ |
| `title` | `ReactNode` | - |
| `description?` | `ReactNode` | - |
| `action?` | `ReactNode` | Rendered opposite the title. Keep it to one control - a page has one primary action, and a second here has nothing to align against. |
| `clamp?` | `boolean` | Set `false` when the description carries a link that must stay readable on a phone. |
| `className?` | `string` | - |

***

### Interface: ConnectPageShellProps [#interface-connectpageshellprops]

#### Properties

| Property | Type | Description |
| ------ | ------ | ------ |
| `title?` | `ReactNode` | - |
| `description?` | `ReactNode` | - |
| `action?` | `ReactNode` | - |
| `clamp?` | `boolean` | - |
| `above?` | `ReactNode` | Rendered above the header - a breadcrumb trail, a back link, a banner. |
| `className?` | `string` | Merged onto the page root, so a utility here beats the default rather than sitting beside it - `className="space-y-8"` really does widen the page gap. See `cn`. |
| `transition?` | `boolean` | The route transition - the outgoing page fades out, the arriving one fades in and rises. On by default; pass `false` where a host already animates its routes, or the two play over each other. See RouteTransition. |
| `children?` | `ReactNode` | - |

***

### Interface: ConnectSectionProps [#interface-connectsectionprops]

#### Properties

| Property | Type | Description |
| ------ | ------ | ------ |
| `title` | `ReactNode` | - |
| `description?` | `ReactNode` | What the block is for. Omit when the title says everything. |
| `action?` | `ReactNode` | Rendered opposite the title. One control - a section has one action. |
| `titleId?` | `string` | Set to reference the heading from an `aria-labelledby` in the body. |
| `className?` | `string` | - |
| `bodyClassName?` | `string` | - |
| `children?` | `ReactNode` | - |

***

### Interface: ConnectSettingRowProps [#interface-connectsettingrowprops]

#### Properties

| Property | Type | Description |
| ------ | ------ | ------ |
| `title` | `ReactNode` | - |
| `description?` | `ReactNode` | - |
| `action?` | `ReactNode` | The control this row is about - a switch, a button, a value with an edit link. |
| `children?` | `ReactNode` | Rendered under both, full width - a validation message, or a nested field the row reveals. |
| `className?` | `string` | - |

***

### Interface: ConnectSetupChecklistProps [#interface-connectsetupchecklistprops]

#### Properties

| Property | Type | Description |
| ------ | ------ | ------ |
| `progress` | [`SetupProgress`](/docs/reference/core#interface-setupprogress) | - |
| `granted` | readonly `string`[] | The viewer's permissions. A step's action is drawn only for a viewer holding its `permission`. |
| `compact?` | `boolean` | One line per step - no descriptions, no progress header. For a recap inside another card. |
| `readOnly?` | `boolean` | Draw no actions and no owner notes - a recap for somebody who can act on none of it (the waiting page), where "Ask an admin" on every row is noise. |
| `renderLink?` | [`ConnectSetupLinkRenderer`](/docs/reference/client#type-alias-connectsetuplinkrenderer) | The host router's link - see `ConnectSetupLinkRenderer`. |
| `className?` | `string` | - |

***

### Interface: ConnectSetupDoneProps [#interface-connectsetupdoneprops]

#### Properties

| Property | Type | Description |
| ------ | ------ | ------ |
| `appName` | `string` | "Support", "CRM". |
| `children?` | `ReactNode` | The try-it actions - a test ticket, the sample data, the app's one primary "Go to …". |
| `progress` | [`SetupProgress`](/docs/reference/core#interface-setupprogress) | - |
| `granted?` | readonly `string`[] | The viewer's permissions. Given, every unfinished row links back to its step; omitted, the recap is read-only. |
| `renderLink?` | [`ConnectSetupLinkRenderer`](/docs/reference/client#type-alias-connectsetuplinkrenderer) | The host router's link - see `ConnectSetupLinkRenderer`. |
| `className?` | `string` | - |

***

### Interface: ConnectSetupWaitingProps [#interface-connectsetupwaitingprops]

#### Properties

| Property | Type | Description |
| ------ | ------ | ------ |
| `appName` | `string` | "Support", "CRM" - the application being set up. |
| `ownerLabel?` | `string` | Who is doing it, as a sentence opens - "Your admin" (the default), "Your workspace owner". |
| `progress?` | [`SetupProgress`](/docs/reference/core#interface-setupprogress)\<`string`\> | Where setup has got to. Drawn as a read-only recap when given. |
| `action?` | `ReactNode` | One way onward, for a member the app is not locked for - "Go to tickets". Omit while locked. |
| `className?` | `string` | - |

***

### Interface: ConnectSetupWizardFooter [#interface-connectsetupwizardfooter]

#### Properties

| Property | Type | Description |
| ------ | ------ | ------ |
| `back?` | `string` \| `null` | The previous step's path, or `null`/omitted on the first. Rendered as a tertiary "Back". |
| `skip?` | `ReactNode` | The app's own "Skip for now" control (a server-action button). Omit on a step that cannot be skipped. |
| `primary` | `ReactNode` | The step's one primary control - a submit button, a link, whatever the step's verb is. |

***

### Interface: ConnectSetupWizardProps [#interface-connectsetupwizardprops]

#### Properties

| Property | Type | Description |
| ------ | ------ | ------ |
| `steps` | readonly [`ConnectSetupWizardStep`](#interface-connectsetupwizardstep)[] | - |
| `current` | `string` | The key of the step this page is. The route knows it - pass it, never read the pathname. |
| `title` | `ReactNode` | The page's own heading. Rendered as the document's `h1` - this frame is the whole page. |
| `description?` | `ReactNode` | - |
| `children?` | `ReactNode` | - |
| `aside?` | `ReactNode` | An illustration beside the content at desktop width. Hidden below `lg`, where it would only push the form down. |
| `footer` | [`ConnectSetupWizardFooter`](#interface-connectsetupwizardfooter) | - |
| `exitHref?` | `string` | Where "Exit setup" goes. Omit while the app is locked - there is nowhere to exit to. |
| `exitLabel?` | `string` | The exit link's words. |
| `renderLink?` | [`ConnectSetupLinkRenderer`](/docs/reference/client#type-alias-connectsetuplinkrenderer) | The host router's link - see `ConnectSetupLinkRenderer`. A plain `<a>` without it. |
| `className?` | `string` | - |

***

### Interface: ConnectSetupWizardStep [#interface-connectsetupwizardstep]

One marker on the wizard's step strip.

#### Properties

| Property | Type | Description |
| ------ | ------ | ------ |
| `key` | `string` | - |
| `label` | `string` | Short - the strip's label, and the "Step 2 of 5 · \<label>" line on a phone. |
| `path` | `string` | - |
| `state` | [`SetupStepState`](/docs/reference/core#type-alias-setupstepstate) | - |

***

### Interface: ConnectStatStripProps [#interface-connectstatstripprops]

#### Properties

| Property | Type | Description |
| ------ | ------ | ------ |
| `children` | `ReactNode` | `ConnectStatTile`s. |
| `columns?` | `6` \| `2` \| `5` \| `4` \| `3` | How many tiles sit abreast from `lg` up (two abreast below `sm`, and an odd last tile spans the row, so a strip never leaves an orphan). |
| `className?` | `string` | - |

***

### Interface: ConnectStatTileProps [#interface-connectstattileprops]

#### Properties

| Property | Type | Description |
| ------ | ------ | ------ |
| `label` | `ReactNode` | - |
| `value` | `ReactNode` | Already formatted - `formatMetricValue(series.total, series.unit)` for a metric. A `null` total formats as a dash; pass `partial` alongside it so the hint can say why. |
| `hint?` | `ReactNode` | What the number is of. Omit only if the label already says it. |
| `delta?` | [`MetricDelta`](/docs/reference/core#interface-metricdelta) \| `null` | How it moved against the comparison period - `metricDelta(current, previous)`. Omit, or pass `null`, when there is nothing honest to compare against: a "+0%" pill would read as a measured result. |
| `polarity?` | `"higher-is-better"` \| `"lower-is-better"` | Whether a rise is good news - decides the pill's colour, never its arrow. |
| `partial?` | `boolean` | The figure leaves out days that are not measured yet (`series.partial`). Adds a short note under the figure rather than presenting a part as the whole. |
| `inset?` | `boolean` | Drawn on `--surface-secondary` with no shadow - for a tile inside another card. |
| `className?` | `string` | - |

***

### Interface: ConnectStatusPresentation\<TStatus\> [#interface-connectstatuspresentation]

How one domain's status union is presented: a tone and a human label per
member.

Both are **total** `Record`s, and that is the load-bearing property - adding
a member to the status union fails the type gate until it has been given a
presentation. A loose `Record<string, …>` map silently renders the new
status as `undefined`.

#### Type Parameters

| Type Parameter |
| ------ |
| `TStatus` *extends* `string` |

#### Properties

| Property | Modifier | Type |
| ------ | ------ | ------ |
| `tone` | `readonly` | `Readonly`\<`Record`\<`TStatus`, [`ConnectStatusTone`](#type-alias-connectstatustone)\>\> |
| `label` | `readonly` | `Readonly`\<`Record`\<`TStatus`, `string`\>\> |

***

### Interface: SetupStepView [#interface-setupstepview]

What one step offers one viewer.

#### Properties

| Property | Type | Description |
| ------ | ------ | ------ |
| `action` | \| \{ `href`: `string`; `label`: `string`; \} \| `null` | The button - only for somebody who may act, and only on a state with something to do. |
| `ownerNote` | `string` \| `null` | "Ask an admin to do this one." - for a viewer who cannot act on an open step. |
| `line` | `string` | The step's second line: the fact once done, the reason in review, what it waits on when blocked. |
## Type Aliases

### Type Alias: ConnectStatusTone [#type-alias-connectstatustone]

```ts
type ConnectStatusTone = "success" | "warning" | "danger" | "accent" | "default";
```

The closed set of tones a status may resolve to.

Deliberately five, and deliberately narrower than HeroUI's `Chip` colour
union: a status is either fine, needs attention, is broken, is in progress,
or is inert. A sixth tone would have to mean one of those five again, which
is where hand-written status chips start disagreeing with each other.
## Variables

### Variable: cn [#variable-cn]

```ts
const cn: <T>(...classnames: T) => CnReturn;
```

Combines class names and merges conflicting Tailwind classes (default config).

#### Type Parameters

| Type Parameter |
| ------ |
| `T` *extends* `CnOptions` |

#### Parameters

| Parameter | Type |
| ------ | ------ |
| ...`classnames` | `T` |

#### Returns

`CnReturn`

***

### Variable: NOT\_YET\_MEASURED [#variable-not_yet_measured]

```ts
const NOT_YET_MEASURED: "not yet measured" = "not yet measured";
```

What a gap says, in the hover and in the legend under the chart.

***

### Variable: SETUP\_STATE\_PRESENTATION [#variable-setup_state_presentation]

```ts
const SETUP_STATE_PRESENTATION: ConnectStatusPresentation<SetupStepState>;
```

Every step state as a chip. Total, so a new state fails the type gate until it is given one.
## Functions

### Function: ConnectDeltaPill() [#function-connectdeltapill]

```ts
function ConnectDeltaPill(__namedParameters: Readonly<{
  delta: MetricDelta;
  polarity?: "higher-is-better" | "lower-is-better";
  className?: string;
}>): Element;
```

How a figure moved, as the tile draws it - exported for a chart card that leads with a figure of its own.

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | `Readonly`\<\{ `delta`: [`MetricDelta`](/docs/reference/core#interface-metricdelta); `polarity?`: `"higher-is-better"` \| `"lower-is-better"`; `className?`: `string`; \}\> |

#### Returns

`Element`

***

### Function: ConnectEmptyState() [#function-connectemptystate]

```ts
function ConnectEmptyState(__namedParameters: Readonly<ConnectEmptyStateProps>): Element;
```

What a list, grid or table shows when it has nothing to show.

**The two empty states are different facts and the copy must say so.** "You
have no contacts" and "no contacts match this filter" call for different
words and a different action - create the thing, versus undo the filter
hiding it. Both render through here; the caller decides which by what it
passes as `action`. Getting this wrong costs a user real time: an
unfiltered-looking empty state in front of a filtered list reads as data
loss.

`variant` chooses the container by what the state stands *in*: `card` (the
default), `dashed` for a region that will be filled in place - a file grid,
a board column - where the outline is what says "things appear here", and
`plain` for a slot already inside a card that would otherwise nest two
borders.

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | `Readonly`\<[`ConnectEmptyStateProps`](#interface-connectemptystateprops)\> |

#### Returns

`Element`

***

### Function: ConnectMetricChart() [#function-connectmetricchart]

```ts
function ConnectMetricChart(__namedParameters: Readonly<ConnectMetricChartProps>): Element | null;
```

One metric series as columns or a line, drawn on the server - no chart
library and no client component, because the geometry is arithmetic and the
hover is a `title` on each bucket's full-height slot.

#### Rules the drawing obeys

- **`null` is a gap, never a zero.** A bucket the rollup has not reached, or
  a `distinct` metric today, keeps its slot and draws a dotted floor - and a
  line *breaks* there rather than diving to the axis. The hover says
  "not yet measured", and a legend line under the chart says what the dots
  mean whenever there is one. Drawing those as zeros is how a dev
  deployment, where the nightly rollup never runs, looks like a dead product.
- **The baseline is zero**, so a column's height reads as its magnitude.
- **Semantic tokens only** - the mark is `--accent`, the rules `--separator`,
  the text `muted` - so the chart takes whatever palette the host defines.
- Labels are HTML around the drawing, never `<text>` in the stretched
  viewBox, so they stay their real size on a phone.

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | `Readonly`\<[`ConnectMetricChartProps`](#interface-connectmetricchartprops)\> |

#### Returns

`Element` \| `null`

***

### Function: ConnectPageHeader() [#function-connectpageheader]

```ts
function ConnectPageHeader(__namedParameters: Readonly<ConnectPageHeaderProps>): Element;
```

The title / description / action block a page opens with.

The structure is the point, not the styling. The action is a peer of the
**title**, not of the block, so nothing below the first line can move it -
the common hand-rolled shape puts the action after the description, which
makes the vertical position of a page's primary control a function of how
long someone wrote the paragraph above it. On a phone that pushes it most of
a thumb's reach down the screen.

Mobile-first, and the two axes are separate decisions: the title row is a
`justify-between` at every width (title left, action right, where a thumb
expects it), while the description is clamped to two lines on a phone and
released from `sm` up.

An `h2`, because the document's `h1` is the application itself.

No hooks and no state, so this renders from a Server Component - which is
why it lives in `@cosmoops/connect-sdk/ui` rather than `/client`.

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | `Readonly`\<[`ConnectPageHeaderProps`](#interface-connectpageheaderprops)\> |

#### Returns

`Element`

***

### Function: ConnectPageShell() [#function-connectpageshell]

```ts
function ConnectPageShell(__namedParameters: Readonly<ConnectPageShellProps>): Element;
```

The frame a page opens with: its vertical rhythm, its header, and the
suspended regions beneath.

**The header is a prop, so it renders in the static shell** - above and
outside every `<Suspense>` boundary. That is the one bug this component
exists to make unrepresentable: rendering the header inside the async child
makes a page's own title wait on a data read, and under Next's partial
prefetching the route's shared App Shell loses it as well. There is no
arrangement of `children` that reaches the header slot.

A detail route is the honest exception, and it has its own door:
`ConnectPageShell.Header` renders the identical header from inside an async
child, for a page whose title is data it does not have yet. Pair it with a
skeleton header in the fallback. The rule is that a *static* title must
never be made to wait, not that every title can be static.

`space-y-5` is the page gap, owned here so it has exactly one definition.

**It is also where the route transition lives**, because it is the one
thing every page opens with. A transition has to wrap the *page*: a layout
persists across navigation, so its enter and exit never fire, and a
`template.tsx` remounts its subtree on every navigation, discarding the
form drafts and scroll positions Next's `<Activity>` keeps. Where a layout
draws the shell instead - a record with tabs - entering and leaving the
record animates and switching tabs does not, which is right: a tab is the
same place. `default="none"` keeps it still during anything else - a
filter written to the URL, a `router.refresh()` after a save. The
animations are `connect-page-enter`/`connect-page-exit` in `theme.css`.

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | `Readonly`\<[`ConnectPageShellProps`](#interface-connectpageshellprops)\> |

#### Returns

`Element`

***

### Function: ConnectSection() [#function-connectsection]

```ts
function ConnectSection(__namedParameters: Readonly<ConnectSectionProps>): Element;
```

One titled block inside a page: a card, its heading, what it is for, and the
one control that acts on it.

The heading is an `h3` - `ConnectPageHeader` renders the page title as an
`h2`, so a block *inside* a page is a level below it. Hand-rolled sections
reliably use `h2`, which makes every settings block a sibling of the page it
sits in and flattens the outline a screen reader announces.

As in the page header, the action is a peer of the title rather than of the
block, so its position does not move with the length of the description.

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | `Readonly`\<[`ConnectSectionProps`](#interface-connectsectionprops)\> |

#### Returns

`Element`

***

### Function: ConnectSettingRow() [#function-connectsettingrow]

```ts
function ConnectSettingRow(__namedParameters: Readonly<ConnectSettingRowProps>): Element;
```

One labelled setting inside a `ConnectSection`.

Stacks on a phone and goes side-by-side from `sm` up, rather than shrinking
a two-column row until neither column is readable. The control keeps its
intrinsic width so truncation lands on the description.

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | `Readonly`\<[`ConnectSettingRowProps`](#interface-connectsettingrowprops)\> |

#### Returns

`Element`

***

### Function: ConnectSetupChecklist() [#function-connectsetupchecklist]

```ts
function ConnectSetupChecklist(__namedParameters: Readonly<ConnectSetupChecklistProps>): Element;
```

Every onboarding step, in order, with where it stands - the `/onboarding`
overview, and the recap on the waiting and done screens.

- **State chips**: done, skipped (amber - "not now", not done), in review
  (with the reason), waiting (grey, with what it waits on).
- **An action only for a step the viewer may act on.** Anybody else is told
  whose job it is ("Ask an admin to do this one.") rather than offered a
  button that ends in a 403.
- **One primary**: `progress.next`'s action. Every other action is
  secondary, and a done step offers a quiet "Change".

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | `Readonly`\<[`ConnectSetupChecklistProps`](#interface-connectsetupchecklistprops)\> |

#### Returns

`Element`

***

### Function: ConnectSetupDone() [#function-connectsetupdone]

```ts
function ConnectSetupDone(__namedParameters: Readonly<ConnectSetupDoneProps>): Element;
```

The wizard's last screen, `/onboarding/done`: what was set up - every step
done, skipped or still open, each unfinished one a link back when the
viewer may act - and then the app's own try-it actions (`children`).
Anything skipped stays on the landing page's "Get started" card.

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | `Readonly`\<[`ConnectSetupDoneProps`](#interface-connectsetupdoneprops)\> |

#### Returns

`Element`

***

### Function: ConnectSetupStepStrip() [#function-connectsetupstepstrip]

```ts
function ConnectSetupStepStrip(__namedParameters: Readonly<{
  steps: readonly ConnectSetupWizardStep[];
  current: string;
  renderLink?: ConnectSetupLinkRenderer;
  className?: string;
}>): Element | null;
```

Where you are in the wizard. At phone width it is one line - "Step 2 of 5 ·
Support email" - because five labelled markers do not fit in 343px and a
wrapped strip reads as two. Done, skipped and in-review steps stay links,
so somebody who picked the wrong industry can go back and say so.

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | `Readonly`\<\{ `steps`: readonly [`ConnectSetupWizardStep`](#interface-connectsetupwizardstep)[]; `current`: `string`; `renderLink?`: [`ConnectSetupLinkRenderer`](/docs/reference/client#type-alias-connectsetuplinkrenderer); `className?`: `string`; \}\> |

#### Returns

`Element` \| `null`

***

### Function: ConnectSetupWaiting() [#function-connectsetupwaiting]

```ts
function ConnectSetupWaiting(__namedParameters: Readonly<ConnectSetupWaitingProps>): Element;
```

What a member without setup permission sees at `/onboarding/waiting`: one
short card, not a wizard they cannot complete and not a 403. Setup is
somebody else's job, and the useful thing to say is so - and, given
`progress`, what is already in place. Reads nothing itself, so a
`forbidden.tsx` can draw it too.

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | `Readonly`\<[`ConnectSetupWaitingProps`](#interface-connectsetupwaitingprops)\> |

#### Returns

`Element`

***

### Function: ConnectSetupWizard() [#function-connectsetupwizard]

```ts
function ConnectSetupWizard(__namedParameters: Readonly<ConnectSetupWizardProps>): Element;
```

The setup wizard's full-page frame: the step strip, the step's title and
description, its content, and a sticky footer - Back on the left, Skip and
the step's one primary on the right.

**It needs no app shell**, because the lock page has none: a workspace
held on `/onboarding` must not be shown a sidebar full of destinations it
cannot reach. It is centred in its own `min-h-dvh` column and brings its
own background, so it also works inside a shell for an app that keeps one.

A Server Component with no state. The current step is a fact about the
route and the page passes it as `current`; reading `usePathname()` here
would put URL data in a shared shell.

**Only `primary` is primary.** Back is tertiary and the app's skip control
should be secondary, so a step reads as one decision with two ways out.
The skip and primary controls are the app's own nodes - typically
server-action buttons that record the skip and move on (`nextSetupPath`).

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | `Readonly`\<[`ConnectSetupWizardProps`](#interface-connectsetupwizardprops)\> |

#### Returns

`Element`

***

### Function: ConnectStatStrip() [#function-connectstatstrip]

```ts
function ConnectStatStrip(__namedParameters: Readonly<ConnectStatStripProps>): Element;
```

A row of stat tiles - the headline strip above a report's charts.

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | `Readonly`\<[`ConnectStatStripProps`](#interface-connectstatstripprops)\> |

#### Returns

`Element`

***

### Function: ConnectStatTile() [#function-connectstattile]

```ts
function ConnectStatTile(__namedParameters: Readonly<ConnectStatTileProps>): Element;
```

A label, a figure, how it moved, and one line saying what the figure counts.

Presentational and server-renderable, like the rest of this entry point -
the figure comes formatted, the delta comes computed (`metricDelta`), and
the tile only lays them out. Semantic tokens only: the pill is `success` /
`danger` tinted, the label and hint `muted`.

**Absence is said, not drawn.** No delta means no pill (not a grey "0%"),
and `partial` adds "Some days not measured yet" so a figure summed over the
days the rollup reached is not read as the whole period.

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | `Readonly`\<[`ConnectStatTileProps`](#interface-connectstattileprops)\> |

#### Returns

`Element`

***

### Function: ConnectStatusChip() [#function-connectstatuschip]

```ts
function ConnectStatusChip<TStatus>(__namedParameters: Readonly<{
  status: TStatus;
  presentation: ConnectStatusPresentation<TStatus>;
  className?: string;
}>): Element;
```

One status, rendered the way every status should be.

Domain knowledge stays in the domain: each caller exports its own
`ConnectStatusPresentation` next to the union it describes, and this renders
it. A status whose *rendering* carries real logic - a scheduled cancellation
outranking a running trial, say - keeps its own component and calls this for
the final chip. A map cannot express precedence.

#### Type Parameters

| Type Parameter |
| ------ |
| `TStatus` *extends* `string` |

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | `Readonly`\<\{ `status`: `TStatus`; `presentation`: [`ConnectStatusPresentation`](#interface-connectstatuspresentation)\<`TStatus`\>; `className?`: `string`; \}\> |

#### Returns

`Element`

***

### Function: setupStepView() [#function-setupstepview]

```ts
function setupStepView(step: SetupStepStatus, granted: readonly string[]): SetupStepView;
```

The one rule every surface reads for a step's button and note.

- `done` - no action (the checklist adds its own "Change"); the line is the
  fact that made it done.
- `blocked` - no action for anybody; "Waiting on \<x>".
- `in_review` - "View" for somebody who may act, the review reason as the
  line, no owner note (there is nothing for the owner to do either).
- `skipped` - "Finish"; `todo` - the step's own verb. Anybody else is told
  whose job it is.

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `step` | [`SetupStepStatus`](/docs/reference/core#interface-setupstepstatus) |
| `granted` | readonly `string`[] |

#### Returns

[`SetupStepView`](#interface-setupstepview)