-
-
Notifications
You must be signed in to change notification settings - Fork 8.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(custom-elemen): ce
support child component style tags and attribute settings
#7942
Conversation
# 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, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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