@cdx-ui/styles 0.0.1-beta.9 → 0.0.1-beta.90

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.
Files changed (71) hide show
  1. package/README.md +116 -20
  2. package/css/theme.css +201 -85
  3. package/css/vanilla.css +124 -54
  4. package/lib/commonjs/applyThemeOverride.js +154 -0
  5. package/lib/commonjs/applyThemeOverride.js.map +1 -0
  6. package/lib/commonjs/index.js +82 -0
  7. package/lib/commonjs/index.js.map +1 -1
  8. package/lib/commonjs/palette.js +262 -0
  9. package/lib/commonjs/palette.js.map +1 -0
  10. package/lib/commonjs/theming.js +255 -0
  11. package/lib/commonjs/theming.js.map +1 -0
  12. package/lib/commonjs/types.js +75 -0
  13. package/lib/commonjs/types.js.map +1 -0
  14. package/lib/commonjs/useCdxFonts.js +4 -231
  15. package/lib/commonjs/useCdxFonts.js.map +1 -1
  16. package/lib/commonjs/useForgeFonts.js +237 -0
  17. package/lib/commonjs/useForgeFonts.js.map +1 -0
  18. package/lib/module/applyThemeOverride.js +149 -0
  19. package/lib/module/applyThemeOverride.js.map +1 -0
  20. package/lib/module/index.js +11 -20
  21. package/lib/module/index.js.map +1 -1
  22. package/lib/module/palette.js +257 -0
  23. package/lib/module/palette.js.map +1 -0
  24. package/lib/module/theming.js +239 -0
  25. package/lib/module/theming.js.map +1 -0
  26. package/lib/module/types.js +71 -0
  27. package/lib/module/types.js.map +1 -0
  28. package/lib/module/useCdxFonts.js +3 -219
  29. package/lib/module/useCdxFonts.js.map +1 -1
  30. package/lib/module/useForgeFonts.js +223 -0
  31. package/lib/module/useForgeFonts.js.map +1 -0
  32. package/lib/runtime/prestige-vs-default.json +1 -0
  33. package/lib/runtime/pulse-vs-default.json +1 -0
  34. package/lib/runtime/token-to-css-var.json +672 -0
  35. package/lib/typescript/applyThemeOverride.d.ts +26 -0
  36. package/lib/typescript/applyThemeOverride.d.ts.map +1 -0
  37. package/lib/typescript/index.d.ts +8 -57
  38. package/lib/typescript/index.d.ts.map +1 -1
  39. package/lib/typescript/palette.d.ts +60 -0
  40. package/lib/typescript/palette.d.ts.map +1 -0
  41. package/lib/typescript/theming.d.ts +40 -0
  42. package/lib/typescript/theming.d.ts.map +1 -0
  43. package/lib/typescript/types.d.ts +90 -0
  44. package/lib/typescript/types.d.ts.map +1 -0
  45. package/lib/typescript/useCdxFonts.d.ts +3 -11
  46. package/lib/typescript/useCdxFonts.d.ts.map +1 -1
  47. package/lib/typescript/useForgeFonts.d.ts +12 -0
  48. package/lib/typescript/useForgeFonts.d.ts.map +1 -0
  49. package/package.json +27 -8
  50. package/runtime/prestige-vs-default.json +1 -0
  51. package/runtime/pulse-vs-default.json +1 -0
  52. package/runtime/token-to-css-var.json +672 -0
  53. package/src/__tests__/applyThemeOverride.test.ts +552 -0
  54. package/src/__tests__/generateColorScale.test.ts +296 -0
  55. package/src/__tests__/presetJson.test.ts +120 -0
  56. package/src/__tests__/sd.config.test.ts +856 -0
  57. package/src/__tests__/theming.test.ts +647 -0
  58. package/src/__tests__/types.test.ts +72 -0
  59. package/src/__tests__/useCdxFonts.test.ts +27 -0
  60. package/src/__tests__/useForgeFonts.test.ts +226 -0
  61. package/src/applyThemeOverride.ts +139 -0
  62. package/src/index.ts +36 -60
  63. package/src/palette.ts +307 -0
  64. package/src/theming.ts +268 -0
  65. package/src/types.ts +112 -0
  66. package/src/useCdxFonts.ts +3 -229
  67. package/src/useForgeFonts.ts +230 -0
  68. package/tokens/presets/.manifest.json +3 -3
  69. package/tokens/presets/poise.json +319 -39
  70. package/tokens/presets/prestige.json +1 -1
  71. package/tokens/presets/pulse.json +1 -1
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+
3
+ import prestigePatch from '../runtime/prestige-vs-default.json';
4
+ import pulsePatch from '../runtime/pulse-vs-default.json';
5
+ import defaultRuntimeMap from '../runtime/token-to-css-var.json';
6
+ import { isSchemaVersionSupported, presetPatchToUniwindMaps, themeOverrideToUniwindMaps } from './theming';
7
+
8
+ // ---------------------------------------------------------------------------
9
+ // Constants
10
+ // ---------------------------------------------------------------------------
11
+
12
+ /** The build-time default preset. Apps ship with Poise baked into CSS. */
13
+ export const DEFAULT_PRESET = 'poise';
14
+
15
+ // ---------------------------------------------------------------------------
16
+ // Preset patch lookup
17
+ // ---------------------------------------------------------------------------
18
+
19
+ const PRESET_PATCHES = {
20
+ poise: null,
21
+ prestige: prestigePatch,
22
+ pulse: pulsePatch
23
+ };
24
+
25
+ // ---------------------------------------------------------------------------
26
+ // Platform detection
27
+ // ---------------------------------------------------------------------------
28
+
29
+ function detectPlatform() {
30
+ try {
31
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
32
+ const {
33
+ Platform: RNPlatform
34
+ } = require('react-native');
35
+ const os = RNPlatform.OS;
36
+ if (os === 'ios' || os === 'android') return os;
37
+ return 'web';
38
+ } catch {
39
+ return 'web';
40
+ }
41
+ }
42
+
43
+ // ---------------------------------------------------------------------------
44
+ // Result type
45
+ // ---------------------------------------------------------------------------
46
+
47
+ // ---------------------------------------------------------------------------
48
+ // Options
49
+ // ---------------------------------------------------------------------------
50
+
51
+ // ---------------------------------------------------------------------------
52
+ // Orchestrator
53
+ // ---------------------------------------------------------------------------
54
+
55
+ /**
56
+ * Apply a `ThemeOverride` end-to-end: schema version gate, preset patch
57
+ * selection, palette generation, and `Uniwind.updateCSSVariables` calls.
58
+ *
59
+ * Encapsulates the full runtime theme application sequence so consuming
60
+ * apps don't need to orchestrate lower-level utilities or import Uniwind
61
+ * directly.
62
+ */
63
+ export function applyThemeOverride(override, options = {}) {
64
+ const {
65
+ runtimeMap = defaultRuntimeMap,
66
+ runtimePlatform = detectPlatform()
67
+ } = options;
68
+
69
+ // --- Schema version gate ---
70
+ if (!isSchemaVersionSupported(override)) {
71
+ return {
72
+ applied: false,
73
+ reason: 'unsupported_schema_version'
74
+ };
75
+ }
76
+ const basePreset = override.$extensions['com.forge.ui.themeOverride'].basePreset;
77
+ const hasInputs = override.inputs !== undefined && Object.keys(override.inputs).length > 0;
78
+ const hasOverrides = override.overrides !== undefined && Object.keys(override.overrides).length > 0;
79
+
80
+ // --- Metadata-only check ---
81
+ const isDefaultPreset = basePreset === DEFAULT_PRESET;
82
+ if (isDefaultPreset && !hasInputs && !hasOverrides) {
83
+ return {
84
+ applied: false,
85
+ reason: 'no_theme_changes'
86
+ };
87
+ }
88
+
89
+ // --- Preset patch step ---
90
+ let presetMaps = {
91
+ light: {},
92
+ dark: {}
93
+ };
94
+ if (!isDefaultPreset) {
95
+ const patch = PRESET_PATCHES[basePreset];
96
+ if (patch) {
97
+ presetMaps = presetPatchToUniwindMaps(patch, runtimeMap, runtimePlatform);
98
+ }
99
+ }
100
+
101
+ // --- FI override step ---
102
+ let overrideMaps = {
103
+ light: {},
104
+ dark: {}
105
+ };
106
+ if (hasInputs || hasOverrides) {
107
+ overrideMaps = themeOverrideToUniwindMaps(override, runtimeMap);
108
+ }
109
+
110
+ // --- Merge per mode (FI wins on collision) ---
111
+ const mergedLight = {
112
+ ...presetMaps.light,
113
+ ...overrideMaps.light
114
+ };
115
+ const mergedDark = {
116
+ ...presetMaps.dark,
117
+ ...overrideMaps.dark
118
+ };
119
+
120
+ // --- Non-default preset with no FI changes still needs patch application ---
121
+ if (Object.keys(mergedLight).length === 0 && Object.keys(mergedDark).length === 0) {
122
+ return {
123
+ applied: false,
124
+ reason: 'no_theme_changes'
125
+ };
126
+ }
127
+
128
+ // --- Apply via Uniwind ---
129
+ try {
130
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
131
+ const {
132
+ Uniwind
133
+ } = require('uniwind');
134
+ if (Object.keys(mergedLight).length > 0) {
135
+ Uniwind.updateCSSVariables('light', mergedLight);
136
+ }
137
+ if (Object.keys(mergedDark).length > 0) {
138
+ Uniwind.updateCSSVariables('dark', mergedDark);
139
+ }
140
+ } catch {
141
+ throw new Error('applyThemeOverride requires "uniwind" to be installed. ' + 'Add it as a dependency in your app.');
142
+ }
143
+ return {
144
+ applied: true,
145
+ light: mergedLight,
146
+ dark: mergedDark
147
+ };
148
+ }
149
+ //# sourceMappingURL=applyThemeOverride.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["prestigePatch","pulsePatch","defaultRuntimeMap","isSchemaVersionSupported","presetPatchToUniwindMaps","themeOverrideToUniwindMaps","DEFAULT_PRESET","PRESET_PATCHES","poise","prestige","pulse","detectPlatform","Platform","RNPlatform","require","os","OS","applyThemeOverride","override","options","runtimeMap","runtimePlatform","applied","reason","basePreset","$extensions","hasInputs","inputs","undefined","Object","keys","length","hasOverrides","overrides","isDefaultPreset","presetMaps","light","dark","patch","overrideMaps","mergedLight","mergedDark","Uniwind","updateCSSVariables","Error"],"sourceRoot":"../../src","sources":["applyThemeOverride.ts"],"mappings":";;AAAA,OAAOA,aAAa,MAAM,qCAAqC;AAC/D,OAAOC,UAAU,MAAM,kCAAkC;AACzD,OAAOC,iBAAiB,MAAM,kCAAkC;AAEhE,SACEC,wBAAwB,EACxBC,wBAAwB,EACxBC,0BAA0B,QAGrB,WAAW;;AAElB;AACA;AACA;;AAEA;AACA,OAAO,MAAMC,cAAsB,GAAG,OAAO;;AAE7C;AACA;AACA;;AAEA,MAAMC,cAAiD,GAAG;EACxDC,KAAK,EAAE,IAAI;EACXC,QAAQ,EAAET,aAAa;EACvBU,KAAK,EAAET;AACT,CAAC;;AAED;AACA;AACA;;AAEA,SAASU,cAAcA,CAAA,EAAa;EAClC,IAAI;IACF;IACA,MAAM;MAAEC,QAAQ,EAAEC;IAAW,CAAC,GAAGC,OAAO,CAAC,cAAc,CAAC;IACxD,MAAMC,EAAE,GAAGF,UAAU,CAACG,EAAY;IAClC,IAAID,EAAE,KAAK,KAAK,IAAIA,EAAE,KAAK,SAAS,EAAE,OAAOA,EAAE;IAC/C,OAAO,KAAK;EACd,CAAC,CAAC,MAAM;IACN,OAAO,KAAK;EACd;AACF;;AAEA;AACA;AACA;;AAMA;AACA;AACA;;AAOA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASE,kBAAkBA,CAChCC,QAAuB,EACvBC,OAAkC,GAAG,CAAC,CAAC,EACb;EAC1B,MAAM;IAAEC,UAAU,GAAGlB,iBAAiB;IAAEmB,eAAe,GAAGV,cAAc,CAAC;EAAE,CAAC,GAAGQ,OAAO;;EAEtF;EACA,IAAI,CAAChB,wBAAwB,CAACe,QAAQ,CAAC,EAAE;IACvC,OAAO;MAAEI,OAAO,EAAE,KAAK;MAAEC,MAAM,EAAE;IAA6B,CAAC;EACjE;EAEA,MAAMC,UAAU,GAAGN,QAAQ,CAACO,WAAW,CAAC,4BAA4B,CAAC,CAACD,UAAU;EAChF,MAAME,SAAS,GAAGR,QAAQ,CAACS,MAAM,KAAKC,SAAS,IAAIC,MAAM,CAACC,IAAI,CAACZ,QAAQ,CAACS,MAAM,CAAC,CAACI,MAAM,GAAG,CAAC;EAC1F,MAAMC,YAAY,GAChBd,QAAQ,CAACe,SAAS,KAAKL,SAAS,IAAIC,MAAM,CAACC,IAAI,CAACZ,QAAQ,CAACe,SAAS,CAAC,CAACF,MAAM,GAAG,CAAC;;EAEhF;EACA,MAAMG,eAAe,GAAGV,UAAU,KAAKlB,cAAc;EACrD,IAAI4B,eAAe,IAAI,CAACR,SAAS,IAAI,CAACM,YAAY,EAAE;IAClD,OAAO;MAAEV,OAAO,EAAE,KAAK;MAAEC,MAAM,EAAE;IAAmB,CAAC;EACvD;;EAEA;EACA,IAAIY,UAA2B,GAAG;IAAEC,KAAK,EAAE,CAAC,CAAC;IAAEC,IAAI,EAAE,CAAC;EAAE,CAAC;EACzD,IAAI,CAACH,eAAe,EAAE;IACpB,MAAMI,KAAK,GAAG/B,cAAc,CAACiB,UAAU,CAAC;IACxC,IAAIc,KAAK,EAAE;MACTH,UAAU,GAAG/B,wBAAwB,CAACkC,KAAK,EAAElB,UAAU,EAAEC,eAAe,CAAC;IAC3E;EACF;;EAEA;EACA,IAAIkB,YAA6B,GAAG;IAAEH,KAAK,EAAE,CAAC,CAAC;IAAEC,IAAI,EAAE,CAAC;EAAE,CAAC;EAC3D,IAAIX,SAAS,IAAIM,YAAY,EAAE;IAC7BO,YAAY,GAAGlC,0BAA0B,CAACa,QAAQ,EAAEE,UAAU,CAAC;EACjE;;EAEA;EACA,MAAMoB,WAAW,GAAG;IAAE,GAAGL,UAAU,CAACC,KAAK;IAAE,GAAGG,YAAY,CAACH;EAAM,CAAC;EAClE,MAAMK,UAAU,GAAG;IAAE,GAAGN,UAAU,CAACE,IAAI;IAAE,GAAGE,YAAY,CAACF;EAAK,CAAC;;EAE/D;EACA,IAAIR,MAAM,CAACC,IAAI,CAACU,WAAW,CAAC,CAACT,MAAM,KAAK,CAAC,IAAIF,MAAM,CAACC,IAAI,CAACW,UAAU,CAAC,CAACV,MAAM,KAAK,CAAC,EAAE;IACjF,OAAO;MAAET,OAAO,EAAE,KAAK;MAAEC,MAAM,EAAE;IAAmB,CAAC;EACvD;;EAEA;EACA,IAAI;IACF;IACA,MAAM;MAAEmB;IAAQ,CAAC,GAAG5B,OAAO,CAAC,SAAS,CAAC;IACtC,IAAIe,MAAM,CAACC,IAAI,CAACU,WAAW,CAAC,CAACT,MAAM,GAAG,CAAC,EAAE;MACvCW,OAAO,CAACC,kBAAkB,CAAC,OAAO,EAAEH,WAAW,CAAC;IAClD;IACA,IAAIX,MAAM,CAACC,IAAI,CAACW,UAAU,CAAC,CAACV,MAAM,GAAG,CAAC,EAAE;MACtCW,OAAO,CAACC,kBAAkB,CAAC,MAAM,EAAEF,UAAU,CAAC;IAChD;EACF,CAAC,CAAC,MAAM;IACN,MAAM,IAAIG,KAAK,CACb,yDAAyD,GACvD,qCACJ,CAAC;EACH;EAEA,OAAO;IAAEtB,OAAO,EAAE,IAAI;IAAEc,KAAK,EAAEI,WAAW;IAAEH,IAAI,EAAEI;EAAW,CAAC;AAChE","ignoreList":[]}
@@ -1,33 +1,24 @@
1
1
  "use strict";
