Askr
UI & Components

Application Layout

Use application layout with the current published Askr packages.

  • @askrjs/themes0.0.13

How to use application layout

Application Layout should use the standard themed surface unless the application is deliberately implementing its own design system on top of @askrjs/ui.

  1. Import the themed component from @askrjs/themes/components; use @askrjs/ui directly only when building a custom visual system.
  2. Keep application layout labels, state, and application actions visible at the call site instead of styling internal DOM nodes.
  3. Verify keyboard behavior, focus movement or return, disabled state, and both standard themes.
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@askrjs/themes/components';

<Card>
  <CardHeader><CardTitle>Project health</CardTitle><CardDescription>Updated just now</CardDescription></CardHeader>
  <CardContent><ProjectHealth /></CardContent>
</Card>

Purpose

There's no single `ApplicationLayout` component in Askr — this page is guidance on composing the layout primitives `@askrjs/themes` does ship (`Block`, `Container`, `Header`, `Main`, `Grid`, `Shell`, `ShellNav`, `ShellMain`) into the shell most apps need: a header, a main content area, and consistent page-level spacing. Treat it as a pattern to follow, not an API to import wholesale.

Install and import

Pull the pieces you need from `@askrjs/themes/core` or the broader `@askrjs/themes/components` barrel: `Block` for general-purpose flex layout, `Container` for width-constrained content, `Header` and `Main` for semantic page regions, and `Shell`/`ShellNav`/`ShellMain` when you want a pre-composed app frame instead of assembling `Block`s by hand.

Live examples

A common shell is a `Shell` containing a `ShellNav` for top-level navigation and a `ShellMain` for routed content, each internally built from `Block` with `direction` and `gap` props rather than custom flexbox CSS. For simpler pages, `Header` plus `Main` plus a `Container` wrapping the main content to cap line length is often enough without reaching for `Shell` at all.

Anatomy

`Block` is the layout engine underneath nearly everything here — it takes `direction`, `align`, `justify`, `gap`, `padding`, and sizing props and renders as whatever native element you specify via `as`. `Header` and `Main` are semantic presets built on top of `Block` for their respective page landmarks; `Shell` composes `ShellNav` and `ShellMain` into the standard nav-plus-content frame.

State model

Nothing at this level tracks an open/closed or collapsed/expanded flag — these components exist to arrange, not to remember. What looks like state is really configuration: responsiveness flows through `Block`'s `ResponsiveValue<T>` props, which take either a single value or a per-breakpoint object keyed by `base`, `sm`, `md`, `lg`, and `xl`, rather than anything you'd track at runtime.

Keyboard and accessibility

Because `Header` and `Main` map to real landmark elements, screen reader users get correct page-region navigation for free as long as you don't override `as` to something non-semantic. Skip-link patterns and focus order are your responsibility to wire up at the app level — the layout primitives don't provide a built-in skip-to-content mechanism.

Styling and tokens

Every spacing, sizing, and breakpoint prop on `Block` resolves through the shared token system rather than raw pixel values, so a layout built from `Block` props stays consistent with the rest of the theme automatically. Follow the mobile-first responsive convention documented in the theme's contract: base styles target narrow screens, and `sm`/`md`/`lg`/`xl` values layer on as `min-width` overrides.

API

`Block` accepts `padding`, `paddingX`, `paddingY`, `margin`, `width`, `height`, `direction`, `align`, `justify`, `gap`, `grow`, `shrink`, `sticky`, `background`, `border`, `radius`, and `shadow`, most typed as `ResponsiveValue<T>` so they can vary per breakpoint. `rowFrom` (typed `BlockRowFrom`, one of `sm | md | lg | xl`) is specifically for switching a stacked mobile layout into a row at a given breakpoint — the standard tool for "stack on mobile, row on desktop" layouts.

Edge cases

Nesting many `Block`s with conflicting `width`/`height` values can produce layouts that don't collapse the way you expect on narrow screens — test at the documented widths (320, 390, 768, 1024, and desktop) rather than assuming a layout that looks right at one size holds at another. `sticky` combined with `zIndex` needs a value from the fixed `BlockZIndex` set (`header`, `sticky`, `fixed`, `dropdown`, `modal`, `popover`, `toast`, `tooltip`) rather than an arbitrary number, so pick the token that matches what the element actually is.

Advanced Layout goes further into sidebar-driven and multi-region shells. Sidebar covers the specific collapsible side-navigation pattern that often pairs with this page's header-plus-main structure. Container and Grid are worth a look for content-width and multi-column needs that a single `Block` doesn't cover cleanly.