> For AI agents: the complete documentation index is available at https://wallarm.github.io/design-system/llms.txt, the full documentation bundle is available at https://wallarm.github.io/design-system/llms-full.txt.

# AppShell

The platform’s outermost frame — global top bar, product rail, and the content surface products mount into, with an optional `AppShellAside` panel docked to its right. There is exactly one, at the app root, and it persists while the content swaps. Do not wrap a page in it: a single product screen renders `RemoteShell` and its own content, blind to the shell. In-product navigation is `NavPanel`, and laying out a page’s insides is `Stack` and `Flex`. The gray surround — header bar plus rail, everything that is not the canvas — is the **Frame**. It carries **Ambient**, a faint still layer of soft blooms, grain and a dot cluster pooled bottom-left, painted under everything. Ambient is on by default; `ambient={false}` leaves the flat Frame fill. The Frame comes in two styles, **Neutral** and **Branded**: a user preference next to light/dark, set with `useTheme().setFrameStyle` (from `ThemeProvider`) and written on `<html>` so every micro-frontend follows it. Branded warms the Frame and turns active navigation to the brand colour; try it from the account item → Appearance.

[Source](https://github.com/wallarm/design-system/tree/main/packages/design-system/src/components/AppShell) · [Storybook](https://wallarm.github.io/design-system/storybook/?path=/docs/navigation-appshell--overview)

```tsx
import { StoryRouter } from './story-content';

export const Basic = ({ ambient }) => (
  <StoryRouter>
    <Shell ambient={ambient} />
  </StoryRouter>
);
```

## Usage

```tsx
import { AppShell } from '@wallarm-org/design-system/AppShell';
```

## Examples

### Loading

How the shell looks while the platform loads. The header actions and the product rail hold skeletons that sit exactly where the real items land, so nothing jumps when they arrive. Turn `loading` off in Controls to watch the swap. Opening a product also shows its own panel and content loading.

```tsx
import { StoryRouter } from './story-content';

export const Loading = ({ ambient, loading }) => (
  <StoryRouter>
    <Shell ambient={ambient} loading={loading} simulateProductLoading />
  </StoryRouter>
);
```

### With aside

`AppShellAside` docks a panel right of the content surface — the real `WallyAssistant` here, driven by the `useMockWally` streaming mock and toggled from the header's `ChatTrigger` — that slides in as the canvas narrows, while closing widens the canvas back and hides the region without unmounting what is inside, so the conversation and text typed into the panel survive a close and reopen.

```tsx
import { StoryRouter } from './story-content';

export const WithAside = ({ ambient }) => (
  <StoryRouter>
    <Shell ambient={ambient} aside />
  </StoryRouter>
);
```

### Reveal flow

`reveal` animates the chrome in on the first application load only. Leave it unset for an ordinary screen; this exists for prototyping the boot moment itself.

```tsx
import { StoryRouter } from './story-content';

export const RevealFlow = () => (
  <StoryRouter>
    <RevealFlowShell />
  </StoryRouter>
);
```

### Login flow

The whole entrance: the splash hands off, the content surface expands from the sign-in card into the full shell. `onRevealed` fires when it has settled.

```tsx
import { StoryRouter } from './story-content';

export const LoginFlow = () => (
  <StoryRouter>
    <LoginFlowShell />
  </StoryRouter>
);
```

### With tan stack router

`AppShell` and a `RemoteShell` per product on one TanStack Router: the root route is
the shell (rail → `navigate`, `AppShellRemote` → `<Outlet />`), `/$product` is the
remote (`RemoteShell` with `pathname` + `onNavigate`, content → `<Outlet />`), and
`/$product/$` is the page. Every way of moving — the rail, the nav panel, the
breadcrumbs, links in the page — goes through the router, and the active items follow.

```tsx
import { useState } from 'react';
import { RouterProvider } from '@tanstack/react-router';

export const WithTanStackRouter = () => {
  const [router] = useState(createShellRouter);

  return <RouterProvider router={router} />;
};
```

## Props

| Prop           | Type                                                 | Default | Description                                                                                                                                           |
| -------------- | ---------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| reveal         | `boolean \| undefined`                               |         |                                                                                                                                                       |
| expandFrom     | `AppShellExpandFrom \| undefined`                    |         |                                                                                                                                                       |
| onRevealed     | `(() => void) \| undefined`                          |         |                                                                                                                                                       |
| appeared       | `boolean \| undefined`                               |         |                                                                                                                                                       |
| ambient        | `boolean \| undefined`                               | `true`  | The Frame's ambient layer — soft blooms, grain and a dot cluster behind the header and rail. On by default; `false` leaves the flat Frame token fill. |
| defaultChecked | `boolean \| undefined`                               |         |                                                                                                                                                       |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |                                                                                                                                                       |
| autoFocus      | `boolean \| undefined`                               |         |                                                                                                                                                       |
| id             | `string \| undefined`                                |         |                                                                                                                                                       |
| tabIndex       | `number \| undefined`                                |         |                                                                                                                                                       |
| title          | `string \| undefined`                                |         |                                                                                                                                                       |
| rel            | `string \| undefined`                                |         |                                                                                                                                                       |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |                                                                                                                                                       |
| data-testid    | `string \| undefined`                                |         |                                                                                                                                                       |

### AppShellAside

| Prop           | Type                                                 | Default | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| -------------- | ---------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| open \*        | `boolean`                                            |         | Shows the panel, sliding it in from the right as the canvas narrows. Closing makes it `hidden` and `inert` at once while the column slides shut, after which it takes no space. The panel stays painted through that slide only where `display` can transition (`transition-behavior: allow-discrete`: Chromium, WebKit); in Firefox it hides at once while the column still closes smoothly. Under reduced motion both directions are instant. Its children stay mounted throughout, so whatever state they hold survives a close and reopen. |
| defaultChecked | `boolean \| undefined`                               |         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| autoFocus      | `boolean \| undefined`                               |         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| id             | `string \| undefined`                                |         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| tabIndex       | `number \| undefined`                                |         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| title          | `string \| undefined`                                |         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| rel            | `string \| undefined`                                |         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |

### AppShellHeader

| Prop           | Type                                                 | Default | Description |
| -------------- | ---------------------------------------------------- | ------- | ----------- |
| defaultChecked | `boolean \| undefined`                               |         |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |             |
| autoFocus      | `boolean \| undefined`                               |         |             |
| id             | `string \| undefined`                                |         |             |
| tabIndex       | `number \| undefined`                                |         |             |
| title          | `string \| undefined`                                |         |             |
| rel            | `string \| undefined`                                |         |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |             |

### AppShellRail

| Prop           | Type                                                 | Default | Description |
| -------------- | ---------------------------------------------------- | ------- | ----------- |
| defaultChecked | `boolean \| undefined`                               |         |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |             |
| autoFocus      | `boolean \| undefined`                               |         |             |
| id             | `string \| undefined`                                |         |             |
| tabIndex       | `number \| undefined`                                |         |             |
| title          | `string \| undefined`                                |         |             |
| rel            | `string \| undefined`                                |         |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |             |

### AppShellRemote

| Prop           | Type                                                 | Default | Description |
| -------------- | ---------------------------------------------------- | ------- | ----------- |
| defaultChecked | `boolean \| undefined`                               |         |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |             |
| autoFocus      | `boolean \| undefined`                               |         |             |
| id             | `string \| undefined`                                |         |             |
| tabIndex       | `number \| undefined`                                |         |             |
| title          | `string \| undefined`                                |         |             |
| rel            | `string \| undefined`                                |         |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |             |

## Explorer

