From 2de24dd2efa1b3db9f5c2365ecb2ef1d9c3b3abf Mon Sep 17 00:00:00 2001
From: raffobaffo <37933664+raffobaffo@users.noreply.github.com>
Date: Mon, 27 Sep 2021 21:34:17 +0200
Subject: [PATCH 1/3] fix(customElementDependencyStyles): Recursively add
styles from imported components. Missing feature, store available styles to
avoid dupes. close #4662
---
.../__tests__/customElement.spec.ts | 43 ++++++++++++++++++
packages/runtime-dom/src/apiCustomElement.ts | 45 +++++++++++++++++--
2 files changed, 85 insertions(+), 3 deletions(-)
diff --git a/packages/runtime-dom/__tests__/customElement.spec.ts b/packages/runtime-dom/__tests__/customElement.spec.ts
index 7e69ec28ef2..a086b31a2f1 100644
--- a/packages/runtime-dom/__tests__/customElement.spec.ts
+++ b/packages/runtime-dom/__tests__/customElement.spec.ts
@@ -1,6 +1,7 @@
import {
defineAsyncComponent,
defineCustomElement,
+ defineComponent,
h,
inject,
nextTick,
@@ -314,6 +315,48 @@ describe('defineCustomElement', () => {
const style = el.shadowRoot?.querySelector('style')!
expect(style.textContent).toBe(`div { color: red; }`)
})
+
+ test('should attach styles of children components to shadow dom', () => {
+ const Bar = defineComponent({
+ styles: [`.green-color { color: green; }`],
+ render() {
+ return h(
+ 'h1',
+ {
+ attrs: { class: 'green-color' }
+ },
+ 'hello'
+ )
+ }
+ })
+ const Foo = defineComponent({
+ components: { Bar },
+ styles: [`.blue-back { color: blue; }`],
+ render() {
+ return h(
+ 'span',
+ {
+ attrs: { class: 'blue-back' }
+ },
+ ''
+ )
+ }
+ })
+
+ const FooBar = defineCustomElement({
+ components: { Foo },
+ styles: [`div { color: red; }`],
+ render() {
+ return h('div', '')
+ }
+ })
+ customElements.define('my-el-with-nested-styles', FooBar)
+ container.innerHTML = ``
+ const el = container.childNodes[0] as VueElement
+ const style = el.shadowRoot?.querySelectorAll('style')!
+ expect(style[0].textContent).toBe(`.green-color { color: green; }`)
+ expect(style[1].textContent).toBe(`.blue-back { color: blue; }`)
+ })
})
describe('async', () => {
diff --git a/packages/runtime-dom/src/apiCustomElement.ts b/packages/runtime-dom/src/apiCustomElement.ts
index f72b8765f6d..d0fdb9c09a9 100644
--- a/packages/runtime-dom/src/apiCustomElement.ts
+++ b/packages/runtime-dom/src/apiCustomElement.ts
@@ -19,7 +19,8 @@ import {
nextTick,
warn,
ConcreteComponent,
- ComponentOptions
+ ComponentOptions,
+ Component
} from '@vue/runtime-core'
import { camelize, extend, hyphenate, isArray, toNumber } from '@vue/shared'
import { hydrate, render } from '.'
@@ -215,7 +216,7 @@ export class VueElement extends BaseClass {
const resolve = (def: InnerComponentDef) => {
this._resolved = true
- const { props, styles } = def
+ const { props } = def
const hasOptions = !isArray(props)
const rawKeys = props ? (hasOptions ? Object.keys(props) : props) : []
@@ -252,7 +253,7 @@ export class VueElement extends BaseClass {
}
})
}
- this._applyStyles(styles)
+ this._applyStyles(this._getChildrenComponentsStyles(def))
}
const asyncDef = (this._def as ComponentOptions).__asyncLoader
@@ -367,4 +368,42 @@ export class VueElement extends BaseClass {
})
}
}
+
+ private _getChildrenComponentsStyles(
+ component: Component & {
+ components?: Record
+ styles?: string[]
+ }
+ ): string[] {
+ let componentStyles: string[] = []
+
+ if (component.components) {
+ componentStyles = Object.values(component.components).reduce(
+ (
+ aggregatedStyles: string[],
+ nestedComponent: Component & {
+ components?: Record
+ styles?: string[]
+ }
+ ) => {
+ if (nestedComponent?.components) {
+ aggregatedStyles = [
+ ...aggregatedStyles,
+ ...this._getChildrenComponentsStyles(nestedComponent)
+ ]
+ }
+ return nestedComponent.styles
+ ? [...aggregatedStyles, ...nestedComponent.styles]
+ : aggregatedStyles
+ },
+ [] as string[]
+ )
+ }
+
+ if (component.styles) {
+ componentStyles.push(...component.styles)
+ }
+
+ return componentStyles
+ }
}
From dd1362025af05d0d9628597c9a201ce75c48bd78 Mon Sep 17 00:00:00 2001
From: raffobaffo <37933664+raffobaffo@users.noreply.github.com>
Date: Tue, 28 Sep 2021 12:28:35 +0200
Subject: [PATCH 2/3] fix(customElementDependencyStyles): Recursively add
styles from imported components. Missing feature, store available styles to
avoid dupes. close #4662
---
packages/runtime-dom/__tests__/customElement.spec.ts | 3 +++
packages/runtime-dom/src/apiCustomElement.ts | 3 ++-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/packages/runtime-dom/__tests__/customElement.spec.ts b/packages/runtime-dom/__tests__/customElement.spec.ts
index a086b31a2f1..c374e6faca7 100644
--- a/packages/runtime-dom/__tests__/customElement.spec.ts
+++ b/packages/runtime-dom/__tests__/customElement.spec.ts
@@ -354,8 +354,11 @@ describe('defineCustomElement', () => {
container.innerHTML = ``
const el = container.childNodes[0] as VueElement
const style = el.shadowRoot?.querySelectorAll('style')!
+
+ expect(style.length).toBe(3)
expect(style[0].textContent).toBe(`.green-color { color: green; }`)
expect(style[1].textContent).toBe(`.blue-back { color: blue; }`)
+ expect(style[2].textContent).toBe(`div { color: red; }`)
})
})
diff --git a/packages/runtime-dom/src/apiCustomElement.ts b/packages/runtime-dom/src/apiCustomElement.ts
index d0fdb9c09a9..ef447990812 100644
--- a/packages/runtime-dom/src/apiCustomElement.ts
+++ b/packages/runtime-dom/src/apiCustomElement.ts
@@ -392,6 +392,7 @@ export class VueElement extends BaseClass {
...this._getChildrenComponentsStyles(nestedComponent)
]
}
+ // Should have a method that adds styles only if not existing
return nestedComponent.styles
? [...aggregatedStyles, ...nestedComponent.styles]
: aggregatedStyles
@@ -404,6 +405,6 @@ export class VueElement extends BaseClass {
componentStyles.push(...component.styles)
}
- return componentStyles
+ return [...new Set(componentStyles)]
}
}
From 2ee4ec71c59c659eb5a7546d2a94fe8d43ab1aeb Mon Sep 17 00:00:00 2001
From: raffobaffo <37933664+raffobaffo@users.noreply.github.com>
Date: Tue, 28 Sep 2021 12:33:08 +0200
Subject: [PATCH 3/3] fix(customElementDependencyStyles): Recursively add
styles from imported components. Missing feature, store available styles to
avoid dupes. close #4662
---
packages/runtime-dom/src/apiCustomElement.ts | 1 -
1 file changed, 1 deletion(-)
diff --git a/packages/runtime-dom/src/apiCustomElement.ts b/packages/runtime-dom/src/apiCustomElement.ts
index ef447990812..04174b4a648 100644
--- a/packages/runtime-dom/src/apiCustomElement.ts
+++ b/packages/runtime-dom/src/apiCustomElement.ts
@@ -392,7 +392,6 @@ export class VueElement extends BaseClass {
...this._getChildrenComponentsStyles(nestedComponent)
]
}
- // Should have a method that adds styles only if not existing
return nestedComponent.styles
? [...aggregatedStyles, ...nestedComponent.styles]
: aggregatedStyles