diff --git a/shared-internals/src/index.d.ts b/shared-internals/src/index.d.ts index d83ff38a43..378c18ac37 100644 --- a/shared-internals/src/index.d.ts +++ b/shared-internals/src/index.d.ts @@ -7,6 +7,9 @@ export function getChildren( vnode: preact.VNode ): Array; export function getComponentVNode(component: preact.Component): preact.VNode; +export function getContainerVNode( + container: Element | Document | ShadowRoot | DocumentFragment +): preact.VNode | null; // // Option hooks diff --git a/shared-internals/src/index.js b/shared-internals/src/index.js index 69b7a08338..8453cac170 100644 --- a/shared-internals/src/index.js +++ b/shared-internals/src/index.js @@ -48,6 +48,17 @@ export function getComponentVNode(component) { return component._vnode; } +/** + * Return the `VNode` that is associated with a DOM node that was rendered into. + * This property only exists on root nodes, commonly called containers. They + * are created via top-level `render(vnode, container)` calls. + * @param {Element | Document | ShadowRoot | DocumentFragment} container + * @returns {import('../../src/internal').VNode | null} + */ +export function getContainerVNode(container) { + return container._children; +} + // Options getters/setters /** diff --git a/shared-internals/test/browser/internals.test.js b/shared-internals/test/browser/internals.test.js index 38a473d1dc..6aff9e6cc2 100644 --- a/shared-internals/test/browser/internals.test.js +++ b/shared-internals/test/browser/internals.test.js @@ -1,4 +1,11 @@ -import { createElement, render, Component, createRef, options } from 'preact'; +import { + createElement, + render, + Component, + createRef, + options, + Fragment +} from 'preact'; import { setupScratch, teardown } from '../../../test/_util/helpers'; import { getParent, @@ -6,6 +13,7 @@ import { getDom, getChildren, getComponentVNode, + getContainerVNode, getOptionsDiff, getOptionsCommit, getOptionsRoot, @@ -109,6 +117,17 @@ describe('shared-internals', () => { }); }); + describe('getContainerVNode', () => { + it('should return undefined', () => { + expect(getContainerVNode(scratch)).to.equal(undefined); + }); + + it('should return root Fragment vnode', () => { + render(
, scratch); + expect(getContainerVNode(scratch).type).to.equal(Fragment); + }); + }); + describe('options', () => { let prevDiff; let prevCommit;