Skip to content

ui/layout

ui/layout

Import from @norbital-ai/ui/layout

The layout layer (§3.6 ./layout): the layoutPack primitives and AppShell. Inset and scroll-port context stay internal.

AppIdentity type

type AppIdentity = {
    readonly title?: string | undefined;
    readonly description?: string | null | undefined;
    readonly icon?: string | undefined;
    readonly banner?: string | null | undefined;
    readonly thumbnail?: string | null | undefined;
    readonly actions?: Snippet | undefined;
};

The one place a running application hands its identity to the shell chrome above it.

The compiler reads static identity out of app source, but translated titles and descriptions (title={t('...')}) are not statically readable — and AppShell already receives them as props. Without this channel every shelled app falls back to a filename-derived label, a fallback icon, and no description in the hero, sidebar, and finder, no matter what the shell was told.

The slot is deliberately narrow: translated identity and artwork, nothing else.

Members

NameTypeDescription
title?string | undefined
description?string | null | undefined
icon?string | undefined
banner?string | null | undefined
thumbnail?string | null | undefined
actions?Snippet | undefined

Source: packages/ui/src/layout/app-identity.svelte.ts:14

AppIdentitySlot type

type AppIdentitySlot = {
    current: AppIdentity | null;
};

The slot an AppShell writes its translated identity into for the chrome above it.

Members

NameTypeDescription
currentAppIdentity | null

Source: packages/ui/src/layout/app-identity.svelte.ts:24

AppShell component

component AppShell(props: AppShellProps)

An app page's shell: the hero (icon, title, description, banner), header actions, and the page body in the shared inset. Every +<page>.page.svelte renders inside one.

Props

NameTypeDescription
iconstring

Icon name rendered in the workspace hero (for example lucide:cpu).

titlestring

Page title rendered in the workspace hero and the document head.

descriptionstring

Page description rendered under the hero title.

banner?string

Banner artwork for the hero background and, unless overridden, the app thumbnail.

thumbnail?string

App card artwork. Defaults to the banner.

variant?AppShellVariant

page (default) wraps content in the shared inset region so it aligns with the hero icon leading edge; full skips the wrapper for tab strips (which carry their own matching inset) and full-bleed surfaces.

actions?Snippet

