diff --git a/patches/@stencil__vue-output-target.patch b/patches/@stencil__vue-output-target.patch new file mode 100644 index 00000000000..ce6ff67a590 --- /dev/null +++ b/patches/@stencil__vue-output-target.patch @@ -0,0 +1,60 @@ +diff --git a/dist/runtime.cjs.js b/dist/runtime.cjs.js +index 8d1b57d4d3581b3681075b35380659f969469f35..29c3763e94e90ce26043aae72ac927eeef91881c 100644 +--- a/dist/runtime.cjs.js ++++ b/dist/runtime.cjs.js +@@ -119,7 +119,7 @@ const ARIA_PROP_PREFIX = 'aria'; + const EMPTY_PROP = Symbol(); + const DEFAULT_EMPTY_PROP = { default: EMPTY_PROP }; + const getComponentClasses = (classes) => { +- return classes?.split(' ') || []; ++ return (classes?.split(' ') || []).filter(Boolean); + }; + const syncElementClasses = (ref, componentClasses, defaultClasses = []) => { + if (ref?.value) { +@@ -258,9 +258,14 @@ const defineContainer = (name, defineCustomElement, componentProps = [], emitPro + }; + return () => { + modelPropValue = props[modelProp]; +- getComponentClasses(attrs.class).forEach((value) => { +- classes.add(value); ++ const nextClasses = new Set(getComponentClasses(attrs.class)); ++ classes.forEach((value) => { ++ if (!nextClasses.has(value)) { ++ containerRef.value?.classList.remove(value); ++ } + }); ++ classes.clear(); ++ nextClasses.forEach((value) => classes.add(value)); + // @ts-expect-error + const oldClick = props.onClick; + const handleClick = (ev) => { +diff --git a/dist/runtime.js b/dist/runtime.js +index 7efe4d9bba43a0533f2d3f6d17d5ed6f816ee04e..b483fcbde01193a76869b9a2c96b48685ad9db92 100644 +--- a/dist/runtime.js ++++ b/dist/runtime.js +@@ -117,7 +117,7 @@ const ARIA_PROP_PREFIX = 'aria'; + const EMPTY_PROP = Symbol(); + const DEFAULT_EMPTY_PROP = { default: EMPTY_PROP }; + const getComponentClasses = (classes) => { +- return classes?.split(' ') || []; ++ return (classes?.split(' ') || []).filter(Boolean); + }; + const syncElementClasses = (ref, componentClasses, defaultClasses = []) => { + if (ref?.value) { +@@ -256,9 +256,14 @@ const defineContainer = (name, defineCustomElement, componentProps = [], emitPro + }; + return () => { + modelPropValue = props[modelProp]; +- getComponentClasses(attrs.class).forEach((value) => { +- classes.add(value); ++ const nextClasses = new Set(getComponentClasses(attrs.class)); ++ classes.forEach((value) => { ++ if (!nextClasses.has(value)) { ++ containerRef.value?.classList.remove(value); ++ } + }); ++ classes.clear(); ++ nextClasses.forEach((value) => classes.add(value)); + // @ts-expect-error + const oldClick = props.onClick; + const handleClick = (ev) => { diff --git a/patches/README.md b/patches/README.md index 00930a42346..9c55c4866fb 100644 --- a/patches/README.md +++ b/patches/README.md @@ -1,4 +1,15 @@ -# Stencil Core Patch +# Stencil Patches + +## Vue Output Target + +`@stencil__vue-output-target.patch` reconciles reactive Vue class bindings in +the generated component runtime. Without the patch, classes are added when a +binding becomes active but are not removed when the binding becomes inactive. + +The patch updates both the ESM and CommonJS runtime bundles and should be +removed after the fix is available in an upstream release. + +## Stencil Core ## Why This Patch Exists diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c792b443da5..c08ddfef214 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -42,6 +42,9 @@ patchedDependencies: '@stencil/core': hash: 5b7b26f1b6644ca4134fe78af13f89b6653dffeffd2c09206b7c9402d0470193 path: patches/@stencil__core.patch + '@stencil/vue-output-target': + hash: 0e5caf71fd3bee7feda1df62521b377f447706f712e9c967844010a9ec63a417 + path: patches/@stencil__vue-output-target.patch importers: @@ -493,7 +496,7 @@ importers: version: 1.11.3(@playwright/test@1.58.1)(@stencil/core@4.43.5(patch_hash=5b7b26f1b6644ca4134fe78af13f89b6653dffeffd2c09206b7c9402d0470193))(happy-dom@20.4.0)(jsdom@25.0.1)(vitest@4.1.4(@types/node@20.16.5)(happy-dom@20.4.0)(jsdom@25.0.1)(msw@2.10.2(@types/node@20.16.5)(typescript@5.4.5))(vite@8.0.10(@types/node@20.16.5)(esbuild@0.27.2)(jiti@2.6.1)(less@4.3.0)(sass-embedded@1.93.0)(sass@1.93.0)(terser@5.48.0)(tsx@4.20.5)(yaml@2.9.0))) '@stencil/vue-output-target': specifier: ^0.13.2 - version: 0.13.2(@stencil/core@4.43.5(patch_hash=5b7b26f1b6644ca4134fe78af13f89b6653dffeffd2c09206b7c9402d0470193))(vue@3.5.17(typescript@5.4.5)) + version: 0.13.2(patch_hash=0e5caf71fd3bee7feda1df62521b377f447706f712e9c967844010a9ec63a417)(@stencil/core@4.43.5(patch_hash=5b7b26f1b6644ca4134fe78af13f89b6653dffeffd2c09206b7c9402d0470193))(vue@3.5.17(typescript@5.4.5)) '@testing-library/dom': specifier: ^10.4.0 version: 10.4.0 @@ -1153,7 +1156,7 @@ importers: version: 3.4.0 '@stencil/vue-output-target': specifier: ^0.13.2 - version: 0.13.2(@stencil/core@4.43.5(patch_hash=5b7b26f1b6644ca4134fe78af13f89b6653dffeffd2c09206b7c9402d0470193))(vue@3.5.17(typescript@5.8.3)) + version: 0.13.2(patch_hash=0e5caf71fd3bee7feda1df62521b377f447706f712e9c967844010a9ec63a417)(@stencil/core@4.43.5(patch_hash=5b7b26f1b6644ca4134fe78af13f89b6653dffeffd2c09206b7c9402d0470193))(vue@3.5.17(typescript@5.8.3)) devDependencies: '@testing-library/vue': specifier: ^8.1.0 @@ -16795,13 +16798,13 @@ snapshots: happy-dom: 20.4.0 jsdom: 25.0.1 - '@stencil/vue-output-target@0.13.2(@stencil/core@4.43.5(patch_hash=5b7b26f1b6644ca4134fe78af13f89b6653dffeffd2c09206b7c9402d0470193))(vue@3.5.17(typescript@5.4.5))': + '@stencil/vue-output-target@0.13.2(patch_hash=0e5caf71fd3bee7feda1df62521b377f447706f712e9c967844010a9ec63a417)(@stencil/core@4.43.5(patch_hash=5b7b26f1b6644ca4134fe78af13f89b6653dffeffd2c09206b7c9402d0470193))(vue@3.5.17(typescript@5.4.5))': dependencies: vue: 3.5.17(typescript@5.4.5) optionalDependencies: '@stencil/core': 4.43.5(patch_hash=5b7b26f1b6644ca4134fe78af13f89b6653dffeffd2c09206b7c9402d0470193) - '@stencil/vue-output-target@0.13.2(@stencil/core@4.43.5(patch_hash=5b7b26f1b6644ca4134fe78af13f89b6653dffeffd2c09206b7c9402d0470193))(vue@3.5.17(typescript@5.8.3))': + '@stencil/vue-output-target@0.13.2(patch_hash=0e5caf71fd3bee7feda1df62521b377f447706f712e9c967844010a9ec63a417)(@stencil/core@4.43.5(patch_hash=5b7b26f1b6644ca4134fe78af13f89b6653dffeffd2c09206b7c9402d0470193))(vue@3.5.17(typescript@5.8.3))': dependencies: vue: 3.5.17(typescript@5.8.3) optionalDependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index b51c98b8dbc..196d5479879 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -25,3 +25,4 @@ overrides: patchedDependencies: '@stencil/core': "patches/@stencil__core.patch" + '@stencil/vue-output-target': "patches/@stencil__vue-output-target.patch"