diff --git a/packages/runtime-dom/__tests__/customElement.spec.ts b/packages/runtime-dom/__tests__/customElement.spec.ts
index 6d210a312..1729129b1 100644
--- a/packages/runtime-dom/__tests__/customElement.spec.ts
+++ b/packages/runtime-dom/__tests__/customElement.spec.ts
@@ -274,4 +274,20 @@ describe('defineCustomElement', () => {
expect(consumer.shadowRoot!.innerHTML).toBe(`
changed!
`)
})
})
+
+ describe('styles', () => {
+ test('should attach styles to shadow dom', () => {
+ const Foo = defineCustomElement({
+ styles: [`div { color: red; }`],
+ render() {
+ return h('div', 'hello')
+ }
+ })
+ customElements.define('my-el-with-styles', Foo)
+ container.innerHTML = ``
+ const el = container.childNodes[0] as VueElement
+ const style = el.shadowRoot?.querySelector('style')!
+ expect(style.textContent).toBe(`div { color: red; }`)
+ })
+ })
})
diff --git a/packages/runtime-dom/src/apiCustomElement.ts b/packages/runtime-dom/src/apiCustomElement.ts
index 5de2ca9c5..adbeb7608 100644
--- a/packages/runtime-dom/src/apiCustomElement.ts
+++ b/packages/runtime-dom/src/apiCustomElement.ts
@@ -1,5 +1,4 @@
import {
- Component,
ComponentOptionsMixin,
ComponentOptionsWithArrayProps,
ComponentOptionsWithObjectProps,
@@ -18,7 +17,8 @@ import {
createVNode,
defineComponent,
nextTick,
- warn
+ warn,
+ ComponentOptions
} from '@vue/runtime-core'
import { camelize, extend, hyphenate, isArray, toNumber } from '@vue/shared'
import { hydrate, render } from '.'
@@ -60,7 +60,7 @@ export function defineCustomElement<
Extends,
E,
EE
- >
+ > & { styles?: string[] }
): VueElementConstructor
// overload 3: object format with array props declaration
@@ -85,7 +85,7 @@ export function defineCustomElement<
Extends,
E,
EE
- >
+ > & { styles?: string[] }
): VueElementConstructor<{ [K in PropNames]: any }>
// overload 4: object format with object props declaration
@@ -110,7 +110,7 @@ export function defineCustomElement<
Extends,
E,
EE
- >
+ > & { styles?: string[] }
): VueElementConstructor>
// overload 5: defining a custom element from the returned value of
@@ -176,7 +176,7 @@ export class VueElement extends BaseClass {
_connected = false
constructor(
- private _def: Component,
+ private _def: ComponentOptions & { styles?: string[] },
private _attrKeys: string[],
private _propKeys: string[],
hydrate?: RootHydrateFunction
@@ -192,6 +192,13 @@ export class VueElement extends BaseClass {
)
}
this.attachShadow({ mode: 'open' })
+ if (_def.styles) {
+ _def.styles.forEach(css => {
+ const s = document.createElement('style')
+ s.textContent = css
+ this.shadowRoot!.appendChild(s)
+ })
+ }
}
}