mirror of
https://github.com/sveltejs/svelte.git
synced 2024-12-01 17:30:59 +01:00
server-side named slots
This commit is contained in:
parent
efe25555cf
commit
1ae3ab7bf9
@ -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<string, string> | 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.elementDepth += 1;
|
||||
|
||||
node.children.forEach((child: Node) => {
|
||||
visit(generator, block, child);
|
||||
});
|
||||
|
||||
generator.elementDepth -= 1;
|
||||
|
||||
const slotted = Object.keys(generator.appendTargets)
|
||||
.map(name => `${name}: () => \`${generator.appendTargets[name]}\``)
|
||||
.join(', ');
|
||||
|
||||
open += `, { slotted: { ${slotted} } }`;
|
||||
generator.setAppendTarget(null);
|
||||
}
|
||||
|
||||
generator.append(open);
|
||||
|
||||
generator.elementDepth += 1;
|
||||
|
||||
node.children.forEach((child: Node) => {
|
||||
visit(generator, block, child);
|
||||
});
|
||||
|
||||
generator.elementDepth -= 1;
|
||||
|
||||
const close = node.children.length ? `\` } })}` : ')}';
|
||||
generator.append(close);
|
||||
generator.append(')}');
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -9,7 +9,11 @@ export default function visitSlot(
|
||||
node: Node
|
||||
) {
|
||||
// TODO named slots
|
||||
generator.append(`<slot>\${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(`<slot${slotName !== 'default' ? ` name='${slotName}'` : ''}>`);
|
||||
generator.append(`\${options && options.slotted && options.slotted.${slotName} ? options.slotted.${slotName}() : '`);
|
||||
|
||||
generator.elementDepth += 1;
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
export default {
|
||||
solo: true,
|
||||
html: `
|
||||
<div>
|
||||
<slot>Hello</slot>
|
||||
|
Loading…
Reference in New Issue
Block a user