diff --git a/packages/adders/common.ts b/packages/adders/common.ts index b45d99cbb..d30781d4e 100644 --- a/packages/adders/common.ts +++ b/packages/adders/common.ts @@ -7,6 +7,7 @@ import { type AstKinds, type AstTypes } from '@svelte-cli/core/js'; +import * as html from '@svelte-cli/core/html'; import { Walker, type Question, type FileEditor } from '@svelte-cli/core'; import { parseScript } from '@svelte-cli/core/parsers'; @@ -370,3 +371,21 @@ function isFunctionDeclaration( ): node is AstTypes.FunctionDeclaration { return node.type === 'FunctionDeclaration' && node.id?.name === funcName; } + +export function addSlot( + jsAst: AstTypes.Program, + htmlAst: html.HtmlDocument, + svelteVersion: string +) { + const slotSyntax = + svelteVersion && (svelteVersion.startsWith('4') || svelteVersion.startsWith('3')); + + if (slotSyntax) { + const slot = html.element('slot'); + html.appendElement(htmlAst.childNodes, slot); + return; + } + + common.addFromString(jsAst, 'let { children } = $props();'); + html.addFromRawHtml(htmlAst.childNodes, '{@render children()}'); +} diff --git a/packages/adders/tailwindcss/index.ts b/packages/adders/tailwindcss/index.ts index 4ff99d161..8b16602ee 100644 --- a/packages/adders/tailwindcss/index.ts +++ b/packages/adders/tailwindcss/index.ts @@ -2,6 +2,7 @@ import { defineAdder, defineAdderOptions } from '@svelte-cli/core'; import { addImports } from '@svelte-cli/core/css'; import { array, common, exports, functions, imports, object } from '@svelte-cli/core/js'; import { parseCss, parseScript, parseJson, parseSvelte } from '@svelte-cli/core/parsers'; +import { addSlot } from '../common.ts'; export const options = defineAdderOptions({ plugins: { @@ -121,12 +122,19 @@ export default defineAdder({ }, { name: ({ kit }) => `${kit?.routesDirectory}/+layout.svelte`, - content: ({ content, typescript }) => { - const { script, generateCode } = parseSvelte(content, { typescript }); + content: ({ content, typescript, dependencyVersion }) => { + const { script, template, generateCode } = parseSvelte(content, { typescript }); imports.addEmpty(script.ast, '../app.css'); + + if (content.length === 0) { + const svelteVersion = dependencyVersion('svelte'); + if (!svelteVersion) throw new Error('Failed to determine svelte version'); + addSlot(script.ast, template.ast, svelteVersion); + } + return generateCode({ script: script.generateCode(), - template: content.length === 0 ? '' : undefined + template: content.length === 0 ? template.generateCode() : undefined }); }, condition: ({ kit }) => Boolean(kit) diff --git a/packages/core/tooling/html/index.ts b/packages/core/tooling/html/index.ts index ecf958ac3..2ec55829a 100644 --- a/packages/core/tooling/html/index.ts +++ b/packages/core/tooling/html/index.ts @@ -1,10 +1,13 @@ import { type HtmlChildNode, + type HtmlDocument, HtmlElement, HtmlElementType, parseHtml } from '@svelte-cli/ast-tooling'; +export type { HtmlDocument }; + export function div(attributes: Record = {}): HtmlElement { return element('div', attributes); }