App shell

Shell Menus

Menus opened from the sidebar bottom bar: workspace switcher, help / what’s new, and Library · Trash.

Usage

  • Use these ready-made menus in the sidebar bottom bar: workspace switching, help, and the apps / trash launcher.
  • Pass your data (workspaces, releases, trash entries) and handlers; the menus own their layout and keyboard behaviour.
  • Don’t rebuild them from Menu parts unless you need different items; keep one menu per trigger.

Installation

Install the package (React 19):

terminal
npm install @krackedui/motion

Import the styles once, in your app entry or root layout:

/src/main.tsx
import '@krackedui/motion/styles.css';

Use it anywhere inside your app's <Theme> (see Installation):

/src/ShellMenusExample.tsx
import { Sidebar, WorkspaceMenu, HelpMenu, AppsMenu } from '@krackedui/motion';

export function ShellMenusExample() {
  return (
    <Sidebar.BottomBar>
      <WorkspaceMenu email="ada@example.com" workspaces={[{ id: 'w1', name: 'Design Team' }, { id: 'w2', name: 'Personal' }]} currentId="w1">
        <Sidebar.WorkspaceSwitcher name="Design Team" />
      </WorkspaceMenu>
      <HelpMenu releases={[{ id: 'r1', title: 'Release 3.8', isNew: true }, { id: 'r2', title: 'Release 3.7' }]}>
        <Sidebar.BarButton icon="questionMarkCircle" label="Help, contact, more…" />
      </HelpMenu>
      <AppsMenu trash={[{ id: 't1', title: 'Old meeting notes', path: 'Team wiki' }, { id: 't2', title: 'Draft spec', path: 'Private' }]}>
        <Sidebar.BarButton icon="circleGrid2X2" label="Library, Trash, more…" />
      </AppsMenu>
    </Sidebar.BottomBar>
  );
}

Examples

Trash list

Pages in Trash for over 30 days will be automatically deleted

Composition

anatomy
<WorkspaceMenu email workspaces currentId>   // Menu.Root, opens upward, 300 wide
  trigger = children (Sidebar.WorkspaceSwitcher)
  header (email · …) · workspace rows (checked) · New workspace · Settings · Invite members · Upgrade
  · Add account · Log out

<HelpMenu releases more>                      // 260 wide
  Documentation · Get support · More › · "What’s new?" · release rows (blue dot + New) · View all releases

<AppsMenu trash>                              // 240 wide
  Library · Templates · Import · Trash › <TrashMenu items/>

<TrashMenu items>                             // 414 wide, also usable inside your own popover
  search · rows (restore / delete) · 30-day footer

API Reference

WorkspaceMenu

PropTypeDefault
children
ReactElement
email
string
workspaces
Workspace[]
currentId
string
onSelect
(id: string) => void
onNewWorkspace
() => void
onSettings
() => void
onInvite
() => void
onUpgrade
() => void
onAddAccount
() => void
onLogOut
() => void
open
boolean
onOpenChange
(open: boolean) => void

HelpMenu

PropTypeDefault
children
ReactElement
releases
ReleaseNote[]
[]
onDocs
() => void
onSupport
() => void
onRelease
(id: string) => void
onAllReleases
() => void
more
ReactNode
Keyboard shortcuts, Send feedback

AppsMenu

PropTypeDefault
children
ReactElement
trash
TrashEntry[]
[]
onLibrary
() => void
onTemplates
() => void
onImport
() => void
onRestore
(id: string) => void
onDelete
(id: string) => void

TrashMenu

PropTypeDefault
items
TrashEntry[]
onOpen
(id: string) => void
onRestore
(id: string) => void
onDelete
(id: string) => void
className
string

Accessibility

  • Built on the Menu component (Radix DropdownMenu): Enter/Space/ArrowDown open from the trigger, arrows move, ArrowRight opens submenus (More, Trash), Escape closes and returns focus.
  • Trash is a labelled list; each row has an open button plus "Restore <page>" and "Delete <page> from Trash" buttons.
  • Workspaces are a labelled radio group (menuitemradio): the current workspace is announced as checked; choosing one calls onSelect.
© 2026 Motion. Internal documentation.