Skip to content

Commit

Permalink
fix(custom-element): fix parent resolving issue when slotted in shado…
Browse files Browse the repository at this point in the history
…w dom (#12479)
  • Loading branch information
lejunyang committed Nov 27, 2024
1 parent 5a5406d commit fce4707
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
25 changes: 25 additions & 0 deletions packages/runtime-dom/__tests__/customElement.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,31 @@ describe('defineCustomElement', () => {
`<div>changedA! changedB!</div>`,
)
})

test('should resolve correct parent when element is slotted in shadow DOM', async () => {
const GrandParent = defineCustomElement({
provide: {
foo: ref('GrandParent'),
},
render() {
return h('my-parent-in-shadow', h('slot'))
},
})
const Parent = defineCustomElement({
provide: {
foo: ref('Parent'),
},
render() {
return h('slot')
},
})
customElements.define('my-grand-parent', GrandParent)
customElements.define('my-parent-in-shadow', Parent)
container.innerHTML = `<my-grand-parent><my-consumer></my-consumer></my-grand-parent>`
const grandParent = container.childNodes[0] as VueElement,
consumer = grandParent.firstElementChild as VueElement
expect(consumer.shadowRoot!.textContent).toBe('Parent')
})
})

describe('styles', () => {
Expand Down
7 changes: 6 additions & 1 deletion packages/runtime-dom/src/apiCustomElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,12 @@ export class VueElement
// locate nearest Vue custom element parent for provide/inject
let parent: Node | null = this
while (
(parent = parent && (parent.parentNode || (parent as ShadowRoot).host))
(parent =
parent &&
// #12479 should check assignedSlot first to get correct parent
((parent as Element).assignedSlot ||
parent.parentNode ||
(parent as ShadowRoot).host))
) {
if (parent instanceof VueElement) {
this._parent = parent
Expand Down

0 comments on commit fce4707

Please sign in to comment.