@diskette/palette 0.10.0 → 0.12.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 +90 -0
- package/dist/css.d.ts +30 -0
- package/dist/css.js +126 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/types.d.ts +1 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +37 -0
- package/package.json +7 -1
- package/dist/lib.d.ts +0 -30
- package/dist/lib.js +0 -89
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,90 @@
|
|
|
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 { accentColors, colors, css, grayColors } from "./index.js";
|
|
6
|
+
function cancel() {
|
|
7
|
+
p.cancel('Operation cancelled.');
|
|
8
|
+
process.exit(0);
|
|
9
|
+
}
|
|
10
|
+
async function askColors(label, choices) {
|
|
11
|
+
const mode = await p.select({
|
|
12
|
+
message: `Which ${label} colors do you want to generate?`,
|
|
13
|
+
options: [
|
|
14
|
+
{ value: 'select', label: 'Select specific colors' },
|
|
15
|
+
{
|
|
16
|
+
value: 'all',
|
|
17
|
+
label: `All ${label} colors`,
|
|
18
|
+
hint: `${choices.length} colors`,
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
});
|
|
22
|
+
if (p.isCancel(mode))
|
|
23
|
+
cancel();
|
|
24
|
+
if (mode === 'all')
|
|
25
|
+
return choices;
|
|
26
|
+
const selected = await p.autocompleteMultiselect({
|
|
27
|
+
message: `Select ${label} colors:`,
|
|
28
|
+
options: choices.map((name) => ({ value: name, label: name })),
|
|
29
|
+
required: false,
|
|
30
|
+
});
|
|
31
|
+
if (p.isCancel(selected))
|
|
32
|
+
cancel();
|
|
33
|
+
return selected;
|
|
34
|
+
}
|
|
35
|
+
async function askOutputDir(message) {
|
|
36
|
+
const outputDir = await p.text({
|
|
37
|
+
message,
|
|
38
|
+
validate(value) {
|
|
39
|
+
if (!value) {
|
|
40
|
+
return 'Please enter a path';
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
const stat = statSync(resolve(process.cwd(), value));
|
|
44
|
+
if (!stat.isDirectory()) {
|
|
45
|
+
return 'Path must be a directory, not a file';
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch { }
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
if (p.isCancel(outputDir))
|
|
52
|
+
cancel();
|
|
53
|
+
return outputDir;
|
|
54
|
+
}
|
|
55
|
+
async function main() {
|
|
56
|
+
p.intro('Palette CSS Generator');
|
|
57
|
+
const selectedAccentColors = await askColors('accent', accentColors);
|
|
58
|
+
const selectedGrayColors = await askColors('gray', grayColors.slice(1));
|
|
59
|
+
const selectedColors = [...selectedAccentColors, ...selectedGrayColors];
|
|
60
|
+
const generateAccents = await p.confirm({
|
|
61
|
+
message: 'Generate accents for selected colors?',
|
|
62
|
+
});
|
|
63
|
+
if (p.isCancel(generateAccents))
|
|
64
|
+
cancel();
|
|
65
|
+
const outputDir = await askOutputDir('Output directory:');
|
|
66
|
+
// --- Generate Files ---
|
|
67
|
+
const s = p.spinner();
|
|
68
|
+
s.start('Generating CSS files...');
|
|
69
|
+
const outputPath = resolve(process.cwd(), outputDir);
|
|
70
|
+
mkdirSync(outputPath, { recursive: true });
|
|
71
|
+
for (const name of selectedColors) {
|
|
72
|
+
const palette = colors.find((c) => c.name === name);
|
|
73
|
+
// Light theme (scales + alphas + semantics)
|
|
74
|
+
writeFileSync(`${outputPath}/${name}.css`, css.palette(name, palette, { schemes: ['light'], alpha: true }));
|
|
75
|
+
// Dark theme (scales + alphas + semantics)
|
|
76
|
+
writeFileSync(`${outputPath}/${name}-dark.css`, css.palette(name, palette, { schemes: ['dark'], alpha: true }));
|
|
77
|
+
}
|
|
78
|
+
// Always generate alpha overlay files
|
|
79
|
+
writeFileSync(`${outputPath}/black-alpha.css`, css.alpha(blackAlpha));
|
|
80
|
+
writeFileSync(`${outputPath}/white-alpha.css`, css.alpha(whiteAlpha));
|
|
81
|
+
// Generate accents
|
|
82
|
+
if (generateAccents) {
|
|
83
|
+
const accents = css.accents([...selectedAccentColors]);
|
|
84
|
+
const grays = css.grays(selectedGrayColors, 'diskette-palette');
|
|
85
|
+
writeFileSync(`${outputPath}/accents.css`, `${accents}\n${grays}`);
|
|
86
|
+
}
|
|
87
|
+
s.stop();
|
|
88
|
+
p.outro(`CSS saved to ${outputPath}`);
|
|
89
|
+
}
|
|
90
|
+
main().catch(console.error);
|
package/dist/css.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { AnyPalette } from './types.ts';
|
|
2
|
+
type AlphaConfig = {
|
|
3
|
+
srgb: Record<string, string>;
|
|
4
|
+
p3: Record<string, string>;
|
|
5
|
+
};
|
|
6
|
+
type PaletteOptions = {
|
|
7
|
+
/** Which color schemes to include. Defaults to ['light'] */
|
|
8
|
+
schemes?: ('light' | 'dark')[];
|
|
9
|
+
/** Include alpha scale variables (e.g., --amber-a1). Defaults to false */
|
|
10
|
+
alpha?: boolean;
|
|
11
|
+
};
|
|
12
|
+
export declare const css: {
|
|
13
|
+
/**
|
|
14
|
+
* Generate combined CSS for scale variables and semantic tokens
|
|
15
|
+
*/
|
|
16
|
+
palette(name: string, config: AnyPalette, options?: PaletteOptions): string;
|
|
17
|
+
/**
|
|
18
|
+
* Generate CSS for alpha-only color scales
|
|
19
|
+
*/
|
|
20
|
+
alpha(config: AlphaConfig): string;
|
|
21
|
+
/**
|
|
22
|
+
* Generate CSS for accent color data attribute selectors
|
|
23
|
+
*/
|
|
24
|
+
accents(colorNames: string[]): string;
|
|
25
|
+
/**
|
|
26
|
+
* Generate CSS for gray color data attribute selectors
|
|
27
|
+
*/
|
|
28
|
+
grays(names: readonly string[], className: string): string;
|
|
29
|
+
};
|
|
30
|
+
export {};
|
package/dist/css.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
const steps = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
|
|
2
|
+
const LIGHT_SELECTOR = ':root, .light, .light-theme';
|
|
3
|
+
const DARK_SELECTOR = '.dark, .dark-theme';
|
|
4
|
+
const schemeSelector = (scheme) => scheme === 'light' ? LIGHT_SELECTOR : DARK_SELECTOR;
|
|
5
|
+
/** Convert "amber9" to "--amber-9" or "amberA9" to "--amber-a9" */
|
|
6
|
+
const toVarName = (key) => `--${key.replace(/A?(\d+)/, (m, n) => (m.startsWith('A') ? `-a${n}` : `-${n}`))}`;
|
|
7
|
+
const formatRule = (selector, vars) => `${selector} {\n ${vars.join(';\n ')};\n}`;
|
|
8
|
+
const formatP3 = (selector, vars) => `@supports (color: color(display-p3 1 1 1)) {\n @media (color-gamut: p3) {\n ${selector} {\n ${vars.join(';\n ')};\n }\n }\n}`;
|
|
9
|
+
const formatNestedBlock = (selector, vars) => `&:where(${selector}) {\n ${vars.join(';\n ')};\n }`;
|
|
10
|
+
export const css = {
|
|
11
|
+
/**
|
|
12
|
+
* Generate combined CSS for scale variables and semantic tokens
|
|
13
|
+
*/
|
|
14
|
+
palette(name, config, options = {}) {
|
|
15
|
+
const { schemes = ['light'], alpha = false } = options;
|
|
16
|
+
const output = [];
|
|
17
|
+
if (schemes.includes('light')) {
|
|
18
|
+
output.push(formatRule(':root', [
|
|
19
|
+
`--${name}-contrast: ${config.contrast}`,
|
|
20
|
+
`--${name}-indicator: var(${toVarName(config.indicator)})`,
|
|
21
|
+
`--${name}-track: var(${toVarName(config.track)})`,
|
|
22
|
+
]));
|
|
23
|
+
}
|
|
24
|
+
for (const scheme of schemes) {
|
|
25
|
+
const isLight = scheme === 'light';
|
|
26
|
+
const selector = schemeSelector(scheme);
|
|
27
|
+
const srgbScale = isLight ? config.srgb.light : config.srgb.dark;
|
|
28
|
+
const p3Scale = isLight ? config.p3.light : config.p3.dark;
|
|
29
|
+
const srgbSurface = isLight
|
|
30
|
+
? config.surface.srgb.light
|
|
31
|
+
: config.surface.srgb.dark;
|
|
32
|
+
const p3Surface = isLight
|
|
33
|
+
? config.surface.p3.light
|
|
34
|
+
: config.surface.p3.dark;
|
|
35
|
+
const srgb = [];
|
|
36
|
+
const p3 = [];
|
|
37
|
+
for (const n of steps) {
|
|
38
|
+
srgb.push(`--${name}-${n}: ${srgbScale[`${name}${n}`]}`);
|
|
39
|
+
p3.push(`--${name}-${n}: ${p3Scale[`${name}${n}`]}`);
|
|
40
|
+
}
|
|
41
|
+
if (alpha) {
|
|
42
|
+
for (const n of steps) {
|
|
43
|
+
srgb.push(`--${name}-a${n}: ${srgbScale[`${name}A${n}`]}`);
|
|
44
|
+
p3.push(`--${name}-a${n}: ${p3Scale[`${name}A${n}`]}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
srgb.push(`--${name}-surface: ${srgbSurface}`);
|
|
48
|
+
p3.push(`--${name}-surface: ${p3Surface}`);
|
|
49
|
+
output.push(formatRule(selector, srgb));
|
|
50
|
+
output.push(formatP3(selector, p3));
|
|
51
|
+
}
|
|
52
|
+
return output.join('\n\n') + '\n';
|
|
53
|
+
},
|
|
54
|
+
/**
|
|
55
|
+
* Generate CSS for alpha-only color scales
|
|
56
|
+
*/
|
|
57
|
+
alpha(config) {
|
|
58
|
+
const srgb = [];
|
|
59
|
+
const p3 = [];
|
|
60
|
+
for (const key in config.srgb) {
|
|
61
|
+
srgb.push(`${toVarName(key)}: ${config.srgb[key]}`);
|
|
62
|
+
}
|
|
63
|
+
for (const key in config.p3) {
|
|
64
|
+
p3.push(`${toVarName(key)}: ${config.p3[key]}`);
|
|
65
|
+
}
|
|
66
|
+
return ([formatRule(':root', srgb), formatP3(':root', p3)].join('\n\n') + '\n');
|
|
67
|
+
},
|
|
68
|
+
/**
|
|
69
|
+
* Generate CSS for accent color data attribute selectors
|
|
70
|
+
*/
|
|
71
|
+
accents(colorNames) {
|
|
72
|
+
const output = colorNames.map((colorName) => {
|
|
73
|
+
const srgb = [];
|
|
74
|
+
const alpha = [];
|
|
75
|
+
for (const n of steps) {
|
|
76
|
+
srgb.push(`--accent-${n}: var(--${colorName}-${n})`);
|
|
77
|
+
alpha.push(`--accent-a${n}: var(--${colorName}-a${n})`);
|
|
78
|
+
}
|
|
79
|
+
const semantic = [
|
|
80
|
+
`--accent-contrast: var(--${colorName}-contrast)`,
|
|
81
|
+
`--accent-surface: var(--${colorName}-surface)`,
|
|
82
|
+
`--accent-indicator: var(--${colorName}-indicator)`,
|
|
83
|
+
`--accent-track: var(--${colorName}-track)`,
|
|
84
|
+
];
|
|
85
|
+
return formatRule(`[data-accent-color='${colorName}']`, [
|
|
86
|
+
...srgb,
|
|
87
|
+
...alpha,
|
|
88
|
+
...semantic,
|
|
89
|
+
]);
|
|
90
|
+
});
|
|
91
|
+
const focus = [];
|
|
92
|
+
const focusAlpha = [];
|
|
93
|
+
for (const n of steps) {
|
|
94
|
+
focus.push(`--focus-${n}: var(--accent-${n})`);
|
|
95
|
+
focusAlpha.push(`--focus-a${n}: var(--accent-a${n})`);
|
|
96
|
+
}
|
|
97
|
+
output.push(formatRule(`[data-accent-color]:where(:not([data-accent-color=''], [data-accent-color='gray']))`, [...focus, ...focusAlpha]));
|
|
98
|
+
return output.join('\n\n') + '\n';
|
|
99
|
+
},
|
|
100
|
+
/**
|
|
101
|
+
* Generate CSS for gray color data attribute selectors
|
|
102
|
+
*/
|
|
103
|
+
grays(names, className) {
|
|
104
|
+
const grays = names.filter((n) => n !== 'gray');
|
|
105
|
+
const blocks = grays.map((colorName) => {
|
|
106
|
+
const srgb = [];
|
|
107
|
+
const alpha = [];
|
|
108
|
+
for (const n of steps) {
|
|
109
|
+
srgb.push(`--gray-${n}: var(--${colorName}-${n})`);
|
|
110
|
+
alpha.push(`--gray-a${n}: var(--${colorName}-a${n})`);
|
|
111
|
+
}
|
|
112
|
+
const semantic = [
|
|
113
|
+
`--gray-contrast: var(--${colorName}-contrast)`,
|
|
114
|
+
`--gray-surface: var(--${colorName}-surface)`,
|
|
115
|
+
`--gray-indicator: var(--${colorName}-indicator)`,
|
|
116
|
+
`--gray-track: var(--${colorName}-track)`,
|
|
117
|
+
];
|
|
118
|
+
return formatNestedBlock(`[data-gray-color='${colorName}']`, [
|
|
119
|
+
...srgb,
|
|
120
|
+
...alpha,
|
|
121
|
+
...semantic,
|
|
122
|
+
]);
|
|
123
|
+
});
|
|
124
|
+
return `.${className} {\n ${blocks.join('\n\n ')}\n}\n`;
|
|
125
|
+
},
|
|
126
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -3939,4 +3939,5 @@ export declare const colors: ({
|
|
|
3939
3939
|
export default colors;
|
|
3940
3940
|
export { accentColors, grayColors } from './types.ts';
|
|
3941
3941
|
export type { AccentColor, AlphaConfig, AlphaScale, Color, ColorPalette, ColorScale, GrayColor, } from './types.ts';
|
|
3942
|
-
export { css
|
|
3942
|
+
export { css } from './css.ts';
|
|
3943
|
+
export { getMatchingGrayColor } from './utils.ts';
|
package/dist/index.js
CHANGED
package/dist/types.d.ts
CHANGED
package/dist/utils.d.ts
ADDED
package/dist/utils.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export function getMatchingGrayColor(accentColor) {
|
|
2
|
+
switch (accentColor) {
|
|
3
|
+
case 'tomato':
|
|
4
|
+
case 'red':
|
|
5
|
+
case 'ruby':
|
|
6
|
+
case 'crimson':
|
|
7
|
+
case 'pink':
|
|
8
|
+
case 'plum':
|
|
9
|
+
case 'purple':
|
|
10
|
+
case 'violet':
|
|
11
|
+
return 'mauve';
|
|
12
|
+
case 'iris':
|
|
13
|
+
case 'indigo':
|
|
14
|
+
case 'blue':
|
|
15
|
+
case 'sky':
|
|
16
|
+
case 'cyan':
|
|
17
|
+
return 'slate';
|
|
18
|
+
case 'teal':
|
|
19
|
+
case 'jade':
|
|
20
|
+
case 'mint':
|
|
21
|
+
case 'green':
|
|
22
|
+
return 'sage';
|
|
23
|
+
case 'grass':
|
|
24
|
+
case 'lime':
|
|
25
|
+
return 'olive';
|
|
26
|
+
case 'yellow':
|
|
27
|
+
case 'amber':
|
|
28
|
+
case 'orange':
|
|
29
|
+
case 'brown':
|
|
30
|
+
case 'gold':
|
|
31
|
+
case 'bronze':
|
|
32
|
+
return 'sand';
|
|
33
|
+
case 'gray':
|
|
34
|
+
default:
|
|
35
|
+
return 'gray';
|
|
36
|
+
}
|
|
37
|
+
}
|
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.12.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",
|
package/dist/lib.d.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
export type AlphaConfig = {
|
|
2
|
-
srgb: Record<string, string>;
|
|
3
|
-
p3: Record<string, string>;
|
|
4
|
-
};
|
|
5
|
-
export type ColorConfig = {
|
|
6
|
-
srgb: {
|
|
7
|
-
light: Record<string, string> & {
|
|
8
|
-
surface: string;
|
|
9
|
-
};
|
|
10
|
-
dark: Record<string, string> & {
|
|
11
|
-
surface: string;
|
|
12
|
-
};
|
|
13
|
-
};
|
|
14
|
-
p3: {
|
|
15
|
-
light: Record<string, string> & {
|
|
16
|
-
surface: string;
|
|
17
|
-
};
|
|
18
|
-
dark: Record<string, string> & {
|
|
19
|
-
surface: string;
|
|
20
|
-
};
|
|
21
|
-
};
|
|
22
|
-
contrast: string;
|
|
23
|
-
indicator: string;
|
|
24
|
-
track: string;
|
|
25
|
-
};
|
|
26
|
-
export declare const css: {
|
|
27
|
-
scale(scheme: "light" | "lightAlpha" | "dark" | "darkAlpha", config: ColorConfig): string;
|
|
28
|
-
alpha(config: AlphaConfig): string;
|
|
29
|
-
semantic(name: string, config: ColorConfig): string;
|
|
30
|
-
};
|
package/dist/lib.js
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
const lightSelector = `:root, .light, .light-theme`;
|
|
2
|
-
const darkSelector = `.dark, .dark-theme`;
|
|
3
|
-
/** Convert color key to CSS variable name (e.g., "blue1" → "--blue-1", "blueA1" → "--blue-a1") */
|
|
4
|
-
const toVarName = (key) => '--' + key.replace(/A?(\d)/, (_, num) => (key.includes('A') ? `-a${num}` : `-${num}`));
|
|
5
|
-
export const css = {
|
|
6
|
-
scale(scheme, config) {
|
|
7
|
-
const isLight = scheme === 'light' || scheme === 'lightAlpha';
|
|
8
|
-
const isAlpha = scheme === 'lightAlpha' || scheme === 'darkAlpha';
|
|
9
|
-
const selector = isLight ? lightSelector : darkSelector;
|
|
10
|
-
const srgbScale = isLight ? config.srgb.light : config.srgb.dark;
|
|
11
|
-
const p3Scale = isLight ? config.p3.light : config.p3.dark;
|
|
12
|
-
const filterEntries = (obj) => Object.entries(obj).filter(([key]) => {
|
|
13
|
-
if (key === 'surface')
|
|
14
|
-
return false;
|
|
15
|
-
const hasAlpha = key.includes('A');
|
|
16
|
-
return isAlpha ? hasAlpha : !hasAlpha;
|
|
17
|
-
});
|
|
18
|
-
const baseVars = filterEntries(srgbScale)
|
|
19
|
-
.map(([key, value]) => ` ${toVarName(key)}: ${value};`)
|
|
20
|
-
.join('\n');
|
|
21
|
-
const p3Vars = filterEntries(p3Scale)
|
|
22
|
-
.map(([key, value]) => ` ${toVarName(key)}: ${value};`)
|
|
23
|
-
.join('\n');
|
|
24
|
-
return `${selector} {
|
|
25
|
-
${baseVars}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
@supports (color: color(display-p3 1 1 1)) {
|
|
29
|
-
@media (color-gamut: p3) {
|
|
30
|
-
${selector} {
|
|
31
|
-
${p3Vars}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
`;
|
|
36
|
-
},
|
|
37
|
-
alpha(config) {
|
|
38
|
-
const baseVars = Object.entries(config.srgb)
|
|
39
|
-
.map(([key, value]) => ` ${toVarName(key)}: ${value};`)
|
|
40
|
-
.join('\n');
|
|
41
|
-
const p3Vars = Object.entries(config.p3)
|
|
42
|
-
.map(([key, value]) => ` ${toVarName(key)}: ${value};`)
|
|
43
|
-
.join('\n');
|
|
44
|
-
return `:root {
|
|
45
|
-
${baseVars}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
@supports (color: color(display-p3 1 1 1)) {
|
|
49
|
-
@media (color-gamut: p3) {
|
|
50
|
-
:root {
|
|
51
|
-
${p3Vars}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
`;
|
|
56
|
-
},
|
|
57
|
-
semantic(name, config) {
|
|
58
|
-
const varRef = (key) => `var(${toVarName(key)})`;
|
|
59
|
-
return `:root {
|
|
60
|
-
--${name}-contrast: ${config.contrast};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
:root,
|
|
64
|
-
.light,
|
|
65
|
-
.light-theme {
|
|
66
|
-
--${name}-surface: ${config.srgb.light.surface};
|
|
67
|
-
--${name}-indicator: ${varRef(config.indicator)};
|
|
68
|
-
--${name}-track: ${varRef(config.track)};
|
|
69
|
-
@supports (color: color(display-p3 1 1 1)) {
|
|
70
|
-
@media (color-gamut: p3) {
|
|
71
|
-
--${name}-surface: ${config.p3.light.surface};
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
.dark,
|
|
77
|
-
.dark-theme {
|
|
78
|
-
--${name}-surface: ${config.srgb.dark.surface};
|
|
79
|
-
--${name}-indicator: ${varRef(config.indicator)};
|
|
80
|
-
--${name}-track: ${varRef(config.track)};
|
|
81
|
-
@supports (color: color(display-p3 1 1 1)) {
|
|
82
|
-
@media (color-gamut: p3) {
|
|
83
|
-
--${name}-surface: ${config.p3.dark.surface};
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
`;
|
|
88
|
-
},
|
|
89
|
-
};
|