material-theme-builder 4.0.0 → 5.1.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
@@ -13,19 +13,17 @@ import {
13
13
  SchemeNeutral,
14
14
  SchemeTonalSpot,
15
15
  SchemeVibrant,
16
- TonalPalette as TonalPalette2
16
+ TonalPalette
17
17
  } from "@material/material-color-utilities";
18
18
  import { kebabCase as kebabCase4, upperFirst as upperFirst2 } from "lodash-es";
19
19
 
20
20
  // src/lib/builder.css.ts
21
- import {
22
- hexFromArgb
23
- } from "@material/material-color-utilities";
21
+ import { hexFromArgb } from "@material/material-color-utilities";
24
22
  import { kebabCase } from "lodash-es";
25
23
  function buildCss(ctx) {
26
24
  const {
27
25
  prefix,
28
- allPalettes,
26
+ refPalettes,
29
27
  mergedColorsLight,
30
28
  mergedColorsDark,
31
29
  tokenToPalette,
@@ -33,10 +31,9 @@ function buildCss(ctx) {
33
31
  } = ctx;
34
32
  function buildRefPaletteLookup() {
35
33
  const lookup = {};
36
- for (const [name, palette] of Object.entries(allPalettes)) {
37
- const paletteName = kebabCase(name);
38
- for (const tone of STANDARD_TONES) {
39
- const hex = hexFromArgb(palette.tone(tone));
34
+ for (const [paletteName, tones] of Object.entries(refPalettes)) {
35
+ for (const { tone, argb } of tones) {
36
+ const hex = hexFromArgb(argb);
40
37
  if (!lookup[hex]) lookup[hex] = [];
41
38
  lookup[hex].push({ paletteName, tone });
42
39
  }
@@ -64,15 +61,12 @@ function buildCss(ctx) {
64
61
  const value = hexFromArgb(colorValue);
65
62
  return `${name}:${value};`;
66
63
  }
67
- function generateTonalPaletteVars(paletteName, palette) {
68
- return STANDARD_TONES.map((tone) => {
69
- const color = palette.tone(tone);
70
- return refPaletteVar(paletteName, tone, color);
71
- }).join(" ");
64
+ function generateTonalPaletteVars(paletteName, tones) {
65
+ return tones.map(({ tone, argb }) => refPaletteVar(paletteName, tone, argb)).join(" ");
72
66
  }
73
67
  function generateTonalVars() {
74
- return Object.entries(allPalettes).map(
75
- ([name, palette]) => generateTonalPaletteVars(kebabCase(name), palette)
68
+ return Object.entries(refPalettes).map(
69
+ ([paletteName, tones]) => generateTonalPaletteVars(paletteName, tones)
76
70
  ).join(" ");
77
71
  }
78
72
  const refPaletteLookup = buildRefPaletteLookup();
@@ -374,29 +368,8 @@ import {
374
368
  DynamicScheme,
375
369
  Hct,
376
370
  hexFromArgb as hexFromArgb4,
377
- MaterialDynamicColors,
378
- TonalPalette
371
+ MaterialDynamicColors
379
372
  } from "@material/material-color-utilities";
380
- var MTB_TONES = [
381
- 0,
382
- 5,
383
- 10,
384
- 15,
385
- 20,
386
- 25,
387
- 30,
388
- 35,
389
- 40,
390
- 50,
391
- 60,
392
- 70,
393
- 80,
394
- 90,
395
- 95,
396
- 98,
397
- 99,
398
- 100
399
- ];
400
373
  var FIXTURE_TOKEN_ORDER = [
401
374
  "primary",
402
375
  "surfaceTint",
@@ -451,7 +424,6 @@ var FIXTURE_TOKEN_ORDER = [
451
424
  function buildJson(ctx) {
452
425
  const {
453
426
  hexSource,
454
- sourceHct,
455
427
  effectiveSourceArgb,
456
428
  primaryHct,
457
429
  SchemeClass,
@@ -462,34 +434,16 @@ function buildJson(ctx) {
462
434
  error,
463
435
  neutral,
464
436
  neutralVariant,
465
- hexCustomColors
437
+ hexCustomColors,
438
+ refPalettes
466
439
  } = ctx;
467
- const neuHct = neutral ? Hct.fromInt(argbFromHex(neutral)) : sourceHct;
468
- const nvHct = neutralVariant ? Hct.fromInt(argbFromHex(neutralVariant)) : sourceHct;
469
- const rawPalettes = {
470
- primary: TonalPalette.fromInt(effectiveSourceArgb),
471
- secondary: secondary ? TonalPalette.fromInt(argbFromHex(secondary)) : TonalPalette.fromHueAndChroma(sourceHct.hue, sourceHct.chroma / 3),
472
- tertiary: tertiary ? TonalPalette.fromInt(argbFromHex(tertiary)) : TonalPalette.fromHueAndChroma(
473
- (sourceHct.hue + 60) % 360,
474
- sourceHct.chroma / 2
475
- ),
476
- neutral: TonalPalette.fromHueAndChroma(
477
- neuHct.hue,
478
- Math.min(neuHct.chroma / 12, 4)
479
- ),
480
- "neutral-variant": TonalPalette.fromHueAndChroma(
481
- nvHct.hue,
482
- Math.min(nvHct.chroma / 6, 8)
483
- )
484
- };
485
440
  function buildJsonSchemes() {
486
- function extractSchemeColors(scheme2, backgroundScheme) {
441
+ function extractSchemeColors(scheme2) {
487
442
  const colors = {};
488
443
  for (const tokenName of FIXTURE_TOKEN_ORDER) {
489
444
  const dynamicColor = MaterialDynamicColors[tokenName];
490
- const useScheme = backgroundScheme && (tokenName === "background" || tokenName === "onBackground") ? backgroundScheme : scheme2;
491
445
  colors[tokenName] = hexFromArgb4(
492
- dynamicColor.getArgb(useScheme)
446
+ dynamicColor.getArgb(scheme2)
493
447
  ).toUpperCase();
494
448
  }
495
449
  return colors;
@@ -529,26 +483,18 @@ function buildJson(ctx) {
529
483
  neutralVariantPalette: nvPalette || baseScheme.neutralVariantPalette
530
484
  });
531
485
  if (errPalette) composedScheme.errorPalette = errPalette;
532
- jsonSchemes[name] = extractSchemeColors(composedScheme, baseScheme);
486
+ jsonSchemes[name] = extractSchemeColors(composedScheme);
533
487
  }
534
488
  return jsonSchemes;
535
489
  }
536
- function rawPalettesToJson() {
490
+ function refPalettesToJson() {
537
491
  const jsonPalettes = {};
538
- const RAW_PALETTE_NAMES = [
539
- "primary",
540
- "secondary",
541
- "tertiary",
542
- "neutral",
543
- "neutral-variant"
544
- ];
545
- for (const name of RAW_PALETTE_NAMES) {
546
- const palette = rawPalettes[name];
547
- const tones = {};
548
- for (const tone of MTB_TONES) {
549
- tones[tone.toString()] = hexFromArgb4(palette.tone(tone)).toUpperCase();
492
+ for (const [name, tones] of Object.entries(refPalettes)) {
493
+ const jsonTones = {};
494
+ for (const { tone, argb } of tones) {
495
+ jsonTones[tone.toString()] = hexFromArgb4(argb).toUpperCase();
550
496
  }
551
- jsonPalettes[name] = tones;
497
+ jsonPalettes[name] = jsonTones;
552
498
  }
553
499
  return jsonPalettes;
554
500
  }
@@ -575,14 +521,14 @@ function buildJson(ctx) {
575
521
  name: c.name,
576
522
  color: c.hex.toUpperCase(),
577
523
  description: "",
578
- harmonized: c.blend ?? DEFAULT_BLEND
524
+ harmonized: c.blend
579
525
  }));
580
526
  return {
581
527
  seed,
582
528
  coreColors,
583
529
  extendedColors,
584
530
  schemes: buildJsonSchemes(),
585
- palettes: rawPalettesToJson()
531
+ palettes: refPalettesToJson()
586
532
  };
587
533
  }
588
534
 
@@ -922,51 +868,53 @@ function getPalette(palettes, colorName) {
922
868
  }
923
869
  return palette;
924
870
  }
925
- function mergeBaseAndCustomColors(scheme, customColors, colorPalettes) {
926
- const baseVars = toRecord(tokenNames, (tokenName) => {
927
- const dynamicColor = MaterialDynamicColors2[tokenName];
928
- const argb = dynamicColor.getArgb(scheme);
929
- return [tokenName, argb];
930
- });
931
- const customVars = {};
932
- customColors.forEach((color) => {
933
- const colorname = color.name;
934
- const getPaletteForColor = () => getPalette(colorPalettes, colorname);
935
- const colorDynamicColor = new DynamicColor(
871
+ function buildCustomColorRoles(colorname, palette) {
872
+ const getPaletteForColor = () => palette;
873
+ return {
874
+ [colorname]: new DynamicColor(
936
875
  colorname,
937
876
  getPaletteForColor,
938
877
  (s) => s.isDark ? 80 : 40,
939
878
  // Main color: lighter in dark mode, darker in light mode
940
879
  true
941
880
  // background
942
- );
943
- const onColorDynamicColor = new DynamicColor(
881
+ ),
882
+ [`on${upperFirst2(colorname)}`]: new DynamicColor(
944
883
  `on${upperFirst2(colorname)}`,
945
884
  getPaletteForColor,
946
885
  (s) => s.isDark ? 20 : 100,
947
886
  // Text on main color: high contrast (dark on light, light on dark)
948
887
  false
949
- );
950
- const containerDynamicColor = new DynamicColor(
888
+ ),
889
+ [`${colorname}Container`]: new DynamicColor(
951
890
  `${colorname}Container`,
952
891
  getPaletteForColor,
953
892
  (s) => s.isDark ? 30 : 90,
954
893
  // Container: subtle variant (darker in dark mode, lighter in light mode)
955
894
  true
956
895
  // background
957
- );
958
- const onContainerDynamicColor = new DynamicColor(
896
+ ),
897
+ [`on${upperFirst2(colorname)}Container`]: new DynamicColor(
959
898
  `on${upperFirst2(colorname)}Container`,
960
899
  getPaletteForColor,
961
900
  (s) => s.isDark ? 90 : 30,
962
901
  // Text on container: high contrast against container background
963
902
  false
964
- );
965
- customVars[colorname] = colorDynamicColor.getArgb(scheme);
966
- customVars[`on${upperFirst2(colorname)}`] = onColorDynamicColor.getArgb(scheme);
967
- customVars[`${colorname}Container`] = containerDynamicColor.getArgb(scheme);
968
- customVars[`on${upperFirst2(colorname)}Container`] = onContainerDynamicColor.getArgb(scheme);
903
+ )
904
+ };
905
+ }
906
+ function mergeBaseAndCustomColors(scheme, customColorRoles) {
907
+ const baseVars = toRecord(tokenNames, (tokenName) => {
908
+ const dynamicColor = MaterialDynamicColors2[tokenName];
909
+ const argb = dynamicColor.getArgb(scheme);
910
+ return [tokenName, argb];
969
911
  });
912
+ const customVars = {};
913
+ for (const roles of Object.values(customColorRoles)) {
914
+ for (const [tokenName, dynamicColor] of Object.entries(roles)) {
915
+ customVars[tokenName] = dynamicColor.getArgb(scheme);
916
+ }
917
+ }
970
918
  return { ...baseVars, ...customVars };
971
919
  }
972
920
  function createColorPalette(colorDef, baseScheme, effectiveSourceForHarmonization) {
@@ -985,7 +933,17 @@ function createColorPalette(colorDef, baseScheme, effectiveSourceForHarmonizatio
985
933
  } else {
986
934
  targetChroma = baseScheme.primaryPalette.chroma;
987
935
  }
988
- return TonalPalette2.fromHueAndChroma(hct.hue, targetChroma);
936
+ return TonalPalette.fromHueAndChroma(hct.hue, targetChroma);
937
+ }
938
+ function buildRefPalettes(allPalettes) {
939
+ const refPalettes = {};
940
+ for (const [name, palette] of Object.entries(allPalettes)) {
941
+ refPalettes[kebabCase4(name)] = STANDARD_TONES.map((tone) => ({
942
+ tone,
943
+ argb: palette.tone(tone)
944
+ }));
945
+ }
946
+ return refPalettes;
989
947
  }
990
948
  function buildTokenToPaletteMap(schemePalettes, scheme) {
991
949
  const result = {};
@@ -1014,7 +972,7 @@ function builder(hexSource, {
1014
972
  neutral,
1015
973
  neutralVariant,
1016
974
  error,
1017
- customColors: hexCustomColors = DEFAULT_CUSTOM_COLORS,
975
+ customColors: customColorInputs = DEFAULT_CUSTOM_COLORS,
1018
976
  prefix = DEFAULT_PREFIX
1019
977
  } = {}) {
1020
978
  const cores = {
@@ -1025,9 +983,12 @@ function builder(hexSource, {
1025
983
  neutral: optionalHex(neutral),
1026
984
  neutralVariant: optionalHex(neutralVariant)
1027
985
  };
1028
- assertHexInputs(hexSource, cores, hexCustomColors);
986
+ assertHexInputs(hexSource, cores, customColorInputs);
987
+ const hexCustomColors = customColorInputs.map((c) => ({
988
+ ...c,
989
+ blend: c.blend ?? DEFAULT_BLEND
990
+ }));
1029
991
  const sourceArgb = argbFromHex2(hexSource);
1030
- const sourceHct = Hct2.fromInt(sourceArgb);
1031
992
  const effectiveSource = cores.primary || hexSource;
1032
993
  const effectiveSourceArgb = argbFromHex2(effectiveSource);
1033
994
  const effectiveSourceForHarmonization = cores.primary ? argbFromHex2(cores.primary) : sourceArgb;
@@ -1118,18 +1079,21 @@ function builder(hexSource, {
1118
1079
  };
1119
1080
  const customColors = definedColors.filter((c) => !c.core).map((c) => ({
1120
1081
  name: c.name,
1121
- blend: c.blend ?? DEFAULT_BLEND,
1122
1082
  value: argbFromHex2(c.hex)
1123
1083
  }));
1084
+ const customColorRoles = Object.fromEntries(
1085
+ customColors.map((color) => [
1086
+ color.name,
1087
+ buildCustomColorRoles(color.name, getPalette(colorPalettes, color.name))
1088
+ ])
1089
+ );
1124
1090
  const mergedColorsLight = mergeBaseAndCustomColors(
1125
1091
  lightScheme,
1126
- customColors,
1127
- colorPalettes
1092
+ customColorRoles
1128
1093
  );
1129
1094
  const mergedColorsDark = mergeBaseAndCustomColors(
1130
1095
  darkScheme,
1131
- customColors,
1132
- colorPalettes
1096
+ customColorRoles
1133
1097
  );
1134
1098
  const schemePalettes = [
1135
1099
  ["primary", lightScheme.primaryPalette],
@@ -1140,6 +1104,7 @@ function builder(hexSource, {
1140
1104
  ["neutral-variant", lightScheme.neutralVariantPalette]
1141
1105
  ];
1142
1106
  const tokenToPalette = buildTokenToPaletteMap(schemePalettes, lightScheme);
1107
+ const refPalettes = buildRefPalettes(allPalettes);
1143
1108
  const allPaletteNamesKebab = new Set(Object.keys(allPalettes).map(kebabCase4));
1144
1109
  const ctx = {
1145
1110
  hexSource,
@@ -1152,11 +1117,11 @@ function builder(hexSource, {
1152
1117
  neutralVariant,
1153
1118
  error,
1154
1119
  hexCustomColors,
1155
- sourceHct,
1156
1120
  effectiveSourceArgb,
1157
1121
  primaryHct,
1158
1122
  SchemeClass,
1159
1123
  allPalettes,
1124
+ refPalettes,
1160
1125
  mergedColorsLight,
1161
1126
  mergedColorsDark,
1162
1127
  tokenToPalette,
@@ -1174,7 +1139,8 @@ function builder(hexSource, {
1174
1139
  toFlutter: () => buildFlutter(ctx),
1175
1140
  mergedColorsLight,
1176
1141
  mergedColorsDark,
1177
- allPalettes
1142
+ allPalettes,
1143
+ customColorRoles
1178
1144
  };
1179
1145
  }
1180
1146
  export {
package/dist/react.d.ts CHANGED
@@ -134,8 +134,13 @@ declare const tokenDescriptions: {
134
134
  type TokenName = keyof typeof tokenDescriptions;
135
135
 
136
136
  /** A custom color defined with a hex string instead of an ARGB integer. */
137
- type HexCustomColor = Omit<CustomColor, "value"> & {
137
+ type HexCustomColor = Omit<CustomColor, "value" | "blend"> & {
138
138
  hex: string;
139
+ /**
140
+ * Harmonize the color with the source (or `primary`, when given) -- "Harmonize"
141
+ * in Material Theme Builder. Default: `DEFAULT_BLEND` (true).
142
+ */
143
+ blend?: boolean;
139
144
  };
140
145
  /** Available Material You color scheme variants. */
141
146
  declare const schemeNames: readonly ["tonalSpot", "monochrome", "neutral", "vibrant", "expressive", "fidelity", "content"];