From c54c1946da497063a45a7236fe4886813d0df638 Mon Sep 17 00:00:00 2001 From: Ryan Christian Date: Fri, 24 Oct 2025 23:32:04 -0500 Subject: [PATCH 1/3] revert: Silly broken code --- package-lock.json | 10 +++++++++- src/index.js | 10 ++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5532c4a..4f18682 100644 --- a/package-lock.json +++ b/package-lock.json @@ -137,6 +137,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.10.tgz", "integrity": "sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw==", "dev": true, + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.22.10", @@ -4083,6 +4084,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true, + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -4719,6 +4721,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001517", "electron-to-chromium": "^1.4.477", @@ -5606,7 +5609,8 @@ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1475386.tgz", "integrity": "sha512-RQ809ykTfJ+dgj9bftdeL2vRVxASAuGU+I9LEx9Ij5TXU5HrgAQVmzi72VA+mkzscE12uzlRv5/tWWv9R9J1SA==", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "peer": true }, "node_modules/diff": { "version": "5.1.0", @@ -6062,6 +6066,7 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "dev": true, + "peer": true, "dependencies": { "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.4.3", @@ -9522,6 +9527,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", @@ -10595,6 +10601,7 @@ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", "dev": true, + "peer": true, "bin": { "rollup": "dist/bin/rollup" }, @@ -11915,6 +11922,7 @@ "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/src/index.js b/src/index.js index 1ae5828..c38ef48 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,4 @@ -import { h, cloneElement, render, hydrate, Fragment } from 'preact'; +import { h, cloneElement, render, hydrate } from 'preact'; /** * @typedef {import('./internal.d.ts').PreactCustomElement} PreactCustomElement @@ -177,8 +177,7 @@ function Slot(props, context) { } } }; - const { useFragment, ...rest } = props; - return h(useFragment ? Fragment : 'slot', { ...rest, ref }); + return h('slot', { ...props, ref }); } function toVdom(element, nodeName, options) { @@ -210,9 +209,8 @@ function toVdom(element, nodeName, options) { const shadow = !!(options && options.shadow); // Only wrap the topmost node with a slot - const wrappedChildren = nodeName - ? h(Slot, { useFragment: !shadow }, children) - : children; + const wrappedChildren = + nodeName && shadow ? h(Slot, null, children) : children; if (!shadow && nodeName) { element.innerHTML = ''; From fea5e4b1b6df02d7952e46131b6043f251d56b7a Mon Sep 17 00:00:00 2001 From: Ryan Christian Date: Sat, 25 Oct 2025 01:00:29 -0500 Subject: [PATCH 2/3] test: Add (failing) test case --- test/browser/index.test.jsx | 40 +++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/test/browser/index.test.jsx b/test/browser/index.test.jsx index 494900b..7e12777 100644 --- a/test/browser/index.test.jsx +++ b/test/browser/index.test.jsx @@ -344,5 +344,45 @@ describe('web components', () => { }); assert.equal(getShadowHTML(), '

Active theme: sunny

'); }); + + it.only('passes context over light DOM custom element boundaries', async () => { + const Theme = createContext('light'); + + function DisplayTheme() { + const theme = useContext(Theme); + return

Active theme: {theme}

; + } + + function Parent({ children, theme = 'dark' }) { + return ( + +
{children}
+
+ ); + } + + registerElement(Parent, 'x-light-dom-parent', ['theme']); + registerElement(DisplayTheme, 'x-light-dom-child', []); + + const el = document.createElement('x-light-dom-parent'); + + const noSlot = document.createElement('x-light-dom-child'); + el.appendChild(noSlot); + + root.appendChild(el); + assert.equal( + root.innerHTML, + '

Active theme: dark

' + ); + + // Trigger context update + act(() => { + el.setAttribute('theme', 'sunny'); + }); + assert.equal( + root.innerHTML, + '

Active theme: sunny

' + ); + }); }); }); From 42f3ea90914046d24a333a726797488f16345ec8 Mon Sep 17 00:00:00 2001 From: Ryan Christian Date: Tue, 25 Nov 2025 23:06:26 -0600 Subject: [PATCH 3/3] test: Add a couple of test cases --- test/browser/index.test.jsx | 70 +++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/test/browser/index.test.jsx b/test/browser/index.test.jsx index 7e12777..931c3c2 100644 --- a/test/browser/index.test.jsx +++ b/test/browser/index.test.jsx @@ -280,11 +280,40 @@ describe('web components', () => { ); }); + it('supports controlling light DOM with other custom elements', () => { + function Parent({ children }) { + return ( + +

Light DOM Children

+
{children}
+
+ ); + } + + function Child() { + return

Child

; + } + + registerElement(Parent, 'light-dom-children-parent', []); + registerElement(Child, 'light-dom-children-child', []); + + const parent = document.createElement('light-dom-children-parent'); + const child = document.createElement('light-dom-children-child'); + + parent.appendChild(child); + root.appendChild(parent); + + assert.equal( + document.querySelector('light-dom-children-parent').innerHTML, + '

Light DOM Children

Child

' + ); + }); + it('supports controlling shadow DOM children', () => { function ShadowDomChildren({ children }) { return ( -

Light DOM Children

+

Shadow DOM Children

{children}
); @@ -298,8 +327,45 @@ describe('web components', () => { assert.equal( document.querySelector('shadow-dom-children').shadowRoot.innerHTML, - '

Light DOM Children

Child 1

Child 2

' + '

Shadow DOM Children

Child 1

Child 2

' + ); + }); + + it('supports controlling shadow DOM with other custom elements', () => { + function Parent({ children }) { + return ( + +

Shadow DOM Children

+
{children}
+
+ ); + } + + function Child() { + return

Child

; + } + + registerElement(Parent, 'shadow-dom-children-parent', [], { + shadow: true, + }); + registerElement(Child, 'shadow-dom-children-child', [], { + shadow: true, + }); + + const parent = document.createElement('shadow-dom-children-parent'); + const child = document.createElement('shadow-dom-children-child'); + + parent.appendChild(child); + root.appendChild(parent); + + const getShadowHTML = (selector) => + document.querySelector(selector).shadowRoot.innerHTML; + + assert.equal( + getShadowHTML('shadow-dom-children-parent'), + '

Shadow DOM Children

' ); + assert.equal(getShadowHTML('shadow-dom-children-child'), '

Child

'); }); });