Skip to content

Commit 229b165

Browse files
committed
cli: tailwind generator now handles plugin correctly
1 parent cf25aa1 commit 229b165

File tree

5 files changed

+205
-32
lines changed

5 files changed

+205
-32
lines changed

apps/website/tailwind.config.cjs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ module.exports = {
1313
join(__dirname, '../../packages/kit-tailwind/src/**/*.{js,ts,jsx,tsx,mdx}'),
1414
join(__dirname, '../../packages/kit-styled/src/**/*.{js,ts,jsx,tsx,mdx}'),
1515
],
16-
// ROOT-START
16+
1717
plugins: [
1818
require('tailwindcss-animate'),
19+
// PLUGIN-START
1920
plugin(function ({ addUtilities }) {
2021
addUtilities({
2122
'.press': {
@@ -29,8 +30,9 @@ module.exports = {
2930
},
3031
});
3132
}),
33+
// PLUGIN-END
3234
],
33-
// ROOT-END
35+
3436
darkMode: 'class',
3537
theme: {
3638
important: true,

packages/cli/project.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@
6060
"copy-global-css": {
6161
"executor": "nx:run-commands",
6262
"options": {
63-
"command": "cp apps/website/src/global.css packages/kit-styled/src/templates"
63+
"commands": [
64+
"cp apps/website/tailwind.config.cjs packages/kit-styled/src/templates",
65+
"cp apps/website/src/global.css packages/kit-styled/src/templates"
66+
]
6467
}
6568
},
6669
"lint": {

packages/cli/src/generators/setup-tailwind/setup-tailwind-generator.spec.ts

Lines changed: 132 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ describe('Setup Tailwind generator', () => {
5858
5959
html {
6060
height: 100%;
61-
min-height: 100%;
61+
min-height: 100%;
6262
scroll-behavior: smooth;
6363
background-color: var(--color-bg) !important;
6464
color: var(--color-text) !important;
@@ -85,7 +85,9 @@ html {
8585
const updatedTailwindConfigContent = tree.read('tailwind.config.cjs', 'utf-8');
8686

8787
expect(updatedTailwindConfigContent).toMatchInlineSnapshot(`
88-
"const { join } = require('path');
88+
"const plugin = require('tailwindcss/plugin');
89+
90+
const { join } = require('path');
8991
9092
/** @type {import('tailwindcss').Config} */
9193
module.exports = {
@@ -95,6 +97,12 @@ html {
9597
'.press': {
9698
transform: 'var(--transform-press)',
9799
},
100+
'.appear': {
101+
opacity: 1,
102+
},
103+
'.disappear': {
104+
opacity: 0,
105+
},
98106
});
99107
}),
100108
],
@@ -151,7 +159,6 @@ html {
151159
xl: 'calc(var(--border-radius) + 0.75rem)',
152160
'2xl': 'calc(var(--border-radius) + 1rem)',
153161
'3xl': 'calc(var(--border-radius) + 1.5rem)',
154-
preset: 'var(--border-radius)',
155162
},
156163
borderWidth: {
157164
base: 'var(--border-width)',
@@ -194,14 +201,22 @@ html {
194201
const updatedTailwindConfigContent = tree.read('tailwind.config.js', 'utf-8');
195202

196203
expect(updatedTailwindConfigContent).toMatchInlineSnapshot(`
197-
"/** @type {import('tailwindcss').Config} */
204+
"import plugin from 'tailwindcss/plugin';
205+
206+
/** @type {import('tailwindcss').Config} */
198207
export default {
199208
plugins: [
200209
plugin(function ({ addUtilities }) {
201210
addUtilities({
202211
'.press': {
203212
transform: 'var(--transform-press)',
204213
},
214+
'.appear': {
215+
opacity: 1,
216+
},
217+
'.disappear': {
218+
opacity: 0,
219+
},
205220
});
206221
}),
207222
],
@@ -258,7 +273,119 @@ html {
258273
xl: 'calc(var(--border-radius) + 0.75rem)',
259274
'2xl': 'calc(var(--border-radius) + 1rem)',
260275
'3xl': 'calc(var(--border-radius) + 1.5rem)',
261-
preset: 'var(--border-radius)',
276+
},
277+
borderWidth: {
278+
base: 'var(--border-width)',
279+
DEFAULT: 'calc(var(--border-width) + 1px)',
280+
2: 'calc(var(--border-width) + 2px)',
281+
4: 'calc(var(--border-width) + 4px)',
282+
8: 'calc(var(--border-width) + 8px)',
283+
},
284+
boxShadow: {
285+
base: 'var(--shadow-base)',
286+
sm: 'var(--shadow-sm)',
287+
DEFAULT: 'var(--shadow)',
288+
md: 'var(--shadow-md)',
289+
lg: 'var(--shadow-lg)',
290+
xl: 'var(--shadow-xl)',
291+
'2xl': 'var(--shadow-2xl)',
292+
inner: 'var(--shadow-inner)',
293+
},
294+
fontFamily: {
295+
sans: ['Inter Variable', 'sans-serif'],
296+
},
297+
},
298+
},
299+
};
300+
"
301+
`);
302+
});
303+
test(`
304+
GIVEN tailwind config has already a plugins array
305+
THEN it should add the plugin with the right plugin and import`, async () => {
306+
const { tree, options } = setupWithProperFiles();
307+
const tailwindConfig = wrapWithEsm(`plugins: [somePlugin],${tailwindConfigContent}`);
308+
tree.write('tailwind.config.js', tailwindConfig);
309+
310+
options.rootCssPath = 'src/global.css';
311+
312+
await setupTailwindGenerator(tree, options);
313+
314+
const updatedTailwindConfigContent = tree.read('tailwind.config.js', 'utf-8');
315+
316+
expect(updatedTailwindConfigContent).toMatchInlineSnapshot(`
317+
"import plugin from 'tailwindcss/plugin';
318+
319+
/** @type {import('tailwindcss').Config} */
320+
export default {
321+
plugins: [
322+
plugin(function ({ addUtilities }) {
323+
addUtilities({
324+
'.press': {
325+
transform: 'var(--transform-press)',
326+
},
327+
'.appear': {
328+
opacity: 1,
329+
},
330+
'.disappear': {
331+
opacity: 0,
332+
},
333+
});
334+
}),
335+
somePlugin,
336+
],
337+
content: [join(__dirname, 'src/**/*.{js,ts,jsx,tsx,mdx}')],
338+
darkMode: 'class',
339+
theme: {
340+
screens: {
341+
sm: '640px',
342+
md: '768px',
343+
lg: '1024px',
344+
xl: '1280px',
345+
'2xl': '1536px',
346+
},
347+
important: true,
348+
extend: {
349+
colors: {
350+
border: 'hsl(var(--border))',
351+
input: 'hsl(var(--input))',
352+
ring: 'hsl(var(--ring))',
353+
background: 'hsl(var(--background))',
354+
foreground: 'hsl(var(--foreground))',
355+
primary: {
356+
DEFAULT: 'hsl(var(--primary))',
357+
foreground: 'hsl(var(--primary-foreground))',
358+
},
359+
secondary: {
360+
DEFAULT: 'hsl(var(--secondary))',
361+
foreground: 'hsl(var(--secondary-foreground))',
362+
},
363+
alert: {
364+
DEFAULT: 'hsl(var(--alert))',
365+
foreground: 'hsl(var(--alert-foreground))',
366+
},
367+
muted: {
368+
DEFAULT: 'hsl(var(--muted))',
369+
foreground: 'hsl(var(--muted-foreground))',
370+
},
371+
accent: {
372+
DEFAULT: 'hsl(var(--accent))',
373+
foreground: 'hsl(var(--accent-foreground))',
374+
},
375+
card: {
376+
DEFAULT: 'hsl(var(--card))',
377+
foreground: 'hsl(var(--card-foreground))',
378+
},
379+
},
380+
borderRadius: {
381+
base: 'var(--border-radius)',
382+
sm: 'calc(var(--border-radius) + 0.125rem)',
383+
DEFAULT: 'calc(var(--border-radius) + 0.25rem)',
384+
md: 'calc(var(--border-radius) + 0.375rem)',
385+
lg: 'calc(var(--border-radius) + 0.5rem)',
386+
xl: 'calc(var(--border-radius) + 0.75rem)',
387+
'2xl': 'calc(var(--border-radius) + 1rem)',
388+
'3xl': 'calc(var(--border-radius) + 1.5rem)',
262389
},
263390
borderWidth: {
264391
base: 'var(--border-width)',

packages/cli/src/generators/setup-tailwind/setup-tailwind-generator.ts

Lines changed: 54 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -60,25 +60,60 @@ function updateTailwindConfig(tree: Tree, projectRoot: string, kitRoot: string)
6060

6161
const tailwindTemplate = readFileSync(tailwindConfigTemplatePath, 'utf-8');
6262

63-
const rootTemplate = extractBetweenComments(
63+
const pluginTemplate = extractBetweenComments(
6464
tailwindTemplate,
65-
'// ROOT-START',
66-
'// ROOT-END',
65+
'// PLUGIN-START',
66+
'// PLUGIN-END',
6767
);
6868
const extendTemplate = extractBetweenComments(
6969
tailwindTemplate,
7070
'// EXTEND-START',
7171
'// EXTEND-END',
7272
);
7373

74+
let modifiedTailwindConfigContent = addPluginToConfig(
75+
pluginTemplate,
76+
tailwindConfigContent,
77+
);
78+
79+
const extendKeyword = /\bextend:\s*\{/;
80+
81+
modifiedTailwindConfigContent = insertAfter({
82+
whatToFind: extendKeyword,
83+
whereToFindIt: modifiedTailwindConfigContent,
84+
whatToInsert: extendTemplate,
85+
shouldThrow: true,
86+
errorTitle: 'extend',
87+
});
88+
89+
tree.write(tailwindConfigPath, modifiedTailwindConfigContent);
90+
}
91+
92+
function addPluginToConfig(pluginTemplate: string, tailwindConfigContent: string) {
93+
let modifiedTailwindConfigContent;
7494
const commonJsModuleExportsRegex = /\bmodule\.exports\s*=\s*\{/;
95+
const isESM = !commonJsModuleExportsRegex.test(tailwindConfigContent);
96+
7597
const esmModuleExportsRegex = /\bexport\s*default\s*\{/;
76-
let modifiedTailwindConfigContent;
98+
const pluginsKeyword = /\bplugins:\s*\[/;
99+
100+
modifiedTailwindConfigContent = insertAfter({
101+
whatToFind: pluginsKeyword,
102+
whereToFindIt: tailwindConfigContent,
103+
whatToInsert: pluginTemplate,
104+
shouldThrow: false,
105+
});
106+
107+
if (modifiedTailwindConfigContent) {
108+
return addPluginImportStatement(modifiedTailwindConfigContent, isESM);
109+
}
110+
111+
pluginTemplate = `plugins: [\n${pluginTemplate}\n ],\n`;
77112

78113
modifiedTailwindConfigContent = insertAfter({
79114
whatToFind: commonJsModuleExportsRegex,
80-
content: tailwindConfigContent,
81-
whatToInsert: rootTemplate,
115+
whereToFindIt: tailwindConfigContent,
116+
whatToInsert: pluginTemplate,
82117
shouldThrow: false,
83118
});
84119

@@ -87,37 +122,36 @@ function updateTailwindConfig(tree: Tree, projectRoot: string, kitRoot: string)
87122
if (!modifiedTailwindConfigContent) {
88123
modifiedTailwindConfigContent = insertAfter({
89124
whatToFind: esmModuleExportsRegex,
90-
content: tailwindConfigContent,
91-
whatToInsert: rootTemplate,
125+
whereToFindIt: tailwindConfigContent,
126+
whatToInsert: pluginTemplate,
92127
shouldThrow: true,
93128
errorTitle: '"module.exports" or "export default"',
94129
});
95130
}
96131

97-
const extendKeyword = /\bextend:\s*\{/;
98-
99-
modifiedTailwindConfigContent = insertAfter({
100-
whatToFind: extendKeyword,
101-
content: modifiedTailwindConfigContent,
102-
whatToInsert: extendTemplate,
103-
shouldThrow: true,
104-
errorTitle: 'extend',
105-
});
132+
return addPluginImportStatement(modifiedTailwindConfigContent, isESM);
133+
}
106134

107-
tree.write(tailwindConfigPath, modifiedTailwindConfigContent);
135+
function addPluginImportStatement(content: string, isESM = false) {
136+
if (isESM) {
137+
return `import plugin from 'tailwindcss/plugin';
138+
${content}`;
139+
}
140+
return `const plugin = require('tailwindcss/plugin');
141+
${content}`;
108142
}
109143

110144
type InsertAfterConfig = {
111145
whatToFind: RegExp;
112-
content: string;
146+
whereToFindIt: string;
113147
whatToInsert: string;
114148
shouldThrow?: boolean;
115149
errorTitle?: string;
116150
};
117151

118152
function insertAfter({
119153
whatToFind,
120-
content,
154+
whereToFindIt: content,
121155
whatToInsert,
122156
shouldThrow,
123157
errorTitle,

packages/kit-styled/src/templates/tailwind.config.cjs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,27 @@ module.exports = {
1313
join(__dirname, '../../packages/kit-tailwind/src/**/*.{js,ts,jsx,tsx,mdx}'),
1414
join(__dirname, '../../packages/kit-styled/src/**/*.{js,ts,jsx,tsx,mdx}'),
1515
],
16-
// ROOT-START
16+
1717
plugins: [
18+
require('tailwindcss-animate'),
19+
// PLUGIN-START
1820
plugin(function ({ addUtilities }) {
1921
addUtilities({
2022
'.press': {
2123
transform: 'var(--transform-press)',
2224
},
25+
'.appear': {
26+
opacity: 1,
27+
},
28+
'.disappear': {
29+
opacity: 0,
30+
},
2331
});
2432
}),
33+
// PLUGIN-END
2534
],
26-
// ROOT-END
27-
darkMode: 'class',
2835

36+
darkMode: 'class',
2937
theme: {
3038
important: true,
3139
extend: {
@@ -73,7 +81,6 @@ module.exports = {
7381
xl: 'calc(var(--border-radius) + 0.75rem)',
7482
'2xl': 'calc(var(--border-radius) + 1rem)',
7583
'3xl': 'calc(var(--border-radius) + 1.5rem)',
76-
preset: 'var(--border-radius)',
7784
},
7885
borderWidth: {
7986
base: 'var(--border-width)',

0 commit comments

Comments
 (0)