diff --git a/compat/src/portals.js b/compat/src/portals.js index ddbcdbd0dd..c480a3d3a3 100644 --- a/compat/src/portals.js +++ b/compat/src/portals.js @@ -40,13 +40,14 @@ function Portal(props) { parentNode: container, childNodes: [], contains: () => true, + // Technically this isn't needed appendChild(child) { this.childNodes.push(child); _this._container.appendChild(child); }, insertBefore(child, before) { this.childNodes.push(child); - _this._container.appendChild(child); + _this._container.insertBefore(child, before); }, removeChild(child) { this.childNodes.splice(this.childNodes.indexOf(child) >>> 1, 1); diff --git a/compat/test/browser/portals.test.js b/compat/test/browser/portals.test.js index 7f5f9b166e..93f7ffbc2d 100644 --- a/compat/test/browser/portals.test.js +++ b/compat/test/browser/portals.test.js @@ -4,7 +4,8 @@ import React, { createPortal, useState, Component, - useEffect + useEffect, + Fragment } from 'preact/compat'; import { setupScratch, teardown } from '../../../test/_util/helpers'; import { setupRerender, act } from 'preact/test-utils'; @@ -64,6 +65,35 @@ describe('Portal', () => { expect(scratch.innerHTML).to.equal('

Hello

'); }); + it('should order portal children well', () => { + let bump; + + function Modal() { + const [state, setState] = useState(0); + bump = () => setState(() => 1); + + return ( + + {state === 1 &&
top
} +
middle
+
bottom
+
+ ); + } + + function Foo(props) { + return createPortal(, scratch); + } + render(, scratch); + expect(scratch.innerHTML).to.equal('
middle
bottom
'); + + bump(); + rerender(); + expect(scratch.innerHTML).to.equal( + '
top
middle
bottom
' + ); + }); + it('should toggle the portal', () => { let toggle;