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; }`)
+ })
+ })
})
import {
- Component,
ComponentOptionsMixin,
ComponentOptionsWithArrayProps,
ComponentOptionsWithObjectProps,
createVNode,
defineComponent,
nextTick,
- warn
+ warn,
+ ComponentOptions
} from '@vue/runtime-core'
import { camelize, extend, hyphenate, isArray, toNumber } from '@vue/shared'
import { hydrate, render } from '.'
Extends,
E,
EE
- >
+ > & { styles?: string[] }
): VueElementConstructor<Props>
// overload 3: object format with array props declaration
Extends,
E,
EE
- >
+ > & { styles?: string[] }
): VueElementConstructor<{ [K in PropNames]: any }>
// overload 4: object format with object props declaration
Extends,
E,
EE
- >
+ > & { styles?: string[] }
): VueElementConstructor<ExtractPropTypes<PropsOptions>>
// overload 5: defining a custom element from the returned value of
_connected = false
constructor(
- private _def: Component,
+ private _def: ComponentOptions & { styles?: string[] },
private _attrKeys: string[],
private _propKeys: string[],
hydrate?: RootHydrateFunction
)
}
this.attachShadow({ mode: 'open' })
+ if (_def.styles) {
+ _def.styles.forEach(css => {
+ const s = document.createElement('style')
+ s.textContent = css
+ this.shadowRoot!.appendChild(s)
+ })
+ }
}
}