tuika 0.8.0

The application framework for Rust terminal UIs — flexbox layout, overlays, focus, keymap, components, and safe ratatui interoperability.
Documentation
# Layout

Tuika uses integer-native flex layout for application structure. `Flex` is the
general container, `Flow` is the concise choice for intrinsic items that wrap,
and `Grid` is a deliberately small equal-column grid. All three measure ordinary
third-party `View` implementations through the same `MeasureRequest` contract.

## Flex containers and items

Container style controls direction, wrapping, padding, gaps, and alignment:

```rust
use tuika::prelude::*;

let tags = Flex::row()
    .wrap(FlexWrap::Wrap)
    .column_gap(1)
    .row_gap(1)
    .align_content(AlignContent::SpaceBetween)
    .auto(element(Text::raw("rust")))
    .auto(element(Text::raw("terminal-ui")));
# let _ = tags;
```

`align` positions items within one line. `align_content` distributes the lines
themselves when wrapping creates more than one. `justify` distributes space on
each line. Use `row_gap` and `column_gap` when the two axes need different
spacing; `gap` sets both.

Child sizing belongs to `FlexItemStyle`, separately from the container:

```rust
# use tuika::prelude::*;
let item = FlexItemStyle::default()
    .basis(Dimension::Fixed(12))
    .grow(1)
    .shrink(1)
    .min_main(6)
    .max_main(20)
    .align_self(Align::Center);
let row = Flex::row().styled(item, element(Text::raw("resizable")));
# let _ = row;
```

The basis is the starting main-axis size. Positive free space is shared by
`grow`; negative free space is removed according to `shrink`, without crossing
the item's min/max constraints. Integer cells are assigned by rounding track
boundaries, so the final child reaches the exact container boundary without
losing or double-counting a cell.

## Wrapping and line alignment

`FlexWrap::Wrap` starts a new line when the next item's outer main size no
longer fits. Each line resolves grow, shrink, justification, and item alignment
independently. `AlignContent::{Start, Center, End, Stretch, SpaceBetween}` then
places completed lines on the cross axis. `NoWrap` remains the default.

`Flow` packages the common intrinsic wrapping case:

```rust
# use tuika::prelude::*;
let flow = Flow::new()
    .gap(1)
    .item(element(Text::raw("one")))
    .item(element(Text::raw("two")))
    .item(element(Text::raw("a-longer-item")));
# let _ = flow;
```

Choose `Flex` when children need grow/shrink, fixed or percentage bases, or
per-item alignment. Choose `Flow` when every child is intrinsic and wrapping is
the main behavior.

## Flow versus Grid

`Flow` packs variable-width items and wraps wherever the next item stops
fitting. `Grid::new(columns)` creates a fixed number of equal-width columns,
fills them row-major, and derives each row's height from its tallest cell.

```rust
# use tuika::prelude::*;
let grid = Grid::new(3)
    .column_gap(1)
    .row_gap(1)
    .cell(element(Text::raw("a")))
    .cell(element(Text::raw("b")))
    .cell(element(Text::raw("c")));
# let _ = grid;
```

Grid intentionally omits CSS Grid's named lines, implicit tracks, spanning,
dense packing, and independent track definitions. Those features add a large
constraint language while terminal applications usually need a stable column
count and predictable clipping. Compose nested Flex/Grid containers when a
screen needs a more irregular structure.

## Measurement requests

`View::measure_request` receives optional known axes and an `AvailableSpace`
mode for unresolved axes:

- `Definite(n)` means at most `n` cells are available.
- `MinContent` asks for the smallest useful intrinsic contribution.
- `MaxContent` asks for the preferred unconstrained contribution.
- `known_width` and `known_height` mean the parent has already fixed that axis.

Flex and Grid preserve those modes when measuring third-party views and add a
known axis once a fixed basis or grid track has been resolved. Existing views
that only implement `measure` remain compatible through the default adapter.
Because `MeasureRequest` and `AvailableSpace` are non-exhaustive, downstream
implementations should match with a fallback arm so future request metadata can
be added compatibly.

## Migrating existing layouts

- `LayoutStyle::gap` became independent `row_gap` and `column_gap` fields. Use
  `Flex::gap(n)` when both should remain equal.
- `Item::dimension` moved into `Item::style.basis`. Prefer
  `Item::styled(FlexItemStyle, intrinsic)` for direct solver use.
- `Flex::{auto,grow,fixed}` remain concise compatibility builders. Use
  `Flex::styled` when shrink, min/max, or per-child alignment matters.
- Existing no-wrap layouts keep their behavior unless `FlexWrap::Wrap` is set.

The public [`solve_layout`](https://docs.rs/tuika/latest/tuika/fn.solve_layout.html)
result includes child rectangles and flex-line metadata for hosts that need hit
testing, scrolling, or layout inspection without painting.