diff --git a/src/index.js b/src/index.js index d1da970..f45ef79 100644 --- a/src/index.js +++ b/src/index.js @@ -53,9 +53,21 @@ function toVdom(element, nodeName) { a = element.attributes, cn = element.childNodes; for (i = a.length; i--; ) { - props[a[i].name] = a[i].value; - props[toCamelCase(a[i].name)] = a[i].value; - } - for (i = cn.length; i--; ) children[i] = toVdom(cn[i]); + if (a[i].name !== 'slot') { + props[a[i].name] = a[i].value; + props[toCamelCase(a[i].name)] = a[i].value; + } + } + + for (i = cn.length; i--; ) { + const vnode = toVdom(cn[i]); + // Move slots correctly + const name = cn[i].slot; + if (name) { + props[name] = h('slot', { name }, vnode); + } else { + children[i] = vnode; + } + } return h(nodeName || element.nodeName.toLowerCase(), props, children); } diff --git a/src/index.test.js b/src/index.test.js index 289f5f6..602ebf5 100644 --- a/src/index.test.js +++ b/src/index.test.js @@ -31,6 +31,44 @@ it('renders ok, updates on attr change', () => { document.body.removeChild(root); }); +function Foo({ text, children }) { + return ( + +
{children}
+
{text}
+
+ ); +} + +registerElement(Foo, 'x-foo', [], { shadow: true }); + +it('renders slots as props with shadow DOM', () => { + const root = document.createElement('div'); + const el = document.createElement('x-foo'); + + // here is a slot + const slot = document.createElement('span'); + slot.textContent = 'here is a slot'; + slot.slot = 'text'; + el.appendChild(slot); + + //
no slot
+ const noSlot = document.createElement('div'); + noSlot.textContent = 'no slot'; + el.appendChild(noSlot); + el.appendChild(slot); + + root.appendChild(el); + document.body.appendChild(root); + + assert.equal(root.innerHTML, '
no slot
here is a slot
'); + + const shadowHTML = document.querySelector('x-foo').shadowRoot.innerHTML; + assert.equal(shadowHTML, '
no slot
here is a slot
'); + + document.body.removeChild(root); +}); + const kebabName = 'custom-date-long-name'; const camelName = 'customDateLongName'; const lowerName = camelName.toLowerCase();