9
9
KEY_BLOCK ,
10
10
ROOT_BLOCK
11
11
} from './block.js' ;
12
- import { destroy_each_item_block } from './each.js' ;
12
+ import { destroy_each_item_block , get_first_element } from './each.js' ;
13
13
import { append_child } from './operations.js' ;
14
14
import { empty } from './render.js' ;
15
15
import {
@@ -21,6 +21,7 @@ import {
21
21
managed_effect ,
22
22
managed_pre_effect ,
23
23
mark_subtree_inert ,
24
+ schedule_task ,
24
25
untrack
25
26
} from './runtime.js' ;
26
27
import { raf } from './timing.js' ;
@@ -411,13 +412,13 @@ function is_transition_block(block) {
411
412
/**
412
413
* @template P
413
414
* @param {HTMLElement } dom
414
- * @param {import('./types.js').TransitionFn<P | undefined> | import('./types.js').AnimateFn<P | undefined> } transition_fn
415
+ * @param {() => import('./types.js').TransitionFn<P | undefined> | import('./types.js').AnimateFn<P | undefined> } get_transition_fn
415
416
* @param {(() => P) | null } props_fn
416
417
* @param {'in' | 'out' | 'both' | 'key' } direction
417
418
* @param {boolean } global
418
419
* @returns {void }
419
420
*/
420
- export function bind_transition ( dom , transition_fn , props_fn , direction , global ) {
421
+ export function bind_transition ( dom , get_transition_fn , props_fn , direction , global ) {
421
422
const transition_effect = /** @type {import('./types.js').EffectSignal } */ ( current_effect ) ;
422
423
const block = current_block ;
423
424
const props = props_fn === null ? { } : props_fn ( ) ;
@@ -432,6 +433,7 @@ export function bind_transition(dom, transition_fn, props_fn, direction, global)
432
433
if ( transition_block . t === EACH_ITEM_BLOCK ) {
433
434
// Lazily apply the each block transition
434
435
transition_block . r = each_item_transition ;
436
+ transition_block . a = each_item_animate ;
435
437
transition_block = transition_block . p ;
436
438
} else if ( transition_block . t === AWAIT_BLOCK && transition_block . n /* pending */ ) {
437
439
can_show_intro_on_mount = false ;
@@ -458,6 +460,11 @@ export function bind_transition(dom, transition_fn, props_fn, direction, global)
458
460
let transition ;
459
461
460
462
effect ( ( ) => {
463
+ if ( transition !== undefined ) {
464
+ // Destroy any existing transitions first
465
+ transition . x ( ) ;
466
+ }
467
+ const transition_fn = get_transition_fn ( ) ;
461
468
/** @param {DOMRect } [from] */
462
469
const init = ( from ) =>
463
470
untrack ( ( ) =>
@@ -641,3 +648,31 @@ function each_item_transition(transition) {
641
648
} ) ;
642
649
transitions . add ( transition ) ;
643
650
}
651
+
652
+ /**
653
+ *
654
+ * @param {import('./types.js').EachItemBlock } block
655
+ * @param {Set<import('./types.js').Transition> } transitions
656
+ * @param {number } index
657
+ * @param {boolean } index_is_reactive
658
+ */
659
+ function each_item_animate ( block , transitions , index , index_is_reactive ) {
660
+ let prev_index = block . i ;
661
+ if ( index_is_reactive ) {
662
+ prev_index = /** @type {import('./types.js').Signal<number> } */ ( prev_index ) . v ;
663
+ }
664
+ const items = block . p . v ;
665
+ if ( prev_index !== index && /** @type {number } */ ( index ) < items . length ) {
666
+ const from_dom = /** @type {Element } */ ( get_first_element ( block ) ) ;
667
+ const from = from_dom . getBoundingClientRect ( ) ;
668
+ // Cancel any existing key transitions
669
+ for ( const transition of transitions ) {
670
+ if ( transition . r === 'key' ) {
671
+ transition . c ( ) ;
672
+ }
673
+ }
674
+ schedule_task ( ( ) => {
675
+ trigger_transitions ( transitions , 'key' , from ) ;
676
+ } ) ;
677
+ }
678
+ }
0 commit comments