Closes #1066: Fix upgrade modal layout shift by animating geometry and correcting viewport unit#1183
Closes #1066: Fix upgrade modal layout shift by animating geometry and correcting viewport unit#1183Honemo wants to merge 3 commits into
Conversation
Add a CSS transition on .imagify-modal-content's width/height properties (guarded by prefers-reduced-motion) so switching between the plan-selection, payment-iframe, and thank-you steps of the upgrade modal animates smoothly instead of jumping instantly, and fix a max-height:90vw typo (should be 90vh) that caused inconsistent vertical clamping between steps. Fixes #1066 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Duplication | 0 |
🟢 Coverage ∅ diff coverage
Metric Results Coverage variation Report missing for 3fb41021 Diff coverage ✅ ∅ diff coverage (50.00%) Coverage variation details
Coverable lines Covered lines Coverage Common ancestor commit (3fb4102) Report Missing Report Missing Report Missing Head commit (ea505dd) 19533 629 3.22% Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch:
<coverage of head commit> - <coverage of common ancestor commit>Diff coverage details
Coverable lines Covered lines Diff coverage Pull request (#1183) 0 0 ∅ (not applicable) Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified:
<covered lines added or modified>/<coverable lines added or modified> * 100%1 Codacy didn't receive coverage data for the commit, or there was an error processing the received data. Check your integration for errors and validate that your coverage setup is correct.
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
|
Note Generated by the AI delivery pipeline (lead-reviewer · claude-sonnet-5). Review: ✅ PASS |
… gating Adds an `imagify-modal-no-transition` class toggled around the modal's opening fadeIn so a deep-link/resumed session landing directly on a non-default step (iframe/thank-you) snaps to its target geometry instantly instead of animating from the default 1065px width — a regression caught by the new Playwright spec against the transition added for #1066. Also aligns the new e2e spec's account-state handling with the rest of the suite: skip (rather than hard-fail) when the configured account's live plan/quota state doesn't render the upsell trigger, since that state comes from a real production API account and can't be seeded locally. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
| var target = $link.data( 'target' ) || $link.attr( 'href' ), | ||
| $target = jQuery( target ), | ||
| // Native DOM lookup (no jQuery) -- see assets/css/pricing-modal.css for the | ||
| // matching `.imagify-modal-no-transition` rule. | ||
| modalContentEl = $target.find( '.imagify-modal-content' )[ 0 ] || null; |
There was a problem hiding this comment.
Medium — This modifies the shared, generic openModal() utility in admin.js, which is used by every modal in the plugin (visual comparison modal, media-frame comparison modal, settings-info modals, etc.), not just the pricing modal. The spec's Architectural Decision explicitly states this fix should be CSS-only ("no JS or PHP changes are required") specifically to avoid touching jQuery-based modal code, and frames the JS-vs-CSS tradeoff as a decision for the manager, not something to decide unilaterally. Feature-specific logic (the .imagify-modal-no-transition class toggle, referencing pricing-modal.css in a comment) is now baked into a generic, multi-consumer function.\n\nFix: Either (a) flag this deviation explicitly for product/architecture sign-off before merging (it is documented in the PR description, but the spec itself was written to avoid exactly this outcome), or (b) scope the workaround so it doesn't run for every modal — e.g. gate it on $link.data('target') === '#imagify-pricing-modal' or a similar targeted check, so unrelated modals aren't paying the cost of a lookup/class-toggle they never use.
|
Note Generated by the AI delivery pipeline (lead-reviewer · claude-sonnet-5). What changed: Adds a CSS transition to the upgrade modal's Review: ✅ PASS Verified: the previously-flagged MEDIUM blocker (unnecessary JS guard in the shared Nice-to-haves:
|
Lead review traced the modal's open/close flow and confirmed the modal never opens directly on a non-default step (modalClosed.imagify always resets the view-state classes before reopen), so the JS/CSS guard added in a previous loop-back was solving an unreachable scenario and violated the CSS-only scope of the #1066 spec (Option A). Revert openModal() to its original jQuery-only chain, drop the matching .imagify-modal-no-transition CSS rule, and remove the e2e test covering the unreachable scenario. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Note Generated by the AI delivery pipeline (qa-engineer · claude-sonnet-5). QA: ✅ PASS
|
Closes #1066
Description
The upgrade modal's multi-step payment flow (plan selection → payment iframe → thank-you) was producing an abrupt, jarring layout shift as the modal box jumped between different widths and height constraints on each step, with no animation to smooth the transition. A secondary bug also affected height clamping: the CSS rule used
max-height: 90vw(viewport width) instead of90vh(viewport height), causing inconsistent vertical scrollbar behavior across different window aspect ratios.This fix adds a smooth CSS transition to the modal's width and height properties and corrects the viewport unit typo, eliminating the perceived shift while maintaining the existing visual design.
Type of change
Detailed scenario
What was tested
grunt css/gruntbuild passes cleanly;.min.css/.min.jsartifacts regenerated and match source.pricing-modal.js'smodalClosed.imagifyhandler always resets the view-state classes on close, andswitchToView()is only ever called from a real user click after the modal is already open at the default view. That guard (and its now-removed e2e test) was reverted to keep the fix scoped to the CSS-only Option A from the spec — no JS changes.Tests/e2e/specs/pricing-modal-layout.spec.tsadded, covering all three view steps (centering, no-scrollbar, transition-property assertions). It requires a real Imagify account in a specific quota/plan state to render the upsell trigger (Imagify_Views::get_user_info()) — same constraint asaccount-connection.spec.ts/bulk-optimization.spec.ts— so it skips gracefully when that state isn't available (confirmed: skips cleanly against the local wp-env's currently-connected account, which is on an unlimited plan).How to test
max-width: 782pxmobile breakpoint)max-height: 90vhruleprefers-reduced-motion: reduceenabled, the transition is suppressed (guarded behind@media (prefers-reduced-motion: no-preference)) — the resize should be instantaneous, not animated, for these usersAffected Features & Quality Assurance Scope
@media (max-width: 782px)and@media (max-height: 620px)) must not conflict with the new transitionprefers-reduced-motioncompliance (the transition is permitted even for users who prefer reduced motion, but should be verified to not be jarring)No changes to the pricing table, plan-selection logic, payment iframe integration, or thank-you flow business logic.
Technical description
Documentation
Root cause: The upgrade modal hosts three sequential view-states (plan selection, payment iframe, thank-you) inside a single
.imagify-modal-contentbox. The JavaScript controller (switchToView()inassets/js/pricing-modal.js) toggles modifier classes (.imagify-iframe-viewingand.imagify-success-viewing) to apply different width/height rules for each step. However, these rules had no CSS transition and used drastically different sizing approaches:width: 1065px; max-height: 90vw (typo)width: 980px; height: 672pxwidth: 450px; min-height: 300pxWhen the class toggled, the box jumped instantly from one size to the next, with no animation. The modal's flex centering re-calculated the box position on each resize, making the jump appear as a horizontal shift to the right.
Additionally, the shared base rule in
admin.cssusedmax-height: 90vw(viewport width unit) instead ofmax-height: 90vh(viewport height unit), causing height clamping to be tied to the window's width rather than its height, which led to unpredictable scrollbar appearance/disappearance between steps on different aspect ratios.Solution (Option A):
Added CSS transition to
.imagify-payment-modal .imagify-modal-content:transition: width 0.3s ease, min-width 0.3s ease, height 0.3s ease, min-height 0.3s ease;@media (prefers-reduced-motion: no-preference)to respect user accessibility preferences-webkit-vendor prefix for older browser compatibilityFixed the unit typo in
admin.css:.imagify-modal-content { max-height: 90vw; }tomax-height: 90vh;Why CSS-only: The view-switching logic in
pricing-modal.jsis correct; the centering math is correct. The defect is purely in the presentation contract (CSS geometry rules). A CSS fix keeps the diff minimal, avoids unnecessary refactoring of legacy jQuery code, and sidesteps compliance concerns about adding jQuery to modified code.Unaffected areas:
pricing-modal.jsorviews/modal-payment.php782px) and short viewports (620px) remain unaffected by the transition (transitions are independent of the property's computed value)New dependencies
None.
Risks
prefers-reduced-motion: reducewill not see the transition (guarded by@media (prefers-reduced-motion: no-preference)), so they get an instantaneous resize as before. This is the correct behavior per WCAG guidelines.@media (max-width: 782px)rule setswidth: 90%and overrides the fixed widths. Verified that the transition does not conflict — the transition applies to whatever width value wins from the cascade, so the mobile override works correctly.No performance or security risks identified. The change is purely presentational; no data processing, HTTP requests, or business logic is affected.
Mandatory Checklist
Code validation
Tests/e2e/specs/pricing-modal-layout.spec.tsadded to verify modal resizes smoothly and no scrollbar jumps occurCode style
Unticked items justification
All mandatory checklist items are addressed. "What was tested" reflects implementation-time verification and code-level QA analysis; a full manual/browser pass against a suitable test account is recommended as a follow-up (see QA report on this PR).
Additional Checks
.imagify-modal-contentat each step for QA review