Skip to content

RFC: UI maturity — remaining structural items (Mantine-first grid, burger, scroll pill) #135

Description

@dkedar7

Summary

Follow-up items deferred from the UI maturity pass (feat/ui-maturity, shipping in 0.5.0). Each was consciously left out because it is either high-risk to do without dedicated verification, or low-value relative to its effort. Collected here so they're tracked rather than lost.

1. Mantine-first grid migration (the big one)

Problem. Fast Dash still loads a Bootswatch (dbc.themes.*) stylesheet, and the output mosaic layout is built from dbc.Row / dbc.Col scaffolding that depends on the Bootstrap grid CSS (g-1 d-flex flex-fill, class_name=..., width=). So two design systems still coexist: Mantine (all the actual controls, chrome, chat) and Bootstrap (the invisible grid + the global stylesheet).

Already done in 0.5.0 (the safe parts): dropped FontAwesome; added the accent= Mantine primaryColor API; enriched the Mantine theme (type/radius/shadow scales, focus ring); swapped the Bootstrap-styled components (TextAreadmc.Textarea, upload labels → html).

Remaining. Replace the dbc.Row/dbc.Col mosaic grid (_do_mosaic, generate_output_component, _prepare_layout in Components.py) with dmc.Grid / CSS grid, then drop the Bootswatch stylesheet and dash-bootstrap-components entirely. Reinterpret theme= as Mantine theme/scheme presets (map the Bootswatch names to curated Mantine palettes so the existing API stays backward-compatible).

Why it's its own RFC. This is load-bearing layout code driving the mosaic feature. It changes the visual baseline of every app and can't be validated by the deterministic suite — it needs a real Selenium/visual pass across mosaic shapes, all output types (Graph/Table/Image/Markdown/multiple), light + dark, and mobile. High reward (single design system, lighter payload, theme= finally themes the chrome), high risk if rushed.

Acceptance: no dbc import in fast_dash/; theme= themes the Mantine chrome; existing mosaic layouts render identically; selenium suite green.

2. Burger shows ✕ at rest

dmc.Burger(opened=True) renders as an ✕ when the sidebar is open (the default), which reads oddly on desktop where the sidebar is a permanent fixture. A clean fix means replacing the Burger (whose opened prop toggle_sidebar reads) with a static hamburger ActionIcon toggled by n_clicks — a rewire of the sidebar-toggle callback. Low value, non-trivial risk; left for this pass.

3. Scroll-to-bottom pill (chat)

The transcript uses flex-direction: column-reverse, so it auto-pins to the newest message in the common case. A "jump to latest" pill only helps the narrow "scrolled up while a reply streams" case, and getting the floating-pill positioning right inside the panel is fiddly. Marginal value.

Related chat follow-ups (from the ship review, for completeness)

  • run_app results aren't fed back into the agent's tool loop — the model can trigger a run but can't see the output (developer can call the fn themselves). Docs note + possible enhancement.
  • A resumed HITL turn gets an empty ctx.inputs (cosmetic; langstage agents don't consume it).
  • run_app outputs stream uncapped over socket.io — documented limitation; add a size cap if it bites.
  • Pre-existing (not this branch): describe_app over MCP exposes a browser-typed PasswordInput's current_value — the browser mirror already copies it. Worth redacting password current_value in _describe_static_inputs.

Non-goals

Not proposing to gate 0.5.0 on any of these — they are post-0.5.0 polish/hardening.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions