Skip to content

Commit 58b1540

Browse files
authored
fix: ensure transitions are applied to nested elements (#14080)
1 parent 0ed914b commit 58b1540

File tree

5 files changed

+62
-0
lines changed

5 files changed

+62
-0
lines changed

.changeset/modern-adults-lay.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: ensure transitions are applied to nested elements

packages/svelte/src/compiler/phases/2-analyze/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ import { SvelteWindow } from './visitors/SvelteWindow.js';
6363
import { TaggedTemplateExpression } from './visitors/TaggedTemplateExpression.js';
6464
import { Text } from './visitors/Text.js';
6565
import { TitleElement } from './visitors/TitleElement.js';
66+
import { TransitionDirective } from './visitors/TransitionDirective.js';
6667
import { UpdateExpression } from './visitors/UpdateExpression.js';
6768
import { UseDirective } from './visitors/UseDirective.js';
6869
import { VariableDeclarator } from './visitors/VariableDeclarator.js';
@@ -172,6 +173,7 @@ const visitors = {
172173
SvelteWindow,
173174
TaggedTemplateExpression,
174175
Text,
176+
TransitionDirective,
175177
TitleElement,
176178
UpdateExpression,
177179
UseDirective,
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/** @import { AST } from '#compiler' */
2+
/** @import { Context } from '../types' */
3+
4+
import { mark_subtree_dynamic } from './shared/fragment.js';
5+
6+
/**
7+
* @param {AST.TransitionDirective} node
8+
* @param {Context} context
9+
*/
10+
export function TransitionDirective(node, context) {
11+
mark_subtree_dynamic(context.path);
12+
13+
context.next();
14+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { flushSync } from '../../../../src/index-client.js';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
async test({ assert, raf, target }) {
6+
assert.htmlEqual(target.innerHTML, '<button>Toggle</button><div><span>123</span></div>');
7+
8+
const btn1 = target.querySelector('button');
9+
btn1?.click();
10+
flushSync();
11+
raf.tick(250);
12+
13+
assert.htmlEqual(
14+
target.innerHTML,
15+
'<button>Toggle</button><div><span style="opacity: 0.5;">123</span></div>'
16+
);
17+
18+
flushSync();
19+
raf.tick(500);
20+
21+
assert.htmlEqual(target.innerHTML, '<button>Toggle</button>');
22+
}
23+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<script>
2+
function fade(_) {
3+
return {
4+
duration: 500,
5+
css: t => `opacity: ${t}`,
6+
}
7+
}
8+
9+
let visible = $state(true);
10+
</script>
11+
12+
<button onclick={() => visible = !visible}>Toggle</button>
13+
14+
{#if visible}
15+
<div>
16+
<span transition:fade>123</span>
17+
</div>
18+
{/if}

0 commit comments

Comments
 (0)