[fix] Local transitions from #key blocks (#7286)

* fix: Local transitions from #key blocks

When adding `|local` to a transition inside a {#key} block, only the outro was triggered not the intro.

This PR fixes #5950

* add test case

Co-authored-by: tanhauhau <lhtan93@gmail.com>
pull/7467/head
Bob Fanger 2 years ago committed by GitHub
parent 09b5afc8fe
commit 0b0221de99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,7 +1,6 @@
import Wrapper from './shared/Wrapper';
import Renderer from '../Renderer';
import Block from '../Block';
import EachBlock from '../../nodes/EachBlock';
import KeyBlock from '../../nodes/KeyBlock';
import create_debugging_comment from './shared/create_debugging_comment';
import FragmentWrapper from './Fragment';
@ -19,7 +18,7 @@ export default class KeyBlockWrapper extends Wrapper {
renderer: Renderer,
block: Block,
parent: Wrapper,
node: EachBlock,
node: KeyBlock,
strip_whitespace: boolean,
next_sibling: Wrapper
) {
@ -107,7 +106,7 @@ export default class KeyBlockWrapper extends Wrapper {
}
${this.var} = ${this.block.name}(#ctx);
${this.var}.c();
${has_transitions && b`@transition_in(${this.var})`}
${has_transitions && b`@transition_in(${this.var}, 1)`}
${this.var}.m(${this.get_update_mount_node(anchor)}, ${anchor});
`;

@ -0,0 +1,37 @@
export default {
props: {
x: false,
y: 1
},
test({ assert, component, target, raf }) {
component.x = true;
let div = target.querySelector('div');
assert.equal(div.foo, undefined);
// play both in and out transition when changed with `{#key}`
component.y = 2;
assert.htmlEqual(target.innerHTML, '<div></div><div></div>');
const [leaving, incoming] = target.querySelectorAll('div');
raf.tick(50);
assert.equal(leaving.foo, 0.5);
assert.equal(incoming.foo, 0.5);
raf.tick(100);
assert.htmlEqual(target.innerHTML, '<div></div>');
assert.equal(leaving.foo, 0);
assert.equal(incoming.foo, 1);
// do not play out transition when removed by `{#if}`
component.x = false;
assert.htmlEqual(target.innerHTML, '');
// do not play in transition when added back with `{#if}`
component.x = true;
assert.htmlEqual(target.innerHTML, '<div></div>');
div = target.querySelector('div');
assert.equal(div.foo, undefined);
}
};

@ -0,0 +1,19 @@
<script>
export let x;
export let y;
function foo(node, _params) {
return {
duration: 100,
tick: t => {
node.foo = t;
}
};
}
</script>
{#if x}
{#key y}
<div transition:foo|local></div>
{/key}
{/if}
Loading…
Cancel
Save