Skip to content

Improve layout flexibility #18

Description

@batpad

Ran into some issues being able to get a more expressive full-screen layout. AI / Claude notes for things that can be improved with the grid / layout:

Layout improvement notes

Collected while doing a design pass on docs/examples/fullscreen-dashboard.ipynb
(a controls-rail + lonboard-map + chart layout inside Fullscreen). Observations
only — none of this is implemented. Ordered roughly by impact.

1. Grid: equal columns only

grid/widget.py has columns = traitlets.Int(2) and grid/src/index.ts hard-codes
repeat(N, minmax(0, 1fr)). There is no way to express the most common dashboard
shape — a narrow control rail beside a wide map (320px 1fr), or a cell spanning
two columns. The workaround in the example (put the chart in the rail so the 50/50
split doesn't leave a dead half-column) works but shouldn't be necessary.

Smallest fix: widen columns to Union([Int(), Unicode()]); when it's a string,
pass it straight through to gridTemplateColumns. ~4 lines across widget.py and
index.ts. Spans would need a per-child wrapper or a spans=[...] trait — bigger
API question.

2. Chart: fixed pixel width only

Chart.width is Int (px). .manywidgets-chart has max-width: 100%, so a chart
can shrink but never fill a wider container. The example exploits this by
oversizing (width=1100 → the column caps it), which works because Chart.js is
responsive: true — but it's a non-obvious trick. Supporting width=None (or
"100%") meaning fill-container would make charts compose into layouts naturally.
Same question applies to height eventually (fill a fixed-height cell).

3. Row/Column: no justify, no per-child sizing

row/, column/ expose only gap and align. Cells are flex: 0 1 auto with no
way to set grow/basis per child, so a Row collapses children without intrinsic
width (lonboard maps — already noted in docs/examples/layout.ipynb). A justify
trait and some per-child flex control (Row(a, b, flex=[0, 1])?) would cover most
gaps; until then Grid is the only reliable side-by-side container.

4. FilterBinder chip / LayerToggle theming

  • FilterBinder renders a status chip styled via inline el.style.cssText
    (lonboard/filter_binder/src/index.ts) — unoverridable, no visible/compact
    trait, and it must stay mounted for static export. In a polished dashboard it
    reads as debug output. A show_status=False mode that renders (say) a 0-height
    element while keeping the JS alive would fix it.
  • lonboard/layer_toggle never calls applyThemeVars and hardcodes its colors
    and sizes, so it ignores theme=/style= and the --mw-toggle-* tokens the
    core Toggle honors. Visually inconsistent next to themed controls.

5. Fullscreen: alt layout can't opt into fill-height

Only the no-alt slot path gets the stretch rules (.mwfs__content > .mwfs__slot);
a fullscreen= layout is height: auto and the panel scrolls. Fine as a default,
but a dashboard usually wants "fill the screen, no scroll" — some opt-in (or a
documented height="70vh"-style recipe, which is what the example uses) would
help. Also the overlay's padding: 24px is hardcoded in fullscreen/style.css
where the panel padding is already tokenized — could be a --mw-* token too.

6. Fixed widget margins

Nearly every widget wrapper carries margin: 10px 0 in its own style.css.
Containers can only add space (gap), never remove it, so tight layouts bottom
out at ~20px rhythm. A --mw-widget-margin token (or containers zeroing child
margins and owning spacing via gap) would give real control.

Aside: what DOES compose well today

style= on any themable widget cascades --mw-* tokens to descendants across
shadow boundaries — e.g. Fullscreen(..., style={"--mw-control-max-width": "100%"})
retunes every control card inside the overlay in one place. This is a genuinely
good lever; worth documenting more prominently in the theming guide.

---- end AI notes -----

@dzole0311 I think some of the flexbox stuff, etc. is beyond me to know exactly what we should do here. Most of the AI notes make sense, but would like to get a sanity check if these seem sensible to do or if we should re-look at some of the grid / layout stuff in a more fundamental way.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions