# Structures

> Structures: anatomy, keyboard behavior, state, and theming in Askr.

Source: [https://askrjs.com/docs/components/structures](https://askrjs.com/docs/components/structures)

Status: stable. Packages: @askrjs/ui, @askrjs/themes.

**Published packages are authoritative.** Examples may lag behind a published contract. When guidance differs, verify the exports and TypeScript declarations in your installed package, then file an issue.

## Example

```tsx
import { Button, Dialog, DialogContent, DialogTitle, DialogTrigger } from '@askrjs/themes/components';

<Dialog>
  <DialogTrigger asChild><Button>Open settings</Button></DialogTrigger>
  <DialogContent>
    <DialogTitle>Project settings</DialogTitle>
    <ProjectSettings />
  </DialogContent>
</Dialog>
```

## Purpose

`Block` is described in the theme's own docs as "the only layout engine" — the single primitive responsible for spacing, sizing, alignment, and responsive flex direction across the whole component catalog. Canonical structural components such as `Container`, `Section`, and `Grid` compose that layout contract rather than introducing separate systems. Use `Block direction="column"` or `Block direction="row"` instead of the legacy `Stack` and `Inline` aliases in new code.

## Install and import

Import structural components from the themes catalog: `import { Block, Container, Section, Grid } from '@askrjs/themes/components'`. Broader layout components such as `Main`, `Sidebar`, `Header`, and `Footer` are exported the same way and compose the same Block layout contract. Use `Block` with an explicit `direction` for row or column composition; `Stack`, `Inline`, and `Shell` are legacy compatibility aliases, not recommendations for new code.

## Live examples

The example on this page composes `Dialog` with its trigger, content, and title as you would in application code. The pattern generalizes across the structural components: a root that owns open state, a trigger that trips it, and a portalled content region that takes focus. Read the composition rather than copying it verbatim — your own content, labels, and actions belong in the same slots.

## Anatomy

Block's layout props are genuinely extensive: `padding`, `paddingX`, `paddingY`, `margin`, `width`, `height`, `direction`, `align`, `justify`, `gap`, `grow`, `shrink`, `background`, `radius`, `shadow`, `sticky`, `top`, and `zIndex`, among others. Every one of these accepts a `ResponsiveValue<T>` — either a bare value or a `Partial<Record<'base' | 'sm' | 'md' | 'lg' | 'xl', T>>` — so a single prop can carry a full mobile-first breakpoint schedule.

## State model

Structural components are stateless by design — they're pure layout, driven entirely by the props you pass in on each render, not by internal open/closed or selected flags the way interactive components are. `direction`, for instance, is just one of Block's `ResponsiveValue` props, resolving to `"row" | "column" | "row-reverse" | "column-reverse"` at whichever breakpoint applies.

## Keyboard and accessibility

Because Block and its presets render plain structural elements rather than interactive controls, there's no dedicated keyboard contract to document here — accessibility for structural components mostly comes down to choosing sensible native elements and letting content inside them (buttons, links, form controls) carry their own accessible behavior. `Main`, `Header`, and similar presets do map to meaningful landmark elements, which is worth preserving when you customize them.

## Styling and tokens

Block-owned layout variables are explicitly called out as part of the public theme contract, meaning they resolve through theme tokens rather than hard-coded pixel values, so retheming spacing or breakpoints doesn't require touching component code. Responsive behavior is additive and mobile-first: base styles apply everywhere, and `sm`, `md`, `lg`, `xl` values layer on top via `min-width` media queries, never the other way around.

## API

The real Block prop types are worth knowing by name: `BlockSpace` for padding/gap/margin scale (`"0" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "page"`), `BlockSize` for width/height (`"auto" | "full" | "screen" | "content" | "sidebar" | "page" | "sm" | "md" | "lg" | "xl"`), `BlockAlign`, `BlockJustify`, `BlockBackground`, `BlockRadius`, `BlockShadow`, and `BlockZIndex` (`"header" | "sticky" | "fixed" | "dropdown" | "modal" | "popover" | "toast" | "tooltip"`). Field and InputGroup, by contrast, are pure visual composition wrappers with no comparable layout prop surface — they exist to arrange form controls, not to lay out arbitrary content.

## Edge cases

Because Block is the only layout engine, resist the temptation to reach for raw flexbox or grid CSS around it for one-off adjustments — inconsistent layout approaches are exactly what the single-engine design is meant to prevent. Also remember that broad slots like `main`, `sidebar`, and `navbar` are semantic presets over Block, not independent components with their own prop vocabulary, so their responsive behavior follows the same breakpoint rules as everything else.

## Related pages

See Portals and Layers for how overlay content escapes normal document flow rather than being laid out by Block, and Customization for how Block's own CSS variables participate in the token override system.

## Documentation navigation

[Previous](https://askrjs.com/docs/components/customization/index.md) | [Next](https://askrjs.com/docs/components/portals-and-layers/index.md)
