1
- import { h , cloneElement , render , hydrate } from 'preact' ;
1
+ import { h , cloneElement , render , hydrate , Fragment } from 'preact' ;
2
2
3
3
/**
4
4
* @typedef {import('./index.d.ts').PreactCustomElement } PreactCustomElement
@@ -26,7 +26,9 @@ export default function register(Component, tagName, propNames, options) {
26
26
}
27
27
PreactElement . prototype = Object . create ( HTMLElement . prototype ) ;
28
28
PreactElement . prototype . constructor = PreactElement ;
29
- PreactElement . prototype . connectedCallback = connectedCallback ;
29
+ PreactElement . prototype . connectedCallback = function ( ) {
30
+ connectedCallback . call ( this , options ) ;
31
+ } ;
30
32
PreactElement . prototype . attributeChangedCallback = attributeChangedCallback ;
31
33
PreactElement . prototype . disconnectedCallback = disconnectedCallback ;
32
34
@@ -89,7 +91,7 @@ function ContextProvider(props) {
89
91
/**
90
92
* @this {PreactCustomElement}
91
93
*/
92
- function connectedCallback ( ) {
94
+ function connectedCallback ( options ) {
93
95
// Obtain a reference to the previous context by pinging the nearest
94
96
// higher up node that was rendered with Preact. If one Preact component
95
97
// higher up receives our ping, it will set the `detail` property of
@@ -106,7 +108,7 @@ function connectedCallback() {
106
108
this . _vdom = h (
107
109
ContextProvider ,
108
110
{ ...this . _props , context } ,
109
- toVdom ( this , this . _vdomComponent )
111
+ toVdom ( this , this . _vdomComponent , options )
110
112
) ;
111
113
( this . hasAttribute ( 'hydrate' ) ? hydrate : render ) ( this . _vdom , this . _root ) ;
112
114
}
@@ -170,10 +172,11 @@ function Slot(props, context) {
170
172
}
171
173
}
172
174
} ;
173
- return h ( 'slot' , { ...props , ref } ) ;
175
+ const { useFragment, ...rest } = props ;
176
+ return h ( useFragment ? Fragment : 'slot' , { ...rest , ref } ) ;
174
177
}
175
178
176
- function toVdom ( element , nodeName ) {
179
+ function toVdom ( element , nodeName , options ) {
177
180
if ( element . nodeType === 3 ) return element . data ;
178
181
if ( element . nodeType !== 1 ) return null ;
179
182
let children = [ ] ,
@@ -189,7 +192,7 @@ function toVdom(element, nodeName) {
189
192
}
190
193
191
194
for ( i = cn . length ; i -- ; ) {
192
- const vnode = toVdom ( cn [ i ] , null ) ;
195
+ const vnode = toVdom ( cn [ i ] , null , options ) ;
193
196
// Move slots correctly
194
197
const name = cn [ i ] . slot ;
195
198
if ( name ) {
@@ -199,7 +202,15 @@ function toVdom(element, nodeName) {
199
202
}
200
203
}
201
204
205
+ const shadow = ! ! ( options && options . shadow ) ;
206
+
202
207
// Only wrap the topmost node with a slot
203
- const wrappedChildren = nodeName ? h ( Slot , null , children ) : children ;
208
+ const wrappedChildren = nodeName
209
+ ? h ( Slot , { useFragment : ! shadow } , children )
210
+ : children ;
211
+
212
+ if ( ! shadow && nodeName ) {
213
+ element . innerHTML = '' ;
214
+ }
204
215
return h ( nodeName || element . nodeName . toLowerCase ( ) , props , wrappedChildren ) ;
205
216
}
0 commit comments