Skip to content

fix(native-ui): stabilize sheet modal dismissal handoff - #329

Merged
rdlabo merged 4 commits into
mainfrom
fix/modal-dismiss-handoff
Oct 24, 2026
Merged

rdlabo merged 4 commits into
mainfrom
fix/modal-dismiss-handoff

Conversation

@rdlabo

@rdlabo rdlabo commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Closing a sheet modal on iPhone Duo could flash the covered page twice: the moving modal kept refreshing native projection, and Ionic's paused sheet-backdrop gesture animation could become visible again during dismissal.

Retire native modal controls once at ionModalWillDismiss, leave the closing animation on the Web, and restore the underlying page projection after ionModalDidDismiss. Geometry refreshes after retirement no longer publish repeated native snapshots, and modal ownership changes use an immediate handoff.

For native vertical-bar sheets, release only Ionic's recognized dormant backdrop gesture effect after dismissal is accepted. Running/custom animations, ordinary Web sheets, and gesture-driven dismissal are left alone. This compatibility handling lives entirely in the library; no consuming-app or Ionic source changes are required.

Validation:

  • 128 related Vitest tests passed, including retirement during repeated frame changes and backdrop-animation exclusions.
  • Native UI TypeScript/package build passed.
  • Production Seatkeep build and iOS simulator build passed with the local library changes.
  • iPhone Duo: three open/close cycles passed; frame-by-frame recording confirmed the background no longer darkens again during fade-out and the double flash is gone.
  • XCTest still occasionally waits for its animation-idle notification; this change does not claim to resolve that separate automation behavior.

Additional Duo rail fixes (0bf0d50c):

  • Prevent the selected tab from briefly losing its rounded shape when native projection resumes after modal dismissal. A newly created native tab host was implicitly animating its initial selection layout, even though the Web fallback retained its measured 22px radius. Unanimated handoffs now disable SwiftUI transaction animations and resolve the initial UIKit layout inside UIView.performWithoutAnimation. Normal animated rail updates retain their existing behavior.
  • Preserve toolbar-button coordinates when the Web fallback group has a fractional border. clientLeft/clientTop round border widths to whole CSS pixels; the coordinate conversion now subtracts the computed border widths instead. This avoids the measured subpixel offset without changing button shapes.
  • Add regression coverage for groups with zero, fractional, and whole-pixel borders. These fixes are entirely in the library; no consuming-app implementation changes are included.

Additional validation:

  • 57 focused Vitest tests passed across rail geometry, modal handoff, and horizontal navigation.
  • Library build, consuming-app production build (npm run cap), npx cap update, and iOS simulator build passed.
  • Three modal open/close cycles passed on iPhone Duo. Frame-by-frame video comparison confirmed the selected tab retains its rounded shape during the return to native rendering.
  • The final build was installed and launched on iPhone Duo; the ledger and walk-in registration rail button passed the final XCTest check.
  • Independent follow-up review: 57 focused Web tests and 54 native snapshot tests passed; Chromium/WebKit checks confirmed coordinate alignment for zero and whole-pixel borders (desktop engines quantize the fractional-border case).

@github-actions

github-actions Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Playwright test results

passed  503 passed
flaky  1 flaky

Details

stats  504 tests across 26 suites
duration  4 minutes, 7 seconds
commit  0bf0d50
info  This detailed result covers Ionic 9 only. Ionic 8 runs against the same screenshots in a separate matrix job; check the workflow run for both results. To update the screenshots, comment with /update-screenshots.

Flaky tests

chromium › native-ui.spec.ts › Duo sheet modal sends one native presentation clock instead of moving frames

@github-actions

github-actions Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

📊 Ionic 9 Playwright Test Report

View the detailed Ionic 9 report after GitHub Pages deployment completes: https://rdlabo-dev.github.io/ionic-theme-ios27/pr-329/

Ionic 8 runs against the same screenshots in a separate matrix job. View both results in the workflow run.

@rdlabo
rdlabo merged commit e7b859f into main Oct 24, 2026
16 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

npm beta published

CI passed for the merge commit e7b859fee773. Install the immutable version with:

npm install @rdlabo/ionic-theme-ios27@2.0.3-beta.pr329.shae7b859fee773 @rdlabo/capacitor-native-ui@2.0.3-beta.pr329.shae7b859fee773

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.

1 participant