diff --git a/.changeset/two-crabs-bow.md b/.changeset/two-crabs-bow.md new file mode 100644 index 000000000..0f84f8cb6 --- /dev/null +++ b/.changeset/two-crabs-bow.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +fix: re-add `tailwindcss` plugins diff --git a/packages/addons/_tests/tailwindcss/test.ts b/packages/addons/_tests/tailwindcss/test.ts index cd692cfa7..9025e297f 100644 --- a/packages/addons/_tests/tailwindcss/test.ts +++ b/packages/addons/_tests/tailwindcss/test.ts @@ -22,22 +22,19 @@ test.concurrent.for(variants)('none - %s', async (variant, { page, ...ctx }) => await expect(el).toHaveCSS('margin-top', '4px'); }); -test.concurrent.for(variants)( - 'typography without plugin - %s', - async (variant, { page, ...ctx }) => { - const cwd = await ctx.run(variant, { tailwindcss }); - - // ...add files - addFixture(cwd, variant); - - const { close } = await prepareServer({ cwd, page }); - // kill server process when we're done - ctx.onTestFinished(async () => await close()); - - const el = page.getByTestId('typography'); - await expect(el).toHaveCSS('font-size', '18px'); - await expect(el).toHaveCSS('line-height', '28px'); - await expect(el).toHaveCSS('text-align', 'right'); - await expect(el).toHaveCSS('text-decoration-line', 'line-through'); - } -); +test.concurrent.for(variants)('typography - %s', async (variant, { page, ...ctx }) => { + const cwd = await ctx.run(variant, { tailwindcss: { plugins: ['typography'] } }); + + // ...add files + addFixture(cwd, variant); + + const { close } = await prepareServer({ cwd, page }); + // kill server process when we're done + ctx.onTestFinished(async () => await close()); + + const el = page.getByTestId('typography'); + await expect(el).toHaveCSS('font-size', '18px'); + await expect(el).toHaveCSS('line-height', '28px'); + await expect(el).toHaveCSS('text-align', 'right'); + await expect(el).toHaveCSS('text-decoration-line', 'line-through'); +}); diff --git a/packages/addons/tailwindcss/index.ts b/packages/addons/tailwindcss/index.ts index 914e20057..a1a30130f 100644 --- a/packages/addons/tailwindcss/index.ts +++ b/packages/addons/tailwindcss/index.ts @@ -1,16 +1,47 @@ -import { defineAddon } from '@sveltejs/cli-core'; -import { addImports } from '@sveltejs/cli-core/css'; +import { defineAddon, defineAddonOptions } from '@sveltejs/cli-core'; +import { addAtRule, addImports } from '@sveltejs/cli-core/css'; import { array, functions, imports, object, exports } from '@sveltejs/cli-core/js'; import { parseCss, parseJson, parseScript, parseSvelte } from '@sveltejs/cli-core/parsers'; import { addSlot } from '@sveltejs/cli-core/html'; +type Plugin = { + id: string; + package: string; + version: string; + identifier: string; +}; + +const plugins: Plugin[] = [ + { + id: 'typography', + package: '@tailwindcss/typography', + version: '^0.5.15', + identifier: 'typography' + }, + { + id: 'forms', + package: '@tailwindcss/forms', + version: '^0.5.9', + identifier: 'forms' + } +]; + +const options = defineAddonOptions({ + plugins: { + type: 'multiselect', + question: 'Which plugins would you like to add?', + options: plugins.map((p) => ({ value: p.id, label: p.id, hint: p.package })), + default: [] + } +}); + export default defineAddon({ id: 'tailwindcss', alias: 'tailwind', shortDescription: 'css framework', homepage: 'https://tailwindcss.com', - options: {}, - run: ({ sv, typescript, kit, dependencyVersion }) => { + options, + run: ({ sv, options, typescript, kit, dependencyVersion }) => { const ext = typescript ? 'ts' : 'js'; const prettierInstalled = Boolean(dependencyVersion('prettier')); @@ -19,6 +50,12 @@ export default defineAddon({ if (prettierInstalled) sv.devDependency('prettier-plugin-tailwindcss', '^0.6.11'); + for (const plugin of plugins) { + if (!options.plugins.includes(plugin.id)) continue; + + sv.devDependency(plugin.package, plugin.version); + } + // add the vite plugin sv.file(`vite.config.${ext}`, (content) => { const { ast, generateCode } = parseScript(content); @@ -46,6 +83,12 @@ export default defineAddon({ const nodes = addImports(ast, ["'tailwindcss'"]); + for (const plugin of plugins) { + if (!options.plugins.includes(plugin.id)) continue; + + addAtRule(ast, 'plugin', `'${plugin.package}'`, true); + } + if ( originalFirst !== ast.first && originalFirst?.type === 'atrule' &&