Application shell

Sidebar, topbar, and hybrid application frames that reflow one AppNavigation tree through an accessible narrow drawer.

Source
app/components/nitro_kit/app_shell.rb
API
NitroKit::AppShell.new(id:, layout: :sidebar, skip_link_label:, open_navigation_label:, close_navigation_label:, navigation_dialog_label:) { |shell| shell.navigation { ... }; shell.main { ... } }

Layout variants

All three layouts reflow the same AppNavigation tree while the application supplies brand, actions, routes, and main content.

Sidebar workspace

A sticky product sidebar surrounds a compact operational dashboard.

ViewportFull width
Rubytest/dummy/app/components/gallery/blocks/app_shell_page.rb
render NitroKit::AppShell.new(
  id:,
  layout:,
  navigation_dialog_label: "Workspace navigation",
  data: {
    gallery_shell_preview: layout,
    gallery_shell_long: long ? "true" : nil
  }.compact
) do |shell|
  shell.brand do
    strong do
      long ? "International Analytical Engine Operations" : "Northstar"
    end
  end if brand

  shell.navigation do
    render_shell_navigation(id:, current:, dense:, long:)
  end

  shell.topbar do
    render NitroKit::ButtonGroup.new(label: "Workspace actions") do |group|
      group.button("Search", href: "#search", variant: :ghost, size: :sm, icon: :search)
      group.button("Account", href: "#account", variant: :ghost, size: :sm, icon: :circle_user_round)
    end
  end if actions

  shell.main { render_workspace_main(layout:, long:) }
end

Topbar workspace

Brand, navigation, and account actions share the desktop header before the same tree becomes a narrow drawer.

ViewportFull width
Rubytest/dummy/app/components/gallery/blocks/app_shell_page.rb
render_workspace_shell(id: "gallery-app-shell-topbar", layout: :topbar, current: :projects)

Hybrid operations

Persistent navigation and a sticky action row combine without a second navigation copy.

ViewportFull width
Rubytest/dummy/app/components/gallery/blocks/app_shell_page.rb
render_workspace_shell(id: "gallery-app-shell-hybrid", layout: :hybrid, current: :incidents, dense: true)

Optional chrome and pressure

Optional regions disappear cleanly while long destinations, nested content, and narrow disclosure keep the same contract.

Navigation and main only

Brand and topbar are optional; the required navigation and main regions still form a complete application frame.

ViewportFull width
Rubytest/dummy/app/components/gallery/blocks/app_shell_page.rb
render_workspace_shell(
  id: "gallery-app-shell-minimal",
  layout: :sidebar,
  current: :overview,
  brand: false,
  actions: false
)

Long workspace pressure

Long brand, route, and content copy shrink inside the owned columns without a layout option or utility class.

ViewportFull width
Rubytest/dummy/app/components/gallery/blocks/app_shell_page.rb
render_workspace_shell(
  id: "gallery-app-shell-long",
  layout: :hybrid,
  current: :capacity,
  long: true,
  dense: true
)