@symblight/md-colors 0.1.1 → 0.2.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 +14 -6
- package/dist/cli.js +93 -38
- package/dist/client.cjs +6492 -0
- package/dist/client.cjs.map +7 -0
- package/dist/client.esm.js +95 -670
- package/dist/client.esm.js.map +4 -4
- package/dist/client.js +3 -3
- package/dist/client.js.map +4 -4
- package/dist/index.js +84 -29
- package/dist/index.js.map +2 -2
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -16,7 +16,8 @@ npm install @symblight/md-colors
|
|
|
16
16
|
|---|---|---|---|
|
|
17
17
|
| Node / bundler | `dist/index.js` | ESM | `generateTokens`, `generateCSSFile` |
|
|
18
18
|
| Browser (bundler) | `dist/client.esm.js` | ESM | Vite, Storybook — named import |
|
|
19
|
-
| Browser (
|
|
19
|
+
| Browser (CJS) | `dist/client.cjs` | CJS | `require("@symblight/md-colors/client")` |
|
|
20
|
+
| Browser (script) | `dist/client.js` | IIFE | Plain `<script>` tag — `window.MdColors` |
|
|
20
21
|
| CLI | `dist/cli.js` | ESM | Terminal usage via `md-colors` |
|
|
21
22
|
|
|
22
23
|
---
|
|
@@ -29,7 +30,11 @@ import { generateTokens, generateCSSFile } from "@symblight/md-colors";
|
|
|
29
30
|
|
|
30
31
|
### `generateTokens(config)`
|
|
31
32
|
|
|
32
|
-
Returns a token map — use it to apply tokens however you like.
|
|
33
|
+
Returns a token map — use it to apply tokens however you like. All 49 MD3
|
|
34
|
+
color roles are resolved from one tonal-spot scheme (the M3 default), including
|
|
35
|
+
`surface-container`, `surface-tint` and the `*-fixed` / `*-fixed-dim` /
|
|
36
|
+
`on-*-fixed` / `on-*-fixed-variant` roles. Missing config fields fall back to
|
|
37
|
+
their defaults; an invalid `sourceColor` or `scheme` throws a `TypeError`.
|
|
33
38
|
|
|
34
39
|
```js
|
|
35
40
|
const tokens = generateTokens({ sourceColor: "#6750A4", scheme: "dark" });
|
|
@@ -43,10 +48,11 @@ const tokens = generateTokens({ sourceColor: "#6750A4", scheme: "dark" });
|
|
|
43
48
|
|
|
44
49
|
### `generateCSSFile(config)`
|
|
45
50
|
|
|
46
|
-
Writes a `colors.css` file with `:root`-scoped tokens.
|
|
51
|
+
Writes a `colors.css` file with `:root`-scoped tokens. Returns a promise that
|
|
52
|
+
resolves with the absolute output path and rejects if the write fails.
|
|
47
53
|
|
|
48
54
|
```js
|
|
49
|
-
generateCSSFile({
|
|
55
|
+
await generateCSSFile({
|
|
50
56
|
sourceColor: "#6750A4",
|
|
51
57
|
scheme: "dark",
|
|
52
58
|
output: "./theme/colors.css",
|
|
@@ -98,7 +104,7 @@ Or with the self-contained IIFE build:
|
|
|
98
104
|
```html
|
|
99
105
|
<script src="node_modules/@symblight/md-colors/dist/client.js"></script>
|
|
100
106
|
<script>
|
|
101
|
-
|
|
107
|
+
MdColors.generateTheme({ sourceColor: "#6750A4", scheme: "dark" });
|
|
102
108
|
</script>
|
|
103
109
|
```
|
|
104
110
|
|
|
@@ -106,7 +112,7 @@ Or with the self-contained IIFE build:
|
|
|
106
112
|
|
|
107
113
|
| Param | Type | Default | Description |
|
|
108
114
|
|---|---|---|---|
|
|
109
|
-
| `options.sourceColor` | `string` |
|
|
115
|
+
| `options.sourceColor` | `string` | `"#1D5D78"` | Seed color as a hex string |
|
|
110
116
|
| `options.scheme` | `"light" \| "dark"` | `"light"` | Color scheme variant |
|
|
111
117
|
|
|
112
118
|
Sets every `--md-sys-color-*` variable on `document.documentElement` via `style.setProperty`.
|
|
@@ -132,6 +138,8 @@ md-colors --sourceColor="#6750A4" --scheme=light --output=./colors.css
|
|
|
132
138
|
| `--scheme` | `-s` | `light` | `light` or `dark` |
|
|
133
139
|
| `--output` | `-o` | `./colors.css` | Output file path |
|
|
134
140
|
|
|
141
|
+
Exits with code 1 on an invalid color, invalid scheme or failed write.
|
|
142
|
+
|
|
135
143
|
---
|
|
136
144
|
|
|
137
145
|
## Development
|
package/dist/cli.js
CHANGED
|
@@ -1,36 +1,94 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
#!/usr/bin/env node
|
|
3
2
|
|
|
4
3
|
// cli.mjs
|
|
5
4
|
import { parseArgs } from "node:util";
|
|
6
5
|
|
|
7
6
|
// create-theme-file.mjs
|
|
8
7
|
import path from "node:path";
|
|
9
|
-
import fs from "node:fs";
|
|
8
|
+
import fs from "node:fs/promises";
|
|
10
9
|
import { fileURLToPath } from "node:url";
|
|
11
10
|
|
|
12
11
|
// tokens.mjs
|
|
13
12
|
import {
|
|
14
13
|
argbFromHex,
|
|
15
|
-
themeFromSourceColor,
|
|
16
14
|
hexFromArgb,
|
|
17
15
|
MaterialDynamicColors,
|
|
18
|
-
|
|
16
|
+
SchemeTonalSpot,
|
|
19
17
|
Hct
|
|
20
18
|
} from "@material/material-color-utilities";
|
|
21
19
|
import { converter, formatCss } from "culori";
|
|
22
20
|
var oklch = converter("oklch");
|
|
23
|
-
var
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
21
|
+
var DEFAULT_SOURCE_COLOR = "#1D5D78";
|
|
22
|
+
var HEX_RE = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;
|
|
23
|
+
var COLOR_ROLES = (
|
|
24
|
+
/** @type {const} */
|
|
25
|
+
[
|
|
26
|
+
"primary",
|
|
27
|
+
"onPrimary",
|
|
28
|
+
"primaryContainer",
|
|
29
|
+
"onPrimaryContainer",
|
|
30
|
+
"inversePrimary",
|
|
31
|
+
"primaryFixed",
|
|
32
|
+
"primaryFixedDim",
|
|
33
|
+
"onPrimaryFixed",
|
|
34
|
+
"onPrimaryFixedVariant",
|
|
35
|
+
"secondary",
|
|
36
|
+
"onSecondary",
|
|
37
|
+
"secondaryContainer",
|
|
38
|
+
"onSecondaryContainer",
|
|
39
|
+
"secondaryFixed",
|
|
40
|
+
"secondaryFixedDim",
|
|
41
|
+
"onSecondaryFixed",
|
|
42
|
+
"onSecondaryFixedVariant",
|
|
43
|
+
"tertiary",
|
|
44
|
+
"onTertiary",
|
|
45
|
+
"tertiaryContainer",
|
|
46
|
+
"onTertiaryContainer",
|
|
47
|
+
"tertiaryFixed",
|
|
48
|
+
"tertiaryFixedDim",
|
|
49
|
+
"onTertiaryFixed",
|
|
50
|
+
"onTertiaryFixedVariant",
|
|
51
|
+
"error",
|
|
52
|
+
"onError",
|
|
53
|
+
"errorContainer",
|
|
54
|
+
"onErrorContainer",
|
|
55
|
+
"surface",
|
|
56
|
+
"onSurface",
|
|
57
|
+
"surfaceVariant",
|
|
58
|
+
"onSurfaceVariant",
|
|
59
|
+
"surfaceDim",
|
|
60
|
+
"surfaceBright",
|
|
61
|
+
"surfaceContainerLowest",
|
|
62
|
+
"surfaceContainerLow",
|
|
63
|
+
"surfaceContainer",
|
|
64
|
+
"surfaceContainerHigh",
|
|
65
|
+
"surfaceContainerHighest",
|
|
66
|
+
"surfaceTint",
|
|
67
|
+
"inverseSurface",
|
|
68
|
+
"inverseOnSurface",
|
|
69
|
+
"outline",
|
|
70
|
+
"outlineVariant",
|
|
71
|
+
"shadow",
|
|
72
|
+
"scrim",
|
|
73
|
+
"background",
|
|
74
|
+
"onBackground"
|
|
75
|
+
]
|
|
76
|
+
);
|
|
77
|
+
function resolveConfig({ sourceColor = DEFAULT_SOURCE_COLOR, scheme = "light" } = {}) {
|
|
78
|
+
if (typeof sourceColor !== "string" || !HEX_RE.test(sourceColor)) {
|
|
79
|
+
throw new TypeError(`sourceColor must be a hex color like "#6750A4", got ${JSON.stringify(sourceColor)}`);
|
|
80
|
+
}
|
|
81
|
+
if (scheme !== "light" && scheme !== "dark") {
|
|
82
|
+
throw new TypeError(`scheme must be "light" or "dark", got ${JSON.stringify(scheme)}`);
|
|
83
|
+
}
|
|
84
|
+
return { sourceColor, scheme: (
|
|
85
|
+
/** @type {ColorScheme} */
|
|
86
|
+
scheme
|
|
87
|
+
) };
|
|
88
|
+
}
|
|
89
|
+
function setSchemeProperties(scheme, suffix = "") {
|
|
32
90
|
let result = {};
|
|
33
|
-
for (const [key, value] of Object.entries(
|
|
91
|
+
for (const [key, value] of Object.entries(scheme)) {
|
|
34
92
|
const token = key.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
35
93
|
const color = hexFromArgb(value);
|
|
36
94
|
const converted = oklch(color);
|
|
@@ -40,20 +98,18 @@ function setSchemeProperties(scheme2, suffix = "") {
|
|
|
40
98
|
}
|
|
41
99
|
return result;
|
|
42
100
|
}
|
|
43
|
-
function generateTokens(config = {
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
Hct.fromInt(argbFromHex(
|
|
47
|
-
|
|
101
|
+
function generateTokens(config = {}) {
|
|
102
|
+
const { sourceColor, scheme } = resolveConfig(config);
|
|
103
|
+
const dynamicScheme = new SchemeTonalSpot(
|
|
104
|
+
Hct.fromInt(argbFromHex(sourceColor)),
|
|
105
|
+
scheme === "dark",
|
|
48
106
|
0
|
|
49
107
|
);
|
|
50
108
|
let palette = {};
|
|
51
|
-
for (const
|
|
52
|
-
palette[
|
|
109
|
+
for (const role of COLOR_ROLES) {
|
|
110
|
+
palette[role] = MaterialDynamicColors[role].getArgb(dynamicScheme);
|
|
53
111
|
}
|
|
54
|
-
|
|
55
|
-
const tokens = setSchemeProperties({ ...currentTheme, ...palette });
|
|
56
|
-
return tokens;
|
|
112
|
+
return setSchemeProperties(palette);
|
|
57
113
|
}
|
|
58
114
|
|
|
59
115
|
// create-theme-file.mjs
|
|
@@ -70,33 +126,32 @@ function normalizeCSSVariablesContent(variables = {}) {
|
|
|
70
126
|
}
|
|
71
127
|
return str;
|
|
72
128
|
}
|
|
73
|
-
function generateCSSFile(config = {}) {
|
|
74
|
-
const {
|
|
129
|
+
async function generateCSSFile(config = {}) {
|
|
130
|
+
const { output: output2, ...tokenConfig } = config;
|
|
75
131
|
const __filename = fileURLToPath(import.meta.url);
|
|
76
132
|
const __dirname = path.dirname(__filename);
|
|
77
133
|
const outputPath = output2 ? path.resolve(output2) : path.join(__dirname, "colors.css");
|
|
78
|
-
const tokens = generateTokens(
|
|
134
|
+
const tokens = generateTokens(tokenConfig);
|
|
79
135
|
const stringTokens = normalizeCSSVariablesContent(tokens);
|
|
80
136
|
const themeBody = template(stringTokens);
|
|
81
|
-
fs.writeFile(outputPath, themeBody
|
|
82
|
-
|
|
83
|
-
console.error(err);
|
|
84
|
-
}
|
|
85
|
-
});
|
|
137
|
+
await fs.writeFile(outputPath, themeBody);
|
|
138
|
+
return outputPath;
|
|
86
139
|
}
|
|
87
140
|
|
|
88
141
|
// cli.mjs
|
|
89
142
|
var { values } = parseArgs({
|
|
90
143
|
options: {
|
|
91
|
-
sourceColor: { type: "string", short: "c", default:
|
|
144
|
+
sourceColor: { type: "string", short: "c", default: DEFAULT_SOURCE_COLOR },
|
|
92
145
|
scheme: { type: "string", short: "s", default: "light" },
|
|
93
146
|
output: { type: "string", short: "o", default: "./colors.css" }
|
|
94
147
|
}
|
|
95
148
|
});
|
|
96
|
-
var {
|
|
97
|
-
|
|
98
|
-
|
|
149
|
+
var { output } = values;
|
|
150
|
+
try {
|
|
151
|
+
const { sourceColor, scheme } = resolveConfig(values);
|
|
152
|
+
const outputPath = await generateCSSFile({ sourceColor, scheme, output });
|
|
153
|
+
console.log(`Generated ${outputPath} (sourceColor: ${sourceColor}, scheme: ${scheme})`);
|
|
154
|
+
} catch (err) {
|
|
155
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
99
156
|
process.exit(1);
|
|
100
157
|
}
|
|
101
|
-
generateCSSFile({ sourceColor, scheme, output });
|
|
102
|
-
console.log(`Generated ${output} (sourceColor: ${sourceColor}, scheme: ${scheme})`);
|