feat(popup): fade the panel in, the way Menu already animates - #698
Merged
Conversation
Menu was the only thing in the library using @starting-style, inherited with the port. The .popup primitive - six components' panels - appeared instantly, so a picker snapped open next to a menu that glided. It fades now, through the same three-part recipe: allow-discrete makes display animatable, @starting-style supplies the state to animate from (the element does not exist to be styled before it is shown), and opacity carries the motion. No scale, deliberately. A popup carries no placement attribute, so a scale would need an origin we cannot know - and on a panel the size of a calendar even 2% reads as the panel jumping rather than appearing. The combobox list hid that; the pickers did not. Verified by sampling computed style through the transition rather than by reading the CSS: opacity 0 at the first frame, 0.91 at ~60ms, 1 when settled. The visual suite cannot see this - it freezes transitions on purpose - but a fading panel is composited, and a composited layer rasterises text differently enough between frames to trip a comparator counting antialiased pixels. The three popup screenshots get a larger allowance for that, and only for that; the icon-colour changes this suite exists to catch move far more pixels.
Coverage Report for CI Build 30948255948Coverage decreased (-0.002%) to 92.963%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsNo coverage regressions found. Coverage Stats💛 - Coveralls |
The fade I just added made a latent split visible: Combobox added .show to the popup only when the panel was teleported, and otherwise relied on `.autocomplete.show &` to set display. That worked while display was the only thing keyed on the class. Once opacity was keyed on it too, the untelevised path left the panel laid out and fully transparent — autocomplete and multi-select opened into nothing. The panel carries its own open state now, teleported or not, and the parallel display rules in the combobox and picker partials are gone. They were what hid this: two selectors driving one state, so a missing class cost nothing until something else depended on it. Caught by mrholek in the browser, not by the suite. The visual suite passes with the panel completely invisible, so the regression test is a contract one — the popup carries .show after show() and loses it after hide() — and it fails without this fix.
mrholek
added a commit
that referenced
this pull request
Aug 7, 2026
An audit of every v6-dev commit against the guide found five user-visible changes with no entry, and one entry that had gone stale. Missing: - **The `*.rtl.css` builds are gone** (#682). The biggest gap: 20 files left `dist/css` and nothing said so. Anyone linking `coreui.rtl.min.css` gets a 404 with no explanation of what to do instead. - **Button always exposes `aria-pressed`** (#706). - **Number Input** (#694) was mentioned only in passing, inside the entry about the frame it shares with Password Input, never announced as new. - **Multi Select option checkboxes are the form-check surface now** (#660, #661), which retires the per-indicator look variables. - **Markers are hidden with `list-style-type: ""`** (#664). Stale: the select-indicator entry still said "the RTL build flips the right/left keyword at compile time" — there is no RTL build. And the popup primitive entry claimed "the anchored presentation is unchanged", which stopped being true when the panel started fading in (#698).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #697. Raising the Firefox floor to 129 bought
@starting-stylefor exactly one component — Menu, which inherited it with the port. Meanwhile.popup, the shared chrome behind six components' panels, had no transition at all: a date picker snapped open next to a menu that glided.All three parts are load-bearing:
allow-discretemakesdisplayanimatable,@starting-stylesupplies the state to animate from (the element does not exist to be styled before it is shown), and opacity carries the motion. Duration and easing are tokens.No scale, deliberately
The first attempt scaled from
.98, mirroring Menu. mrholek caught it immediately: the pickers popped, the combobox did not. Menu keystransform-originoffdata-coreui-placement; a popup carries no such attribute, so any origin is wrong half the time — above the field, or in RTL. And on a panel the size of a calendar even 2% reads as a jump rather than an appearance. The combobox list is small enough to hide it; the pickers are not.Verification
The visual suite cannot see this: it freezes transitions on purpose, so a screenshot proves nothing about motion. Sampling computed style through the transition instead:
prefers-reduced-motionis handled by ourtransition()mixin, which emitstransition: noneunder it.One harness change, and why
A fading panel is composited, and a composited layer rasterises text differently enough between frames to move ~3% of pixels — enough to trip a comparator configured with
includeAA: true. That setting is not negotiable: it is what catches an adornment icon changing colour, which was itself a bug found by this suite.So the three popup screenshots get a larger allowance, passed per call rather than globally, with the reason in the code. Everything else keeps the tight one. Verified stable across three consecutive runs.
shoot()also waits two frames before capturing now, which is correct regardless.