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) + }) + } } }