From 6655f2c5d2d873f0bed4bf45220d185bb8a189a8 Mon Sep 17 00:00:00 2001 From: Paolo Ricciuti Date: Thu, 6 Jun 2024 21:58:18 +0200 Subject: [PATCH] feat: better dynamic component css props (#11792) * feat: better dynamic component css props * chore: fix tests * chore: remove anchor from `$.component` * chore: better old test fixing * changeset --------- Co-authored-by: Rich Harris --- .changeset/smart-spiders-fetch.md | 5 +++ .../3-transform/client/visitors/template.js | 37 ++++++++++++------- .../client/dom/blocks/svelte-component.js | 3 +- .../_config.js | 2 +- .../_config.js | 2 +- .../_config.js | 3 +- 6 files changed, 32 insertions(+), 20 deletions(-) create mode 100644 .changeset/smart-spiders-fetch.md diff --git a/.changeset/smart-spiders-fetch.md b/.changeset/smart-spiders-fetch.md new file mode 100644 index 0000000000..d931681cba --- /dev/null +++ b/.changeset/smart-spiders-fetch.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +feat: always create wrapper `
` for `` with CSS custom properties diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js index 195f064864..519423a5ce 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js @@ -916,6 +916,27 @@ function serialize_inline_component(node, component_name, context) { ); } + if (node.type === 'SvelteComponent') { + const prev = fn; + fn = (node_id) => { + let component = b.call( + '$.component', + b.thunk(/** @type {import('estree').Expression} */ (context.visit(node.expression))), + b.arrow( + [b.id(component_name)], + b.block([ + b.stmt( + context.state.options.dev + ? b.call('$.validate_dynamic_component', b.thunk(prev(node_id))) + : prev(node_id) + ) + ]) + ) + ); + return component; + }; + } + if (Object.keys(custom_css_props).length > 0) { const prev = fn; fn = (node_id) => @@ -2938,7 +2959,6 @@ export const template_visitors = { b.stmt( b.call( '$.component', - context.state.node, // TODO use untrack here to not update when binding changes? // Would align with Svelte 4 behavior, but it's arguably nicer/expected to update this b.thunk( @@ -2962,19 +2982,8 @@ export const template_visitors = { context.state.template.push(''); let component = serialize_inline_component(node, '$$component', context); - if (context.state.options.dev) { - component = b.stmt(b.call('$.validate_dynamic_component', b.thunk(b.block([component])))); - } - context.state.init.push( - b.stmt( - b.call( - '$.component', - context.state.node, - b.thunk(/** @type {import('estree').Expression} */ (context.visit(node.expression))), - b.arrow([b.id('$$component')], b.block([component])) - ) - ) - ); + + context.state.init.push(component); }, Attribute(node, context) { if (is_event_attribute(node)) { diff --git a/packages/svelte/src/internal/client/dom/blocks/svelte-component.js b/packages/svelte/src/internal/client/dom/blocks/svelte-component.js index f96e91d1ec..8487852b35 100644 --- a/packages/svelte/src/internal/client/dom/blocks/svelte-component.js +++ b/packages/svelte/src/internal/client/dom/blocks/svelte-component.js @@ -5,12 +5,11 @@ import { block, branch, pause_effect } from '../../reactivity/effects.js'; /** * @template P * @template {(props: P) => void} C - * @param {Comment} anchor * @param {() => C} get_component * @param {(component: C) => import('#client').Dom | void} render_fn * @returns {void} */ -export function component(anchor, get_component, render_fn) { +export function component(get_component, render_fn) { /** @type {C} */ let component; diff --git a/packages/svelte/tests/runtime-browser/samples/svelte-component-css-custom-properties/_config.js b/packages/svelte/tests/runtime-browser/samples/svelte-component-css-custom-properties/_config.js index 90bbb46a0a..4f82db0a05 100644 --- a/packages/svelte/tests/runtime-browser/samples/svelte-component-css-custom-properties/_config.js +++ b/packages/svelte/tests/runtime-browser/samples/svelte-component-css-custom-properties/_config.js @@ -61,7 +61,7 @@ export default test({ component.componentName = 'Slider2'; assert_slider_2(); component.componentName = undefined; - assert.equal(window.document.querySelector('div'), null); + assert.equal(window.document.querySelector('div')?.firstElementChild, null); component.componentName = 'Slider1'; assert_slider_1(); } diff --git a/packages/svelte/tests/runtime-browser/samples/svelte-component-css-custom-properties2/_config.js b/packages/svelte/tests/runtime-browser/samples/svelte-component-css-custom-properties2/_config.js index 0d49af8931..09f725bb3d 100644 --- a/packages/svelte/tests/runtime-browser/samples/svelte-component-css-custom-properties2/_config.js +++ b/packages/svelte/tests/runtime-browser/samples/svelte-component-css-custom-properties2/_config.js @@ -63,7 +63,7 @@ export default test({ component.componentName = 'Slider2'; assert_slider_2(); component.componentName = undefined; - assert.equal(window.document.querySelector('div'), null); + assert.equal(window.document.querySelector('div')?.firstElementChild, null); component.componentName = 'Slider1'; assert_slider_1(); } diff --git a/packages/svelte/tests/runtime-browser/samples/svelte-self-css-custom-properties2/_config.js b/packages/svelte/tests/runtime-browser/samples/svelte-self-css-custom-properties2/_config.js index e921666aed..a7d8c1bc38 100644 --- a/packages/svelte/tests/runtime-browser/samples/svelte-self-css-custom-properties2/_config.js +++ b/packages/svelte/tests/runtime-browser/samples/svelte-self-css-custom-properties2/_config.js @@ -35,7 +35,6 @@ export default test({ const nest_track_color1 = target.querySelector('#nest-component1 span'); const nest_rail_color2 = target.querySelector('#nest-component2 p'); const nest_track_color2 = target.querySelector('#nest-component2 span'); - assert_ok(rail_color1); assert_ok(track_color1); assert_ok(rail_color2); @@ -96,7 +95,7 @@ export default test({ component.componentName = 'Slider2'; assert_slider_2(); component.componentName = undefined; - assert.equal(window.document.querySelector('div'), null); + assert.equal(window.document.querySelector('div')?.firstElementChild, null); component.componentName = 'Slider1'; assert_slider_1(); }