Theme
Customize the design system

Every control starts at the preset. Change one and every preview on the site follows, on this page and the next, until you reset it.

Contrast

Text against what it sits on. Below 4.5:1 fails WCAG AA for body text — the check a reviewer runs on any surface that takes a tone.

Waiting for the first preview to report its palette.

Corners

Sets all three radii at once. The individual values are under Geometry.

Brand 5

The accent seam an app actually brands itself through. Change these and you have made the decision a real `DesignTokens.graphite(...)` call makes.

Geometry 15

Square or rounded, and how heavy every line is. The radius row above the controls sets all three corners at once, because "what does square feel like" is one decision rather than three numbers.

Surfaces 17

Everything the app is painted ON — the ground behind the content (the frame paints it too), the cards over it, the well inset in a card, and the washes that show state.

Bands 10

The rail's head and the view bar beside it (one band across the top at 960 and wider), a pushed screen's bar, the compact bar and the compact nav bar — the band's fill, its rule, its hover and active faces, the resting field box on it, and the ink and accent control that sit on it. The rail's tree and its footer stay on the ground.

Text and controls 11

The ink ramp, the control outlines and the field's focus halo. Every pair the panel can break is watched by a contrast badge above.

Status 7

The three voices that mean something — danger, caution and ok — each as a foreground and a surface wash, danger with a border as well.

Data 5

The default pin head, its glyph and its halo, and the group bands. A pin's category color comes from the palette, named in the theme seed.

Map 11

The basemap's roles — land, water, parks, roads and their casings, buildings, labels — and the pending pin's gray. A raster basemap keeps its own imagery; these paint the map's plate and any kit-drawn map.

Scrollbars 6

Every scroller's bar: the thumb at rest and while hovered or dragged, the strip it rides, and the desk bar's thickness, side gap and corners. The desk half shows only while a fine pointer is attached; at touch the platform's own overlay keeps its size.

Advanced 6

Real controls that are not decisions — motion durations, the focus ring offset, the touch floor. Opens collapsed on purpose.

Take it with you

The Dart that reproduces what you are looking at. It is a real constructor call, because the configurator edits a real preset — what you copy is what an app can paste.

Wiring

Media

Install this to give every stored-image reference beneath it one cache and one resolution ladder; AppImage is what renders through it.

2
Classes
8
Knobs

Live

Real widgets, built from the real kit. Turn a knob and it rebuilds; the theme bar above applies the design system's own tokens — including anything you changed under Customize — and the device selector uses the same sizes the golden baselines gate on, so what you see here is what CI holds the widget to.

Press Focus on any preview to take it to the full window — at a desktop width that renders most devices at 1:1, which is when the widget's own controls become clickable. The bar always states the device and the scale, so a shrunk preview says it is shrunk. Esc leaves.

MediaCacheScope

No live preview — media scope — provides one cache and resolution ladder. Its knobs are documented below.

AppImage

No live preview — needs a Size — a hand-written builder is not wired yet. Its knobs are documented below.

The API

MediaCacheScope widget

Publishes a MediaCache to descendants, making remote images and basemap tiles survive an app restart and a dead signal. Entirely optional: with no scope above them, `AppImage` falls back to `NetworkImage` and the map falls back to flutter_map's default network tile provider — the pre-cache behavior,…

Full dartdoc

Publishes a MediaCache to descendants, making remote images and basemap tiles survive an app restart and a dead signal. Entirely optional: with no scope above them, `AppImage` falls back to `NetworkImage` and the map falls back to flutter_map's default network tile provider — the pre-cache behavior, unchanged. The host installs the scope once at the composition root, above the Navigator so pushed routes inherit it, the same placement `AppNetworkAuth` needs. The kit depends only on the MediaCache interface; the host supplies the implementation, which is what keeps the widget layer free of the sync engine.

MediaCacheScopedefault constructor

Knob Type Default What it does
cache * MediaCache — The durable byte cache backing network media below this scope.
child * dynamic —

AppImage widget

A tandem-faithful image widget over the shared resolution ladder (storedImageProvider → resolveImageSource → imageProviderFor): local staged bytes, a bundled asset, an authenticated network URL, an origin-relative path, or a branded fallback. Harvested from the detail media header and hardened with…

Full dartdoc

A tandem-faithful image widget over the shared resolution ladder (storedImageProvider → resolveImageSource → imageProviderFor): local staged bytes, a bundled asset, an authenticated network URL, an origin-relative path, or a branded fallback. Harvested from the detail media header and hardened with the decodeSize perf contract (card_deck / gallery / form image editors). decodeSize is REQUIRED — the slot's logical size. The widget DPR-scales it to a decode `cacheWidth` so a multi-megabyte source photo never decodes at full resolution into a thumbnail slot. Reads AppNetworkAuth (headers + base URL) and StagedFilesScope (staged-file local paths) from the tree, plus MediaCacheScope when one is installed — with it, the network and origin branches survive an app restart and a dead signal; without it they fall back to memory-only NetworkImage.

AppImagedefault constructor

Knob Type Default What it does
value * String — The stored image reference — any ladder shape, or blank.
decodeSize * Size — The slot's logical size; DPR-scaled to the decode `cacheWidth`.
errorBuilder WidgetBuilder? null Builds the load-error branch (D5 br5 — path present but the bytes are bad/undecodable) when the caller needs it visually distinct from the absent fallback: a corrupt attachment will not self-heal on the next sync, so it must not read as "no image". `null` (the default) keeps the old behavior —…
fallbackBuilder WidgetBuilder? null Builds the fallback shown for a blank value, a not-yet-staged marker, or a load error. Defaults to a muted placeholder.
fit BoxFit BoxFit.cover How the image inscribes its slot (default BoxFit.cover).
pendingOverlay Widget? null Optional overlay drawn over a `staged://` (pending-upload) image — e.g. an "Uploading…" badge. Shown only on the staged branch.

Where it lives

Class File
MediaCacheScope packages/app_widgets/lib/src/media/media_cache_scope.dart
AppImage packages/app_widgets/lib/src/image/app_image.dart