@kyralabs/m3e-tokens 1.0.1 → 1.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/theme.d.ts CHANGED
@@ -28,9 +28,32 @@ declare const SPEC_2025_ONLY_ROLES: readonly string[];
28
28
  */
29
29
  declare const COLOR_ROLES: readonly string[];
30
30
  declare const rolesFor: (specVersion: SpecVersion) => readonly string[];
31
+ /**
32
+ * Optional source colors for the palettes other than primary, like Material Theme Builder's
33
+ * "core colors". Each one replaces the palette the variant would derive from `seed` with
34
+ * `TonalPalette.fromInt(color)` (the color's own hue and chroma); the variant still maps the
35
+ * roles to tones. Keys are the `DynamicScheme` palette names (`dynamiccolor/dynamic_scheme.d.ts`
36
+ * L63–L68, MCU 0.4.0). The same mapping as Angular Material's `theme-color` schematic
37
+ * (`TonalPalette.fromHct` per custom color); Theme Builder's own is `TODO(verify)` (SOURCES.md
38
+ * register #62).
39
+ *
40
+ * `neutralVariant` has no effect with spec 2025 (tonalSpot, neutral, vibrant, expressive): that
41
+ * spec draws on-surface-variant, outline and outline-variant from the neutral palette with a
42
+ * chroma multiplier (`dynamiccolor/color_spec_2025.js` L449–L524) and maps surface-variant to
43
+ * surface-container-highest (L1105–L1107), so set `neutral` instead.
44
+ */
45
+ declare const CORE_COLORS: readonly ["secondary", "tertiary", "neutral", "neutralVariant", "error"];
46
+ type CoreColor = (typeof CORE_COLORS)[number];
47
+ /** `undefined` means unset, the same as leaving the key out. */
48
+ type CoreColors = Partial<Record<CoreColor, string | undefined>>;
31
49
  interface CreateThemeOptions {
32
50
  /** Source color, `#rgb` or `#rrggbb`. */
33
51
  seed: string;
52
+ /**
53
+ * Optional source colors for the secondary, tertiary, neutral, neutral variant and error
54
+ * palettes (`#rgb` or `#rrggbb`). Unset palettes come from `seed` and `variant` as usual.
55
+ */
56
+ coreColors?: CoreColors;
34
57
  variant?: Variant;
35
58
  mode?: ThemeMode;
36
59
  /** −1…1 (0 = standard) or a preset name. Spec 2025 treats negative contrast as 0. */
@@ -50,6 +73,8 @@ interface Theme {
50
73
  cssText: string;
51
74
  tokens: {
52
75
  seed: string;
76
+ /** Normalized core colors; present only when at least one was given. */
77
+ coreColors?: CoreColors;
53
78
  variant: Variant;
54
79
  contrast: number;
55
80
  specVersion: SpecVersion;
@@ -59,7 +84,7 @@ interface Theme {
59
84
  };
60
85
  }
61
86
  /** Resolves every role of one scheme to `#rrggbb`. */
62
- declare function schemeColors(seed: string, variant: Variant, isDark: boolean, contrast: number, specVersion: SpecVersion): Record<string, string>;
87
+ declare function schemeColors(seed: string, variant: Variant, isDark: boolean, contrast: number, specVersion: SpecVersion, coreColors?: CoreColors): Record<string, string>;
63
88
  declare function createTheme(options: CreateThemeOptions): Theme;
64
89
 
65
- export { COLOR_ROLES, CONTRAST, ColorRoles, type CreateThemeOptions, DEFAULT_SPEC_VERSION, MotionScheme, SPEC_2025_ONLY_ROLES, SPEC_VERSIONS, type SpecVersion, type Theme, ThemeMode, VARIANTS, type Variant, createTheme, rolesFor, schemeColors };
90
+ export { COLOR_ROLES, CONTRAST, CORE_COLORS, ColorRoles, type CoreColor, type CoreColors, type CreateThemeOptions, DEFAULT_SPEC_VERSION, MotionScheme, SPEC_2025_ONLY_ROLES, SPEC_VERSIONS, type SpecVersion, type Theme, ThemeMode, VARIANTS, type Variant, createTheme, rolesFor, schemeColors };
package/dist/theme.js CHANGED
@@ -5087,13 +5087,55 @@ var COLOR_ROLES = Object.getOwnPropertyNames(
5087
5087
  var rolesFor = (specVersion) => specVersion === "2025" ? COLOR_ROLES : COLOR_ROLES.filter((r) => !SPEC_2025_ONLY_ROLES.includes(r));
5088
5088
  var HEX = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;
5089
5089
  var normalizeHex = (hex) => hexFromArgb(argbFromHex(hex));
5090
- function schemeColors(seed, variant, isDark, contrast, specVersion) {
5091
- const scheme = new SCHEMES[variant](
5090
+ var CORE_COLORS = ["secondary", "tertiary", "neutral", "neutralVariant", "error"];
5091
+ function normalizeCoreColors(coreColors, caller) {
5092
+ const out = {};
5093
+ for (const key of Object.keys(coreColors)) {
5094
+ if (!CORE_COLORS.includes(key)) {
5095
+ throw new Error(`${caller}: unknown core color "${key}"`);
5096
+ }
5097
+ }
5098
+ for (const key of CORE_COLORS) {
5099
+ const hex = coreColors[key];
5100
+ if (hex === void 0) continue;
5101
+ if (typeof hex !== "string" || !HEX.test(hex)) {
5102
+ throw new Error(
5103
+ `${caller}: core color ${key} must be #rgb or #rrggbb, got ${JSON.stringify(hex)}`
5104
+ );
5105
+ }
5106
+ out[key] = normalizeHex(hex);
5107
+ }
5108
+ return out;
5109
+ }
5110
+ function withCoreColors(scheme, coreColors) {
5111
+ if (CORE_COLORS.every((key) => coreColors[key] === void 0)) return scheme;
5112
+ const palette = (key) => {
5113
+ const hex = coreColors[key];
5114
+ return hex === void 0 ? void 0 : TonalPalette.fromInt(argbFromHex(hex));
5115
+ };
5116
+ return new DynamicScheme({
5117
+ sourceColorHct: scheme.sourceColorHct,
5118
+ variant: scheme.variant,
5119
+ contrastLevel: scheme.contrastLevel,
5120
+ isDark: scheme.isDark,
5121
+ platform: scheme.platform,
5122
+ specVersion: scheme.specVersion,
5123
+ primaryPalette: scheme.primaryPalette,
5124
+ secondaryPalette: palette("secondary") ?? scheme.secondaryPalette,
5125
+ tertiaryPalette: palette("tertiary") ?? scheme.tertiaryPalette,
5126
+ neutralPalette: palette("neutral") ?? scheme.neutralPalette,
5127
+ neutralVariantPalette: palette("neutralVariant") ?? scheme.neutralVariantPalette,
5128
+ errorPalette: palette("error") ?? scheme.errorPalette
5129
+ });
5130
+ }
5131
+ function schemeColors(seed, variant, isDark, contrast, specVersion, coreColors = {}) {
5132
+ const variantScheme = new SCHEMES[variant](
5092
5133
  Hct.fromInt(argbFromHex(seed)),
5093
5134
  isDark,
5094
5135
  contrast,
5095
5136
  specVersion
5096
5137
  );
5138
+ const scheme = withCoreColors(variantScheme, normalizeCoreColors(coreColors, "schemeColors"));
5097
5139
  const out = {};
5098
5140
  for (const role of rolesFor(specVersion)) {
5099
5141
  const method = dynamicColors[role];
@@ -5125,9 +5167,11 @@ function createTheme(options) {
5125
5167
  `createTheme: contrast must be within [-1, 1], got ${String(options.contrast)}`
5126
5168
  );
5127
5169
  }
5170
+ const coreColors = normalizeCoreColors(options.coreColors ?? {}, "createTheme");
5171
+ const hasCoreColors = Object.keys(coreColors).length > 0;
5128
5172
  const roles = rolesFor(specVersion);
5129
5173
  const build = (isDark, extra) => {
5130
- const colors = schemeColors(seed, variant, isDark, contrast, specVersion);
5174
+ const colors = schemeColors(seed, variant, isDark, contrast, specVersion, coreColors);
5131
5175
  for (const [role, hex] of Object.entries(extra ?? {})) {
5132
5176
  if (!roles.includes(role)) throw new Error(`createTheme: unknown color role "${role}"`);
5133
5177
  if (!HEX.test(hex)) throw new Error(`createTheme: override ${role} must be a hex color`);
@@ -5148,6 +5192,7 @@ function createTheme(options) {
5148
5192
  cssText,
5149
5193
  tokens: {
5150
5194
  seed: normalizeHex(seed),
5195
+ ...hasCoreColors ? { coreColors } : {},
5151
5196
  variant,
5152
5197
  contrast,
5153
5198
  specVersion,
@@ -5269,6 +5314,6 @@ function createTheme(options) {
5269
5314
  *)
5270
5315
  */
5271
5316
 
5272
- export { COLOR_ROLES, CONTRAST, DEFAULT_SPEC_VERSION, SPEC_2025_ONLY_ROLES, SPEC_VERSIONS, VARIANTS, colorVar, createTheme, rolesFor, schemeColors, themeCss };
5317
+ export { COLOR_ROLES, CONTRAST, CORE_COLORS, DEFAULT_SPEC_VERSION, SPEC_2025_ONLY_ROLES, SPEC_VERSIONS, VARIANTS, colorVar, createTheme, rolesFor, schemeColors, themeCss };
5273
5318
  //# sourceMappingURL=theme.js.map
5274
5319
  //# sourceMappingURL=theme.js.map