Skip to content

Commit a7fa4ac

Browse files
committed
feat(runtime-dom): support specifying shadow dom styles in defineCustomElement
1 parent f0ca233 commit a7fa4ac

File tree

2 files changed

+29
-6
lines changed

2 files changed

+29
-6
lines changed

packages/runtime-dom/__tests__/customElement.spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,4 +274,20 @@ describe('defineCustomElement', () => {
274274
expect(consumer.shadowRoot!.innerHTML).toBe(`<div>changed!</div>`)
275275
})
276276
})
277+
278+
describe('styles', () => {
279+
test('should attach styles to shadow dom', () => {
280+
const Foo = defineCustomElement({
281+
styles: [`div { color: red; }`],
282+
render() {
283+
return h('div', 'hello')
284+
}
285+
})
286+
customElements.define('my-el-with-styles', Foo)
287+
container.innerHTML = `<my-el-with-styles></my-el-with-styles>`
288+
const el = container.childNodes[0] as VueElement
289+
const style = el.shadowRoot?.querySelector('style')!
290+
expect(style.textContent).toBe(`div { color: red; }`)
291+
})
292+
})
277293
})

packages/runtime-dom/src/apiCustomElement.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import {
2-
Component,
32
ComponentOptionsMixin,
43
ComponentOptionsWithArrayProps,
54
ComponentOptionsWithObjectProps,
@@ -18,7 +17,8 @@ import {
1817
createVNode,
1918
defineComponent,
2019
nextTick,
21-
warn
20+
warn,
21+
ComponentOptions
2222
} from '@vue/runtime-core'
2323
import { camelize, extend, hyphenate, isArray, toNumber } from '@vue/shared'
2424
import { hydrate, render } from '.'
@@ -60,7 +60,7 @@ export function defineCustomElement<
6060
Extends,
6161
E,
6262
EE
63-
>
63+
> & { styles?: string[] }
6464
): VueElementConstructor<Props>
6565

6666
// overload 3: object format with array props declaration
@@ -85,7 +85,7 @@ export function defineCustomElement<
8585
Extends,
8686
E,
8787
EE
88-
>
88+
> & { styles?: string[] }
8989
): VueElementConstructor<{ [K in PropNames]: any }>
9090

9191
// overload 4: object format with object props declaration
@@ -110,7 +110,7 @@ export function defineCustomElement<
110110
Extends,
111111
E,
112112
EE
113-
>
113+
> & { styles?: string[] }
114114
): VueElementConstructor<ExtractPropTypes<PropsOptions>>
115115

116116
// overload 5: defining a custom element from the returned value of
@@ -176,7 +176,7 @@ export class VueElement extends BaseClass {
176176
_connected = false
177177

178178
constructor(
179-
private _def: Component,
179+
private _def: ComponentOptions & { styles?: string[] },
180180
private _attrKeys: string[],
181181
private _propKeys: string[],
182182
hydrate?: RootHydrateFunction
@@ -192,6 +192,13 @@ export class VueElement extends BaseClass {
192192
)
193193
}
194194
this.attachShadow({ mode: 'open' })
195+
if (_def.styles) {
196+
_def.styles.forEach(css => {
197+
const s = document.createElement('style')
198+
s.textContent = css
199+
this.shadowRoot!.appendChild(s)
200+
})
201+
}
195202
}
196203
}
197204

0 commit comments

Comments
 (0)