feat(custom-elemen): ce support child component style tags and attribute settings#7942
feat(custom-elemen): ce support child component style tags and attribute settings#7942baiwusanyu-c wants to merge 94 commits intovuejs:mainfrom
ce support child component style tags and attribute settings#7942Conversation
# Conflicts: # packages/compiler-core/src/transforms/vIf.ts # packages/compiler-core/src/utils.ts
# Conflicts: # packages/runtime-dom/src/apiCustomElement.ts # pnpm-lock.yaml
# Conflicts: # packages/runtime-dom/src/apiCustomElement.ts # pnpm-lock.yaml
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎ 1 Ignored Deployment
|
|
Works similarly well as #6610 and solves #4662. ( With this PR, under some circumstances, the style tags are duplicated, see for example:
Edit:
Probably all the same underlying issue, if I had to guess. |
|
Hello @LinusBorg , Could you please look at this PR and decide if that's a valid fix for #4662 once you have some time? Thank you so much, |
johnp
left a comment
There was a problem hiding this comment.
Here are the issues as tests (expect the possible style grouping issue):
test('nested child components w/ fragments in shadow dom should have styles', async () => {
const GrandChild = {
styles: [`.my-green { color: green; }`],
render() {
return h('p', { class: "my-green" }, "This should be green")
}
}
const Child = {
components: { GrandChild },
styles: [`.my-blue { color: blue; }`],
render() {
return h('div', {}, [
h('p', { class: "my-blue" }, "This should be blue"),
h('div', {}, h(GrandChild))
])
}
}
const Foo = defineCustomElement({
components: { Child },
styles: [`.my-red { color: red; }`],
render() {
return [
h('p', { class: "my-red" }, "This should be red"),
h(Child)
]
}
})
customElements.define('my-el-with-grandchild-styles', Foo)
container.innerHTML = `<my-el-with-grandchild-styles></my-el-with-grandchild-styles>`
await nextTick()
const el = container.childNodes[0] as VueElement
const style = el.shadowRoot?.querySelectorAll('style')!
expect(style.length).toBe(3)
expect(style[0].textContent).toBe(`.my-red { color: red; }`)
expect(style[1].textContent).toBe(`.my-blue { color: blue; }`)
expect(style[2].textContent).toBe(`.my-green { color: green; }`)
})
test('deeply nested child components w/ fragments in shadow dom should have styles', async () => {
const GreatGrandChild = {
styles: [`.my-grey { color: grey; }`],
render() {
return h('p', { class: "my-grey" }, "This should be grey")
}
}
const GrandChild = {
components: { GreatGrandChild },
styles: [`.my-green { color: green; }`],
render() {
return [
h('p', { class: "my-green" }, "This should be green"),
h('span', {}, h(GreatGrandChild))
]
}
}
const Child = {
components: { GrandChild },
styles: [`.my-blue { color: blue; }`],
render() {
return h('div', {}, [
h('p', { class: "my-blue" }, "This should be blue"),
h('div', {}, h(GrandChild))
])
}
}
const Foo = defineCustomElement({
components: { Child },
styles: [`.my-red { color: red; }`],
render() {
return [
h('p', { class: "my-red" }, "This should be red"),
h(Child)
]
}
})
customElements.define('my-el-with-greatgrandchild-styles', Foo)
container.innerHTML = `<my-el-with-greatgrandchild-styles></my-el-with-greatgrandchild-styles>`
await nextTick()
const el = container.childNodes[0] as VueElement
const style = el.shadowRoot?.querySelectorAll('style')!
expect(style.length).toBe(4)
expect(style[0].textContent).toBe(`.my-red { color: red; }`)
expect(style[1].textContent).toBe(`.my-blue { color: blue; }`)
expect(style[2].textContent).toBe(`.my-green { color: green; }`)
expect(style[3].textContent).toBe(`.my-grey { color: grey; }`)
})# Conflicts: # pnpm-lock.yaml
# Conflicts: # packages/compiler-sfc/src/parse.ts
|
Can this be merged? |
CodSpeed Performance ReportMerging #7942 will not alter performanceComparing Summary
|
|
Shadow DOM should support |
# Conflicts: # packages/compiler-sfc/src/compileScript.ts # packages/compiler-sfc/src/parse.ts # packages/compiler-sfc/src/script/normalScript.ts # packages/compiler-sfc/src/style/cssVars.ts # packages/runtime-core/src/renderer.ts # packages/runtime-dom/__tests__/customElement.spec.ts
|
I've been following this PR and thank you for your hard work so much. However, does the |
|
Hello everyone ✋ I have a simpler solution for those who want to bootstrap their vue app inside a shadowRoot: here is a simple vitejs plugin that will inject all styles using the adoptedStylesheets API. |
|
ping @LinusBorg |
|
@yyx990803 please 😭😭 |
| // TODO unit test | ||
|
|
||
| /* | ||
| const __sfc__ = {}; | ||
| import { openBlock as _openBlock, createElementBlock as _createElementBlock, defineCustomElement as _defineCustomElement } from "vue" | ||
| function render(_ctx, _cache) { | ||
| return (_openBlock(), _createElementBlock("h1", null, " app ")) | ||
| } | ||
| __sfc__.render = render | ||
| __sfc__.__file = "src/App.vue" | ||
| export default customElements.define(name, _defineCustomElement(constructor), options); | ||
| */ | ||
|
|
||
| // :id="{ id: msg3, 'other-attr': msg }" | ||
| // id="{ id: msg3, 'other-attr': msg }" | ||
| // .id="{ id: msg3, 'other-attr': msg }" | ||
| // v-bind:src="msg2s" | ||
| // v-bind:[msg]="msg2" | ||
| // :[msg]="msg2" | ||
| // :xlink:special="msg3" |
There was a problem hiding this comment.
question (if-minor): should this be removed or enabled? Like now it looks like temporary outcommented code that might never be worked on in the future, if not worked on now.
This PR contains two parts.
Based on the existing CE style implementation design, cooperate with
plugin-vue(using the styles attribute provided by the compiler) to implement CE's sub-component style injection.close: #7941
close: #4662
close: #6530
more: vuejs/rfcs#596