Skip to content

Commit

Permalink
feat(custom-element): useHost() helper
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Aug 8, 2024
1 parent e044b6e commit 775103a
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 13 deletions.
23 changes: 19 additions & 4 deletions packages/runtime-dom/__tests__/customElement.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
ref,
render,
renderSlot,
useHost,
useShadowRoot,
} from '../src'

Expand Down Expand Up @@ -975,8 +976,22 @@ describe('defineCustomElement', () => {
})
})

describe('useShadowRoot', () => {
test('should work for style injection', () => {
describe('helpers', () => {
test('useHost', () => {
const Foo = defineCustomElement({
setup() {
const host = useHost()!
host.setAttribute('id', 'host')
return () => h('div', 'hello')
},
})
customElements.define('my-el-use-host', Foo)
container.innerHTML = `<my-el-use-host>`
const el = container.childNodes[0] as VueElement
expect(el.id).toBe('host')
})

test('useShadowRoot for style injection', () => {
const Foo = defineCustomElement({
setup() {
const root = useShadowRoot()!
Expand All @@ -986,8 +1001,8 @@ describe('defineCustomElement', () => {
return () => h('div', 'hello')
},
})
customElements.define('my-el', Foo)
container.innerHTML = `<my-el></my-el>`
customElements.define('my-el-use-shadow-root', Foo)
container.innerHTML = `<my-el-use-shadow-root>`
const el = container.childNodes[0] as VueElement
const style = el.shadowRoot?.querySelector('style')!
expect(style.textContent).toBe(`div { color: red; }`)
Expand Down
25 changes: 16 additions & 9 deletions packages/runtime-dom/src/apiCustomElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -653,24 +653,31 @@ export class VueElement
}
}

/**
* Retrieve the shadowRoot of the current custom element. Only usable in setup()
* of a `defineCustomElement` component.
*/
export function useShadowRoot(): ShadowRoot | null {
export function useHost(caller?: string): VueElement | null {
const instance = getCurrentInstance()
const el = instance && instance.ce
const el = instance && (instance.ce as VueElement)
if (el) {
return (el as VueElement).shadowRoot
return el
} else if (__DEV__) {
if (!instance) {
warn(`useShadowRoot called without an active component instance.`)
warn(
`${caller || 'useHost'} called without an active component instance.`,
)
} else {
warn(
`useShadowRoot can only be used in components defined via ` +
`${caller || 'useHost'} can only be used in components defined via ` +
`defineCustomElement.`,
)
}
}
return null
}

/**
* Retrieve the shadowRoot of the current custom element. Only usable in setup()
* of a `defineCustomElement` component.
*/
export function useShadowRoot(): ShadowRoot | null {
const el = __DEV__ ? useHost('useShadowRoot') : useHost()
return el && el.shadowRoot
}
1 change: 1 addition & 0 deletions packages/runtime-dom/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ export {
defineCustomElement,
defineSSRCustomElement,
useShadowRoot,
useHost,
VueElement,
type VueElementConstructor,
type CustomElementOptions,
Expand Down

0 comments on commit 775103a

Please # to comment.