Getting StartedComponentsDesign TokensThemingTheme SynthesizerFrameworksAccessibilityUtilitiesServer RenderingBrowser SupportContributingChangelog App ShellAspect GridAuth ShellCenterContainerDashboard GridFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSkeletonSpinnerStackVideoVirtual List Activity HeatmapAnimated NumberBadgeChartClockComparisonCountdown TimerData GridDescription ListDiffGaugeJSON TreeKanbanLevel MeterListMeterSparklineStatStepperTagTimelineUptimeValue CardWaveform BlockquoteCode BlockGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree Select AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuHover CardLoading OverlayNotification PanelPopoverProgressSheetToastTooltip
ARC UI ARC Radiant Components
v4.2 Docs Components Tokens Synthesizer
Getting StartedFrameworksServer Rendering Design TokensThemingTheme SynthesizerTypographyUtilities All ComponentsAccessibilityBrowser SupportChangelogContributingStats App ShellAspect GridAuth ShellCenterContainerDashboard GridFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSkeletonSpinnerStackVideoVirtual List Activity HeatmapAnimated NumberBadgeChartClockComparisonCountdown TimerData GridDescription ListDiffGaugeJSON TreeKanbanLevel MeterListMeterSparklineStatStepperTagTimelineUptimeValue CardWaveform BlockquoteCode BlockGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree Select AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuHover CardLoading OverlayNotification PanelPopoverProgressSheetToastTooltip

App Shell

Full-page layout scaffold that composes a TopBar, Sidebar, and scrollable content area into a cohesive application frame. Handles responsive collapse, sidebar toggling, and optional table-of-contents rail out of the box.

Components App Shell
layout hybrid
<arc-app-shell>

Overview

AppShell is the outermost structural component for any ARC UI application. It establishes the canonical three-zone layout — a fixed top bar, a collapsible sidebar, and a flexible main content area — so that every page in your app shares a consistent chrome without duplicating layout logic. The component manages responsive behavior automatically. On screens narrower than 768 px the sidebar collapses out of view and can be toggled back with the `sidebar-open` attribute, making it suitable for both desktop dashboards and mobile-first admin panels. A fourth optional slot, `toc`, provides a right-hand rail for table-of-contents or contextual widgets; it hides below 1280 px to keep the content area readable. Because AppShell is slot-based, it composes freely with other ARC UI primitives. Drop an `arc-top-bar` into the `topbar` slot, an `arc-sidebar` (or any nav markup) into `sidebar`, and your page content into the default slot. The shell handles all the flex math, scroll containment, and z-index layering so you can focus on what goes inside each zone rather than how the zones relate to each other.

Guidelines

When to use

  • Use one AppShell as the root layout wrapper for each page or route
  • Place an arc-top-bar in the "topbar" slot for a consistent fixed header
  • Provide a sidebar toggle button in the top bar that sets sidebar-open on mobile
  • Use the "toc" slot for table-of-contents navigation on documentation pages
  • Combine with Container or Section components inside the default slot for consistent content widths

When not to use

  • Do not nest one AppShell inside another — it is designed as a singleton page frame
  • Do not put scrollable content directly in the sidebar slot without its own overflow handling
  • Do not rely on the toc slot for critical navigation — it hides on narrower viewports
  • Do not override min-height: 100vh on the host unless you are embedding a preview or iframe
  • Do not use AppShell for simple marketing pages that do not need a persistent sidebar or top bar

Features

  • Three-zone layout: fixed top bar, collapsible sidebar, scrollable main content
  • Optional fourth "toc" slot for a right-hand table-of-contents rail
  • Responsive sidebar collapse at 768 px with toggle via sidebar-open attribute
  • Table-of-contents rail auto-hides below 1280 px
  • Slot-based composition works with any TopBar, Sidebar, or custom markup
  • Full-viewport min-height ensures the shell always fills the screen
  • CSS custom property integration for consistent spacing and color tokens
  • Exposed CSS parts (shell, body, sidebar, main, content, toc) for deep style overrides

Preview

Welcome back

Here is what happened while you were away.

Revenue
$48.2k
Users
1,247
Uptime
99.9%

Usage

Layout and styling work without JavaScript via the HTML/CSS versions. Interactive features like events and state management require the Web Component or a framework wrapper.

<script type="module" src="@arclux/arc-ui"></script>

<arc-app-shell>
  <arc-top-bar slot="topbar" heading="Dashboard"></arc-top-bar>
  <nav slot="sidebar" style="width: 200px; padding: 16px;">
    <a href="/overview">Overview</a>
    <a href="/analytics">Analytics</a>
    <a href="/settings">Settings</a>
  </nav>
  <main>
    <h1>Welcome back</h1>
    <p>Here is what happened while you were away.</p>
  </main>
</arc-app-shell>
import { AppShell, TopBar } from '@arclux/arc-ui-react';

export function DashboardLayout({ children }: { children: React.ReactNode }) {
  return (
    <AppShell>
      <TopBar slot="topbar" heading="Dashboard" />
      <nav slot="sidebar" style={{ width: 200, padding: 16 }}>
        <a href="/overview">Overview</a>
        <a href="/analytics">Analytics</a>
        <a href="/settings">Settings</a>
      </nav>
      <main>{children}</main>
    </AppShell>
  );
}
<script setup>
import { AppShell, TopBar } from '@arclux/arc-ui-vue';
</script>

<template>
  <AppShell>
    <TopBar slot="topbar" heading="Dashboard" />
    <nav slot="sidebar" style="width: 200px; padding: 16px;">
      <a href="/overview">Overview</a>
      <a href="/analytics">Analytics</a>
      <a href="/settings">Settings</a>
    </nav>
    <main>
      <slot />
    </main>
  </AppShell>
</template>
<script>
  import { AppShell, TopBar } from '@arclux/arc-ui-svelte';
</script>

<AppShell>
  <TopBar slot="topbar" heading="Dashboard" />
  <nav slot="sidebar" style="width: 200px; padding: 16px;">
    <a href="/overview">Overview</a>
    <a href="/analytics">Analytics</a>
    <a href="/settings">Settings</a>
  </nav>
  <main>
    <slot />
  </main>
</AppShell>
import { Component } from '@angular/core';
import { AppShell, TopBar } from '@arclux/arc-ui-angular';

@Component({
  imports: [AppShell, TopBar],
  template: `
    <arc-app-shell>
      <arc-top-bar slot="topbar" heading="Dashboard"></arc-top-bar>
      <nav slot="sidebar" style="width: 200px; padding: 16px;">
        <a href="/overview">Overview</a>
        <a href="/analytics">Analytics</a>
        <a href="/settings">Settings</a>
      </nav>
      <main>
        <ng-content />
      </main>
    </arc-app-shell>
  `,
})
export class DashboardLayoutComponent {}
import { AppShell, TopBar } from '@arclux/arc-ui-solid';
import type { ParentProps } from 'solid-js';

export function DashboardLayout(props: ParentProps) {
  return (
    <AppShell>
      <TopBar slot="topbar" heading="Dashboard" />
      <nav slot="sidebar" style={{ width: '200px', padding: '16px' }}>
        <a href="/overview">Overview</a>
        <a href="/analytics">Analytics</a>
        <a href="/settings">Settings</a>
      </nav>
      <main>{props.children}</main>
    </AppShell>
  );
}
import { AppShell, TopBar } from '@arclux/arc-ui-preact';
import type { ComponentChildren } from 'preact';

export function DashboardLayout({ children }: { children: ComponentChildren }) {
  return (
    <AppShell>
      <TopBar slot="topbar" heading="Dashboard" />
      <nav slot="sidebar" style={{ width: 200, padding: 16 }}>
        <a href="/overview">Overview</a>
        <a href="/analytics">Analytics</a>
        <a href="/settings">Settings</a>
      </nav>
      <main>{children}</main>
    </AppShell>
  );
}
<!-- Auto-generated by @arclux/prism — do not edit manually -->
<!-- arc-app-shell — requires app-shell.css + base.css (or arc-ui.css) -->
<div class="arc-app-shell">
  <div class="shell">
    <div class="shell__body">
      <div class="shell__sidebar">
        <!-- sidebar nav goes here -->
      </div>
      <div class="shell__main">
        <div class="shell__content">
          AppShell
        </div>
        <div class="shell__toc">
          <!-- optional table-of-contents -->
        </div>
      </div>
    </div>
  </div>
</div>
<!-- Auto-generated by @arclux/prism — do not edit manually -->
<!-- arc-app-shell — self-contained, no external CSS needed -->
<style>
  @media (max-width: 1280px) {
    .arc-app-shell .shell__toc { display: none; }
  }
  @media (max-width: 768px) {
    .arc-app-shell .shell__sidebar { display: none; }
  }
  @media (max-width: 768px) {
    .arc-app-shell([sidebar-open]) .shell__sidebar { display: block; }
  }
</style>
<div class="arc-app-shell" style="display: block; min-height: 100vh; background: rgb(3, 3, 7); color: rgb(232, 232, 236)">
  <div class="shell" style="display: flex; flex-direction: column; min-height: 100vh">
    <div style="display: flex; flex: 1; padding-top: 64px">
      <div class="shell__sidebar" style="flex-shrink: 0">
        <!-- sidebar nav goes here -->
      </div>
      <div style="flex: 1; min-width: 0; display: flex">
        <div style="flex: 1; min-width: 0; padding: 40px 40px; max-width: 860px">
          AppShell
        </div>
        <div class="shell__toc" style="flex-shrink: 0; width: 220px">
          <!-- optional table-of-contents -->
        </div>
      </div>
    </div>
  </div>
</div>

API

breakpoint number
Viewport width in pixels at which the layout switches between mobile and desktop modes.
sidebarOpen boolean false
Controls whether the sidebar is visible on mobile viewports (below 768 px). On desktop the sidebar is always shown regardless of this attribute. Toggle it from a hamburger button in your TopBar to give mobile users access to navigation.
embedded boolean false
Fills the container instead of the viewport. The shell takes the height you give it (height: 100% of a bounded parent, or any length), its content area becomes the scroll context rather than the page, and the sidebar rail is stretched by the body rather than sized from the screen — a sticky rail has nothing to stick against once the page is not what scrolls. Use it for a shell inside a card, a dashboard cell, a split pane, or a documentation preview; leave it off for the full-page layout, which is what the component is for.

Events

arc-sidebar-toggle detail: { value: boolean }
Fired when the shell itself opens or closes the mobile sidebar — on a backdrop click, on Escape, on navigation, or when the viewport widens past the breakpoint and the drawer stops existing. Listened to by arc-top-bar so its hamburger stays in step, and by any wrapper binding sidebarOpen. Not fired for a toggle the shell merely received, so the two cannot echo each other.

See Also