@symblight/md-colors 0.1.0 → 0.1.1
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 +63 -24
- package/dist/cli.js +102 -0
- package/dist/client.esm.js +5 -5
- package/dist/client.esm.js.map +2 -2
- package/dist/client.js +1 -1
- package/dist/client.js.map +3 -3
- package/dist/index.js +33 -0
- package/dist/index.js.map +3 -3
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -10,44 +10,55 @@ Built on [`@material/material-color-utilities`](https://github.com/material-foun
|
|
|
10
10
|
npm install @symblight/md-colors
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Builds
|
|
14
14
|
|
|
15
15
|
| Build | Entry | Format | Use case |
|
|
16
16
|
|---|---|---|---|
|
|
17
|
-
| Node / bundler | `dist/index.js` | ESM |
|
|
18
|
-
| Browser (bundler) | `dist/client.esm.js` | ESM | Vite, Storybook
|
|
19
|
-
| Browser (script) | `dist/client.js` | IIFE | Plain `<script>` tag
|
|
17
|
+
| Node / bundler | `dist/index.js` | ESM | `generateTokens`, `generateCSSFile` |
|
|
18
|
+
| Browser (bundler) | `dist/client.esm.js` | ESM | Vite, Storybook — named import |
|
|
19
|
+
| Browser (script) | `dist/client.js` | IIFE | Plain `<script>` tag |
|
|
20
|
+
| CLI | `dist/cli.js` | ESM | Terminal usage via `md-colors` |
|
|
20
21
|
|
|
21
22
|
---
|
|
22
23
|
|
|
23
24
|
## Node — programmatic API
|
|
24
25
|
|
|
25
|
-
Import `generateTokens` to build token maps in Node.js scripts or server-side tooling.
|
|
26
|
-
|
|
27
26
|
```js
|
|
28
|
-
import { generateTokens } from "@symblight/md-colors";
|
|
27
|
+
import { generateTokens, generateCSSFile } from "@symblight/md-colors";
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### `generateTokens(config)`
|
|
29
31
|
|
|
32
|
+
Returns a token map — use it to apply tokens however you like.
|
|
33
|
+
|
|
34
|
+
```js
|
|
30
35
|
const tokens = generateTokens({ sourceColor: "#6750A4", scheme: "dark" });
|
|
31
36
|
// { "--md-sys-color-primary": "oklch(…)", … }
|
|
32
37
|
```
|
|
33
38
|
|
|
34
|
-
### `generateTokens(config)`
|
|
35
|
-
|
|
36
39
|
| Param | Type | Default | Description |
|
|
37
40
|
|---|---|---|---|
|
|
38
41
|
| `config.sourceColor` | `string` | `"#1D5D78"` | Seed color as a hex string |
|
|
39
42
|
| `config.scheme` | `"light" \| "dark"` | `"light"` | Color scheme variant |
|
|
40
43
|
|
|
41
|
-
|
|
44
|
+
### `generateCSSFile(config)`
|
|
42
45
|
|
|
43
|
-
|
|
46
|
+
Writes a `colors.css` file with `:root`-scoped tokens.
|
|
44
47
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
```js
|
|
49
|
+
generateCSSFile({
|
|
50
|
+
sourceColor: "#6750A4",
|
|
51
|
+
scheme: "dark",
|
|
52
|
+
output: "./theme/colors.css",
|
|
53
|
+
});
|
|
49
54
|
```
|
|
50
55
|
|
|
56
|
+
| Param | Type | Default | Description |
|
|
57
|
+
|---|---|---|---|
|
|
58
|
+
| `config.sourceColor` | `string` | `"#1D5D78"` | Seed color as a hex string |
|
|
59
|
+
| `config.scheme` | `"light" \| "dark"` | `"light"` | Color scheme variant |
|
|
60
|
+
| `config.output` | `string` | `./colors.css` (next to module) | Output file path |
|
|
61
|
+
|
|
51
62
|
Output:
|
|
52
63
|
|
|
53
64
|
```css
|
|
@@ -59,32 +70,39 @@ Output:
|
|
|
59
70
|
}
|
|
60
71
|
```
|
|
61
72
|
|
|
62
|
-
Source color and scheme are configured directly in `create-theme-file.mjs`.
|
|
63
|
-
|
|
64
73
|
---
|
|
65
74
|
|
|
66
75
|
## Browser client — runtime theming
|
|
67
76
|
|
|
68
|
-
|
|
77
|
+
Import `generateTheme` and call it directly — no globals, no window assignment.
|
|
69
78
|
|
|
70
|
-
###
|
|
79
|
+
### Named import (Vite, Storybook, bundler)
|
|
71
80
|
|
|
72
81
|
```js
|
|
73
|
-
import "@symblight/md-colors/client";
|
|
82
|
+
import { generateTheme } from "@symblight/md-colors/client";
|
|
74
83
|
|
|
75
|
-
|
|
84
|
+
generateTheme({ sourceColor: "#6750A4", scheme: "dark" });
|
|
76
85
|
```
|
|
77
86
|
|
|
78
87
|
### Via `<script>` tag (no bundler)
|
|
79
88
|
|
|
89
|
+
```html
|
|
90
|
+
<script type="module">
|
|
91
|
+
import { generateTheme } from "./node_modules/@symblight/md-colors/dist/client.esm.js";
|
|
92
|
+
generateTheme({ sourceColor: "#6750A4", scheme: "dark" });
|
|
93
|
+
</script>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Or with the self-contained IIFE build:
|
|
97
|
+
|
|
80
98
|
```html
|
|
81
99
|
<script src="node_modules/@symblight/md-colors/dist/client.js"></script>
|
|
82
100
|
<script>
|
|
83
|
-
|
|
101
|
+
// client.js exposes nothing on window — use it as an ES module instead (see above)
|
|
84
102
|
</script>
|
|
85
103
|
```
|
|
86
104
|
|
|
87
|
-
### `
|
|
105
|
+
### `generateTheme(options)`
|
|
88
106
|
|
|
89
107
|
| Param | Type | Default | Description |
|
|
90
108
|
|---|---|---|---|
|
|
@@ -95,11 +113,32 @@ Sets every `--md-sys-color-*` variable on `document.documentElement` via `style.
|
|
|
95
113
|
|
|
96
114
|
---
|
|
97
115
|
|
|
116
|
+
## CLI
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
# npx (no install)
|
|
120
|
+
npx md-colors --sourceColor="#6750A4" --scheme=dark --output=./theme/colors.css
|
|
121
|
+
|
|
122
|
+
# global install
|
|
123
|
+
npm install -g @symblight/md-colors
|
|
124
|
+
md-colors --sourceColor="#6750A4" --scheme=light --output=./colors.css
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Options
|
|
128
|
+
|
|
129
|
+
| Flag | Short | Default | Description |
|
|
130
|
+
|---|---|---|---|
|
|
131
|
+
| `--sourceColor` | `-c` | `#1D5D78` | Seed color as a hex string |
|
|
132
|
+
| `--scheme` | `-s` | `light` | `light` or `dark` |
|
|
133
|
+
| `--output` | `-o` | `./colors.css` | Output file path |
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
98
137
|
## Development
|
|
99
138
|
|
|
100
139
|
```bash
|
|
101
140
|
pnpm build # Build all dist outputs
|
|
102
|
-
pnpm generate-theme # Write colors.css
|
|
141
|
+
pnpm generate-theme # Write colors.css via CLI (uses defaults)
|
|
103
142
|
pnpm test # Run Jest tests
|
|
104
143
|
```
|
|
105
144
|
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
#!/usr/bin/env node
|
|
3
|
+
|
|
4
|
+
// cli.mjs
|
|
5
|
+
import { parseArgs } from "node:util";
|
|
6
|
+
|
|
7
|
+
// create-theme-file.mjs
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import fs from "node:fs";
|
|
10
|
+
import { fileURLToPath } from "node:url";
|
|
11
|
+
|
|
12
|
+
// tokens.mjs
|
|
13
|
+
import {
|
|
14
|
+
argbFromHex,
|
|
15
|
+
themeFromSourceColor,
|
|
16
|
+
hexFromArgb,
|
|
17
|
+
MaterialDynamicColors,
|
|
18
|
+
SchemeContent,
|
|
19
|
+
Hct
|
|
20
|
+
} from "@material/material-color-utilities";
|
|
21
|
+
import { converter, formatCss } from "culori";
|
|
22
|
+
var oklch = converter("oklch");
|
|
23
|
+
var materialColors = {
|
|
24
|
+
"surface-container-highest": MaterialDynamicColors.surfaceContainerHighest,
|
|
25
|
+
"surface-container-high": MaterialDynamicColors.surfaceContainerHigh,
|
|
26
|
+
"surface-dim": MaterialDynamicColors.surfaceDim,
|
|
27
|
+
"surface-bright": MaterialDynamicColors.surfaceBright,
|
|
28
|
+
"surface-container-lowest": MaterialDynamicColors.surfaceContainerLowest,
|
|
29
|
+
"surface-container-low": MaterialDynamicColors.surfaceContainerLow
|
|
30
|
+
};
|
|
31
|
+
function setSchemeProperties(scheme2, suffix = "") {
|
|
32
|
+
let result = {};
|
|
33
|
+
for (const [key, value] of Object.entries(scheme2)) {
|
|
34
|
+
const token = key.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
35
|
+
const color = hexFromArgb(value);
|
|
36
|
+
const converted = oklch(color);
|
|
37
|
+
const name = formatCss(converted);
|
|
38
|
+
const variableName = `--md-sys-color-${token}${suffix}`;
|
|
39
|
+
result[variableName] = name;
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
function generateTokens(config = { scheme: "light", sourceColor: "#1D5D78" }) {
|
|
44
|
+
const theme = themeFromSourceColor(argbFromHex(config.sourceColor), []);
|
|
45
|
+
const scheme2 = new SchemeContent(
|
|
46
|
+
Hct.fromInt(argbFromHex(config.sourceColor)),
|
|
47
|
+
config.scheme === "dark",
|
|
48
|
+
0
|
|
49
|
+
);
|
|
50
|
+
let palette = {};
|
|
51
|
+
for (const [key, value] of Object.entries(materialColors)) {
|
|
52
|
+
palette[key] = value.getArgb(scheme2);
|
|
53
|
+
}
|
|
54
|
+
const currentTheme = theme.schemes[config.scheme].toJSON();
|
|
55
|
+
const tokens = setSchemeProperties({ ...currentTheme, ...palette });
|
|
56
|
+
return tokens;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// create-theme-file.mjs
|
|
60
|
+
function template(variables) {
|
|
61
|
+
return `:root {
|
|
62
|
+
${variables}
|
|
63
|
+
}`;
|
|
64
|
+
}
|
|
65
|
+
function normalizeCSSVariablesContent(variables = {}) {
|
|
66
|
+
let str = "";
|
|
67
|
+
for (const cssVar in variables) {
|
|
68
|
+
str += `${cssVar}: ${variables[cssVar]};
|
|
69
|
+
`;
|
|
70
|
+
}
|
|
71
|
+
return str;
|
|
72
|
+
}
|
|
73
|
+
function generateCSSFile(config = {}) {
|
|
74
|
+
const { scheme: scheme2 = "light", sourceColor: sourceColor2 = "#1D5D78", output: output2 } = config;
|
|
75
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
76
|
+
const __dirname = path.dirname(__filename);
|
|
77
|
+
const outputPath = output2 ? path.resolve(output2) : path.join(__dirname, "colors.css");
|
|
78
|
+
const tokens = generateTokens({ scheme: scheme2, sourceColor: sourceColor2 });
|
|
79
|
+
const stringTokens = normalizeCSSVariablesContent(tokens);
|
|
80
|
+
const themeBody = template(stringTokens);
|
|
81
|
+
fs.writeFile(outputPath, themeBody, (err) => {
|
|
82
|
+
if (err) {
|
|
83
|
+
console.error(err);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// cli.mjs
|
|
89
|
+
var { values } = parseArgs({
|
|
90
|
+
options: {
|
|
91
|
+
sourceColor: { type: "string", short: "c", default: "#1D5D78" },
|
|
92
|
+
scheme: { type: "string", short: "s", default: "light" },
|
|
93
|
+
output: { type: "string", short: "o", default: "./colors.css" }
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
var { sourceColor, scheme, output } = values;
|
|
97
|
+
if (scheme !== "light" && scheme !== "dark") {
|
|
98
|
+
console.error(`Error: --scheme must be "light" or "dark", got "${scheme}"`);
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
generateCSSFile({ sourceColor, scheme, output });
|
|
102
|
+
console.log(`Generated ${output} (sourceColor: ${sourceColor}, scheme: ${scheme})`);
|
package/dist/client.esm.js
CHANGED
|
@@ -6939,15 +6939,15 @@ function generateTokens(config = { scheme: "light", sourceColor: "#1D5D78" }) {
|
|
|
6939
6939
|
}
|
|
6940
6940
|
|
|
6941
6941
|
// client.mjs
|
|
6942
|
-
|
|
6943
|
-
const tokens = generateTokens({
|
|
6944
|
-
sourceColor,
|
|
6945
|
-
scheme
|
|
6946
|
-
});
|
|
6942
|
+
function generateTheme({ sourceColor, scheme = "light" } = {}) {
|
|
6943
|
+
const tokens = generateTokens({ sourceColor, scheme });
|
|
6947
6944
|
const root = document.documentElement;
|
|
6948
6945
|
for (const [variable, value] of Object.entries(tokens)) {
|
|
6949
6946
|
root.style.setProperty(variable, value);
|
|
6950
6947
|
}
|
|
6948
|
+
}
|
|
6949
|
+
export {
|
|
6950
|
+
generateTheme
|
|
6951
6951
|
};
|
|
6952
6952
|
/*! Bundled license information:
|
|
6953
6953
|
|