Skip to content

Commit e2e70c5

Browse files
committed
Begin to replace tailwind plugin / config with app.css
1 parent 80f666c commit e2e70c5

File tree

9 files changed

+358
-111
lines changed

9 files changed

+358
-111
lines changed

packages/tailwind/package.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,16 @@
77
"version": "1.0.0",
88
"scripts": {
99
"dev": "rimraf dist && tsc -p tsconfig.build.json --watch",
10-
"build": "rimraf dist && tsc -p tsconfig.build.json && cp -r ./src/lib/plugin* dist",
10+
"build": "rimraf dist && tsc -p tsconfig.build.json && cp -r ./src/lib/plugin* dist && pnpm cli",
1111
"preview": "vite preview",
1212
"package": "svelte-package",
1313
"prepublishOnly": "svelte-package",
1414
"check": "tsc --noEmit",
1515
"check:watch": "tsc --noEmit --watch",
1616
"test:unit": "TZ=UTC+4 vitest",
1717
"lint": "prettier --check .",
18-
"format": "prettier --write ."
18+
"format": "prettier --write .",
19+
"cli": "tsc --noEmit && tsx ./src/lib/cli.ts"
1920
},
2021
"devDependencies": {
2122
"@skeletonlabs/tw-plugin": "^0.4.1",
@@ -27,6 +28,7 @@
2728
"prettier": "^3.5.2",
2829
"rimraf": "6.0.1",
2930
"tslib": "^2.8.1",
31+
"tsx": "^4.19.3",
3032
"typescript": "^5.7.3",
3133
"vite": "^6.2.0",
3234
"vitest": "^3.0.7"
@@ -47,7 +49,8 @@
4749
".": "./dist/index.js",
4850
"./daisy": "./dist/daisy.js",
4951
"./skeleton": "./dist/skeleton.js",
50-
"./plugin": "./dist/plugin.cjs"
52+
"./plugin": "./dist/plugin.cjs",
53+
"./css/*": "./dist/css/*"
5154
},
5255
"files": [
5356
"dist"

packages/tailwind/src/lib/cli.ts

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import { parseArgs } from 'node:util';
2+
import { writeFileSync, mkdirSync } from 'node:fs';
3+
import { dirname, join } from 'node:path';
4+
import { format } from 'prettier';
5+
6+
import { entries } from '@layerstack/utils';
7+
8+
import {
9+
colorNames,
10+
createThemeColors,
11+
processThemeColors,
12+
themeStylesString,
13+
type NestedColors,
14+
type SupportedColorSpace,
15+
} from './theme.js';
16+
import { themes as daisyThemes } from './daisy.js';
17+
import { themes as skeletonThemes } from './skeleton/index.js';
18+
19+
const options = {
20+
daisy: {
21+
type: 'boolean',
22+
short: 'd',
23+
},
24+
skeleton: {
25+
type: 'string',
26+
},
27+
} as const;
28+
29+
const { values, positionals } = parseArgs({ args: process.argv, options, allowPositionals: true });
30+
31+
/**
32+
* Build theme CSS variables
33+
*/
34+
function buildThemeCss(colorSpace: SupportedColorSpace) {
35+
let result: string[] = [];
36+
37+
result.push('@theme {');
38+
39+
// Register theme colors variables with placeholder values
40+
colorNames.forEach((color) => {
41+
result.push(`--color-${color}: ${colorSpace}(0 0 0);`);
42+
});
43+
44+
result.push('}');
45+
46+
return format(result.join('\n\n'), { parser: 'css' });
47+
}
48+
49+
/**
50+
* Build themes as CSS files
51+
*/
52+
async function buildThemesCss(themes: NestedColors, colorSpace: SupportedColorSpace) {
53+
let result: string[] = [];
54+
55+
let rootThemeName: string = '';
56+
entries(themes).map(([themeName, themeColors], index) => {
57+
if (index === 0) {
58+
// Root / default theme
59+
result.push(`:root { ${themeStylesString(themeColors as NestedColors, colorSpace)} }`);
60+
rootThemeName = themeName;
61+
} else if (index === 1) {
62+
// Dark theme
63+
result.push(`@media (prefers-color-scheme: dark) {
64+
:root { ${themeStylesString(themeColors as NestedColors, colorSpace)} }
65+
}`);
66+
67+
// Also register first and second theme by name AFTER @media for precedence
68+
result.push(
69+
`[data-theme=${rootThemeName}] { ${themeStylesString(themes[rootThemeName] as NestedColors, colorSpace)} }`
70+
);
71+
result.push(
72+
`[data-theme=${themeName}] { ${themeStylesString(themeColors as NestedColors, colorSpace)} }`
73+
);
74+
} else {
75+
result.push(
76+
`[data-theme=${themeName}] { ${themeStylesString(themeColors as NestedColors, colorSpace)} }`
77+
);
78+
}
79+
});
80+
81+
return format(result.join('\n\n'), { parser: 'css' });
82+
}
83+
84+
function writeFile(filePath: string, data: string) {
85+
mkdirSync(dirname(filePath), { recursive: true });
86+
writeFileSync(filePath, data);
87+
console.log(`Wrote ${filePath}`);
88+
}
89+
90+
const themeCss = await buildThemeCss('hsl');
91+
writeFile(join('dist/css', 'theme.css'), themeCss);
92+
93+
const daisyCss = await buildThemesCss(daisyThemes, 'hsl');
94+
writeFile('dist/css/daisy.css', daisyCss);
95+
96+
// const skeletonCss = await buildThemesCss(skeletonThemes, 'hsl');
97+
// writeFile('dist/css/skeleton.css', skeletonCss);

packages/tailwind/src/lib/daisy.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ const daisyColorMap = {
4949
};
5050

5151
/**
52-
* Map Daisy UI color names to Svelte UX names, and sort themes
52+
* Map Daisy UI color names to LayerStack names, and sort themes
5353
*/
5454
function mapColorsName(themes: typeof daisyThemes, colorMap: typeof daisyColorMap) {
5555
let themesGeneric = themes as unknown as Record<Theme, Record<string, string>>;

packages/tailwind/src/lib/theme.ts

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,10 @@ export const colorNames = [
3939
];
4040

4141
/**
42-
* Generate theme colors (ex. { primary: hsl(var(--color-primary) / <alpha-value>), ... })
42+
* Generate theme colors (ex. { primary: hsl(var(--color-primary)), ... })
4343
*/
4444
export function createThemeColors(colorSpace: SupportedColorSpace) {
45-
return fromEntries(
46-
colorNames.map((color) => [color, `${colorSpace}(var(--color-${color}) / <alpha-value>)`])
47-
);
45+
return fromEntries(colorNames.map((color) => [color, `${colorSpace}(var(--color-${color}))`]));
4846
}
4947

5048
/**
@@ -153,8 +151,8 @@ export function processThemeColors(themeColors: NestedColors, colorSpace: Suppor
153151
const result = fromEntries(
154152
entries(colors).map(([name, value]) => {
155153
if (colorNames.includes(String(name))) {
156-
// Add space separated color variables for each color
157-
return [`--color-${name}`, colorVariableValue(value, colorSpace)];
154+
// Convert each color to common colorspace and add variable
155+
return [`--color-${name}`, convertColor(value, colorSpace)];
158156
} else {
159157
// Additional properties such as `color-scheme` or CSS variable
160158
return [name, value];
@@ -212,29 +210,25 @@ function darkenColor(color: Color | string, percentage: number) {
212210
/**
213211
* Convert color to space separated components string
214212
*/
215-
export function colorVariableValue(
216-
color: Color | string,
217-
colorSpace: SupportedColorSpace,
218-
decimals = 4
219-
) {
213+
export function convertColor(color: Color | string, colorSpace: SupportedColorSpace, decimals = 4) {
220214
try {
221215
if (colorSpace === 'rgb') {
222216
const computedColor = typeof color === 'string' ? rgb(color) : (color as Rgb);
223217
if (computedColor) {
224218
const { r, g, b } = computedColor;
225-
return `${round(r * 255, decimals)} ${round(g * 255, decimals)} ${round(b * 255, decimals)}`;
219+
return `rgb(${round(r * 255, decimals)} ${round(g * 255, decimals)} ${round(b * 255, decimals)})`;
226220
}
227221
} else if (colorSpace === 'hsl') {
228222
const computedColor = typeof color === 'string' ? hsl(clampRgb(color)) : (color as Hsl);
229223
if (computedColor) {
230224
const { h, s, l } = computedColor;
231-
return `${round(h ?? 0, decimals)} ${round(s * 100, decimals)}% ${round(l * 100, decimals)}%`;
225+
return `hsl(${round(h ?? 0, decimals)} ${round(s * 100, decimals)}% ${round(l * 100, decimals)}%)`;
232226
}
233227
} else if (colorSpace === 'oklch') {
234228
const computedColor = typeof color === 'string' ? oklch(clampRgb(color)) : (color as Oklch);
235229
if (computedColor) {
236230
const { l, c, h } = computedColor;
237-
return `${round(l, decimals)} ${round(c, decimals)} ${round(h ?? 0, decimals)}`;
231+
return `oklch(${round(l, decimals)} ${round(c, decimals)} ${round(h ?? 0, decimals)})`;
238232
}
239233
}
240234
} catch (e) {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
22
"extends": "./tsconfig.json",
3-
"exclude": ["./src/**/*.test.ts"]
3+
"exclude": ["./src/**/*.test.ts", "./src/lib/cli.ts"]
44
}

0 commit comments

Comments
 (0)