Skip to content

Fix(fields): Keep the fullscreen panel's surface over the whole viewport while the keyboard is up - #277

Merged
mikakoskinencsc merged 5 commits into
mainfrom
development
Sep 15, 2026
Merged

mikakoskinencsc merged 5 commits into
mainfrom
development

Conversation

@razorfever

Copy link
Copy Markdown
Contributor

With the on-screen keyboard open, the fullscreen panel of c-tree-select and
c-autocomplete no longer covered the screen: the panel itself was sized to
the visual viewport's box, so any gap between what visualViewport reports
and what is actually visible showed the page. The panel (c-dropdown: the
dialog) is now a fixed inset: 0 surface over the layout viewport, which
the keyboard overlays but never shrinks; only the card (c-dropdown: the
inner column) follows the visual viewport, so the heading row and search
input still end above the keyboard.

  • visualViewport.ts: FULLSCREEN_SURFACE_STYLE and contentBoxStyle
    (plus the imperative twins) replace the single fullscreen box
  • useAnchoredPanel: panelStyle is the surface, new cardStyle the box
  • src/test/fakeVisualViewport.ts swaps the API's getters — headless
    Chromium has no keyboard; one regression case per component, red before
  • ADR-0050 decision 4 refined in place; glossary and usage prose updated

Co-Authored-By: Claude Fable 5.1 noreply@anthropic.com

razorfever and others added 5 commits September 15, 2026 06:00
…ort while the keyboard is up

With the on-screen keyboard open, the fullscreen panel of c-tree-select and
c-autocomplete no longer covered the screen: the panel itself was sized to
the visual viewport's box, so any gap between what `visualViewport` reports
and what is actually visible showed the page. The panel (c-dropdown: the
dialog) is now a fixed `inset: 0` surface over the layout viewport, which
the keyboard overlays but never shrinks; only the card (c-dropdown: the
inner column) follows the visual viewport, so the heading row and search
input still end above the keyboard.

- `visualViewport.ts`: `FULLSCREEN_SURFACE_STYLE` and `contentBoxStyle`
  (plus the imperative twins) replace the single fullscreen box
- `useAnchoredPanel`: `panelStyle` is the surface, new `cardStyle` the box
- `src/test/fakeVisualViewport.ts` swaps the API's getters — headless
  Chromium has no keyboard; one regression case per component, red before
- ADR-0050 decision 4 refined in place; glossary and usage prose updated

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… fix

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…nes under it

`src/test/fonts.conf` had never loaded: a double hyphen inside its XML
comment (a CLI flag spelled out) made fontconfig reject the whole file, and
Chromium fell back to the system config without a word. Under that config
the `--c-font-family` stack still reached Liberation Sans in the
devcontainer (the Latin chain ends in Arial, metric-aliased to Liberation),
but Tailwind's preflight stack — inherited by option rows, tags and tabs
inside their shadow roots — resolved to WenQuanYi Zen Hei, and on
ubuntu-latest both stacks went to DejaVu Sans. The first CI run of the
visual comparison therefore failed nine text-heavy shots, three of them by
a 7 px wider panel (the `<input>` default width follows the font's average
character width).

The comment is repaired (no flag spelled with `--` in it) and every family
the pin names now resolves to Liberation on both machines. All 50 baselines
are deleted and re-authored under the effective pin — `test:update` alone
rewrites only references that fail the comparison — and a clean run of the
whole suite passes against them.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…se the same font files

With the font pin loading, CI still failed five visual comparisons: three
anchored panels 253 px wide against 246 px references and two tree-select
shots at 2%. Both machines rendered Liberation Sans, but not the same one:
ubuntu-latest ships Liberation 2.1.5, the Debian 12 devcontainer 1.07.4.
Liberation 2 carries a different OS/2 average character width, which is what
sizes a default input box and therefore the field and its panel, and its
outlines differ enough for row-heavy shots.

The harness now bundles one exact set, the Liberation 2.1.5 Sans faces and
Mono Regular with their OFL licence under `src/test/fonts` (provenance and
checksum in `fonts.conf`). `fonts.conf` adds that directory and rejects every
system copy of Liberation, so the bundled files win on any distro.
`fonts.node.spec.ts` asks fontconfig that the config parses and that the
aliased families resolve to the bundled faces, catching both a malformed
config and a system copy winning. All 50 baselines re-authored under the
bundled font; the c-select panel now measures the runner's 253 px here too.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The docs viewport smoke ran in CI for the first time once the visual suite
went green, and failed one route: `/components/c-checkbox` at 362 px,
widened by the inline code `c-checkbox:state(checked)::part(indicator)` in
the usage prose. The smoke launched Chromium without the harness font pin,
so the runner rendered DejaVu Sans (wider) where the devcontainer did not;
it now hands Chromium the same FONTCONFIG_FILE as the visual baselines (the
bundled Liberation 2.1.5), and setting the variable overrides it to probe
another stack — a DejaVu stack reproduces the failure locally. Inline
`code` in the docs gets `overflow-wrap: anywhere`, so a long token breaks
instead of widening the page under any font; `pre` keeps its own scroll.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@mikakoskinencsc
mikakoskinencsc merged commit 30e085a into main Sep 15, 2026
3 checks passed
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.

2 participants