-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpostcss.config.js
More file actions
124 lines (108 loc) · 3.5 KB
/
postcss.config.js
File metadata and controls
124 lines (108 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
const path = require('node:path');
const fs = require('node:fs');
// Simple token generation function (duplicated from tailwind config for now)
function extractCssVariableBlocks(css) {
const findAllBlocks = (marker, excludeMarker) => {
const blocks = [];
let searchStart = 0;
while (true) {
const start = css.indexOf(marker, searchStart);
if (start === -1) break;
if (excludeMarker) {
const excludeStart = start - (excludeMarker.length - marker.length);
if (
excludeStart >= 0 &&
css.slice(excludeStart, start + marker.length) === excludeMarker
) {
searchStart = start + marker.length;
continue;
}
}
const braceStart = css.indexOf('{', start);
if (braceStart === -1) break;
let depth = 0;
for (let i = braceStart; i < css.length; i++) {
const ch = css[i];
if (ch === '{') depth++;
if (ch === '}') {
depth--;
if (depth === 0) {
blocks.push(css.slice(braceStart + 1, i));
searchStart = i + 1;
break;
}
}
}
if (depth !== 0) break;
}
return blocks;
};
const rootBlocks = findAllBlocks(':root', '.dark:root');
const darkRootBlocks = findAllBlocks('.dark:root');
const rootBlock = rootBlocks.join(' ');
const darkRootBlock = darkRootBlocks.join(' ');
return { rootBlock, darkRootBlock };
}
function parseVariables(block) {
const vars = {};
block
.split(/\n|;/g)
.map((l) => l.trim())
.filter((l) => l.startsWith('--'))
.forEach((line) => {
const idx = line.indexOf(':');
if (idx === -1) return;
const key = line.slice(0, idx).trim();
const raw = line.slice(idx + 1).trim();
const value = raw.replace(/;$/, '');
vars[key] = value;
});
return vars;
}
function generateTokens() {
try {
console.log('[PostCSS] Generating tailwindcss tokens');
const cssPath = path.resolve(process.cwd(), 'global.css');
if (!fs.existsSync(cssPath)) return;
const css = fs.readFileSync(cssPath, 'utf8');
const { rootBlock, darkRootBlock } = extractCssVariableBlocks(css);
if (!rootBlock || !darkRootBlock) return;
const lightVars = parseVariables(rootBlock);
const darkVars = parseVariables(darkRootBlock);
const outPath = path.resolve(process.cwd(), 'generated-tokens.ts');
const file = `export const cssTokens = {\n light: ${JSON.stringify(
{ ...darkVars, ...lightVars },
null,
4
).replaceAll('"', "'")},\n dark: ${JSON.stringify(
{ ...lightVars, ...darkVars },
null,
4
).replaceAll('"', "'")}\n} as const;\n`
.replace('},', ' },')
.replace('}\n}', ' }\n}');
fs.writeFileSync(outPath, file, 'utf8');
console.log('[PostCSS] Successfully generated tailwindcss tokens');
} catch (error) {
console.error('[PostCSS] Error generating tailwindcss tokens:', error);
}
}
// PostCSS plugin that regenerates tokens when global.css is processed
const generateTokensPlugin = () => {
return {
postcssPlugin: 'generate-tokens',
Once(root, { result }) {
// Only regenerate tokens when processing global.css
if (result.root.source && result.root.source.input.file) {
const filePath = result.root.source.input.file;
if (filePath.includes('global.css')) {
generateTokens();
}
}
}
};
};
generateTokensPlugin.postcss = true;
module.exports = {
plugins: [require('tailwindcss'), generateTokensPlugin]
};