@diskette/palette 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -176
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +135 -0
- package/package.json +7 -1
package/README.md
CHANGED
|
@@ -224,182 +224,6 @@ css.semantic(name: string, config: ColorConfig): string
|
|
|
224
224
|
|
|
225
225
|
</details>
|
|
226
226
|
|
|
227
|
-
## Examples
|
|
228
|
-
|
|
229
|
-
### Generate a Complete CSS File
|
|
230
|
-
|
|
231
|
-
```ts
|
|
232
|
-
// scripts/generate-css.ts
|
|
233
|
-
import { writeFileSync } from 'node:fs'
|
|
234
|
-
import { css, colors } from '@diskette/palette'
|
|
235
|
-
import { blackAlpha, whiteAlpha } from '@diskette/palette/colors'
|
|
236
|
-
|
|
237
|
-
let output = ''
|
|
238
|
-
|
|
239
|
-
// Generate scales for all colors
|
|
240
|
-
for (const color of colors) {
|
|
241
|
-
output += css.scale('light', color)
|
|
242
|
-
output += css.scale('lightAlpha', color)
|
|
243
|
-
output += css.scale('dark', color)
|
|
244
|
-
output += css.scale('darkAlpha', color)
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
// Generate alpha colors
|
|
248
|
-
output += css.alpha(blackAlpha)
|
|
249
|
-
output += css.alpha(whiteAlpha)
|
|
250
|
-
|
|
251
|
-
writeFileSync('dist/colors.css', output)
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
### Generate CSS for Selected Colors
|
|
255
|
-
|
|
256
|
-
```ts
|
|
257
|
-
// scripts/generate-theme.ts
|
|
258
|
-
import { writeFileSync } from 'node:fs'
|
|
259
|
-
import { css } from '@diskette/palette'
|
|
260
|
-
import blue from '@diskette/palette/colors/blue'
|
|
261
|
-
import gray from '@diskette/palette/colors/gray'
|
|
262
|
-
|
|
263
|
-
const output = [
|
|
264
|
-
// Base scales
|
|
265
|
-
css.scale('light', blue),
|
|
266
|
-
css.scale('dark', blue),
|
|
267
|
-
css.scale('light', gray),
|
|
268
|
-
css.scale('dark', gray),
|
|
269
|
-
|
|
270
|
-
// Semantic tokens
|
|
271
|
-
css.semantic('blue', blue),
|
|
272
|
-
css.semantic('gray', gray),
|
|
273
|
-
].join('\n')
|
|
274
|
-
|
|
275
|
-
writeFileSync('src/styles/theme.css', output)
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
### Generate CSS with Custom Build Script
|
|
279
|
-
|
|
280
|
-
```ts
|
|
281
|
-
// build-colors.ts
|
|
282
|
-
import { writeFileSync, mkdirSync } from 'node:fs'
|
|
283
|
-
import { css, colors } from '@diskette/palette'
|
|
284
|
-
|
|
285
|
-
mkdirSync('dist', { recursive: true })
|
|
286
|
-
|
|
287
|
-
// Generate individual files per color
|
|
288
|
-
for (const color of colors) {
|
|
289
|
-
const name = Object.keys(color.srgb.light)[0].replace(/\d+$/, '')
|
|
290
|
-
|
|
291
|
-
const content = [
|
|
292
|
-
css.scale('light', color),
|
|
293
|
-
css.scale('dark', color),
|
|
294
|
-
css.semantic(name, color),
|
|
295
|
-
].join('\n')
|
|
296
|
-
|
|
297
|
-
writeFileSync(`dist/${name}.css`, content)
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
// Generate combined file
|
|
301
|
-
let combined = ''
|
|
302
|
-
for (const color of colors) {
|
|
303
|
-
const name = Object.keys(color.srgb.light)[0].replace(/\d+$/, '')
|
|
304
|
-
combined += css.scale('light', color)
|
|
305
|
-
combined += css.scale('dark', color)
|
|
306
|
-
combined += css.semantic(name, color)
|
|
307
|
-
}
|
|
308
|
-
writeFileSync('dist/all-colors.css', combined)
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
### Use with vanilla-extract
|
|
312
|
-
|
|
313
|
-
```ts
|
|
314
|
-
// src/styles/colors.css.ts
|
|
315
|
-
import { createGlobalTheme } from '@vanilla-extract/css'
|
|
316
|
-
import blue from '@diskette/palette/colors/blue'
|
|
317
|
-
import gray from '@diskette/palette/colors/gray'
|
|
318
|
-
|
|
319
|
-
// Create CSS variables from the palette
|
|
320
|
-
createGlobalTheme(':root', {
|
|
321
|
-
colors: {
|
|
322
|
-
blue1: blue.srgb.light.blue1,
|
|
323
|
-
blue2: blue.srgb.light.blue2,
|
|
324
|
-
blue3: blue.srgb.light.blue3,
|
|
325
|
-
// ... etc
|
|
326
|
-
blue9: blue.srgb.light.blue9,
|
|
327
|
-
blue10: blue.srgb.light.blue10,
|
|
328
|
-
blue11: blue.srgb.light.blue11,
|
|
329
|
-
blue12: blue.srgb.light.blue12,
|
|
330
|
-
gray1: gray.srgb.light.gray1,
|
|
331
|
-
// ... etc
|
|
332
|
-
},
|
|
333
|
-
})
|
|
334
|
-
|
|
335
|
-
// For dark mode
|
|
336
|
-
createGlobalTheme('.dark', {
|
|
337
|
-
colors: {
|
|
338
|
-
blue1: blue.srgb.dark.blue1,
|
|
339
|
-
blue2: blue.srgb.dark.blue2,
|
|
340
|
-
// ... etc
|
|
341
|
-
},
|
|
342
|
-
})
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
### Generate Semantic Tokens Only
|
|
346
|
-
|
|
347
|
-
```ts
|
|
348
|
-
// scripts/semantic-tokens.ts
|
|
349
|
-
import { writeFileSync } from 'node:fs'
|
|
350
|
-
import { css, colors } from '@diskette/palette'
|
|
351
|
-
|
|
352
|
-
let output = ''
|
|
353
|
-
|
|
354
|
-
for (const color of colors) {
|
|
355
|
-
// Extract color name from first key (e.g., "blue1" -> "blue")
|
|
356
|
-
const name = Object.keys(color.srgb.light)[0].replace(/\d+$/, '')
|
|
357
|
-
output += css.semantic(name, color)
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
writeFileSync('dist/semantic.css', output)
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
### Access Colors Directly in JavaScript
|
|
364
|
-
|
|
365
|
-
```ts
|
|
366
|
-
import blue from '@diskette/palette/colors/blue'
|
|
367
|
-
|
|
368
|
-
// Use in CSS-in-JS libraries
|
|
369
|
-
const styles = {
|
|
370
|
-
button: {
|
|
371
|
-
backgroundColor: blue.srgb.light.blue9,
|
|
372
|
-
color: blue.contrast,
|
|
373
|
-
'&:hover': {
|
|
374
|
-
backgroundColor: blue.srgb.light.blue10,
|
|
375
|
-
},
|
|
376
|
-
},
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
// Use P3 colors for wider gamut displays
|
|
380
|
-
const p3Styles = {
|
|
381
|
-
button: {
|
|
382
|
-
backgroundColor: blue.p3.light.blue9,
|
|
383
|
-
},
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
// Access surface colors for overlays
|
|
387
|
-
const overlay = {
|
|
388
|
-
backgroundColor: blue.surface.srgb.light, // '#f1f9ffcc'
|
|
389
|
-
}
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
### NPM Script Integration
|
|
393
|
-
|
|
394
|
-
```json
|
|
395
|
-
{
|
|
396
|
-
"scripts": {
|
|
397
|
-
"build:css": "tsx scripts/generate-css.ts",
|
|
398
|
-
"build": "pnpm build:css && vite build"
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
```
|
|
402
|
-
|
|
403
227
|
## Credits
|
|
404
228
|
|
|
405
229
|
Color values are derived from [Radix Colors](https://www.radix-ui.com/colors) by [WorkOS](https://workos.com/).
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import * as p from '@clack/prompts';
|
|
2
|
+
import { mkdirSync, statSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { resolve } from 'node:path';
|
|
4
|
+
import { blackAlpha, whiteAlpha } from "./colors/index.js";
|
|
5
|
+
import { colors, css, grayColors } from "./index.js";
|
|
6
|
+
function colorOptions() {
|
|
7
|
+
return colors.map((color) => {
|
|
8
|
+
const option = {
|
|
9
|
+
value: color.name,
|
|
10
|
+
label: color.name,
|
|
11
|
+
};
|
|
12
|
+
if (grayColors.includes(color.name)) {
|
|
13
|
+
option.hint = 'gray';
|
|
14
|
+
}
|
|
15
|
+
return option;
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
async function askOutputDir(message) {
|
|
19
|
+
const outputDir = await p.text({
|
|
20
|
+
message,
|
|
21
|
+
validate(value) {
|
|
22
|
+
if (!value) {
|
|
23
|
+
return 'Please enter a path';
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const stat = statSync(resolve(process.cwd(), value));
|
|
27
|
+
if (!stat.isDirectory()) {
|
|
28
|
+
return 'Path must be a directory, not a file';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch { }
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
if (p.isCancel(outputDir)) {
|
|
35
|
+
p.cancel('Operation cancelled.');
|
|
36
|
+
process.exit(0);
|
|
37
|
+
}
|
|
38
|
+
return outputDir;
|
|
39
|
+
}
|
|
40
|
+
async function main() {
|
|
41
|
+
p.intro('Palette CSS Generator');
|
|
42
|
+
// --- Color Scales ---
|
|
43
|
+
const scaleMode = await p.select({
|
|
44
|
+
message: 'Which color scales do you want to generate?',
|
|
45
|
+
options: [
|
|
46
|
+
{ value: 'all', label: 'All colors', hint: `${colors.length} colors` },
|
|
47
|
+
{ value: 'select', label: 'Select specific colors' },
|
|
48
|
+
],
|
|
49
|
+
});
|
|
50
|
+
if (p.isCancel(scaleMode)) {
|
|
51
|
+
p.cancel('Operation cancelled.');
|
|
52
|
+
process.exit(0);
|
|
53
|
+
}
|
|
54
|
+
let scaleColors = colors;
|
|
55
|
+
if (scaleMode === 'select') {
|
|
56
|
+
const scaleChoices = await p.autocompleteMultiselect({
|
|
57
|
+
message: 'Select colors for scales:',
|
|
58
|
+
options: colorOptions(),
|
|
59
|
+
required: true,
|
|
60
|
+
});
|
|
61
|
+
if (p.isCancel(scaleChoices)) {
|
|
62
|
+
p.cancel('Operation cancelled.');
|
|
63
|
+
process.exit(0);
|
|
64
|
+
}
|
|
65
|
+
scaleColors = colors.filter((c) => scaleChoices.includes(c.name));
|
|
66
|
+
}
|
|
67
|
+
const scalesOutputDir = await askOutputDir('Output directory for color scales:');
|
|
68
|
+
// --- Semantic Tokens ---
|
|
69
|
+
const generateSemantic = await p.confirm({
|
|
70
|
+
message: 'Generate semantic tokens?',
|
|
71
|
+
});
|
|
72
|
+
if (p.isCancel(generateSemantic)) {
|
|
73
|
+
p.cancel('Operation cancelled.');
|
|
74
|
+
process.exit(0);
|
|
75
|
+
}
|
|
76
|
+
let semanticColors = colors;
|
|
77
|
+
let semanticOutputDir = null;
|
|
78
|
+
if (generateSemantic) {
|
|
79
|
+
const semanticMode = await p.select({
|
|
80
|
+
message: 'Which colors for semantic tokens?',
|
|
81
|
+
options: [
|
|
82
|
+
{ value: 'all', label: 'All colors', hint: `${colors.length} colors` },
|
|
83
|
+
{ value: 'select', label: 'Select specific colors' },
|
|
84
|
+
],
|
|
85
|
+
});
|
|
86
|
+
if (p.isCancel(semanticMode)) {
|
|
87
|
+
p.cancel('Operation cancelled.');
|
|
88
|
+
process.exit(0);
|
|
89
|
+
}
|
|
90
|
+
if (semanticMode === 'select') {
|
|
91
|
+
const semanticChoices = await p.autocompleteMultiselect({
|
|
92
|
+
message: 'Select colors for semantic tokens:',
|
|
93
|
+
options: colorOptions(),
|
|
94
|
+
required: true,
|
|
95
|
+
});
|
|
96
|
+
if (p.isCancel(semanticChoices)) {
|
|
97
|
+
p.cancel('Operation cancelled.');
|
|
98
|
+
process.exit(0);
|
|
99
|
+
}
|
|
100
|
+
semanticColors = colors.filter((c) => semanticChoices.includes(c.name));
|
|
101
|
+
}
|
|
102
|
+
semanticOutputDir = await askOutputDir('Output directory for semantic tokens:');
|
|
103
|
+
}
|
|
104
|
+
// --- Generate Files ---
|
|
105
|
+
const s = p.spinner();
|
|
106
|
+
s.start('Generating CSS files...');
|
|
107
|
+
// Generate color scales
|
|
108
|
+
const scalesPath = resolve(process.cwd(), scalesOutputDir);
|
|
109
|
+
mkdirSync(scalesPath, { recursive: true });
|
|
110
|
+
for (const color of scaleColors) {
|
|
111
|
+
const name = color.name;
|
|
112
|
+
writeFileSync(`${scalesPath}/${name}.css`, css.scale('light', color));
|
|
113
|
+
writeFileSync(`${scalesPath}/${name}-alpha.css`, css.scale('lightAlpha', color));
|
|
114
|
+
writeFileSync(`${scalesPath}/${name}-dark.css`, css.scale('dark', color));
|
|
115
|
+
writeFileSync(`${scalesPath}/${name}-dark-alpha.css`, css.scale('darkAlpha', color));
|
|
116
|
+
}
|
|
117
|
+
// Always generate alpha overlay files
|
|
118
|
+
writeFileSync(`${scalesPath}/black-alpha.css`, css.alpha(blackAlpha));
|
|
119
|
+
writeFileSync(`${scalesPath}/white-alpha.css`, css.alpha(whiteAlpha));
|
|
120
|
+
// Generate semantic tokens
|
|
121
|
+
if (generateSemantic && semanticOutputDir) {
|
|
122
|
+
const semanticPath = resolve(process.cwd(), semanticOutputDir);
|
|
123
|
+
mkdirSync(semanticPath, { recursive: true });
|
|
124
|
+
for (const color of semanticColors) {
|
|
125
|
+
writeFileSync(`${semanticPath}/${color.name}.css`, css.semantic(color.name, color));
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
s.stop();
|
|
129
|
+
let message = `Color scales saved to ${scalesPath}`;
|
|
130
|
+
if (semanticOutputDir) {
|
|
131
|
+
message += `\nSemantic tokens saved to ${resolve(process.cwd(), semanticOutputDir)}`;
|
|
132
|
+
}
|
|
133
|
+
p.outro(message);
|
|
134
|
+
}
|
|
135
|
+
main().catch(console.error);
|
package/package.json
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diskette/palette",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.11.0",
|
|
5
|
+
"bin": {
|
|
6
|
+
"palette": "./dist/cli.js"
|
|
7
|
+
},
|
|
5
8
|
"exports": {
|
|
6
9
|
".": {
|
|
7
10
|
"types": "./dist/index.d.ts",
|
|
@@ -39,6 +42,9 @@
|
|
|
39
42
|
"singleQuote": true
|
|
40
43
|
},
|
|
41
44
|
"license": "MIT",
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@clack/prompts": "1.0.0-alpha.7"
|
|
47
|
+
},
|
|
42
48
|
"scripts": {
|
|
43
49
|
"build": "rm -rf dist && tsc -p tsconfig.build.json",
|
|
44
50
|
"typecheck": "tsc",
|