Skip to content
This repository was archived by the owner on May 5, 2024. It is now read-only.

Commit e20fd99

Browse files
committed
⚡️ feat: Tailwind 3 (alpha) option
1 parent 4b4cb3c commit e20fd99

File tree

3 files changed

+89
-56
lines changed

3 files changed

+89
-56
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ This adder supports SvelteKit and Vite-powered Svelte apps (all the environments
1616

1717
### ⚙️ Options
1818

19-
- `jit` (default `true`): whether or not to use [Tailwind Just-in-Time Mode](https://tailwindcss.com/docs/just-in-time-mode)
19+
- `v3` (default `false`): whether or not to use [Tailwind 3](https://github.com/tailwindlabs/tailwindcss/discussions/5668), which is currently in alpha.
2020

2121
## 🛠 Using Tailwind CSS
2222

__metadata.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
export const name = "Tailwind CSS";
22

3-
/** @typedef {{ jit: boolean }} Options */
3+
/** @typedef {{ v3: boolean }} Options */
44

55
/** @type {import("../..").AdderOptions<Options>} */
66
export const options = {
7-
jit: {
8-
context: "https://tailwindcss.com/docs/just-in-time-mode\nIt is recommended, but you will see warning messages in the terminal (because it is in preview) and potentially run into unexpected issues, especially with @apply or nested selectors.",
9-
default: true,
10-
question: "Do you want to use Tailwind Just-in-Time mode?",
7+
v3: {
8+
context: "It is currently in alpha.",
9+
default: false,
10+
question: "Do you want to use Tailwind 3?",
1111
},
1212
};

__run.js

+83-50
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,20 @@
11
import { walk } from "estree-walker";
22
import { AtRule } from "postcss";
3-
import { newTypeScriptEstreeAst } from "../../ast-io.js";
4-
import { addImport, findImport, getConfigExpression, setDefault } from "../../ast-tools.js";
3+
import { addImport, findImport, getConfigExpression, setDefault, setPropertyValue } from "../../ast-tools.js";
54
import { extension, postcssConfigCjsPath, stylesHint } from "../postcss/stuff.js";
65
import { tailwindConfigCjsPath } from "./stuff.js";
76

8-
const tailwindAotConfig = `const { tailwindExtractor } = require("tailwindcss/lib/lib/purgeUnusedStyles");
9-
10-
const config = {
11-
mode: "aot",
12-
purge: {
13-
content: [
14-
"./src/**/*.{html,js,svelte,ts}",
15-
],
16-
options: {
17-
defaultExtractor: (content) => [
18-
// If this stops working, please open an issue at https://github.com/svelte-add/svelte-add/issues rather than bothering Tailwind Labs about it
19-
...tailwindExtractor(content),
20-
// Match Svelte class: directives (https://github.com/tailwindlabs/tailwindcss/discussions/1731)
21-
...[...content.matchAll(/(?:class:)*([\\w\\d-/:%.]+)/gm)].map(([_match, group, ..._rest]) => group),
22-
],
23-
},
24-
safelist: [/^svelte-[\\d\\w]+$/],
25-
},
26-
theme: {
27-
extend: {},
28-
},
29-
variants: {
30-
extend: {},
31-
},
32-
plugins: [],
33-
};
34-
35-
module.exports = config;
36-
`;
37-
38-
const tailwindJitConfig = `const config = {
39-
mode: "jit",
40-
purge: [
41-
"./src/**/*.{html,js,svelte,ts}",
42-
],
43-
theme: {
44-
extend: {},
45-
},
46-
plugins: [],
47-
};
48-
49-
module.exports = config;
50-
`;
51-
527
/**
538
* @param {import("../../ast-io.js").RecastAST} postcssConfigAst
9+
* @returns {import("../../ast-io.js").RecastAST}
5410
*/
5511
const updatePostcssConfig = (postcssConfigAst) => {
5612
const configObject = getConfigExpression({
5713
cjs: true,
5814
typeScriptEstree: postcssConfigAst,
5915
});
6016

61-
if (configObject.type !== "ObjectExpression") throw new Error("postcss config must be an object");
17+
if (configObject.type !== "ObjectExpression") throw new Error("PostCSS config must be an object");
6218

6319
const pluginsList = setDefault({
6420
default: {
@@ -173,6 +129,83 @@ const updatePostcssConfig = (postcssConfigAst) => {
173129
return postcssConfigAst;
174130
};
175131

132+
/**
133+
* @param {import("../../ast-io.js").RecastAST} tailwindConfigAst
134+
* @param {boolean} tailwind3
135+
* @returns {import("../../ast-io.js").RecastAST}
136+
*/
137+
const updateTailwindConfig = (tailwindConfigAst, tailwind3) => {
138+
const configObject = getConfigExpression({
139+
cjs: true,
140+
typeScriptEstree: tailwindConfigAst,
141+
});
142+
143+
if (configObject.type !== "ObjectExpression") throw new Error("Tailwind config must be an object");
144+
145+
if (!tailwind3) {
146+
setPropertyValue({
147+
object: configObject,
148+
property: "mode",
149+
value: {
150+
type: "Literal",
151+
value: "jit",
152+
},
153+
});
154+
}
155+
156+
/** @type {import("estree").ArrayExpression} */
157+
const content = {
158+
type: "ArrayExpression",
159+
elements: [
160+
{
161+
type: "Literal",
162+
value: "./src/**/*.{html,js,svelte,ts}",
163+
},
164+
],
165+
};
166+
setDefault({
167+
default: content,
168+
object: configObject,
169+
property: tailwind3 ? "content" : "purge",
170+
});
171+
172+
/** @type {import("estree").ObjectExpression} */
173+
const emptyTheme = {
174+
type: "ObjectExpression",
175+
properties: [],
176+
};
177+
const themeConfig = setDefault({
178+
default: emptyTheme,
179+
object: configObject,
180+
property: "theme",
181+
});
182+
if (themeConfig.type !== "ObjectExpression") throw new Error("`theme` in Tailwind config must be an object");
183+
184+
/** @type {import("estree").ObjectExpression} */
185+
const emptyThemeExtend = {
186+
type: "ObjectExpression",
187+
properties: [],
188+
};
189+
setDefault({
190+
default: emptyThemeExtend,
191+
object: themeConfig,
192+
property: "extend",
193+
});
194+
195+
/** @type {import("estree").ArrayExpression} */
196+
const emptyPlugins = {
197+
type: "ArrayExpression",
198+
elements: [],
199+
};
200+
setDefault({
201+
default: emptyPlugins,
202+
object: configObject,
203+
property: "plugins",
204+
});
205+
206+
return tailwindConfigAst;
207+
};
208+
176209
/**
177210
*
178211
* @param {import("../../ast-io.js").PostCSSAst} postcss
@@ -219,9 +252,9 @@ const updateGlobalStylesheet = (postcss) => {
219252
export const run = async ({ install, options, updateCss, updateJavaScript }) => {
220253
await updateJavaScript({
221254
path: tailwindConfigCjsPath,
222-
async script() {
255+
async script({ typeScriptEstree }) {
223256
return {
224-
typeScriptEstree: newTypeScriptEstreeAst(options.jit ? tailwindJitConfig : tailwindAotConfig),
257+
typeScriptEstree: updateTailwindConfig(typeScriptEstree, options.v3),
225258
};
226259
},
227260
});
@@ -244,5 +277,5 @@ export const run = async ({ install, options, updateCss, updateJavaScript }) =>
244277
},
245278
});
246279

247-
await install({ package: "tailwindcss" });
280+
await install({ package: "tailwindcss", versionOverride: options.v3 ? "next" : undefined });
248281
};

0 commit comments

Comments
 (0)