Pular para o conteúdo

Layout — Window size classes

app-layout specs/app-layout/window-size-classes.kmd

4 canonical window-size classes (Compact / Medium / Expanded / Large) that Koder UIs adapt to. Defines breakpoints in dp, detection per surface (Flutter, Web, native Android), and the expected layout responses at each class. Material parity (`/foundations/layout/applying-layout/window-size-classes`).

Quando esta spec se aplica

Triggers primários

Todos os triggers

Corpo da especificação

Spec — Window size classes

Facet Visual do Koder Design. Material parity: https://m3.material.io/foundations/layout/applying-layout/window-size-classes.

The 4 classes

ClassWidth (dp)Typical surfacesColumns (grid)
Compact0–599Phone portrait, watch4
Medium600–839Phone landscape, small tablet, foldable inner8
Expanded840–1199Large tablet, small laptop, foldable outer12
Large≥ 1200Desktop, ultrawide, TV12+

Breakpoints are in density-independent pixels (dp) so Flutter, Web, and Android share the mental model. Web converts to CSS px 1:1 below high-DPI; above HDPI it follows window.devicePixelRatio.

R1 — Detect class per surface

Flutter

WindowSizeClass classOf(BuildContext context) {
  final w = MediaQuery.of(context).size.width;
  if (w < 600)  return WindowSizeClass.compact;
  if (w < 840)  return WindowSizeClass.medium;
  if (w < 1200) return WindowSizeClass.expanded;
  return WindowSizeClass.large;
}

koder_kit exposes KoderWindowClass.of(context) (planned).

Web

:root {
  --wc-compact:  599px;
  --wc-medium:   839px;
  --wc-expanded: 1199px;
}

@media (max-width: 599px)  { /* Compact */ }
@media (min-width: 600px) and (max-width: 839px)  { /* Medium */ }
@media (min-width: 840px) and (max-width: 1199px) { /* Expanded */ }
@media (min-width: 1200px) { /* Large */ }

koder_web_kit exposes data-window-class="compact|medium|..." attribute on <html> (planned).

Native Android

WindowSizeClass from Jetpack androidx.window.core.layout (Android 12+). Mapping is 1:1 with the above thresholds.

CLI / TUI

TTY columns (terminfo). Adapt at:

  • Compact: < 80 cols → single column, abbreviate labels
  • Medium: 80–119 cols → 2 columns, full labels
  • Expanded: 120–159 cols → 3 columns, descriptions
  • Large: ≥ 160 cols → full table layouts, side panes

R2 — Layout response per class

What changes at each class (canonical):

ElementCompactMediumExpandedLarge
NavigationBottom barBottom barNav railNav drawer (persistent)
Container padding16dp16dp24dp32dp
Card/grid columns1234+
List densityComfortableComfortableComfortableCompact (optional)
DialogFull-screen sheetFull-screenCentered modalCentered modal
Date pickerCalendar full-screenCalendar full-screenInline + popupInline + popup
SearchFull-width bar in app barBar in app barInline search fieldInline + always-visible

R3 — Multi-window / split-screen

Foldables and desktops support split-screen. Koder UIs:

  • Listen for class changes (MediaQuery rebuild, ResizeObserver)
  • Pick canonical layout fresh per class change
  • Preserve state across transitions (scroll, form input, selection)

Anti-pattern: hard-coding "isPhone" — use class detection so the same code works on tablet split-screen Compact.

R4 — Orientation independence

Window class is determined by width, not orientation. A landscape phone is Medium, not Compact. Avoid Orientation queries except for truly orientation-sensitive UI (camera viewfinder, AR).

R5 — Type scale

Type scale adjusts per class:

ClassDisplayHeadlineBody
Compact-1 step-1 stepbase
Mediumbasebasebase
Expanded+1 stepbasebase
Large+1 step+1 stepbase

(Concrete sizes in future typography.kmd.)

R6 — Forbidden patterns

  • ❌ Single hardcoded breakpoint (if width < 768) without class taxonomy
  • ❌ Orientation-only checks (portrait vs landscape)
  • ❌ Different code paths for "mobile" vs "desktop" with no class
  • ❌ Pixel hardcoding (width: 320px); use dp + class
  • adaptive-design.kmd — strategies (resize/reflow/transform)
  • canonical-layouts.kmd — 4 layouts per class behavior
  • safe-area.kmd — insets at every class

Referências