Skip to content

Pages opened from a tab wear the design's bar, not Material's (#513) - #526

Merged
maximsan merged 3 commits into
mainfrom
feat/subheader-design-bar
Sep 5, 2026
Merged

Pages opened from a tab wear the design's bar, not Material's (#513)#526
maximsan merged 3 commits into
mainfrom
feat/subheader-design-bar

Conversation

@maximsan

@maximsan maximsan commented Sep 5, 2026

Copy link
Copy Markdown
Owner

Closes #513.

Eight pages sat under a solid grey strip with a small title in it, there from the first frame to the last. Each now opens on its own name set large, with only a back arrow floating over it, and the strip fades in as you scroll — carrying the name you have just scrolled past. The same pair #441 built for the tabs, at the shorter height the design gives a sub-screen.

SubScreenScaffold ties together the four things every one of them needs: the bar, the scroll flag, the room the scroll leaves for the bar, and the reset. HeaderChrome and HeaderCompactTitle move out of lib/app/ into lib/core/widgets/ — a feature screen may not import the app layer, and they are the design's one bar chrome rather than the tab header's private one.

Worth a look

  • The dictionary is the page the reset exists for. Its masthead, search and filters were fixed above a scroller, so the bar had nothing to take over from. They are inside one sliver view now; drilling into a category returns the page and the bar to the top together, and backing out of a category goes to the index rather than out of the dictionary.
  • The design's measurements are per page, not one number. The scroll pad is 108 where a page opens on a large title, 84 on the tree and the streak, 100 on the grove. The scroll threshold is 40 everywhere except the Saved shelf, which the design gives 72. Both were uniform in the first pass and are named per page now.
  • Not ported: the design's solid bar. Its only host is the Roasty dress-up screen, which this app has not built. The two pages here that open on a hero — the streak and the grove — are not that case: the design passes them the ordinary scrolled flag.
  • Six full-screen flows still draw an AppBar — a lesson, the mini-games, the two drills, Term of the Day. They want the design's floating bar, not this back bar: a different component, filed as The bar over a lesson or mini-game is a solid strip, where the design lets the page show through #525. A guard lists all six, so the list cannot go stale.

Checks

dart format, flutter analyze, the metrics gate and the full suite (2578) all clean on the merge with main.

…rial's (#513)

Eight screens sat under a solid strip with a small title in it, always there.
Each now opens on its own large title with a back arrow floating over it, and
the strip fades in as the page scrolls — the page pulled over itself, blurred,
hairlined, carrying the name that has just gone under it. The same pair #441
built for the tabs, at the shorter height the design gives a sub-screen.

`SubScreenScaffold` ties together the four things every one of them needs: the
bar, the scroll flag, the room the scroll leaves for the bar, and the reset.
`HeaderChrome` and `HeaderCompactTitle` move from `lib/app/` into
`lib/core/widgets/` — a feature screen may not import the app layer, and they
are the design's one bar chrome rather than the tab header's private one.

The dictionary is the page the reset exists for. Its masthead, search and
filters were fixed above a scroller, so the bar had nothing to take over from;
they are inside the one scroll now, and drilling into a category returns the
page and the bar to the top together. Backing out of a category goes to the
index rather than out of the dictionary.

`ScrollFlagScope` carries the design's one scroll hook — the threshold, the
depth-0 rule and the reset — where `FloatTopbar` had its own copy of the first
two. `HeaderCompactTitle` draws no eyebrow line when there is no eyebrow, which
the design does and the app could not, because until now every caller had one.

Not ported: the design's `solid` bar variant, whose only host is a screen the
app has not built. The six full-screen flows that still draw an `AppBar` are
#525, and a guard lists them so the list cannot go stale.
… can leave

Spec review, all against the design's own numbers:

- The scroll pad is not one number. The design opens the tree and the streak
  at 84 and the grove at 100, not the 108 a page with a large title takes —
  three pages were opening up to 24px too low. Each names its own now.
- Nor is the threshold. The design's Saved shelf passes `useScrollFlag(72)`
  where every other page takes the default 40, so `ScrollFlagScope` takes one
  and the shelf passes it. The doc that claimed a page could not pick its own
  was simply wrong.
- The back control is the design's again: the mark at 18 bare and 15 ringed,
  the ringed one in muted ink, and the 4px pull left that puts the bare mark
  on the bar's inset rather than 4 inside it.
- The coffee tree hand-rolled its kicker and heading, so it alone missed the
  `Semantics(header: true)` the other pages gained. It takes `PageLargeTitle`,
  which grew the centring the design gives that one page.
- The comment claiming the design retitles the dictionary when you drill into
  a category was false — only its bar follows. The page heading following it
  is the masthead's own divergence, left as found and now recorded as such.

Standards review:

- The dictionary lost its way back while loading or failing: the bar was
  inside the `when` rather than around it. A page you cannot leave is a trap.
- `DictionaryTermList` became a `Column` on the claim that its rows were built
  eagerly anyway. They were built eagerly and *inflated* lazily, so that was
  wrong and all 73 rows were inflating at once. It is a sliver now.
- The status-bar height and the 260ms fade were each written twice. One home
  each: `HeaderChrome.designStatusBarHeight` and `scrolledFade`.
- `backLabel` and `floatingActionButton` had no callers; both are gone.
- `.add(x).resolve(TextDirection.ltr)` hardcoded a direction in five places
  where both operands are non-directional. Plain `+`.
- The not-found term page set a bar title nothing could ever reveal. It is a
  titled page now, like the rest.
@maximsan
maximsan merged commit 2b284f7 into main Sep 5, 2026
6 checks passed
@maximsan
maximsan deleted the feat/subheader-design-bar branch September 5, 2026 20:56
@maximsan maximsan mentioned this pull request Sep 5, 2026
27 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Pages opened from a tab wear a stock Material bar, not the design's

1 participant