Skip to content
ARC UI ARC Reactive Components
Docs Components Tokens Synthesizer
v2.1.0
Getting Started Frameworks Design Tokens Theming Theme Synthesizer Accessibility Browser Support Changelog Contributing All Components App ShellAspect GridAuth ShellCenterClusterContainerDashboard GridDockFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkSpeed DialStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCalloutCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageInfinite ScrollMarqueeScroll AreaSeparatorSkeletonSpinnerStackVirtual List Animated NumberBadgeComparisonCountdown TimerData TableDescription ListDiffKey ValueListMeterSparklineStatStepperTableTagTimelineValue Card BlockquoteCode BlockGradient TextHighlightKbdMarkdownNumber FormatProseTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerFieldsetFile UploadFormHotkeyIcon ButtonInputInput GroupLabelMulti SelectNumber InputOTP InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSliderSortable ListSwitch GroupTextareaTheme ToggleTime PickerToggle AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuDialogDropdown MenuGuided TourHover CardInline MessageLoading OverlayModalNotification PanelPopoverProgressProgress ToastSheetSnackbarSpotlightToastTooltip
Components App Shell
layout hybrid
<arc-app-shell>

Overview

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

  • Nest one AppShell inside another — it is designed as a singleton page frame
  • Put scrollable content directly in the sidebar slot without its own overflow handling
  • Rely on the toc slot for critical navigation — it hides on narrower viewports
  • Override min-height: 100vh on the host unless you are embedding a preview or iframe
  • 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: `
    <AppShell>
      <TopBar slot="topbar" heading="Dashboard"></TopBar>
      <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>
    </AppShell>
  `,
})
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">
          App Shell
        </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">
          App Shell
        </div>
        <div class="shell__toc" style="flex-shrink: 0; width: 220px">
          <!-- optional table-of-contents -->
        </div>
      </div>
    </div>
  </div>
</div>

API

Prop Type Default Description
sidebar-open 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.
breakpoint number 768 Viewport width in pixels at which the layout switches between mobile and desktop modes.

See Also