2
2
 
3
3
  // ---------------------------------------------------------------------------
4
- // Types
4
+ // Types & Constants
5
5
  // ---------------------------------------------------------------------------
6
6
 
7
- /** A DTCG token leaf node. */
8
-
9
- /** Recursive token group — every non-leaf node in a theme object. */
10
-
11
- /** Theme metadata stored under `$extensions.com.candescent.theme`. */
12
-
13
- /** Override metadata stored under `$extensions.com.candescent.themeOverride`. */
14
-
15
- /**
16
- * A complete CDX UI theme object (DTCG-compatible).
17
- *
18
- * Presets (Poise, Prestige, Pulse) are full theme objects. At runtime the
19
- * build-time default preset is augmented by FI overrides via
20
- * `applyThemeOverrides`.
21
- */
7
+ export { OVERRIDE_SCHEMA_VERSION, SUPPORTED_OVERRIDE_SCHEMA_VERSIONS, INPUT_TOKEN_MAP, presetFonts } from './types';
8
+ // ---------------------------------------------------------------------------
9
+ // Palette generation
10
+ // ---------------------------------------------------------------------------
22
11
 
23
- /**
24
- * A theme override — a strict subset of the theme object schema containing
25
- * only the token paths that differ from the base preset.
26
- */
12
+ export { generateColorScale, generatePalettesFromInputs, deriveBaseColorKey } from './palette';
13
+ // ---------------------------------------------------------------------------
14
+ // Theming utilities
15
+ // ---------------------------------------------------------------------------
27
16
 
