From c0d884373b683bd16ff1adedf3cc66b806380fe4 Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Mon, 9 Sep 2024 13:03:02 +0200 Subject: [PATCH] fix: separate `template_effect` for dynamic class/style directive with dynamic attributes --- .changeset/nasty-eggs-walk.md | 5 ++++ .../client/visitors/shared/element.js | 12 +++++++-- .../_config.js | 23 ++++++++++++++++ .../main.svelte | 26 +++++++++++++++++++ 4 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 .changeset/nasty-eggs-walk.md create mode 100644 packages/svelte/tests/runtime-runes/samples/dynamic-attribute-and-attribute-directive/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/dynamic-attribute-and-attribute-directive/main.svelte diff --git a/.changeset/nasty-eggs-walk.md b/.changeset/nasty-eggs-walk.md new file mode 100644 index 0000000000..2e4b061dd5 --- /dev/null +++ b/.changeset/nasty-eggs-walk.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: separate `template_effect` for dynamic class/style directive with dynamic attributes diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/element.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/element.js index 5ac6d0afa0..09f95513e6 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/element.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/element.js @@ -46,7 +46,11 @@ export function build_style_directives( if (!is_attributes_reactive && has_call) { state.init.push(build_update(update)); } else if (is_attributes_reactive || has_state || has_call) { - state.update.push(update); + if (has_state || has_call) { + state.init.push(build_update(update)); + } else { + state.update.push(update); + } } else { state.init.push(update); } @@ -77,7 +81,11 @@ export function build_class_directives( if (!is_attributes_reactive && has_call) { state.init.push(build_update(update)); } else if (is_attributes_reactive || has_state || has_call) { - state.update.push(update); + if (has_state || has_call) { + state.init.push(build_update(update)); + } else { + state.update.push(update); + } } else { state.init.push(update); } diff --git a/packages/svelte/tests/runtime-runes/samples/dynamic-attribute-and-attribute-directive/_config.js b/packages/svelte/tests/runtime-runes/samples/dynamic-attribute-and-attribute-directive/_config.js new file mode 100644 index 0000000000..6d4a142ae0 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/dynamic-attribute-and-attribute-directive/_config.js @@ -0,0 +1,23 @@ +import { flushSync } from 'svelte'; +import { ok, test } from '../../test'; + +export default test({ + test({ target, logs, assert }) { + const [div, div2] = target.querySelectorAll('div'); + + const button = target.querySelector('button'); + ok(button); + + assert.deepEqual(logs, ['called', 'called']); + + // this is to assert that the order of the attributes is still not relevant + // and directives take precedence over generic attribute + assert.equal(div.classList.contains('dark'), false); + assert.equal(div2.style.color, 'red'); + + flushSync(() => { + button.click(); + }); + assert.deepEqual(logs, ['called', 'called']); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/dynamic-attribute-and-attribute-directive/main.svelte b/packages/svelte/tests/runtime-runes/samples/dynamic-attribute-and-attribute-directive/main.svelte new file mode 100644 index 0000000000..762f0b852e --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/dynamic-attribute-and-attribute-directive/main.svelte @@ -0,0 +1,26 @@ + + +
+
+ \ No newline at end of file