Kite docs

FAQ and troubleshooting

The traps this build actually hit. Each one cost time to find, so they are written down rather than left for you to rediscover.

Layout

My stat cards get taller on wide screens

They are in a GridView with a childAspectRatio, which ties height to width. Use KiteStatGrid: fixed height, flexible width.

Aspect ratio is right for content that genuinely scales with size — thumbnails, media cards. It is wrong for anything with a fixed amount to say.

My maxWidth is being ignored

SingleChildScrollView passes a tight width constraint, and ConstrainedBox cannot shrink below a tight incoming constraint. Loosen it first:

SingleChildScrollView(
  padding: const EdgeInsets.all(KiteSpace.xl),
  child: Align(                                  // ← without this, no-op
    alignment: AlignmentDirectional.topStart,
    child: ConstrainedBox(
      constraints: const BoxConstraints(maxWidth: 960),
      child: …,
    ),
  ),
)

A card in a Row has dead space at the bottom

Siblings in a Row stretch to match the tallest. Either give the shorter card a footer of supporting facts, or drop the IntrinsicHeight and let each size itself.

My layout breaks in Arabic

Something names a physical side. Alignment.topLeft, EdgeInsets.only(left:), Border(right:) and Positioned(right:) are all direction-agnostic — they stay physically left even in RTL. See Localisation for the directional equivalents.

Data and rendering

Pagination shows the wrong number of pages

ListResult.total is being set to the page length rather than the row count. See Data layer — it comes from X-Total-Count or Content-Range, not rows.length.

Currency sorts wrongly

The value was formatted into a string before reaching the cell, so $9.00 sorts after $1,264.55. Use TrinaColumnType.currency and keep the numeric value.

A chart tooltip shows a long decimal

Pass valueLabel to KiteLineChart. Without it, a hover prints the raw double.

"Unsupported operation: Not available for web"

Almost certainly ShadAvatar handed an empty string rather than null — it renders its placeholder only when src is null, and a non-null empty string reaches an image loader that has no web implementation. KiteAvatar already guards this.

A disabled button looks enabled

Nulling onPressed is not enough — pass enabled: false, which is what dims it.

Build and CI

CI fails on formatting but my code looks fine

You ran dart format lib/. CI runs dart format --set-exit-if-changed . across the whole tree, including test/. Run it from the project root.

The size job fails after I added a screen

Check the composition before raising the budget — fonts and assets are usually the cause, not Dart. If the growth is legitimate, raise WASM_GZIP_BUDGET_KB in the workflow and say why in the commit. The budget exists to make growth visible, not to be moved quietly.

The architecture job fails

Something outside lib/kite_ui/ imports package:shadcn_ui. Wrap what you need in kite_ui and import that instead — see the one rule.

Icons render as empty boxes

The font subsetter dropped the base Lucide family. Exactly one must survive; the fonts CI job fails on zero or more than one.

Refreshing a detail page 404s

The host is not falling back to index.html for unknown paths. See Deploying.

Product questions

Can I use forui, or plain Material, instead of shadcn_ui?

Yes — that is what kite_ui is for. lib/kite_ui/_shadcn.dart is the single import surface; change it and reimplement the wrappers. Nothing in features/ moves.

Why is the session lost on reload?

It is in-memory on purpose. Persisting it means choosing a storage package and a token format on your behalf — decisions that belong to your auth provider. See State for the two methods to change.

Is it really free?

MIT. Commercial use, no attribution required, no asterisk.

Something is missing or wrong here

Open an issue on GitHub. If it cost you an hour, it is worth a paragraph in these docs.