Skip to content
Entangle UI v0.13.0

AppShell

Top-level layout shell that provides the structural skeleton for editor applications. Uses a compound component pattern with named slots for menu bar, toolbars (top, left, right), a central dock area, and a status bar. Includes a context-based toolbar visibility system and configurable chrome separators.

Live Preview

import { AppShell } from 'entangle-ui';
<AppShell viewportLock>
<AppShell.MenuBar>{/* MenuBar component goes here */}</AppShell.MenuBar>
<AppShell.Toolbar position="top">{/* Top toolbar */}</AppShell.Toolbar>
<AppShell.Toolbar position="left">{/* Left side toolbar */}</AppShell.Toolbar>
<AppShell.Dock>{/* Main content / viewport */}</AppShell.Dock>
<AppShell.Toolbar position="right">
{/* Right side toolbar */}
</AppShell.Toolbar>
<AppShell.StatusBar>{/* Status bar */}</AppShell.StatusBar>
</AppShell>

AppShell uses a compound component pattern. Each slot renders an appropriate semantic HTML element:

| Slot | Element | Purpose | | -------------------- | -------------------- | -------------------------------- | | AppShell.MenuBar | <header> | Application menu bar area | | AppShell.Toolbar | <div> or <aside> | Toolbar slots (top, left, right) | | AppShell.Dock | <main> | Central content / viewport area | | AppShell.StatusBar | <footer> | Bottom status bar |

The AppShell.MenuBar slot paints the menu-bar chrome background (--etui-shell-menubar-bg) by default, and a MenuBar placed inside it stretches to fill the slot. Together they read as one continuous chrome strip instead of a lighter content-width block — no per-app styling required. The MenuBar triggers inset their hover/active fill from the strip edges so the chrome reads cleanly.

There is no separate “panel dock” slot. Dock panels — a PropertyPanel, inspector, outliner, etc. — into the side toolbar slots (AppShell.Toolbar position="left" / position="right"). They render <aside> landmarks, size to their content, and pick up the sideChromeSeparator. The central AppShell.Dock is the viewport/canvas area; for resizable docks compose SplitPane inside it.

<AppShell.Dock>{/* viewport / canvas */}</AppShell.Dock>
<AppShell.Toolbar position="right">
<PropertyPanel>{/* docked inspector */}</PropertyPanel>
</AppShell.Toolbar>

When viewportLock is enabled, the shell locks to the full viewport, preventing page scroll. This is the typical setup for editor applications.

<AppShell viewportLock>{/* Full-viewport editor layout */}</AppShell>

Control the visual separator between chrome areas (toolbars) and content. Separate options exist for the top chrome (menu + top toolbar) and side chrome (left/right toolbars).

<AppShell topChromeSeparator="shadow" sideChromeSeparator="none">
<AppShell.Toolbar position="top">{/* ... */}</AppShell.Toolbar>
<AppShell.Dock>{/* ... */}</AppShell.Dock>
</AppShell>

| Value | Effect | | -------- | -------------------------- | | none | No visual separator | | border | Thin border line (default) | | shadow | Drop shadow | | both | Border and shadow combined |

The AppShell.Toolbar slot accepts a position prop that determines where the toolbar is placed in the layout.

<AppShell>
<AppShell.Toolbar position="top">
{/* Horizontal toolbar below the menu bar */}
</AppShell.Toolbar>
<AppShell.Toolbar position="left">
{/* Vertical toolbar on the left */}
</AppShell.Toolbar>
<AppShell.Dock>{/* ... */}</AppShell.Dock>
<AppShell.Toolbar position="right">
{/* Vertical toolbar on the right */}
</AppShell.Toolbar>
</AppShell>

AppShell provides a context-based system for toggling toolbar visibility. Use the useAppShell hook to programmatically show or hide toolbars.

import { useAppShell } from 'entangle-ui';
function ToggleToolbarButton() {
const { isToolbarVisible, setToolbarVisible } = useAppShell();
return (
<button
onClick={() => setToolbarVisible('left', !isToolbarVisible('left'))}
>
Toggle Left Panel
</button>
);
}
Prop Type Default Description
viewportLock boolean false Lock the shell to the viewport, preventing page scroll. Injects global html/body styles.
topChromeSeparator 'none' | 'border' | 'shadow' | 'both' 'border' Visual separator under the top chrome area (menu + top toolbar).
sideChromeSeparator 'none' | 'border' | 'shadow' | 'both' 'border' Visual separator between side toolbars and dock content.
children ReactNode — Slot components (AppShell.MenuBar, AppShell.Toolbar, AppShell.Dock, AppShell.StatusBar).
className string — Additional CSS class names.
style CSSProperties — Inline styles.
testId string — Test identifier for automated testing.
ref Ref<HTMLDivElement> — Ref to the root element.
Prop Type Default Description
children ReactNode — Menu bar content.
className string — Additional CSS class names.
style CSSProperties — Inline styles.
testId string — Test identifier for automated testing.
ref Ref<HTMLElement> — Ref to the header element.
Prop Type Default Description
position 'top' | 'left' | 'right' 'top' Toolbar placement in the layout. Side positions render as <aside> elements.
children ReactNode — Toolbar content.
className string — Additional CSS class names.
style CSSProperties — Inline styles.
testId string — Test identifier for automated testing.
ref Ref<HTMLElement> — Ref to the toolbar element.
Prop Type Default Description
children ReactNode — Main content area.
className string — Additional CSS class names.
style CSSProperties — Inline styles.
testId string — Test identifier for automated testing.
ref Ref<HTMLElement> — Ref to the main element.
Prop Type Default Description
children ReactNode — Status bar content.
className string — Additional CSS class names.
style CSSProperties — Inline styles.
testId string — Test identifier for automated testing.
ref Ref<HTMLElement> — Ref to the footer element.

AppShell defines no component-level CSS custom properties of its own; it is re-skinned through the shared --etui-* theme tokens below.

| Token | Used for | | --------------------------------------------------------------------------------------------------- | ------------------------------- | | --etui-color-bg-primary | Shell background | | --etui-color-text-primary | Shell text color | | --etui-font-family-sans | Shell font family | | --etui-shell-menubar-bg | Menu-bar slot chrome background | | --etui-color-border-default | Chrome separator borders | | --etui-shadow-separator-bottom / --etui-shadow-separator-right / --etui-shadow-separator-left | Chrome separator shadows | | --etui-z-base | Toolbar slot stacking order |

  • The root element has role="application", signaling to assistive technologies that this is an interactive application region
  • AppShell.MenuBar renders a semantic <header> element
  • AppShell.Dock renders a semantic <main> element
  • AppShell.StatusBar renders a semantic <footer> element
  • Side toolbars render as <aside> elements for landmark navigation