diff --git a/src/generators/server-side-rendering/index.ts b/src/generators/server-side-rendering/index.ts index 662ce21be2..9419bde3d5 100644 --- a/src/generators/server-side-rendering/index.ts +++ b/src/generators/server-side-rendering/index.ts @@ -12,6 +12,8 @@ export class SsrGenerator extends Generator { bindings: string[]; renderCode: string; elementDepth: number; // TODO is this necessary? appears to be unused + appendTargets: Record | null; + appendTarget: string | null; constructor( parsed: Parsed, @@ -24,6 +26,7 @@ export class SsrGenerator extends Generator { this.bindings = []; this.renderCode = ''; this.elementDepth = 0; + this.appendTargets = null; // in an SSR context, we don't need to include events, methods, oncreate or ondestroy const { templateProperties, defaultExport } = this; @@ -59,7 +62,23 @@ export class SsrGenerator extends Generator { } append(code: string) { - this.renderCode += code; + if (this.appendTarget) { + this.appendTargets[this.appendTarget] += code; + } else { + this.renderCode += code; + } + } + + removeAppendTarget() { + this.appendTarget = this.appendTargets = null; + } + + setAppendTarget(name: string) { + if (!this.appendTargets[name]) { + this.appendTargets[name] = ''; + } + + this.appendTarget = name; } } diff --git a/src/generators/server-side-rendering/visitors/Component.ts b/src/generators/server-side-rendering/visitors/Component.ts index 3922717e15..eb3dbf4f14 100644 --- a/src/generators/server-side-rendering/visitors/Component.ts +++ b/src/generators/server-side-rendering/visitors/Component.ts @@ -80,19 +80,25 @@ export default function visitComponent( let open = `\${${expression}.render({${props}}`; if (node.children.length) { - open += `, { slotted: { default: () => \``; - } + generator.appendTargets = {}; + generator.setAppendTarget('default'); - generator.append(open); + generator.elementDepth += 1; - generator.elementDepth += 1; + node.children.forEach((child: Node) => { + visit(generator, block, child); + }); - node.children.forEach((child: Node) => { - visit(generator, block, child); - }); + generator.elementDepth -= 1; - generator.elementDepth -= 1; + const slotted = Object.keys(generator.appendTargets) + .map(name => `${name}: () => \`${generator.appendTargets[name]}\``) + .join(', '); - const close = node.children.length ? `\` } })}` : ')}'; - generator.append(close); + open += `, { slotted: { ${slotted} } }`; + generator.setAppendTarget(null); + } + + generator.append(open); + generator.append(')}'); } diff --git a/src/generators/server-side-rendering/visitors/Element.ts b/src/generators/server-side-rendering/visitors/Element.ts index 1f9388eaf9..7d2ba15030 100644 --- a/src/generators/server-side-rendering/visitors/Element.ts +++ b/src/generators/server-side-rendering/visitors/Element.ts @@ -47,6 +47,11 @@ export default function visitElement( let openingTag = `<${node.name}`; let textareaContents; // awkward special case + const slot = node.attributes.find((attribute: Node) => attribute.name === 'slot'); + if (slot) { + generator.setAppendTarget(slot.value[0].data); + } + node.attributes.forEach((attribute: Node) => { if (attribute.type !== 'Attribute') return; diff --git a/src/generators/server-side-rendering/visitors/Slot.ts b/src/generators/server-side-rendering/visitors/Slot.ts index a622814d1a..8288b283fe 100644 --- a/src/generators/server-side-rendering/visitors/Slot.ts +++ b/src/generators/server-side-rendering/visitors/Slot.ts @@ -9,7 +9,11 @@ export default function visitSlot( node: Node ) { // TODO named slots - generator.append(`\${options && options.slotted && options.slotted.default ? options.slotted.default() : '`); + const name = node.attributes.find((attribute: Node) => attribute.name); + const slotName = name && name.value[0].data || 'default'; + + generator.append(``); + generator.append(`\${options && options.slotted && options.slotted.${slotName} ? options.slotted.${slotName}() : '`); generator.elementDepth += 1; diff --git a/test/runtime/samples/component-slot-named/_config.js b/test/runtime/samples/component-slot-named/_config.js index 17b59a1bd4..b4d803a5d8 100644 --- a/test/runtime/samples/component-slot-named/_config.js +++ b/test/runtime/samples/component-slot-named/_config.js @@ -1,5 +1,4 @@ export default { - solo: true, html: `
Hello