@@ -267,6 +267,13 @@ export function ComposerMorph<T extends { key: string }>(props: {
267267 ) ,
268268 )
269269
270+ // A face that turns instant mid-flight lands at once.
271+ createEffect ( ( ) => {
272+ const list = untrack ( faces )
273+
274+ if ( stop && list . some ( ( item ) => props . instant ?.( item . value ( ) ) ) ) settle ( list )
275+ } )
276+
270277 onCleanup ( observeReducedMotion ( ( ) => prefersReducedMotion ( ) && stop && settle ( untrack ( faces ) ) ) )
271278 onCleanup ( ( ) => stop ?.( ) )
272279
@@ -357,6 +364,16 @@ export function Grow<T>(props: {
357364 let el : HTMLDivElement | undefined
358365 let entering = ! ! props . when && ! ! props . appear
359366
367+ const closed = ( ) => {
368+ setPresent ( false )
369+ props . onClosed ?.( )
370+ }
371+
372+ // Turning instant mid-grow finishes the grow where it was going.
373+ createEffect ( ( ) => {
374+ if ( props . instant && el ) growing . get ( el ) ?. end ?.( )
375+ } )
376+
360377 createEffect (
361378 on (
362379 ( ) => [ ! ! props . when , present ( ) ] as const ,
@@ -370,18 +387,22 @@ export function Grow<T>(props: {
370387 if ( ! el || ( ! entering && ( ! prev || prev [ 0 ] === when ) ) ) return
371388 entering = false
372389
373- if ( props . instant && ! growing . has ( el ) ) {
374- if ( when ) return
390+ if ( props . instant ) {
391+ const current = growing . get ( el )
392+
393+ if ( current ) {
394+ current . open = when
395+ current . done = closed
375396
376- setPresent ( false )
397+ return current . end ?.( )
398+ }
377399
378- return props . onClosed ?.( )
400+ if ( when ) return
401+
402+ return closed ( )
379403 }
380404
381- grow ( el , when , props . fade , props . card , props . close ?.( ) , ( ) => {
382- setPresent ( false )
383- props . onClosed ?.( )
384- } )
405+ grow ( el , when , props . fade , props . card , props . close ?.( ) , closed )
385406 } ,
386407 ) ,
387408 )
@@ -409,7 +430,9 @@ export function Grow<T>(props: {
409430 )
410431}
411432
412- const growing = new WeakMap < HTMLElement , { spring : Spring ; presence : Spring ; open : boolean ; done ?: ( ) => void } > ( )
433+ type Growth = { spring : Spring ; presence : Spring ; open : boolean ; done ?: ( ) => void ; end ?: ( ) => void }
434+
435+ const growing = new WeakMap < HTMLElement , Growth > ( )
413436
414437function grow (
415438 el : HTMLElement ,
@@ -436,7 +459,7 @@ function grow(
436459 const prevMb =
437460 ( ! mb && el . previousElementSibling ? parseFloat ( getComputedStyle ( el . previousElementSibling ) . marginBottom ) : 0 ) || 0
438461
439- const state = {
462+ const state : Growth = {
440463 spring : Spring . fromDuration (
441464 open ? 0 : el . getBoundingClientRect ( ) . height ,
442465 reduced ? fade : open ? morph ( ) : ( close ?? morph ( ) ) ,
@@ -475,7 +498,8 @@ function grow(
475498 } )
476499
477500 if ( child ) observer . observe ( child )
478- frameLoop . add ( ( dt ) => {
501+
502+ const stop = frameLoop . add ( ( dt ) => {
479503 if ( ! el . isConnected ) {
480504 observer . disconnect ( )
481505 growing . delete ( el )
@@ -527,6 +551,13 @@ function grow(
527551
528552 return true
529553 } )
554+
555+ state . end = ( ) => {
556+ stop ( )
557+ observer . disconnect ( )
558+ growing . delete ( el )
559+ finish ( el , state . open , state . done )
560+ }
530561}
531562
532563function finish ( el : HTMLElement , open : boolean , done ?: ( ) => void ) {
0 commit comments