affectUI › Screens › App screens

App Shell Inset

Collapsible sidebar with workspace, menu, projects and account – the frame every screen sits in.

Part of affectUI Pro. Install: npx shadcn@latest add https://www.affectui.com/r/app-shell.json · Import from @/components/ui/app-shell

When to use

  • The base of an AI assistant, internal tool or SaaS dashboard
  • Building your own screens on the same frame as the other affectUI screens

When not to use

  • Marketing pages – use a block or a plain layout
  • Apps with deep, multi-level navigation trees

Usage

import { AppShell } from "@/components/ui/app-shell";

export function Layout({ children }: { children: React.ReactNode }) {
  return (
    <AppShell active="New chat" workspace="Acme" user={{ name: "Alex Morgan" }} onNavigate={(label) => router.push(routes[label])}>
      <div className="ui-as-page">{children}</div>
    </AppShell>
  );
}

Props

NameTypeDefaultDescription
childrenReactNodeThe page shown next to the sidebar
activestringLabel of the menu item or project that is open
onNavigate(label: string) => voidCalled with the label of a menu item or project when it is clicked
workspacestring"Acme"Workspace name; its first letter becomes the logo
user{ name: string; avatar?: string }{ name: "Alex Morgan" }Account at the bottom; without an avatar it shows initials
navShellNavItem[]New chat, Folders, IntegrationsMenu items, each { label, icon }
projectsstring[]Project list under the menu
sidebarWidth{ default?: number; min?: number; max?: number }{ default: 272, min: 220, max: 380 }Sidebar width in px – drag its edge between min and max, double-click the edge for the default
header{ title: ReactNode; actions?: ReactNode } | falseA header across the whole app, like Claude's – sidebar toggle and search, the page's title (BarTitle) and actions, the work area's title; one line under it
panelReactNodeA work area on the right of the page (tools, a preview, files) – resizable and collapsible like the sidebar
panelTitlestring"Workspace"Heading of the work area on the right
panelWidth{ default?: number; min?: number; max?: number }{ default: 360, min: 280, max: 560 }Width of the work area in px, like sidebarWidth
layout"inset" | "flat""inset"Inset: the page as a rounded panel on the gray page. Flat: edge to edge next to the sidebar, split by a hairline. Without it, data-shell="flat" on an ancestor (e.g. <html>) makes every App Shell flat
classNamestringExtra class on the root

Accessibility

  • Sidebar items, projects and the collapse toggle are real buttons with labels
  • Icons are decorative and hidden from screen readers
  • The edges are separators you can focus: arrow keys resize (Shift for bigger steps), Home and End jump to the minimum and maximum

Responsive

  • Fills its container – give it the full viewport height in your app
  • Dark mode built in: switches when an ancestor (usually <html>) has the class dark or data-theme="dark"; colors are CSS variables on .ui-as
  • Inset or flat for a whole app at once: data-shell="flat" on <html> – every screen built on App Shell follows

Requirements

  • React 19
  • @hugeicons/react
  • @hugeicons/core-free-icons