]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat(runtime-dom): support specifying shadow dom styles in defineCustomElement
authorEvan You <yyx990803@gmail.com>
Thu, 22 Jul 2021 20:33:32 +0000 (16:33 -0400)
committerEvan You <yyx990803@gmail.com>
Thu, 22 Jul 2021 20:33:32 +0000 (16:33 -0400)
packages/runtime-dom/__tests__/customElement.spec.ts
packages/runtime-dom/src/apiCustomElement.ts

index 6d210a3125d2c08c29f5e4b916d2a96467f71983..1729129b1bb28786cf95cd4c0e03e5193695f33f 100644 (file)
@@ -274,4 +274,20 @@ describe('defineCustomElement', () => {
       expect(consumer.shadowRoot!.innerHTML).toBe(`<div>changed!</div>`)
     })
   })
+
+  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 = `<my-el-with-styles></my-el-with-styles>`
+      const el = container.childNodes[0] as VueElement
+      const style = el.shadowRoot?.querySelector('style')!
+      expect(style.textContent).toBe(`div { color: red; }`)
+    })
+  })
 })
index 5de2ca9c564b3f3b2a776b29a212eb6c0f0a25cf..adbeb7608b5a03e6f8ffa603476efa1373f0d524 100644 (file)
@@ -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<Props>
 
 // 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<ExtractPropTypes<PropsOptions>>
 
 // 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)
+        })
+      }
     }
   }