17
+ export { isSchemaVersionSupported, presetPatchToUniwindMaps, themeOverrideToUniwindMaps, applyThemeOverride, DEFAULT_PRESET } from './theming';
28
18
  // ---------------------------------------------------------------------------
29
19
  // Hooks
30
20
  // ---------------------------------------------------------------------------
31
21
 
22
+ export { useForgeFonts } from './useForgeFonts';
32
23
  export { useCdxFonts } from './useCdxFonts';
33
24
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["useCdxFonts"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA;AACA;AACA;;AAEA;;AAOA;;AAKA;;AAOA;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;;AAiBA;AACA;AACA;AACA;;AAWA;AACA;AACA;;AAEA,SAASA,WAAW,QAAQ,eAAe","ignoreList":[]}
1
+ {"version":3,"names":["OVERRIDE_SCHEMA_VERSION","SUPPORTED_OVERRIDE_SCHEMA_VERSIONS","INPUT_TOKEN_MAP","presetFonts","generateColorScale","generatePalettesFromInputs","deriveBaseColorKey","isSchemaVersionSupported","presetPatchToUniwindMaps","themeOverrideToUniwindMaps","applyThemeOverride","DEFAULT_PRESET","useForgeFonts","useCdxFonts"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA;AACA;AACA;;AAEA,SACEA,uBAAuB,EACvBC,kCAAkC,EAClCC,eAAe,EACfC,WAAW,QACN,SAAS;AAahB;AACA;AACA;;AAEA,SAASC,kBAAkB,EAAEC,0BAA0B,EAAEC,kBAAkB,QAAQ,WAAW;AAG9F;AACA;AACA;;AAEA,SACEC,wBAAwB,EACxBC,wBAAwB,EACxBC,0BAA0B,EAC1BC,kBAAkB,EAClBC,cAAc,QACT,WAAW;AAIlB;AACA;AACA;;AAEA,SAASC,aAAa,QAAQ,iBAAiB;AAC/C,SAASC,WAAW,QAAQ,eAAe","ignoreList":[]}
@@ -0,0 +1,257 @@
1
+ "use strict";
2
+
3
+ import { BackgroundColor, Color, Theme } from '@adobe/leonardo-contrast-colors';
4
+
5
+ // ---------------------------------------------------------------------------
6
+ // Types
7
+ // ---------------------------------------------------------------------------
8
+
9
+ /** Palette step keys produced by `generateColorScale`. */
10
+
11
+ /** Token category that supports palette generation. */
12
+
13
+ /** Map of palette step → resolved hex color. */
14
+
15
+ /** Map of token dot-path → resolved hex color (e.g. `color.brand.500` → `#548cdc`). */
16
+
17
+ // ---------------------------------------------------------------------------
18
+ // Constants
19
+ // ---------------------------------------------------------------------------
20
+
21
+ const REFERENCE_BACKGROUND = '#ffffff';
22
+ const PALETTE_STEPS = ['50', '100', '200', '300', '400', '500', '600', '700', '800', '900', '950'];
23
+
24
+ /**
25
+ * Contrast ratios for each palette step against white (#ffffff).
26
+ *
27
+ * Step 700 targets WCAG AA for normal text (≥ 4.5:1).
28
+ */
29
+ const CONTRAST_RATIOS = {
30
+ '50': 1.04,
31
+ '100': 1.16,
32
+ '200': 1.46,
33
+ '300': 1.85,
34
+ '400': 2.45,
35
+ '500': 3.4,
36
+ '600': 4.8,
37
+ '700': 6.4,
38
+ '800': 8.6,
39
+ '900': 12,
40
+ '950': 16.8
41
+ };
42
+ const HEX_REGEX = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;
43
+
44
+ // ---------------------------------------------------------------------------
45
+ // Validation
46
+ // ---------------------------------------------------------------------------
47
+
48
+ /**
49
+ * Validate and normalise a hex color string.
50
+ *
51
+ * Accepts `#RGB` (4 chars) or `#RRGGBB` (7 chars). Throws a descriptive
52
+ * `TypeError` for any other input.
53
+ *
54
+ * @returns The normalised 7-character hex string (e.g. `#aabbcc`).
55
+ */
56
+ function validateHex(hex) {
57
+ if (typeof hex !== 'string') {
58
+ throw new TypeError(`Invalid hex color: expected a string, received ${typeof hex}`);
59
+ }
60
+ if (!HEX_REGEX.test(hex)) {
61
+ throw new TypeError(`Invalid hex color "${hex}": must be a 4-character (#RGB) or 7-character (#RRGGBB) hex string starting with "#"`);
62
+ }
63
+ if (hex.length === 4) {
64
+ const [, r, g, b] = hex;
65
+ return `#${r}${r}${g}${g}${b}${b}`.toLowerCase();
66
+ }
67
+ return hex.toLowerCase();
68
+ }
69
+
70
+ // ---------------------------------------------------------------------------
71
+ // Core generation — wraps Leonardo behind a thin interface
72
+ // ---------------------------------------------------------------------------
73
+
74
+ /**
75
+ * Generate an 11-step contrast-based color scale from a single hex color.
76
+ *
77
+ * Uses `@adobe/leonardo-contrast-colors` internally. The generation algorithm
78
+ * is wrapped behind this function so the underlying library is swappable
79
+ * without changing the public API.
80
+ *
81
+ * @param hex - A valid hex color string (`#RGB` or `#RRGGBB`).
82
+ * @param category - The token namespace (`'brand'` or `'accent'`).
83
+ * @returns A `PaletteTokenMap` keyed by token dot-paths
84
+ * (e.g. `"color.brand.50"` through `"color.brand.950"` plus `"color.brand.input"`).
85
+ */
86
+ export function generateColorScale(hex, category) {
87
+ const normalised = validateHex(hex);
88
+ const ratiosObject = {};
89
+ for (const step of PALETTE_STEPS) {
90
+ ratiosObject[step] = CONTRAST_RATIOS[step];
91
+ }
92
+ const color = new Color({
93
+ name: 'palette',
94
+ colorKeys: [normalised],
95
+ colorSpace: 'CAM02p',
96
+ ratios: ratiosObject,
97
+ smooth: true,
98
+ output: 'HEX'
99
+ });
100
+ const bg = new BackgroundColor({
101
+ name: 'background',
102
+ colorKeys: [REFERENCE_BACKGROUND],
103
+ colorSpace: 'CAM02p',
104
+ smooth: true,
105
+ ratios: [],
106
+ output: 'HEX'
107
+ });
108
+ const theme = new Theme({
109
+ colors: [color],
110
+ backgroundColor: bg,
111
+ lightness: 100,
112
+ contrast: 1,
113
+ saturation: 100,
114
+ output: 'HEX',
115
+ formula: 'wcag2'
116
+ });
117
+ const pairs = theme.contrastColorPairs;
118
+ const tokenPrefix = `color.${category}`;
119
+ const result = {};
120
+ for (const step of PALETTE_STEPS) {
121
+ result[`${tokenPrefix}.${step}`] = pairs[step].toLowerCase();
122
+ }
123
+ result[`${tokenPrefix}.input`] = normalised;
124
+ return result;
125
+ }
126
+
127
+ // ---------------------------------------------------------------------------
128
+ // Base color-key derivation
129
+ // ---------------------------------------------------------------------------
130
+
131
+ /** Saturation (0–1) applied to the brand hue to produce the base color key. */
132
+ const BASE_SATURATION = 0.05;
133
+
134
+ /** Convert a normalised hex string to HSL (`h` in degrees, `s`/`l` in 0–1). */
135
+ function hexToHsl(hex) {
136
+ const r = parseInt(hex.slice(1, 3), 16) / 255;
137
+ const g = parseInt(hex.slice(3, 5), 16) / 255;
138
+ const b = parseInt(hex.slice(5, 7), 16) / 255;
139
+ const max = Math.max(r, g, b);
140
+ const min = Math.min(r, g, b);
141
+ const delta = max - min;
142
+ const l = (max + min) / 2;
143
+ let h = 0;
144
+ let s = 0;
145
+ if (delta !== 0) {
146
+ s = l > 0.5 ? delta / (2 - max - min) : delta / (max + min);
147
+ switch (max) {
148
+ case r:
149
+ h = (g - b) / delta + (g < b ? 6 : 0);
150
+ break;
151
+ case g:
152
+ h = (b - r) / delta + 2;
153
+ break;
154
+ default:
155
+ h = (r - g) / delta + 4;
156
+ break;
157
+ }
158
+ h *= 60;
159
+ }
160
+ return {
161
+ h,
162
+ s,
163
+ l
164
+ };
165
+ }
166
+
167
+ /** Convert HSL (`h` in degrees, `s`/`l` in 0–1) to a normalised hex string. */
168
+ function hslToHex({
169
+ h,
170
+ s,
171
+ l
172
+ }) {
173
+ const c = (1 - Math.abs(2 * l - 1)) * s;
174
+ const hp = (h % 360 + 360) % 360 / 60;
175
+ const x = c * (1 - Math.abs(hp % 2 - 1));
176
+ let r = 0;
177
+ let g = 0;
178
+ let b = 0;
179
+ if (hp < 1) [r, g, b] = [c, x, 0];else if (hp < 2) [r, g, b] = [x, c, 0];else if (hp < 3) [r, g, b] = [0, c, x];else if (hp < 4) [r, g, b] = [0, x, c];else if (hp < 5) [r, g, b] = [x, 0, c];else [r, g, b] = [c, 0, x];
180
+ const m = l - c / 2;
181
+ const toHex = v => Math.round((v + m) * 255).toString(16).padStart(2, '0');
182
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
183
+ }
184
+
185
+ /**
186
+ * Derive the base palette color key from a brand color.
187
+ *
188
+ * The base scale shares the brand's hue and lightness but is nearly neutral:
189
+ * the brand color is converted to HSL and its saturation is lowered to
190
+ * {@link BASE_SATURATION} (5%). The resulting hex is the color key fed to
191
+ * {@link generateColorScale} for the `base` category.
192
+ *
193
+ * @param brandHex - A valid hex color string (`#RGB` or `#RRGGBB`).
194
+ * @returns The normalised hex color key for the base scale.
195
+ */
196
+ export function deriveBaseColorKey(brandHex) {
197
+ const {
198
+ h,
199
+ l
200
+ } = hexToHsl(validateHex(brandHex));
201
+ return hslToHex({
202
+ h,
203
+ s: BASE_SATURATION,
204
+ l
205
+ });
206
+ }
207
+
208
+ // ---------------------------------------------------------------------------
209
+ // Convenience wrapper
210
+ // ---------------------------------------------------------------------------
211
+
212
+ /**
213
+ * Colour-input keys whose token path starts with `color.` — these trigger
214
+ * palette generation. Mirrors the colour entries from `INPUT_TOKEN_MAP`
215
+ * (defined in the package barrel) without creating a circular import.
216
+ *
217
+ * Keep in sync with `INPUT_TOKEN_MAP` in `./index.ts`.
218
+ */
219
+ const COLOR_INPUT_ENTRIES = [['brandPrimary', 'color.brand'], ['accentPrimary', 'color.accent'], ['basePrimary', 'color.base']];
220
+
221
+ /**
222
+ * Generate palettes for all colour inputs in a theme override `inputs` object.
223
+ *
224
+ * Iterates over known colour-input keys that map to a `color.*` token
225
+ * namespace. For each matching key present in `inputs`, runs
226
+ * `generateColorScale` and merges the results into a single flat map of
227
+ * token dot-paths to hex values — ready for the S5 override application
228
+ * merge step.
229
+ *
230
+ * Non-colour inputs (e.g. `displayFont`) are silently skipped.
231
+ *
232
+ * @param inputs - The `inputs` object from a `ThemeOverride`.
233
+ * @returns A merged `Record<string, string>` of all generated token
234
+ * dot-paths to hex values.
235
+ *
236
+ * @example
237
+ * ```ts
238
+ * const inputs = { brandPrimary: '#0052cc', accentPrimary: '#FF8C42', displayFont: 'Poppins' };
239
+ * const result = generatePalettesFromInputs(inputs);
240
+ * // {
241
+ * // "color.brand.50": "#...", …, "color.brand.input": "#0052cc",
242
+ * // "color.accent.50": "#...", …, "color.accent.input": "#ff8c42"
243
+ * // }
244
+ * ```
245
+ */
246
+ export function generatePalettesFromInputs(inputs) {
247
+ const result = {};
248
+ for (const [inputKey, tokenPath] of COLOR_INPUT_ENTRIES) {
249
+ const value = inputs[inputKey];
250
+ if (typeof value !== 'string') continue;
251
+ const category = tokenPath.replace('color.', '');
252
+ const scale = generateColorScale(value, category);
253
+ Object.assign(result, scale);
254
+ }
255
+ return result;
256
+ }
257
+ //# sourceMappingURL=palette.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["BackgroundColor","Color","Theme","REFERENCE_BACKGROUND","PALETTE_STEPS","CONTRAST_RATIOS","HEX_REGEX","validateHex","hex","TypeError","test","length","r","g","b","toLowerCase","generateColorScale","category","normalised","ratiosObject","step","color","name","colorKeys","colorSpace","ratios","smooth","output","bg","theme","colors","backgroundColor","lightness","contrast","saturation","formula","pairs","contrastColorPairs","tokenPrefix","result","BASE_SATURATION","hexToHsl","parseInt","slice","max","Math","min","delta","l","h","s","hslToHex","c","abs","hp","x","m","toHex","v","round","toString","padStart","deriveBaseColorKey","brandHex","COLOR_INPUT_ENTRIES","generatePalettesFromInputs","inputs","inputKey","tokenPath","value","replace","scale","Object","assign"],"sourceRoot":"../../src","sources":["palette.ts"],"mappings":"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","ignoreList":[]}