diff --git a/demo/src/native-ui-shell-transition.spec.ts b/demo/src/native-ui-shell-transition.spec.ts index ccb180751..4bc6e577f 100644 --- a/demo/src/native-ui-shell-transition.spec.ts +++ b/demo/src/native-ui-shell-transition.spec.ts @@ -57,10 +57,10 @@ const fixture = () => { return { animation, calls, ready, finish: (step: 0 | 1) => finish(step, animation) }; }; -test('normal transition waits for native suspension', async () => { +test('play starts before native suspension settles', async () => { const { animation, calls, ready } = fixture(); const played = animation.play(); - expect(calls).toEqual([]); + expect(calls).toEqual(['play']); ready(); await played; expect(calls).toEqual(['play', 'resume:false']); @@ -87,7 +87,7 @@ test('destroy during bridge preparation cannot start an abandoned transition', a animation.destroy(); ready(); await played; - expect(calls).toEqual(['destroy', 'resume:true']); + expect(calls).toEqual(['play', 'destroy', 'resume:true']); }); test('without native enablement the animation remains untouched', () => { diff --git a/packages/theme-ios27/src/transition/native-ui.ts b/packages/theme-ios27/src/transition/native-ui.ts index 4898ba90c..bc89054e3 100644 --- a/packages/theme-ios27/src/transition/native-ui.ts +++ b/packages/theme-ios27/src/transition/native-ui.ts @@ -56,11 +56,14 @@ export const connectNativeUIShellTransition = (animation: Animation, entering: H }; animation.onFinish((step) => finish(step === 0)); animation.play = async (options) => { - await prepare(); + // Overlap suspend with the slide. Awaiting it first retires native chrome while the page is still + // at rest, which flashes Web for a frame before the slide starts. + const ready = prepare(); if (disposed) return; try { await play(options); } finally { + await ready; finish(); } };