diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts index 90cc22f5470..b849898d555 100644 --- a/packages/runtime-core/src/renderer.ts +++ b/packages/runtime-core/src/renderer.ts @@ -86,6 +86,7 @@ import { isAsyncWrapper } from './apiAsyncComponent' import { isCompatEnabled } from './compat/compatConfig' import { DeprecationTypes } from './compat/compatConfig' import type { TransitionHooks } from './components/BaseTransition' +import type { VueElement } from '@vue/runtime-dom' export interface Renderer { render: RootRenderFunction @@ -1348,7 +1349,10 @@ function baseCreateRenderer( } else { // custom element style injection if (root.ce) { - root.ce._injectChildStyle(type) + // @ts-expect-error _def is private + if ((root.ce as VueElement)._def.shadowRoot !== false) { + root.ce._injectChildStyle(type) + } } if (__DEV__) { diff --git a/packages/runtime-dom/__tests__/customElement.spec.ts b/packages/runtime-dom/__tests__/customElement.spec.ts index df438d47eee..45c51375c91 100644 --- a/packages/runtime-dom/__tests__/customElement.spec.ts +++ b/packages/runtime-dom/__tests__/customElement.spec.ts @@ -791,6 +791,30 @@ describe('defineCustomElement', () => { assertStyles(el, [`div { color: blue; }`, `div { color: red; }`]) }) + test("child components should not inject styles to root element's shadow root w/ shadowRoot false", async () => { + const Bar = defineComponent({ + styles: [`div { color: green; }`], + render() { + return 'bar' + }, + }) + const Baz = () => h(Bar) + const Foo = defineCustomElement( + { + render() { + return [h(Baz)] + }, + }, + { shadowRoot: false }, + ) + + customElements.define('my-foo-with-shadowroot-false', Foo) + container.innerHTML = `` + const el = container.childNodes[0] as VueElement + const style = el.shadowRoot?.querySelector('style') + expect(style).toBeUndefined() + }) + test('with nonce', () => { const Foo = defineCustomElement( {