Skip to content

AppFrame

AppFrame is the chrome every Synapse app starts with: a fixed header, a scrollable body, and an optional fixed footer that fill the host pane. A body layout (SidebarLayout, ListDetailLayout, or plain content) goes inside AppFrame.Body. It establishes the definite-height ancestor chain the shell needs on render, so it fills the pane instead of collapsing to content height.

import { AppFrame } from "@nimblebrain/synapse/ui";
<AppFrame>
<AppFrame.Header>…</AppFrame.Header>
<AppFrame.Body>…</AppFrame.Body>
<AppFrame.Footer>…</AppFrame.Footer>
</AppFrame>;
  • AppFrame.Header: fixed at the top, doesn’t scroll.
  • AppFrame.Body: the scrollable region. Pass bleed to host a full-bleed layout (a SidebarLayout or a ListDetailLayout) edge-to-edge, where the panes manage their own scroll; leave it off for plain content, which gets a padded column.
  • AppFrame.Footer: fixed at the bottom, bordered.

The contentWidth knob is a personality lever: reading centers header, body, and footer in a ~760px column (good for conversations or a report), while full uses the whole pane (good for a CRM or dashboard).

The space between the frame’s edge and its content is the kit’s gutter token, and nothing else draws it. The host hands your app an edge-to-edge slot, and an app names no spacing of its own. Containers (the frame, a pane, a scroll area) run edge to edge, so their scrollbars and dividers sit on the edges; the content inside them insets itself by the gutter. AppFrame.Header, Footer and a plain Body inset by it. With bleed, a ListDetailLayout’s panes inset their own content; a SidebarLayout’s Main leaves the inset to what you put in it.

The gutter follows the frame’s own width: 1.5rem, and 1rem once the frame is 640px or narrower. Set --nb-gutter to override it.

Prop Type Default
contentWidth "reading" | "full" "full"
Prop Type Default
bleed boolean false