Layout
IAppShell
The page frame: header, sidebar, main and footer. Every slot takes whatever you put in it — navigation, account menu and routing stay yours, and ISidebar works with or without the shell.
Row 1
Row 2
Row 3
Row 4
Row 5
Row 6
Row 7
Row 8
Row 9
Row 10
Row 11
Row 12
Each of header, sidebar and footer is rendered only when you fill it, so a shell with just a header is a header and a content column, with no empty rails left behind.
Two scroll models
scroll picks between two layouts.
main, the default, pins the shell to the viewport and scrolls only the content column. The header and sidebar never move — what a data app wants.
page scrolls the document, with a sticky header and a sticky sidebar. Anchor links and the browser's scroll restoration work in this mode, so content and marketing pages want it. Being sticky rather than fixed, the sidebar travels up with the end of the body and the footer pushes it off screen.
Row 1
Row 2
Row 3
Row 4
Row 5
Row 6
Row 7
Row 8
Row 9
Row 10
Row 11
Row 12
The shell itself is the scroll container here, and the header sticks within it.
page mode sizes its sidebar against 100svh, so the boxed demo above overrides three values to keep the rail inside its frame:
<IAppShell
scroll="page"
:ui="{
root: 'h-72 min-h-0 overflow-y-auto',
body: 'flex-none',
sidebar: 'h-[calc(18rem-var(--iryx-shell-header-height,0px))] max-h-none',
}"
>A full-page shell needs none of that.
In page mode the shell measures its own header and publishes the height as --iryx-shell-header-height. Use that variable to offset anything you stick below the header yourself.
Sidebar on the right
Row 1
Row 2
Row 3
Row 4
Row 5
Row 6
sidebarPosition moves the column; ISidebar's own side decides which edge carries its border. Set both.
Where the footer sits
Without a sidebar the shell is a header, a content column and the footer.
Row 1
Row 2
Row 3
Row 4
Row 5
Row 6
Row 7
Row 8
In main mode the footer is pinned below the scrolling column, so it stays visible however long the page is. In page mode it sits at the end of the document, where a footer normally lives.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
as | string | 'div' | Element or component to render as |
scroll | 'main' | 'page' | 'main' | Scroll the content column, or the document |
sidebarPosition | 'left' | 'right' | 'left' | Which side the sidebar rail sits on |
unstyled | boolean | — | Drop built-in classes |
class | string | — | Merged with the built-in classes |
ui | { root?, header?, body?, sidebar?, main?, footer? } | — | Per-slot class overrides |
Slots
| Slot | When to use it |
|---|---|
| default | The page itself, inside <main> |
header | App bar. Measured in page mode to position the sticky sidebar |
sidebar | The navigation rail — usually ISidebar |
footer | Pinned below the content in main mode, at the end of the document in page mode |
Pair it with IContainer for the content width and IPageHeader for the title row.