Header actions the shell places beside the hero title (today's AppHeaderActions).

childrenSnippet

Example

<AppShell icon="lucide:briefcase" title={bolt.t('jobs.title')} description={bolt.t('jobs.description')}>
<Table of="jobs" />
</AppShell>

Source: packages/ui/src/layout/app-shell.svelte:1

AppShellProps interface

interface AppShellProps {
    /** Icon name rendered in the workspace hero (for example `lucide:cpu`). */
    icon: string;
    /** Page title rendered in the workspace hero and the document head. */
    title: string;
    /** Page description rendered under the hero title. */
    description: string;
    /** Banner artwork for the hero background and, unless overridden, the app thumbnail. */
    banner?: string;
    /** App card artwork. Defaults to the banner. */
    thumbnail?: string;
    /**
     * `page` (default) wraps content in the shared inset region so it aligns with the
     * hero icon leading edge; `full` skips the wrapper for tab strips (which carry their
     * own matching inset) and full-bleed surfaces.
     */
    variant?: AppShellVariant;
    /** Header actions the shell places beside the hero title (today's `AppHeaderActions`). */
    actions?: Snippet;
    children: Snippet;
}

The props of AppShell.

Members

NameTypeDescription
iconstring

Icon name rendered in the workspace hero (for example lucide:cpu).

titlestring

Page title rendered in the workspace hero and the document head.

descriptionstring

Page description rendered under the hero title.

banner?string

Banner artwork for the hero background and, unless overridden, the app thumbnail.

thumbnail?string

App card artwork. Defaults to the banner.

variant?AppShellVariant

page (default) wraps content in the shared inset region so it aligns with the hero icon leading edge; full skips the wrapper for tab strips (which carry their own matching inset) and full-bleed surfaces.

actions?Snippet

Header actions the shell places beside the hero title (today's AppHeaderActions).

childrenSnippet

Source: packages/ui/src/layout/app-shell.svelte:17

AppShellVariant type

type AppShellVariant = 'page' | 'full';

page wraps the body in the shared inset; full leaves it edge to edge (tab strips, full-bleed surfaces).

Source: packages/ui/src/layout/app-shell.svelte:14

Bound component

component Bound(props: BoundProps)

A region with a named height contract (compact, standard, tall, fit, full, auto), optional padding, inset and clipping: the box a scrollport or a view fills.

Props

NameTypeDescription
as?LayoutElement
size?BoundSize

The named height contract. compact/standard/tall are fixed panes; fit tracks the viewer: min(42rem, 100dvh − 14rem) with a standard floor, so a scrollport claims the space below a ~14rem chrome band instead of guessing a pane size; full fills whatever definite height the parent grants; auto is content height — a clip or inset boundary with no height contract of its own.

pad?LayoutPad
inset?boolean
clip?boolean
grow?boolean

Take the remaining space along the parent's main axis.

shrink?boolean

Allow this region to shrink when its parent is constrained.

childrenSnippet
ref?HTMLElement | null

The rendered element, for measurement or focus.

Source: packages/ui/src/layout/bound.svelte:1

BoundProps interface

interface BoundProps extends LayoutAttributes {
    as?: LayoutElement;
    /**
     * The named height contract. `compact`/`standard`/`tall` are fixed panes;
     * `fit` tracks the viewer: `min(42rem, 100dvh − 14rem)` with a `standard` floor, so a
     * scrollport claims the space below a ~14rem chrome band instead of guessing a pane size;
     * `full` fills whatever definite height the parent grants; `auto` is content height — a clip
     * or inset boundary with no height contract of its own.
     */
    size?: BoundSize;
    pad?: LayoutPad;
    inset?: boolean;
    clip?: boolean;
    /** Take the remaining space along the parent's main axis. */
    grow?: boolean;
    /** Allow this region to shrink when its parent is constrained. */
    shrink?: boolean;
    children: Snippet;
}

The props of Bound.

Members

NameTypeDescription
as?LayoutElement
size?BoundSize

The named height contract. compact/standard/tall are fixed panes; fit tracks the viewer: min(42rem, 100dvh − 14rem) with a standard floor, so a scrollport claims the space below a ~14rem chrome band instead of guessing a pane size; full fills whatever definite height the parent grants; auto is content height — a clip or inset boundary with no height contract of its own.

pad?LayoutPad
inset?boolean
clip?boolean
grow?boolean

Take the remaining space along the parent's main axis.

shrink?boolean

Allow this region to shrink when its parent is constrained.

childrenSnippet
ref?HTMLElement | null

The rendered element, for measurement or focus.

Source: packages/ui/src/layout/bound.svelte:14

BoundSize type

type BoundSize = 'compact' | 'standard' | 'tall' | 'fit' | 'full' | 'auto';

A Bound's height contract: fixed panes, fit to the viewport, full of a definite parent, or auto content height.

Source: packages/ui/src/layout/bound.svelte:12

Center component

component Center(props: CenterProps)

Centres its content at a reading measure (narrow, reading, wide, full), optionally laying out its children as a stack, row, cluster or grid.

Props

NameTypeDescription
as?LayoutElement
measure?CenterMeasure
layout?CenterLayout

Arrange direct children while keeping centring and composition on the same element.

gap?LayoutGap
align?'start' | 'center' | 'end' | 'baseline' | 'stretch'
justify?'start' | 'center' | 'end' | 'between'
childrenSnippet
ref?HTMLElement | null

The rendered element, for measurement or focus.

Source: packages/ui/src/layout/center.svelte:1

CenterMeasure type

type CenterMeasure = 'narrow' | 'reading' | 'wide' | 'full';

The maximum width a Center holds its content to.

Source: packages/ui/src/layout/center.svelte:10

CenterProps interface

interface CenterProps extends LayoutAttributes {
    as?: LayoutElement;
    measure?: CenterMeasure;
    /** Arrange direct children while keeping centring and composition on the same element. */
    layout?: CenterLayout;
    gap?: LayoutGap;
    align?: 'start' | 'center' | 'end' | 'baseline' | 'stretch';
    justify?: 'start' | 'center' | 'end' | 'between';
    children: Snippet;
}

The props of Center.

Members

NameTypeDescription
as?LayoutElement
measure?CenterMeasure
layout?CenterLayout

Arrange direct children while keeping centring and composition on the same element.

gap?LayoutGap
align?'start' | 'center' | 'end' | 'baseline' | 'stretch'
justify?'start' | 'center' | 'end' | 'between'
childrenSnippet
ref?HTMLElement | null

The rendered element, for measurement or focus.

Source: packages/ui/src/layout/center.svelte:13

Cluster component

component Cluster(props: ClusterProps)

A wrapping row of items with a gap: tags, buttons, metadata. Children wrap to the next line when the row is full.

Props

NameTypeDescription
as?LayoutElement
gap?LayoutGap
align?'start' | 'center' | 'end' | 'baseline'
justify?'start' | 'center' | 'end' | 'between'
grow?boolean

Take the remaining space along the parent's main axis.

fill?boolean

Fill the parent's height.

shrink?boolean

Allow this region to shrink when its parent is constrained.

divided?boolean

A hairline between children — a segmented strip. Pair with gap="none".

childrenSnippet
ref?HTMLElement | null

The rendered element, for measurement or focus.

Source: packages/ui/src/layout/cluster.svelte:1

ClusterProps interface

interface ClusterProps extends LayoutAttributes {
    as?: LayoutElement;
    gap?: LayoutGap;
    align?: 'start' | 'center' | 'end' | 'baseline';
    justify?: 'start' | 'center' | 'end' | 'between';
    /** Take the remaining space along the parent's main axis. */
    grow?: boolean;
    /** Fill the parent's height. */
    fill?: boolean;
    /** Allow this region to shrink when its parent is constrained. */
    shrink?: boolean;
    /** A hairline between children — a segmented strip. Pair with `gap="none"`. */
    divided?: boolean;
    children: Snippet;
}

The props of Cluster.

Members

NameTypeDescription
as?LayoutElement
gap?LayoutGap
align?'start' | 'center' | 'end' | 'baseline'
justify?'start' | 'center' | 'end' | 'between'
grow?boolean

Take the remaining space along the parent's main axis.

fill?boolean

Fill the parent's height.

shrink?boolean

Allow this region to shrink when its parent is constrained.

divided?boolean

A hairline between children — a segmented strip. Pair with gap="none".

childrenSnippet
ref?HTMLElement | null

The rendered element, for measurement or focus.

Source: packages/ui/src/layout/cluster.svelte:10

Column component

component Column(props: ColumnProps)

One cell of a Grid or Columns spanning span columns (or all); it throws outside those parents.

Props

NameTypeDescription
as?LayoutElement
span?ColumnSpan
childrenSnippet
ref?HTMLElement | null

The rendered element, for measurement or focus.

Source: packages/ui/src/layout/column.svelte:1

ColumnCount type

type ColumnCount = 1 | 2 | 3 | 4 | 5 | 6 | 7;

The number of columns of a Columns.

Source: packages/ui/src/layout/columns.svelte:10

ColumnProps interface

interface ColumnProps extends LayoutAttributes {
    as?: LayoutElement;
    span?: ColumnSpan;
    children: Snippet;
}

The props of Column.

Members

NameTypeDescription
as?LayoutElement
span?ColumnSpan
childrenSnippet
ref?HTMLElement | null

The rendered element, for measurement or focus.

Source: packages/ui/src/layout/column.svelte:12

ColumnSpan type

type ColumnSpan = 1 | 2 | 3 | 4 | 5 | 6 | 'all';

How many columns a Column spans.

Source: packages/ui/src/layout/column.svelte:10

Columns component

component Columns(props: ColumnsProps)

A fixed number of equal columns (1–7) that collapse to one per row below a width of the element itself.

Props

NameTypeDescription
as?LayoutElement
count?ColumnCount
gap?LayoutGap
collapse?'compact' | 'narrow' | 'none'

Below this width of the Columns itself, every child takes a full row. none keeps the count at any width — only for content that is meaningless stacked (a calendar week).

childrenSnippet
ref?HTMLElement | null

The rendered element, for measurement or focus.

Source: packages/ui/src/layout/columns.svelte:1

ColumnsProps interface

interface ColumnsProps extends LayoutAttributes {
    as?: LayoutElement;
    count?: ColumnCount;
    gap?: LayoutGap;
    /**
     * Below this width of the Columns itself, every child takes a full row. `none` keeps the
     * count at any width — only for content that is meaningless stacked (a calendar week).
     */
    collapse?: 'compact' | 'narrow' | 'none';
    children: Snippet;
}

The props of Columns.

Members

NameTypeDescription
as?LayoutElement
count?ColumnCount
gap?LayoutGap
collapse?'compact' | 'narrow' | 'none'

Below this width of the Columns itself, every child takes a full row. none keeps the count at any width — only for content that is meaningless stacked (a calendar week).

childrenSnippet
ref?HTMLElement | null

The rendered element, for measurement or focus.

Source: packages/ui/src/layout/columns.svelte:12

Cover component

component Cover(props: CoverProps)

A full-height region with optional top and bottom chrome and a body between them, optionally centred: an empty state, a sign-in card, a page with a footer bar.

Props

NameTypeDescription
as?LayoutElement
gap?LayoutGap
pad?LayoutPad
grow?boolean

Take the remaining space along the parent's main axis.

shrink?boolean

Allow this region to shrink when its parent is constrained.

center?boolean

Centre the body's content in the space between top and bottom — Every Layout's Cover principal: an empty state, a sign-in card, a splash. Without it the body is a scroll owner's slot and starts at the top.

top?Snippet
bottom?Snippet
childrenSnippet
ref?HTMLElement | null

The rendered element, for measurement or focus.

Source: packages/ui/src/layout/cover.svelte:1

CoverProps interface

interface CoverProps extends LayoutAttributes {
    as?: LayoutElement;
    gap?: LayoutGap;
    pad?: LayoutPad;
    /** Take the remaining space along the parent's main axis. */
    grow?: boolean;
    /** Allow this region to shrink when its parent is constrained. */
    shrink?: boolean;
    /**
     * Centre the body's content in the space between `top` and `bottom` — Every Layout's Cover
     * principal: an empty state, a sign-in card, a splash. Without it the body is a scroll owner's
     * slot and starts at the top.
     */
    center?: boolean;
    top?: Snippet;
    bottom?: Snippet;
    children: Snippet;
}

The props of Cover.

Members

NameTypeDescription
as?LayoutElement
gap?LayoutGap
pad?LayoutPad
grow?boolean

Take the remaining space along the parent's main axis.

shrink?boolean

Allow this region to shrink when its parent is constrained.

center?boolean

Centre the body's content in the space between top and bottom — Every Layout's Cover principal: an empty state, a sign-in card, a splash. Without it the body is a scroll owner's slot and starts at the top.

top?Snippet
bottom?Snippet
childrenSnippet
ref?HTMLElement | null

The rendered element, for measurement or focus.

Source: packages/ui/src/layout/cover.svelte:10

Frame component

component Frame(props: FrameProps)

Crops media to a named aspect ratio (square, portrait, landscape, widescreen, banner).

Props

NameTypeDescription
as?LayoutElement
ratio?FrameRatio
shrink?boolean

Allow this region to shrink when its parent is constrained.

childrenSnippet
ref?HTMLElement | null

The rendered element, for measurement or focus.

Source: packages/ui/src/layout/frame.svelte:1

FrameProps interface

interface FrameProps extends LayoutAttributes {
    as?: LayoutElement;
    ratio?: FrameRatio;
    /** Allow this region to shrink when its parent is constrained. */
    shrink?: boolean;
    children: Snippet;
}

The props of Frame.

Members

NameTypeDescription
as?LayoutElement
ratio?FrameRatio
shrink?boolean

Allow this region to shrink when its parent is constrained.

childrenSnippet
ref?HTMLElement | null

The rendered element, for measurement or focus.

Source: packages/ui/src/layout/frame.svelte:12

FrameRatio type

type FrameRatio = 'square' | 'portrait' | 'landscape' | 'widescreen' | 'banner';

Named media crops. banner is the compact overview / sheet hero (2:1).

Source: packages/ui/src/layout/frame.svelte:10

Grid component

component Grid(props: GridProps)

An auto-fitting grid of cards at a minimum cell width (compact, card, panel), or explicit column tracks.

Props

NameTypeDescription
as?LayoutElement
gap?LayoutGap
rowGap?LayoutGap

Space between rows when it differs from gap (a definition list: wide columns, tight rows).

align?'start' | 'center' | 'end' | 'stretch'

Block-axis placement of every cell.

minimum?GridMinimum
tracks?string

Explicit column tracks. When set, this is the grid template (via style, not a Tailwind class) and minimum is ignored. Use minimum for intrinsic auto-fit cards; use tracks when the columns are a known, uneven measure — a log table, a definition list.

childrenSnippet
ref?HTMLElement | null

The rendered element, for measurement or focus.

Source: packages/ui/src/layout/grid.svelte:1

GridMinimum type

type GridMinimum = 'compact' | 'card' | 'panel';

The smallest cell width an auto-fit Grid keeps before wrapping.

Source: packages/ui/src/layout/grid.svelte:10

GridProps interface

interface GridProps extends LayoutAttributes {
    as?: LayoutElement;
    gap?: LayoutGap;
    /** Space between rows when it differs from `gap` (a definition list: wide columns, tight rows). */
    rowGap?: LayoutGap;
    /** Block-axis placement of every cell. */
    align?: 'start' | 'center' | 'end' | 'stretch';
    minimum?: GridMinimum;
    /**
     * Explicit column tracks. When set, this is the grid template (via `style`, not a Tailwind
     * class) and `minimum` is ignored. Use `minimum` for intrinsic auto-fit cards; use `tracks`
     * when the columns are a known, uneven measure — a log table, a definition list.
     */
    tracks?: string;
    children: Snippet;
}

The props of Grid.

Members

NameTypeDescription
as?LayoutElement
gap?LayoutGap
rowGap?LayoutGap

Space between rows when it differs from gap (a definition list: wide columns, tight rows).

align?'start' | 'center' | 'end' | 'stretch'

Block-axis placement of every cell.

minimum?GridMinimum
tracks?string

Explicit column tracks. When set, this is the grid template (via style, not a Tailwind class) and minimum is ignored. Use minimum for intrinsic auto-fit cards; use tracks when the columns are a known, uneven measure — a log table, a definition list.

childrenSnippet
ref?HTMLElement | null

The rendered element, for measurement or focus.

Source: packages/ui/src/layout/grid.svelte:12

INSET_MX_CLASS const

const INSET_MX_CLASS: "mx-4 sm:mx-6"

Chrome that draws its own background and so cannot pad itself (tab list).

Source: packages/ui/src/layout/layout.shared.ts:134

INSET_X_CLASS const

const INSET_X_CLASS: "px-4 sm:px-6"

Full-bleed chrome with its own vertical rhythm (PageHeader).

Source: packages/ui/src/layout/layout.shared.ts:132

Imposter component

component Imposter(props: ImposterProps)

A layer positioned over its relative parent: a scrim, a pinned badge, a bar or a centred dialog body, at a stacking layer.

Props

NameTypeDescription
as?LayoutElement
placement?ImposterPlacement

Where the layer sits over its positioned (relative) parent. fill covers it (a scrim, a camera guide); top/bottom are full-width bars, start/end full-height strips; the corners pin a badge or control; center-start/center-end centre it on an edge.

offset?ImposterOffset

Distance from the edges it is pinned to: sm (0.5rem) for a corner or an edge-centred control, none for a bar, a strip or fill, which run to the edge by default.

layer?ImposterLayer

The stacking layer. under sits beneath later siblings (a decorative backdrop), raised above them, overlay above page chrome (a drag preview, a table-of-contents panel), modal above everything (a full-screen takeover).

position?'absolute' | 'fixed' | 'sticky'

absolute pins to the parent; fixed to the viewport; sticky stays in flow and sticks to its scrollport's edge — a table header, a rail.

contain?boolean

Keep the layer inside the parent: never larger than it, scrolling if it must.

children?Snippet

Absent for a purely decorative layer (a track line, a hit area).

ref?HTMLElement | null

The rendered element, for measurement or focus.

Source: packages/ui/src/layout/imposter.svelte:1

ImposterPlacement type

type ImposterPlacement = 'center' | 'fill' | 'top' | 'bottom' | 'start' | 'end' | 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' | 'center-start' | 'center-end';

Where an Imposter sits over its parent: centred, filling it, along an edge or in a corner.

Source: packages/ui/src/layout/imposter.svelte:10

ImposterProps interface

interface ImposterProps extends LayoutAttributes {
    as?: LayoutElement;
    /**
     * Where the layer sits over its positioned (`relative`) parent. `fill` covers it (a scrim, a
     * camera guide); `top`/`bottom` are full-width bars, `start`/`end` full-height strips; the
     * corners pin a badge or control; `center-start`/`center-end` centre it on an edge.
     */
    placement?: ImposterPlacement;
    /**
     * Distance from the edges it is pinned to: `sm` (0.5rem) for a corner or an edge-centred
     * control, `none` for a bar, a strip or `fill`, which run to the edge by default.
     */
    offset?: ImposterOffset;
    /**
     * The stacking layer. `under` sits beneath later siblings (a decorative backdrop), `raised`
     * above them, `overlay` above page chrome (a drag preview, a table-of-contents panel),
     * `modal` above everything (a full-screen takeover).
     */
    layer?: ImposterLayer;
    /**
     * `absolute` pins to the parent; `fixed` to the viewport; `sticky` stays in flow and sticks to
     * its scrollport's edge — a table header, a rail.
     */
    position?: 'absolute' | 'fixed' | 'sticky';
    /** Keep the layer inside the parent: never larger than it, scrolling if it must. */
    contain?: boolean;
    /** Absent for a purely decorative layer (a track line, a hit area). */
    children?: Snippet;
}

The props of Imposter.

Members

NameTypeDescription
as?LayoutElement
placement?ImposterPlacement

Where the layer sits over its positioned (relative) parent. fill covers it (a scrim, a camera guide); top/bottom are full-width bars, start/end full-height strips; the corners pin a badge or control; center-start/center-end centre it on an edge.

offset?ImposterOffset

Distance from the edges it is pinned to: sm (0.5rem) for a corner or an edge-centred control, none for a bar, a strip or fill, which run to the edge by default.

layer?ImposterLayer

The stacking layer. under sits beneath later siblings (a decorative backdrop), raised above them, overlay above page chrome (a drag preview, a table-of-contents panel), modal above everything (a full-screen takeover).

position?'absolute' | 'fixed' | 'sticky'

absolute pins to the parent; fixed to the viewport; sticky stays in flow and sticks to its scrollport's edge — a table header, a rail.

contain?boolean

Keep the layer inside the parent: never larger than it, scrolling if it must.

children?Snippet

Absent for a purely decorative layer (a track line, a hit area).

ref?HTMLElement | null

The rendered element, for measurement or focus.

Source: packages/ui/src/layout/imposter.svelte:26

Inline component

component Inline(props: InlineProps)

A single non-wrapping row of children with a gap and alignment: a toolbar, a label and its value.

Props

NameTypeDescription
as?LayoutElement
gap?LayoutGap
align?'start' | 'center' | 'end' | 'baseline' | 'stretch'
justify?'start' | 'center' | 'end' | 'between'
grow?boolean

Take the remaining space along the parent's main axis.

fill?boolean

Fill the parent's height.

shrink?boolean

Allow this region to shrink when its parent is constrained.

divided?boolean

A hairline between children — a segmented strip. Pair with gap="none".

childrenSnippet
ref?HTMLElement | null

The rendered element, for measurement or focus.

Source: packages/ui/src/layout/inline.svelte:1

InlineProps interface

interface InlineProps extends LayoutAttributes {
    as?: LayoutElement;
    gap?: LayoutGap;
    align?: 'start' | 'center' | 'end' | 'baseline' | 'stretch';
    justify?: 'start' | 'center' | 'end' | 'between';
    /** Take the remaining space along the parent's main axis. */
    grow?: boolean;
    /** Fill the parent's height. */
    fill?: boolean;
    /** Allow this region to shrink when its parent is constrained. */
    shrink?: boolean;
    /** A hairline between children — a segmented strip. Pair with `gap="none"`. */
    divided?: boolean;
    children: Snippet;
}

The props of Inline.

Members

NameTypeDescription
as?LayoutElement
gap?LayoutGap
align?'start' | 'center' | 'end' | 'baseline' | 'stretch'
justify?'start' | 'center' | 'end' | 'between'
grow?boolean

Take the remaining space along the parent's main axis.

fill?boolean

Fill the parent's height.

shrink?boolean

Allow this region to shrink when its parent is constrained.

divided?boolean

A hairline between children — a segmented strip. Pair with gap="none".

childrenSnippet
ref?HTMLElement | null

The rendered element, for measurement or focus.

Source: packages/ui/src/layout/inline.svelte:10

LayoutGap type

type LayoutGap = 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';

The spacing scale layout primitives take for gap.

Source: packages/ui/src/layout/layout.shared.ts:51

LayoutPad type

type LayoutPad = Exclude<LayoutGap, 'xl'>;

The spacing scale for pad: LayoutGap without xl.

Source: packages/ui/src/layout/layout.shared.ts:53

SCROLL_AXIS_CLASSES const

const SCROLL_AXIS_CLASSES: Record<ScrollAxis, string>

The scrollport classes, per axis — the one definition of what "this region scrolls" means.

Per-axis overscroll-contain: an x-only reel must not trap the parent's vertical scroll, and the axis that does not scroll is clipped rather than left visible, so a wide child cannot paint outside the region.

Scroll is how a region declares itself a scrollport, and is what almost every caller wants. This token exists for the boxes Scroll cannot be: it fills its parent unconditionally, so a pane bounded by its own max-height (a popover, a collapsible) or by a fixed height (a chip reel) cannot be one — and neither can an element a third-party component or a ProseMirror editor owns. Those honour the same contract by naming it, the way INSET_MX_CLASS lets chrome that cannot pad itself still keep the app inset.

Source: packages/ui/src/layout/layout.shared.ts:99

Scroll component

component Scroll(props: ScrollProps)

The one scroll owner of a region: scrolls on axis, fades edges with content beyond them, and optionally snaps children. name identifies it (a page restores its position).

Props

NameTypeDescription
as?LayoutElement
axis?ScrollAxis
namestring
inset?boolean
fade?boolean

Fade the edges that have content beyond them. On by default: it is what tells a reader there is more below now that the scroll bar hides at rest. Turn it off for a region whose own content must stay at full opacity to its edge — a media surface, a chart, anything where a soft edge would read as a rendering fault.

layout?ScrollLayout

Arrange direct children without introducing a second wrapper or scroll owner.

gap?LayoutGap
align?'start' | 'center' | 'end' | 'baseline' | 'stretch'
justify?'start' | 'center' | 'end' | 'between'
grow?boolean

Take the remaining space along the parent's main axis.

shrink?boolean

Allow this region to shrink when its parent is constrained.

snap?boolean

Snap children to the start edge along the scroll axis — a reel of lanes or cards.

max?'compact' | 'standard' | 'tall'

Grow with the content up to a named cap instead of filling the parent — a popover list, a disclosure body. Same scale as Bound size.

ref?HTMLElement | null

The rendered element, for measurement or focus.

childrenSnippet

Source: packages/ui/src/layout/scroll.svelte:1

ScrollProps interface

interface ScrollProps extends LayoutAttributes {
    as?: LayoutElement;
    axis?: ScrollAxis;
    name: string;
    inset?: boolean;
    /**
     * Fade the edges that have content beyond them. On by default: it is what tells a
     * reader there is more below now that the scroll bar hides at rest. Turn it off for a
     * region whose own content must stay at full opacity to its edge — a media surface, a
     * chart, anything where a soft edge would read as a rendering fault.
     */
    fade?: boolean;
    /** Arrange direct children without introducing a second wrapper or scroll owner. */
    layout?: ScrollLayout;
    gap?: LayoutGap;
    align?: 'start' | 'center' | 'end' | 'baseline' | 'stretch';
    justify?: 'start' | 'center' | 'end' | 'between';
    /** Take the remaining space along the parent's main axis. */
    grow?: boolean;
    /** Allow this region to shrink when its parent is constrained. */
    shrink?: boolean;
    /** Snap children to the start edge along the scroll axis — a reel of lanes or cards. */
    snap?: boolean;
    /**
     * Grow with the content up to a named cap instead of filling the parent — a popover list, a
     * disclosure body. Same scale as `Bound size`.
     */
    max?: 'compact' | 'standard' | 'tall';
    ref?: HTMLElement | null;
    children: Snippet;
}

The props of Scroll.

Members

NameTypeDescription
as?LayoutElement
axis?ScrollAxis
namestring
inset?boolean
fade?boolean

Fade the edges that have content beyond them. On by default: it is what tells a reader there is more below now that the scroll bar hides at rest. Turn it off for a region whose own content must stay at full opacity to its edge — a media surface, a chart, anything where a soft edge would read as a rendering fault.

layout?ScrollLayout

Arrange direct children without introducing a second wrapper or scroll owner.

gap?LayoutGap
align?'start' | 'center' | 'end' | 'baseline' | 'stretch'
justify?'start' | 'center' | 'end' | 'between'
grow?boolean

Take the remaining space along the parent's main axis.

shrink?boolean

Allow this region to shrink when its parent is constrained.

snap?boolean

Snap children to the start edge along the scroll axis — a reel of lanes or cards.

max?'compact' | 'standard' | 'tall'

Grow with the content up to a named cap instead of filling the parent — a popover list, a disclosure body. Same scale as Bound size.

ref?HTMLElement | null

The rendered element, for measurement or focus.

childrenSnippet

Source: packages/ui/src/layout/scroll.svelte:11

Split component

component Split(props: SplitProps)

Two panes side by side at a ratio (rail, sidebar, third, half, wide) that stack, or switch with a tab pair, below a width.

Props

NameTypeDescription
as?LayoutElement
ratio?SplitRatio
collapse?SplitCollapse
collapseAt?'compact' | 'narrow'
gap?LayoutGap
fill?boolean

Fill a definite-height parent so both panes can hand that height to their contents.

startSnippet
endSnippet
switchLabels?readonly [string, string]
ref?HTMLElement | null

The rendered element, for measurement or focus.

Source: packages/ui/src/layout/split.svelte:1

SplitCollapse type

type SplitCollapse = 'stack' | 'switch' | 'none';

What a Split does when narrow: stack the panes, switch between them, or none.

Source: packages/ui/src/layout/split.svelte:12

SplitProps interface

interface SplitProps extends LayoutAttributes {
    as?: LayoutElement;
    ratio?: SplitRatio;
    collapse?: SplitCollapse;
    collapseAt?: 'compact' | 'narrow';
    gap?: LayoutGap;
    /** Fill a definite-height parent so both panes can hand that height to their contents. */
    fill?: boolean;
    start: Snippet;
    end: Snippet;
    switchLabels?: readonly [string, string];
}

The props of Split.

Members

NameTypeDescription
as?LayoutElement
ratio?SplitRatio
collapse?SplitCollapse
collapseAt?'compact' | 'narrow'
gap?LayoutGap
fill?boolean

Fill a definite-height parent so both panes can hand that height to their contents.

startSnippet
endSnippet
switchLabels?readonly [string, string]
ref?HTMLElement | null

The rendered element, for measurement or focus.

Source: packages/ui/src/layout/split.svelte:14

SplitRatio type

type SplitRatio = 'rail' | 'sidebar' | 'third' | 'half' | 'wide';

How a Split divides its width between start and end.

Source: packages/ui/src/layout/split.svelte:10

Stack component

component Stack(props: StackProps)

A vertical flow of children with a gap: the default layout of a page body, a form or a card.

Props

NameTypeDescription
as?LayoutElement
gap?LayoutGap
align?'start' | 'center' | 'end' | 'stretch'

Cross-axis (horizontal) placement of the children.

justify?'start' | 'center' | 'end' | 'between'

Main-axis (vertical) placement of the children.

grow?boolean

Take the remaining space along the parent's main axis.

fill?boolean

Fill the parent's height, so justify has room to distribute.

shrink?boolean

Allow this region to shrink when its parent is constrained.

divided?boolean

A hairline between children — a list of rows. Pair with gap="none".

reverse?boolean

Last child on top: a log read newest-first without reversing the data.

childrenSnippet
ref?HTMLElement | null

The rendered element, for measurement or focus.

Example

<Stack gap="md">
<h2>{title}</h2>
<Table of="jobs" />
</Stack>

Source: packages/ui/src/layout/stack.svelte:1

StackProps interface

interface StackProps extends LayoutAttributes {
    as?: LayoutElement;
    gap?: LayoutGap;
    /** Cross-axis (horizontal) placement of the children. */
    align?: 'start' | 'center' | 'end' | 'stretch';
    /**
     * Main-axis (vertical) placement of the children.
     *
     * Only meaningful when the Stack has more height than its content — inside a `Cover` body, a
     * `Bound size="full"`, or anything else that hands it a definite height. A Stack whose height
     * comes from its own content has nothing to distribute, which is why placing content against
     * a `min-h-*` parent silently does nothing and the content stays at the top. Pair with `fill`.
     */
    justify?: 'start' | 'center' | 'end' | 'between';
    /** Take the remaining space along the parent's main axis. */
    grow?: boolean;
    /** Fill the parent's height, so `justify` has room to distribute. */
    fill?: boolean;
    /** Allow this region to shrink when its parent is constrained. */
    shrink?: boolean;
    /** A hairline between children — a list of rows. Pair with `gap="none"`. */
    divided?: boolean;
    /** Last child on top: a log read newest-first without reversing the data. */
    reverse?: boolean;
    children: Snippet;
}

The props of Stack.

Members

NameTypeDescription
as?LayoutElement
gap?LayoutGap
align?'start' | 'center' | 'end' | 'stretch'

Cross-axis (horizontal) placement of the children.

justify?'start' | 'center' | 'end' | 'between'

Main-axis (vertical) placement of the children.

grow?boolean

Take the remaining space along the parent's main axis.

fill?boolean

Fill the parent's height, so justify has room to distribute.

shrink?boolean

Allow this region to shrink when its parent is constrained.

divided?boolean

A hairline between children — a list of rows. Pair with gap="none".

reverse?boolean

Last child on top: a log read newest-first without reversing the data.

childrenSnippet
ref?HTMLElement | null

The rendered element, for measurement or focus.

Source: packages/ui/src/layout/stack.svelte:15

getAppIdentitySlot function

function getAppIdentitySlot(): AppIdentitySlot | null

null when no shell is above this component — an app mounted standalone in a test or a story. Callers fall back to static metadata in that case rather than dropping identity on the floor.

Source: packages/ui/src/layout/app-identity.svelte.ts:36

insetReader function

function insetReader(): () => boolean

Whether an ancestor already pads this subtree's edge. Call at init; the reader is reactive.

Source: packages/ui/src/layout/inset.svelte.ts:23

ownInset function

function ownInset(): boolean

A scrollport with inset: pads unless an owner above already does; takes over a provisional one.

Source: packages/ui/src/layout/inset.svelte.ts:29

provisionalInset function

function provisionalInset(): { readonly padded: boolean; }

A non-scrolling panel: pads until a scrollport inside claims the inset.

Source: packages/ui/src/layout/inset.svelte.ts:38

resetInset function

function resetInset(owned: boolean): void

An overlay's content: a new page edge, owned by owned (a padded sheet) or by nobody yet.

Parameters

NameTypeDescription
ownedboolean

Source: packages/ui/src/layout/inset.svelte.ts:59

setAppIdentitySlot function

function setAppIdentitySlot(slot: AppIdentitySlot): AppIdentitySlot

Opens the slot for everything rendered beneath the shell.

Parameters

NameTypeDescription
slotAppIdentitySlot
  • current: AppIdentity | null

Source: packages/ui/src/layout/app-identity.svelte.ts:29