@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/dist/index.js CHANGED
@@ -1,22 +1,81 @@
1
1
  // tokens.mjs
2
2
  import {
3
3
  argbFromHex,
4
- themeFromSourceColor,
5
4
  hexFromArgb,
6
5
  MaterialDynamicColors,
7
- SchemeContent,
6
+ SchemeTonalSpot,
8
7
  Hct
9
8
  } from "@material/material-color-utilities";
10
9
  import { converter, formatCss } from "culori";
11
10
  var oklch = converter("oklch");
12
- var materialColors = {
13
- "surface-container-highest": MaterialDynamicColors.surfaceContainerHighest,
14
- "surface-container-high": MaterialDynamicColors.surfaceContainerHigh,
15
- "surface-dim": MaterialDynamicColors.surfaceDim,
16
- "surface-bright": MaterialDynamicColors.surfaceBright,
17
- "surface-container-lowest": MaterialDynamicColors.surfaceContainerLowest,
18
- "surface-container-low": MaterialDynamicColors.surfaceContainerLow
19
- };
11
+ var DEFAULT_SOURCE_COLOR = "#1D5D78";
12
+ var HEX_RE = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;
13
+ var COLOR_ROLES = (
14
+ /** @type {const} */
15
+ [
16
+ "primary",
17
+ "onPrimary",
18
+ "primaryContainer",
19
+ "onPrimaryContainer",
20
+ "inversePrimary",
21
+ "primaryFixed",
22
+ "primaryFixedDim",
23
+ "onPrimaryFixed",
24
+ "onPrimaryFixedVariant",
25
+ "secondary",
26
+ "onSecondary",
27
+ "secondaryContainer",
28
+ "onSecondaryContainer",
29
+ "secondaryFixed",
30
+ "secondaryFixedDim",
31
+ "onSecondaryFixed",
32
+ "onSecondaryFixedVariant",
33
+ "tertiary",
34
+ "onTertiary",
35
+ "tertiaryContainer",
36
+ "onTertiaryContainer",
37
+ "tertiaryFixed",
38
+ "tertiaryFixedDim",
39
+ "onTertiaryFixed",
40
+ "onTertiaryFixedVariant",
41
+ "error",
42
+ "onError",
43
+ "errorContainer",
44
+ "onErrorContainer",
45
+ "surface",
46
+ "onSurface",
47
+ "surfaceVariant",
48
+ "onSurfaceVariant",
49
+ "surfaceDim",
50
+ "surfaceBright",
51
+ "surfaceContainerLowest",
52
+ "surfaceContainerLow",
53
+ "surfaceContainer",
54
+ "surfaceContainerHigh",
55
+ "surfaceContainerHighest",
56
+ "surfaceTint",
57
+ "inverseSurface",
58
+ "inverseOnSurface",
59
+ "outline",
60
+ "outlineVariant",
61
+ "shadow",
62
+ "scrim",
63
+ "background",
64
+ "onBackground"
65
+ ]
66
+ );
67
+ function resolveConfig({ sourceColor = DEFAULT_SOURCE_COLOR, scheme = "light" } = {}) {
68
+ if (typeof sourceColor !== "string" || !HEX_RE.test(sourceColor)) {
69
+ throw new TypeError(`sourceColor must be a hex color like "#6750A4", got ${JSON.stringify(sourceColor)}`);
70
+ }
71
+ if (scheme !== "light" && scheme !== "dark") {
72
+ throw new TypeError(`scheme must be "light" or "dark", got ${JSON.stringify(scheme)}`);
73
+ }
74
+ return { sourceColor, scheme: (
75
+ /** @type {ColorScheme} */
76
+ scheme
77
+ ) };
78
+ }
20
79
  function setSchemeProperties(scheme, suffix = "") {
21
80
  let result = {};
22
81
  for (const [key, value] of Object.entries(scheme)) {
@@ -29,25 +88,23 @@ function setSchemeProperties(scheme, suffix = "") {
29
88
  }
30
89
  return result;
31
90
  }
32
- function generateTokens(config = { scheme: "light", sourceColor: "#1D5D78" }) {
33
- const theme = themeFromSourceColor(argbFromHex(config.sourceColor), []);
34
- const scheme = new SchemeContent(
35
- Hct.fromInt(argbFromHex(config.sourceColor)),
36
- config.scheme === "dark",
91
+ function generateTokens(config = {}) {
92
+ const { sourceColor, scheme } = resolveConfig(config);
93
+ const dynamicScheme = new SchemeTonalSpot(
94
+ Hct.fromInt(argbFromHex(sourceColor)),
95
+ scheme === "dark",
37
96
  0
38
97
  );
39
98
  let palette = {};
40
- for (const [key, value] of Object.entries(materialColors)) {
41
- palette[key] = value.getArgb(scheme);
99
+ for (const role of COLOR_ROLES) {
100
+ palette[role] = MaterialDynamicColors[role].getArgb(dynamicScheme);
42
101
  }
43
- const currentTheme = theme.schemes[config.scheme].toJSON();
44
- const tokens = setSchemeProperties({ ...currentTheme, ...palette });
45
- return tokens;
102
+ return setSchemeProperties(palette);
46
103
  }
47
104
 
48
105
  // create-theme-file.mjs
49
106
  import path from "node:path";
50
- import fs from "node:fs";
107
+ import fs from "node:fs/promises";
51
108
  import { fileURLToPath } from "node:url";
52
109
  function template(variables) {
53
110
  return `:root {
@@ -62,21 +119,19 @@ function normalizeCSSVariablesContent(variables = {}) {
62
119
  }
63
120
  return str;
64
121
  }
65
- function generateCSSFile(config = {}) {
66
- const { scheme = "light", sourceColor = "#1D5D78", output } = config;
122
+ async function generateCSSFile(config = {}) {
123
+ const { output, ...tokenConfig } = config;
67
124
  const __filename = fileURLToPath(import.meta.url);
68
125
  const __dirname = path.dirname(__filename);
69
126
  const outputPath = output ? path.resolve(output) : path.join(__dirname, "colors.css");
70
- const tokens = generateTokens({ scheme, sourceColor });
127
+ const tokens = generateTokens(tokenConfig);
71
128
  const stringTokens = normalizeCSSVariablesContent(tokens);
72
129
  const themeBody = template(stringTokens);
73
- fs.writeFile(outputPath, themeBody, (err) => {
74
- if (err) {
75
- console.error(err);
76
- }
77
- });
130
+ await fs.writeFile(outputPath, themeBody);
131
+ return outputPath;
78
132
  }
79
133
  export {
134
+ DEFAULT_SOURCE_COLOR,
80
135
  generateCSSFile,
81
136
  generateTokens,
82
137
  setSchemeProperties
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../tokens.mjs", "../create-theme-file.mjs"],
4
- "sourcesContent": ["import {\n argbFromHex,\n themeFromSourceColor,\n hexFromArgb,\n MaterialDynamicColors,\n SchemeContent,\n Hct,\n} from \"@material/material-color-utilities\";\nimport { converter, formatCss } from \"culori\";\n\nlet oklch = converter(\"oklch\");\n\nconst materialColors = {\n \"surface-container-highest\": MaterialDynamicColors.surfaceContainerHighest,\n \"surface-container-high\": MaterialDynamicColors.surfaceContainerHigh,\n \"surface-dim\": MaterialDynamicColors.surfaceDim,\n \"surface-bright\": MaterialDynamicColors.surfaceBright,\n \"surface-container-lowest\": MaterialDynamicColors.surfaceContainerLowest,\n \"surface-container-low\": MaterialDynamicColors.surfaceContainerLow,\n};\n\n/**\n * Converts a Material color scheme object into a map of CSS custom property\n * names to oklch color values.\n *\n * Each camelCase key is converted to kebab-case and prefixed with\n * `--md-sys-color-`. An optional suffix can be appended to the variable name.\n *\n * @param {Record<string, number>} scheme - Map of token names to ARGB integers.\n * @param {string} [suffix=\"\"] - Optional suffix appended to every variable name.\n * @returns {Record<string, string>} Map of CSS variable names to oklch strings.\n *\n * @example\n * const vars = setSchemeProperties({ primary: 0xff1d5d78 });\n * // { \"--md-sys-color-primary\": \"oklch(\u2026)\" }\n */\nexport function setSchemeProperties(scheme, suffix = \"\") {\n let result = {};\n for (const [key, value] of Object.entries(scheme)) {\n const token = key.replace(/([a-z])([A-Z])/g, \"$1-$2\").toLowerCase();\n const color = hexFromArgb(value);\n const converted = oklch(color);\n const name = formatCss(converted);\n const variableName = `--md-sys-color-${token}${suffix}`;\n result[variableName] = name;\n }\n\n return result;\n}\n\n/**\n * Generates a full set of Material Design 3 color tokens for a given source\n * color and color scheme.\n *\n * Tokens cover the standard MD3 scheme palette plus additional surface\n * container roles provided by {@link MaterialDynamicColors}. All color values\n * are expressed as oklch CSS strings so they can be used directly in\n * `var(--md-sys-color-*)` declarations.\n *\n * @param {{ scheme?: \"light\" | \"dark\", sourceColor?: string }} [config]\n * @param {string} [config.sourceColor=\"#1D5D78\"] - Seed color as a hex string (e.g. `\"#6750A4\"`).\n * @param {\"light\" | \"dark\"} [config.scheme=\"light\"] - Color scheme variant.\n * @returns {Record<string, string>} Map of CSS variable names to oklch color strings.\n *\n * @example\n * const tokens = generateTokens({ sourceColor: \"#6750A4\", scheme: \"dark\" });\n * // { \"--md-sys-color-primary\": \"oklch(\u2026)\", \u2026 }\n */\nexport function generateTokens(config = { scheme: \"light\", sourceColor: \"#1D5D78\" }) {\n const theme = themeFromSourceColor(argbFromHex(config.sourceColor), []);\n\n const scheme = new SchemeContent(\n Hct.fromInt(argbFromHex(config.sourceColor)),\n config.scheme === \"dark\",\n 0\n );\n let palette = {};\n for (const [key, value] of Object.entries(materialColors)) {\n palette[key] = value.getArgb(scheme);\n }\n const currentTheme = theme.schemes[config.scheme].toJSON();\n const tokens = setSchemeProperties({ ...currentTheme, ...palette });\n\n return tokens;\n}\n", "import path from \"node:path\";\nimport fs from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\n\nimport * as tokensUtils from \"./tokens.mjs\";\n\n/**\n * @param {Record<string, string>} variables\n * @returns {string}\n */\nfunction template(variables) {\n return `:root {\n ${variables}\n }`;\n}\n\n/**\n * @param {Record<string, string>} variables\n * @returns {string}\n */\nfunction normalizeCSSVariablesContent(variables = {}) {\n let str = \"\";\n for (const cssVar in variables) {\n str += `${cssVar}: ${variables[cssVar]};\\n`;\n }\n return str;\n}\n\n/**\n * Generates a `colors.css` file containing `:root`-scoped MD3 color tokens\n * derived from the given source color and scheme.\n *\n * @param {{ scheme?: \"light\" | \"dark\", sourceColor?: string, output?: string }} [config]\n * @param {string} [config.sourceColor=\"#1D5D78\"] - Seed color as a hex string.\n * @param {\"light\" | \"dark\"} [config.scheme=\"light\"] - Color scheme variant.\n * @param {string} [config.output] - Absolute or relative output path for the CSS file.\n * Defaults to `colors.css` next to this module.\n * @returns {void}\n *\n * @example\n * import { generateCSSFile } from \"@symblight/md-colors\";\n * generateCSSFile({ sourceColor: \"#6750A4\", scheme: \"dark\", output: \"./theme/colors.css\" });\n */\nexport function generateCSSFile(config = {}) {\n const { scheme = \"light\", sourceColor = \"#1D5D78\", output } = config;\n\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const outputPath = output\n ? path.resolve(output)\n : path.join(__dirname, \"colors.css\");\n\n const tokens = tokensUtils.generateTokens({ scheme, sourceColor });\n const stringTokens = normalizeCSSVariablesContent(tokens);\n const themeBody = template(stringTokens);\n\n fs.writeFile(outputPath, themeBody, (err) => {\n if (err) {\n console.error(err);\n }\n });\n}\n"],
5
- "mappings": ";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,WAAW,iBAAiB;AAErC,IAAI,QAAQ,UAAU,OAAO;AAE7B,IAAM,iBAAiB;AAAA,EACrB,6BAA6B,sBAAsB;AAAA,EACnD,0BAA0B,sBAAsB;AAAA,EAChD,eAAe,sBAAsB;AAAA,EACrC,kBAAkB,sBAAsB;AAAA,EACxC,4BAA4B,sBAAsB;AAAA,EAClD,yBAAyB,sBAAsB;AACjD;AAiBO,SAAS,oBAAoB,QAAQ,SAAS,IAAI;AACvD,MAAI,SAAS,CAAC;AACd,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,UAAM,QAAQ,IAAI,QAAQ,mBAAmB,OAAO,EAAE,YAAY;AAClE,UAAM,QAAQ,YAAY,KAAK;AAC/B,UAAM,YAAY,MAAM,KAAK;AAC7B,UAAM,OAAO,UAAU,SAAS;AAChC,UAAM,eAAe,kBAAkB,KAAK,GAAG,MAAM;AACrD,WAAO,YAAY,IAAI;AAAA,EACzB;AAEA,SAAO;AACT;AAoBO,SAAS,eAAe,SAAS,EAAE,QAAQ,SAAS,aAAa,UAAU,GAAG;AACnF,QAAM,QAAQ,qBAAqB,YAAY,OAAO,WAAW,GAAG,CAAC,CAAC;AAEtE,QAAM,SAAS,IAAI;AAAA,IACjB,IAAI,QAAQ,YAAY,OAAO,WAAW,CAAC;AAAA,IAC3C,OAAO,WAAW;AAAA,IAClB;AAAA,EACF;AACA,MAAI,UAAU,CAAC;AACf,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,cAAc,GAAG;AACzD,YAAQ,GAAG,IAAI,MAAM,QAAQ,MAAM;AAAA,EACrC;AACA,QAAM,eAAe,MAAM,QAAQ,OAAO,MAAM,EAAE,OAAO;AACzD,QAAM,SAAS,oBAAoB,EAAE,GAAG,cAAc,GAAG,QAAQ,CAAC;AAElE,SAAO;AACT;;;ACpFA,OAAO,UAAU;AACjB,OAAO,QAAQ;AACf,SAAS,qBAAqB;AAQ9B,SAAS,SAAS,WAAW;AAC3B,SAAO;AAAA,YACG,SAAS;AAAA;AAErB;AAMA,SAAS,6BAA6B,YAAY,CAAC,GAAG;AACpD,MAAI,MAAM;AACV,aAAW,UAAU,WAAW;AAC9B,WAAO,GAAG,MAAM,KAAK,UAAU,MAAM,CAAC;AAAA;AAAA,EACxC;AACA,SAAO;AACT;AAiBO,SAAS,gBAAgB,SAAS,CAAC,GAAG;AAC3C,QAAM,EAAE,SAAS,SAAS,cAAc,WAAW,OAAO,IAAI;AAE9D,QAAM,aAAa,cAAc,YAAY,GAAG;AAChD,QAAM,YAAY,KAAK,QAAQ,UAAU;AACzC,QAAM,aAAa,SACf,KAAK,QAAQ,MAAM,IACnB,KAAK,KAAK,WAAW,YAAY;AAErC,QAAM,SAAqB,eAAe,EAAE,QAAQ,YAAY,CAAC;AACjE,QAAM,eAAe,6BAA6B,MAAM;AACxD,QAAM,YAAY,SAAS,YAAY;AAEvC,KAAG,UAAU,YAAY,WAAW,CAAC,QAAQ;AAC3C,QAAI,KAAK;AACP,cAAQ,MAAM,GAAG;AAAA,IACnB;AAAA,EACF,CAAC;AACH;",
4
+ "sourcesContent": ["import {\n argbFromHex,\n hexFromArgb,\n MaterialDynamicColors,\n SchemeTonalSpot,\n Hct,\n} from \"@material/material-color-utilities\";\nimport { converter, formatCss } from \"culori\";\n\n/**\n * Color scheme variant.\n * @typedef {\"light\" | \"dark\"} ColorScheme\n */\n\n/**\n * Options for {@link generateTokens}.\n * @typedef {object} TokenConfig\n * @property {string} sourceColor - Seed color as a hex string (e.g. `\"#6750A4\"`).\n * @property {ColorScheme} scheme - Color scheme variant.\n */\n\n/**\n * Map of `--md-sys-color-*` CSS custom property names to oklch color strings.\n * @typedef {Record<string, string>} ColorTokens\n */\n\n/**\n * Converts an sRGB hex string to a culori oklch color object.\n * @type {(color: string) => { mode: \"oklch\", l: number, c: number, h?: number, alpha?: number } | undefined}\n */\nlet oklch = converter(\"oklch\");\n\n/** Seed color used when none is given. */\nexport const DEFAULT_SOURCE_COLOR = \"#1D5D78\";\n\n/** Matches `#rgb` and `#rrggbb` hex colors. */\nconst HEX_RE = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;\n\n/**\n * MD3 color roles emitted as tokens, in output order. Names match the static\n * members of {@link MaterialDynamicColors} and are kebab-cased into\n * `--md-sys-color-*` names. `background`, `onBackground` and `surfaceVariant`\n * are deprecated in M3 but kept for compatibility.\n *\n * @see https://m3.material.io/styles/color/roles\n */\nconst COLOR_ROLES = /** @type {const} */ ([\n \"primary\",\n \"onPrimary\",\n \"primaryContainer\",\n \"onPrimaryContainer\",\n \"inversePrimary\",\n \"primaryFixed\",\n \"primaryFixedDim\",\n \"onPrimaryFixed\",\n \"onPrimaryFixedVariant\",\n \"secondary\",\n \"onSecondary\",\n \"secondaryContainer\",\n \"onSecondaryContainer\",\n \"secondaryFixed\",\n \"secondaryFixedDim\",\n \"onSecondaryFixed\",\n \"onSecondaryFixedVariant\",\n \"tertiary\",\n \"onTertiary\",\n \"tertiaryContainer\",\n \"onTertiaryContainer\",\n \"tertiaryFixed\",\n \"tertiaryFixedDim\",\n \"onTertiaryFixed\",\n \"onTertiaryFixedVariant\",\n \"error\",\n \"onError\",\n \"errorContainer\",\n \"onErrorContainer\",\n \"surface\",\n \"onSurface\",\n \"surfaceVariant\",\n \"onSurfaceVariant\",\n \"surfaceDim\",\n \"surfaceBright\",\n \"surfaceContainerLowest\",\n \"surfaceContainerLow\",\n \"surfaceContainer\",\n \"surfaceContainerHigh\",\n \"surfaceContainerHighest\",\n \"surfaceTint\",\n \"inverseSurface\",\n \"inverseOnSurface\",\n \"outline\",\n \"outlineVariant\",\n \"shadow\",\n \"scrim\",\n \"background\",\n \"onBackground\",\n]);\n\n/**\n * Validates and normalizes a partial token config, filling in defaults per\n * field. Accepts unchecked strings (e.g. CLI input).\n *\n * @param {{ sourceColor?: string, scheme?: string }} [config]\n * @returns {TokenConfig}\n * @throws {TypeError} If `sourceColor` is not a hex color or `scheme` is not `\"light\"` / `\"dark\"`.\n */\nexport function resolveConfig({ sourceColor = DEFAULT_SOURCE_COLOR, scheme = \"light\" } = {}) {\n if (typeof sourceColor !== \"string\" || !HEX_RE.test(sourceColor)) {\n throw new TypeError(`sourceColor must be a hex color like \"#6750A4\", got ${JSON.stringify(sourceColor)}`);\n }\n if (scheme !== \"light\" && scheme !== \"dark\") {\n throw new TypeError(`scheme must be \"light\" or \"dark\", got ${JSON.stringify(scheme)}`);\n }\n return { sourceColor, scheme: /** @type {ColorScheme} */ (scheme) };\n}\n\n/**\n * Converts a Material color scheme object into a map of CSS custom property\n * names to oklch color values.\n *\n * Each camelCase key is converted to kebab-case and prefixed with\n * `--md-sys-color-`. An optional suffix can be appended to the variable name.\n *\n * @param {Record<string, number>} scheme - Map of token names to ARGB integers.\n * @param {string} [suffix=\"\"] - Optional suffix appended to every variable name.\n * @returns {ColorTokens} Map of CSS variable names to oklch strings.\n *\n * @example\n * const vars = setSchemeProperties({ primary: 0xff1d5d78 });\n * // { \"--md-sys-color-primary\": \"oklch(\u2026)\" }\n */\nexport function setSchemeProperties(scheme, suffix = \"\") {\n /** @type {ColorTokens} */\n let result = {};\n for (const [key, value] of Object.entries(scheme)) {\n const token = key.replace(/([a-z])([A-Z])/g, \"$1-$2\").toLowerCase();\n const color = hexFromArgb(value);\n const converted = oklch(color);\n const name = formatCss(converted);\n const variableName = `--md-sys-color-${token}${suffix}`;\n result[variableName] = name;\n }\n\n return result;\n}\n\n/**\n * Generates the full set of Material Design 3 color tokens for a given source\n * color and color scheme.\n *\n * Every role is resolved from a single tonal-spot {@link SchemeTonalSpot}\n * (the M3 default variant), so surface tones keep their spec ordering. All\n * color values are expressed as oklch CSS strings so they can be used directly\n * in `var(--md-sys-color-*)` declarations.\n *\n * @param {Partial<TokenConfig>} [config] - Missing fields default to\n * `sourceColor: \"#1D5D78\"` and `scheme: \"light\"`.\n * @returns {ColorTokens} Map of CSS variable names to oklch color strings.\n * @throws {TypeError} If `sourceColor` is not a hex color or `scheme` is not `\"light\"` / `\"dark\"`.\n *\n * @example\n * const tokens = generateTokens({ sourceColor: \"#6750A4\", scheme: \"dark\" });\n * // { \"--md-sys-color-primary\": \"oklch(\u2026)\", \u2026 }\n */\nexport function generateTokens(config = {}) {\n const { sourceColor, scheme } = resolveConfig(config);\n const dynamicScheme = new SchemeTonalSpot(\n Hct.fromInt(argbFromHex(sourceColor)),\n scheme === \"dark\",\n 0\n );\n\n /** @type {Record<string, number>} */\n let palette = {};\n for (const role of COLOR_ROLES) {\n palette[role] = MaterialDynamicColors[role].getArgb(dynamicScheme);\n }\n\n return setSchemeProperties(palette);\n}\n", "import path from \"node:path\";\nimport fs from \"node:fs/promises\";\nimport { fileURLToPath } from \"node:url\";\n\nimport * as tokensUtils from \"./tokens.mjs\";\n\n/** @typedef {import(\"./tokens.mjs\").ColorScheme} ColorScheme */\n/** @typedef {import(\"./tokens.mjs\").ColorTokens} ColorTokens */\n\n/**\n * Options for {@link generateCSSFile}.\n * @typedef {object} CSSFileConfig\n * @property {string} [sourceColor=\"#1D5D78\"] - Seed color as a hex string.\n * @property {ColorScheme} [scheme=\"light\"] - Color scheme variant.\n * @property {string} [output] - Absolute or relative output path for the CSS file.\n * Relative paths resolve against `process.cwd()`. Defaults to `colors.css`\n * next to this module.\n */\n\n/**\n * Wraps serialized declarations in a `:root` rule.\n *\n * @param {string} variables - Declarations produced by {@link normalizeCSSVariablesContent}.\n * @returns {string} A complete `:root { \u2026 }` rule.\n */\nfunction template(variables) {\n return `:root {\n ${variables}\n }`;\n}\n\n/**\n * Serializes a token map into newline-separated CSS declarations.\n *\n * @param {ColorTokens} [variables={}] - Map of CSS variable names to values.\n * @returns {string} One `name: value;` declaration per line.\n *\n * @example\n * normalizeCSSVariablesContent({ \"--md-sys-color-primary\": \"oklch(\u2026)\" });\n * // \"--md-sys-color-primary: oklch(\u2026);\\n\"\n */\nfunction normalizeCSSVariablesContent(variables = {}) {\n let str = \"\";\n for (const cssVar in variables) {\n str += `${cssVar}: ${variables[cssVar]};\\n`;\n }\n return str;\n}\n\n/**\n * Generates a `colors.css` file containing `:root`-scoped MD3 color tokens\n * derived from the given source color and scheme.\n *\n * @param {CSSFileConfig} [config]\n * @returns {Promise<string>} Resolves with the absolute path of the written file.\n * @throws {TypeError} If `sourceColor` is not a hex color or `scheme` is not `\"light\"` / `\"dark\"`.\n * Rejects if the file cannot be written.\n *\n * @example\n * import { generateCSSFile } from \"@symblight/md-colors\";\n * await generateCSSFile({ sourceColor: \"#6750A4\", scheme: \"dark\", output: \"./theme/colors.css\" });\n */\nexport async function generateCSSFile(config = {}) {\n const { output, ...tokenConfig } = config;\n\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const outputPath = output\n ? path.resolve(output)\n : path.join(__dirname, \"colors.css\");\n\n const tokens = tokensUtils.generateTokens(tokenConfig);\n const stringTokens = normalizeCSSVariablesContent(tokens);\n const themeBody = template(stringTokens);\n\n await fs.writeFile(outputPath, themeBody);\n return outputPath;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@symblight/md-colors",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Material Design 3 color token generator — CSS custom property output in oklch format",
5
5
  "type": "module",
6
6
  "private": false,
7
7
  "main": "./dist/index.js",
8
+ "unpkg": "./dist/client.js",
8
9
  "bin": {
9
10
  "md-colors": "./dist/cli.js"
10
11
  },
@@ -14,8 +15,9 @@
14
15
  },
15
16
  "./client": {
16
17
  "import": "./dist/client.esm.js",
17
- "default": "./dist/client.js"
18
- }
18
+ "require": "./dist/client.cjs"
19
+ },
20
+ "./client.iife": "./dist/client.js"
19
21
  },
20
22
  "files": [
21
23
  "dist",