@wordpress/theme 0.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.
Files changed (168) hide show
  1. package/LICENSE.md +788 -0
  2. package/README.md +67 -0
  3. package/bin/build-tokens.js +83 -0
  4. package/bin/generate-primitive-tokens/index.ts +115 -0
  5. package/bin/terrazzo-plugin-ds-tokens-docs/index.ts +103 -0
  6. package/bin/terrazzo-plugin-figma-ds-token-manager/index.ts +210 -0
  7. package/bin/terrazzo-plugin-figma-ds-token-manager/lib.ts +1 -0
  8. package/bin/terrazzo-plugin-known-wpds-css-variables/index.ts +72 -0
  9. package/build/color-ramps/index.js +132 -0
  10. package/build/color-ramps/index.js.map +7 -0
  11. package/build/color-ramps/lib/cache-utils.js +57 -0
  12. package/build/color-ramps/lib/cache-utils.js.map +7 -0
  13. package/build/color-ramps/lib/constants.js +105 -0
  14. package/build/color-ramps/lib/constants.js.map +7 -0
  15. package/build/color-ramps/lib/find-color-with-constraints.js +141 -0
  16. package/build/color-ramps/lib/find-color-with-constraints.js.map +7 -0
  17. package/build/color-ramps/lib/index.js +264 -0
  18. package/build/color-ramps/lib/index.js.map +7 -0
  19. package/build/color-ramps/lib/ramp-configs.js +315 -0
  20. package/build/color-ramps/lib/ramp-configs.js.map +7 -0
  21. package/build/color-ramps/lib/taper-chroma.js +159 -0
  22. package/build/color-ramps/lib/taper-chroma.js.map +7 -0
  23. package/build/color-ramps/lib/types.js +17 -0
  24. package/build/color-ramps/lib/types.js.map +7 -0
  25. package/build/color-ramps/lib/utils.js +106 -0
  26. package/build/color-ramps/lib/utils.js.map +7 -0
  27. package/build/context.js +34 -0
  28. package/build/context.js.map +7 -0
  29. package/build/index.js +29 -0
  30. package/build/index.js.map +7 -0
  31. package/build/lock-unlock.js +35 -0
  32. package/build/lock-unlock.js.map +7 -0
  33. package/build/prebuilt/js/design-tokens.js +135 -0
  34. package/build/prebuilt/js/design-tokens.js.map +7 -0
  35. package/build/prebuilt/json/figma.json +1317 -0
  36. package/build/prebuilt/ts/design-tokens.js +354 -0
  37. package/build/prebuilt/ts/design-tokens.js.map +7 -0
  38. package/build/private-apis.js +36 -0
  39. package/build/private-apis.js.map +7 -0
  40. package/build/style.module.css.js +2 -0
  41. package/build/theme-provider.js +92 -0
  42. package/build/theme-provider.js.map +7 -0
  43. package/build/types/css-modules.d.js +2 -0
  44. package/build/types/css-modules.d.js.map +7 -0
  45. package/build/types.js +17 -0
  46. package/build/types.js.map +7 -0
  47. package/build/use-theme-provider-styles.js +230 -0
  48. package/build/use-theme-provider-styles.js.map +7 -0
  49. package/build-module/color-ramps/index.js +95 -0
  50. package/build-module/color-ramps/index.js.map +7 -0
  51. package/build-module/color-ramps/lib/cache-utils.js +31 -0
  52. package/build-module/color-ramps/lib/cache-utils.js.map +7 -0
  53. package/build-module/color-ramps/lib/constants.js +63 -0
  54. package/build-module/color-ramps/lib/constants.js.map +7 -0
  55. package/build-module/color-ramps/lib/find-color-with-constraints.js +112 -0
  56. package/build-module/color-ramps/lib/find-color-with-constraints.js.map +7 -0
  57. package/build-module/color-ramps/lib/index.js +235 -0
  58. package/build-module/color-ramps/lib/index.js.map +7 -0
  59. package/build-module/color-ramps/lib/ramp-configs.js +290 -0
  60. package/build-module/color-ramps/lib/ramp-configs.js.map +7 -0
  61. package/build-module/color-ramps/lib/taper-chroma.js +125 -0
  62. package/build-module/color-ramps/lib/taper-chroma.js.map +7 -0
  63. package/build-module/color-ramps/lib/types.js +1 -0
  64. package/build-module/color-ramps/lib/types.js.map +7 -0
  65. package/build-module/color-ramps/lib/utils.js +84 -0
  66. package/build-module/color-ramps/lib/utils.js.map +7 -0
  67. package/build-module/context.js +10 -0
  68. package/build-module/context.js.map +7 -0
  69. package/build-module/index.js +5 -0
  70. package/build-module/index.js.map +7 -0
  71. package/build-module/lock-unlock.js +10 -0
  72. package/build-module/lock-unlock.js.map +7 -0
  73. package/build-module/prebuilt/js/design-tokens.js +115 -0
  74. package/build-module/prebuilt/js/design-tokens.js.map +7 -0
  75. package/build-module/prebuilt/json/figma.json +1317 -0
  76. package/build-module/prebuilt/ts/design-tokens.js +334 -0
  77. package/build-module/prebuilt/ts/design-tokens.js.map +7 -0
  78. package/build-module/private-apis.js +12 -0
  79. package/build-module/private-apis.js.map +7 -0
  80. package/build-module/style.module.css.js +1 -0
  81. package/build-module/theme-provider.js +58 -0
  82. package/build-module/theme-provider.js.map +7 -0
  83. package/build-module/types/css-modules.d.js +1 -0
  84. package/build-module/types/css-modules.d.js.map +7 -0
  85. package/build-module/types.js +1 -0
  86. package/build-module/types.js.map +7 -0
  87. package/build-module/use-theme-provider-styles.js +200 -0
  88. package/build-module/use-theme-provider-styles.js.map +7 -0
  89. package/build-style/style.css +3 -0
  90. package/build-types/color-ramps/index.d.ts +44 -0
  91. package/build-types/color-ramps/index.d.ts.map +1 -0
  92. package/build-types/color-ramps/lib/cache-utils.d.ts +22 -0
  93. package/build-types/color-ramps/lib/cache-utils.d.ts.map +1 -0
  94. package/build-types/color-ramps/lib/constants.d.ts +38 -0
  95. package/build-types/color-ramps/lib/constants.d.ts.map +1 -0
  96. package/build-types/color-ramps/lib/find-color-with-constraints.d.ts +37 -0
  97. package/build-types/color-ramps/lib/find-color-with-constraints.d.ts.map +1 -0
  98. package/build-types/color-ramps/lib/index.d.ts +11 -0
  99. package/build-types/color-ramps/lib/index.d.ts.map +1 -0
  100. package/build-types/color-ramps/lib/ramp-configs.d.ts +7 -0
  101. package/build-types/color-ramps/lib/ramp-configs.d.ts.map +1 -0
  102. package/build-types/color-ramps/lib/taper-chroma.d.ts +32 -0
  103. package/build-types/color-ramps/lib/taper-chroma.d.ts.map +1 -0
  104. package/build-types/color-ramps/lib/types.d.ts +78 -0
  105. package/build-types/color-ramps/lib/types.d.ts.map +1 -0
  106. package/build-types/color-ramps/lib/utils.d.ts +38 -0
  107. package/build-types/color-ramps/lib/utils.d.ts.map +1 -0
  108. package/build-types/color-ramps/stories/index.story.d.ts +14 -0
  109. package/build-types/color-ramps/stories/index.story.d.ts.map +1 -0
  110. package/build-types/color-ramps/stories/ramp-table.d.ts +19 -0
  111. package/build-types/color-ramps/stories/ramp-table.d.ts.map +1 -0
  112. package/build-types/context.d.ts +10 -0
  113. package/build-types/context.d.ts.map +1 -0
  114. package/build-types/index.d.ts +2 -0
  115. package/build-types/index.d.ts.map +1 -0
  116. package/build-types/lock-unlock.d.ts +2 -0
  117. package/build-types/lock-unlock.d.ts.map +1 -0
  118. package/build-types/prebuilt/js/design-tokens.d.ts +3 -0
  119. package/build-types/prebuilt/js/design-tokens.d.ts.map +1 -0
  120. package/build-types/prebuilt/ts/design-tokens.d.ts +7 -0
  121. package/build-types/prebuilt/ts/design-tokens.d.ts.map +1 -0
  122. package/build-types/private-apis.d.ts +2 -0
  123. package/build-types/private-apis.d.ts.map +1 -0
  124. package/build-types/stories/index.story.d.ts +15 -0
  125. package/build-types/stories/index.story.d.ts.map +1 -0
  126. package/build-types/theme-provider.d.ts +3 -0
  127. package/build-types/theme-provider.d.ts.map +1 -0
  128. package/build-types/types.d.ts +42 -0
  129. package/build-types/types.d.ts.map +1 -0
  130. package/build-types/use-theme-provider-styles.d.ts +17 -0
  131. package/build-types/use-theme-provider-styles.d.ts.map +1 -0
  132. package/docs/ds-tokens.md +283 -0
  133. package/package.json +58 -0
  134. package/src/color-ramps/index.ts +155 -0
  135. package/src/color-ramps/lib/cache-utils.ts +56 -0
  136. package/src/color-ramps/lib/constants.ts +85 -0
  137. package/src/color-ramps/lib/find-color-with-constraints.ts +190 -0
  138. package/src/color-ramps/lib/index.ts +369 -0
  139. package/src/color-ramps/lib/ramp-configs.ts +309 -0
  140. package/src/color-ramps/lib/taper-chroma.ts +226 -0
  141. package/src/color-ramps/lib/types.ts +90 -0
  142. package/src/color-ramps/lib/utils.ts +161 -0
  143. package/src/color-ramps/stories/index.story.tsx +264 -0
  144. package/src/color-ramps/stories/ramp-table.tsx +212 -0
  145. package/src/color-ramps/test/__snapshots__/index.test.ts.snap +1280 -0
  146. package/src/color-ramps/test/index.test.ts +94 -0
  147. package/src/context.ts +19 -0
  148. package/src/index.ts +2 -0
  149. package/src/lock-unlock.ts +10 -0
  150. package/src/prebuilt/css/design-tokens.css +401 -0
  151. package/src/prebuilt/js/design-tokens.js +116 -0
  152. package/src/prebuilt/json/figma.json +1317 -0
  153. package/src/prebuilt/ts/design-tokens.ts +335 -0
  154. package/src/private-apis.ts +12 -0
  155. package/src/stories/index.story.tsx +426 -0
  156. package/src/style.module.css +3 -0
  157. package/src/theme-provider.tsx +87 -0
  158. package/src/types/css-modules.d.ts +4 -0
  159. package/src/types.ts +44 -0
  160. package/src/use-theme-provider-styles.ts +247 -0
  161. package/terrazzo.config.ts +102 -0
  162. package/tokens/border.json +34 -0
  163. package/tokens/color.json +877 -0
  164. package/tokens/elevation.json +201 -0
  165. package/tokens/spacing.json +45 -0
  166. package/tokens/typography.json +93 -0
  167. package/tsconfig.json +9 -0
  168. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,230 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var use_theme_provider_styles_exports = {};
30
+ __export(use_theme_provider_styles_exports, {
31
+ useThemeProviderStyles: () => useThemeProviderStyles
32
+ });
33
+ module.exports = __toCommonJS(use_theme_provider_styles_exports);
34
+ var import_colorjs = __toESM(require("colorjs.io"));
35
+ var import_element = require("@wordpress/element");
36
+ var import_context = require("./context");
37
+ var import_design_tokens = __toESM(require("./prebuilt/ts/design-tokens"));
38
+ var import_color_ramps = require("./color-ramps");
39
+ const legacyWpComponentsOverridesCSS = [
40
+ ["--wp-components-color-accent", "var(--wp-admin-theme-color)"],
41
+ [
42
+ "--wp-components-color-accent-darker-10",
43
+ "var(--wp-admin-theme-color-darker-10)"
44
+ ],
45
+ [
46
+ "--wp-components-color-accent-darker-20",
47
+ "var(--wp-admin-theme-color-darker-20)"
48
+ ],
49
+ [
50
+ "--wp-components-color-accent-inverted",
51
+ "var(--wpds-color-fg-interactive-brand-strong)"
52
+ ],
53
+ [
54
+ "--wp-components-color-background",
55
+ "var(--wpds-color-bg-surface-neutral-strong)"
56
+ ],
57
+ [
58
+ "--wp-components-color-foreground",
59
+ "var(--wpds-color-fg-content-neutral)"
60
+ ],
61
+ [
62
+ "--wp-components-color-foreground-inverted",
63
+ "var(--wpds-color-bg-surface-neutral)"
64
+ ],
65
+ [
66
+ "--wp-components-color-gray-100",
67
+ "var(--wpds-color-bg-surface-neutral)"
68
+ ],
69
+ [
70
+ "--wp-components-color-gray-200",
71
+ "var(--wpds-color-stroke-surface-neutral)"
72
+ ],
73
+ [
74
+ "--wp-components-color-gray-300",
75
+ "var(--wpds-color-stroke-surface-neutral)"
76
+ ],
77
+ [
78
+ "--wp-components-color-gray-400",
79
+ "var(--wpds-color-stroke-interactive-neutral)"
80
+ ],
81
+ [
82
+ "--wp-components-color-gray-600",
83
+ "var(--wpds-color-stroke-interactive-neutral)"
84
+ ],
85
+ [
86
+ "--wp-components-color-gray-700",
87
+ "var(--wpds-color-fg-content-neutral-weak)"
88
+ ],
89
+ [
90
+ "--wp-components-color-gray-800",
91
+ "var(--wpds-color-fg-content-neutral)"
92
+ ]
93
+ ];
94
+ function customRgbFormat(color) {
95
+ const rgb = color.to("srgb");
96
+ return [rgb.r, rgb.g, rgb.b].map((n) => Math.round(n * 255)).join(", ");
97
+ }
98
+ function legacyWpAdminThemeOverridesCSS(accent) {
99
+ const parsedAccent = new import_colorjs.default(accent).to("hsl");
100
+ const hsl = parsedAccent.coords;
101
+ const darker10 = new import_colorjs.default("hsl", [
102
+ hsl[0],
103
+ // h
104
+ hsl[1],
105
+ // s
106
+ Math.max(0, Math.min(100, hsl[2] - 5))
107
+ // l (reduced by 5%)
108
+ ]).to("srgb");
109
+ const darker20 = new import_colorjs.default("hsl", [
110
+ hsl[0],
111
+ // h
112
+ hsl[1],
113
+ // s
114
+ Math.max(0, Math.min(100, hsl[2] - 10))
115
+ // l (reduced by 10%)
116
+ ]).to("srgb");
117
+ return [
118
+ [
119
+ "--wp-admin-theme-color",
120
+ parsedAccent.to("srgb").toString({ format: "hex" })
121
+ ],
122
+ ["--wp-admin-theme-color--rgb", customRgbFormat(parsedAccent)],
123
+ [
124
+ "--wp-admin-theme-color-darker-10",
125
+ darker10.toString({ format: "hex" })
126
+ ],
127
+ [
128
+ "--wp-admin-theme-color-darker-10--rgb",
129
+ customRgbFormat(darker10)
130
+ ],
131
+ [
132
+ "--wp-admin-theme-color-darker-20",
133
+ darker20.toString({ format: "hex" })
134
+ ],
135
+ [
136
+ "--wp-admin-theme-color-darker-20--rgb",
137
+ customRgbFormat(darker20)
138
+ ]
139
+ ];
140
+ }
141
+ function semanticTokensCSS(filterFn = () => true) {
142
+ return Object.entries(import_design_tokens.default).filter(filterFn).map(([variableName, modesAndValues]) => [
143
+ variableName,
144
+ modesAndValues["."]
145
+ ]);
146
+ }
147
+ const toKebabCase = (str) => str.replace(
148
+ /[A-Z]+(?![a-z])|[A-Z]/g,
149
+ ($, ofs) => (ofs ? "-" : "") + $.toLowerCase()
150
+ );
151
+ function colorRampCSS(ramp, prefix) {
152
+ return [...Object.entries(ramp.ramp)].map(
153
+ ([tokenName, tokenValue]) => [
154
+ `${prefix}${toKebabCase(tokenName)}`,
155
+ tokenValue.color
156
+ ]
157
+ );
158
+ }
159
+ function generateStyles({
160
+ primary,
161
+ computedColorRamps
162
+ }) {
163
+ return Object.fromEntries(
164
+ [
165
+ // Primitive tokens
166
+ Array.from(computedColorRamps).map(([rampName, computedColorRamp]) => [
167
+ colorRampCSS(
168
+ computedColorRamp,
169
+ `--wpds-color-private-${rampName}-`
170
+ )
171
+ ]).flat(2),
172
+ // Semantic color tokens (other semantic tokens for now are static)
173
+ semanticTokensCSS(([key]) => /color/.test(key)),
174
+ // Legacy overrides
175
+ legacyWpAdminThemeOverridesCSS(primary),
176
+ legacyWpComponentsOverridesCSS
177
+ ].flat()
178
+ );
179
+ }
180
+ function useThemeProviderStyles({
181
+ color = {}
182
+ } = {}) {
183
+ const { resolvedSettings: inheritedSettings } = (0, import_element.useContext)(import_context.ThemeContext);
184
+ const primary = color.primary ?? inheritedSettings.color?.primary ?? import_color_ramps.DEFAULT_SEED_COLORS.primary;
185
+ const bg = color.bg ?? inheritedSettings.color?.bg ?? import_color_ramps.DEFAULT_SEED_COLORS.bg;
186
+ const resolvedSettings = (0, import_element.useMemo)(
187
+ () => ({
188
+ color: {
189
+ primary,
190
+ bg
191
+ }
192
+ }),
193
+ [primary, bg]
194
+ );
195
+ const themeProviderStyles = (0, import_element.useMemo)(() => {
196
+ const seeds = {
197
+ ...import_color_ramps.DEFAULT_SEED_COLORS,
198
+ bg,
199
+ primary
200
+ };
201
+ const computedColorRamps = /* @__PURE__ */ new Map();
202
+ const bgRamp = (0, import_color_ramps.buildBgRamp)({ seed: seeds.bg });
203
+ Object.entries(seeds).forEach(([rampName, seed]) => {
204
+ if (rampName === "bg") {
205
+ computedColorRamps.set(rampName, bgRamp);
206
+ } else {
207
+ computedColorRamps.set(
208
+ rampName,
209
+ (0, import_color_ramps.buildAccentRamp)({
210
+ seed,
211
+ bgRamp
212
+ })
213
+ );
214
+ }
215
+ });
216
+ return generateStyles({
217
+ primary: seeds.primary,
218
+ computedColorRamps
219
+ });
220
+ }, [primary, bg]);
221
+ return {
222
+ resolvedSettings,
223
+ themeProviderStyles
224
+ };
225
+ }
226
+ // Annotate the CommonJS export names for ESM import in node:
227
+ 0 && (module.exports = {
228
+ useThemeProviderStyles
229
+ });
230
+ //# sourceMappingURL=use-theme-provider-styles.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/use-theme-provider-styles.ts"],
4
+ "sourcesContent": ["/**\n * External dependencies\n */\nimport type { CSSProperties } from 'react';\nimport Color from 'colorjs.io';\n\n/**\n * WordPress dependencies\n */\nimport { useMemo, useContext } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport { ThemeContext } from './context';\nimport semanticVariables from './prebuilt/ts/design-tokens';\nimport {\n\tbuildBgRamp,\n\tbuildAccentRamp,\n\tDEFAULT_SEED_COLORS,\n\ttype RampResult,\n} from './color-ramps';\nimport type { ThemeProviderProps } from './types';\n\ntype Entry = [ string, string ];\n\nconst legacyWpComponentsOverridesCSS: Entry[] = [\n\t[ '--wp-components-color-accent', 'var(--wp-admin-theme-color)' ],\n\t[\n\t\t'--wp-components-color-accent-darker-10',\n\t\t'var(--wp-admin-theme-color-darker-10)',\n\t],\n\t[\n\t\t'--wp-components-color-accent-darker-20',\n\t\t'var(--wp-admin-theme-color-darker-20)',\n\t],\n\t[\n\t\t'--wp-components-color-accent-inverted',\n\t\t'var(--wpds-color-fg-interactive-brand-strong)',\n\t],\n\t[\n\t\t'--wp-components-color-background',\n\t\t'var(--wpds-color-bg-surface-neutral-strong)',\n\t],\n\t[\n\t\t'--wp-components-color-foreground',\n\t\t'var(--wpds-color-fg-content-neutral)',\n\t],\n\t[\n\t\t'--wp-components-color-foreground-inverted',\n\t\t'var(--wpds-color-bg-surface-neutral)',\n\t],\n\t[\n\t\t'--wp-components-color-gray-100',\n\t\t'var(--wpds-color-bg-surface-neutral)',\n\t],\n\t[\n\t\t'--wp-components-color-gray-200',\n\t\t'var(--wpds-color-stroke-surface-neutral)',\n\t],\n\t[\n\t\t'--wp-components-color-gray-300',\n\t\t'var(--wpds-color-stroke-surface-neutral)',\n\t],\n\t[\n\t\t'--wp-components-color-gray-400',\n\t\t'var(--wpds-color-stroke-interactive-neutral)',\n\t],\n\t[\n\t\t'--wp-components-color-gray-600',\n\t\t'var(--wpds-color-stroke-interactive-neutral)',\n\t],\n\t[\n\t\t'--wp-components-color-gray-700',\n\t\t'var(--wpds-color-fg-content-neutral-weak)',\n\t],\n\t[\n\t\t'--wp-components-color-gray-800',\n\t\t'var(--wpds-color-fg-content-neutral)',\n\t],\n];\n\nfunction customRgbFormat( color: Color ) {\n\tconst rgb = color.to( 'srgb' );\n\treturn [ rgb.r, rgb.g, rgb.b ]\n\t\t.map( ( n ) => Math.round( n * 255 ) )\n\t\t.join( ', ' );\n}\n\nfunction legacyWpAdminThemeOverridesCSS( accent: string ): Entry[] {\n\tconst parsedAccent = new Color( accent ).to( 'hsl' );\n\n\tconst hsl = parsedAccent.coords;\n\tconst darker10 = new Color( 'hsl', [\n\t\thsl[ 0 ], // h\n\t\thsl[ 1 ], // s\n\t\tMath.max( 0, Math.min( 100, hsl[ 2 ] - 5 ) ), // l (reduced by 5%)\n\t] ).to( 'srgb' );\n\tconst darker20 = new Color( 'hsl', [\n\t\thsl[ 0 ], // h\n\t\thsl[ 1 ], // s\n\t\tMath.max( 0, Math.min( 100, hsl[ 2 ] - 10 ) ), // l (reduced by 10%)\n\t] ).to( 'srgb' );\n\n\treturn [\n\t\t[\n\t\t\t'--wp-admin-theme-color',\n\t\t\tparsedAccent.to( 'srgb' ).toString( { format: 'hex' } ),\n\t\t],\n\t\t[ '--wp-admin-theme-color--rgb', customRgbFormat( parsedAccent ) ],\n\t\t[\n\t\t\t'--wp-admin-theme-color-darker-10',\n\t\t\tdarker10.toString( { format: 'hex' } ),\n\t\t],\n\t\t[\n\t\t\t'--wp-admin-theme-color-darker-10--rgb',\n\t\t\tcustomRgbFormat( darker10 ),\n\t\t],\n\t\t[\n\t\t\t'--wp-admin-theme-color-darker-20',\n\t\t\tdarker20.toString( { format: 'hex' } ),\n\t\t],\n\t\t[\n\t\t\t'--wp-admin-theme-color-darker-20--rgb',\n\t\t\tcustomRgbFormat( darker20 ),\n\t\t],\n\t];\n}\n\nfunction semanticTokensCSS(\n\tfilterFn: ( entry: [ string, Record< string, string > ] ) => boolean = () =>\n\t\ttrue\n): Entry[] {\n\treturn Object.entries( semanticVariables )\n\t\t.filter( filterFn )\n\t\t.map( ( [ variableName, modesAndValues ] ) => [\n\t\t\tvariableName,\n\t\t\tmodesAndValues[ '.' ],\n\t\t] );\n}\n\nconst toKebabCase = ( str: string ) =>\n\tstr.replace(\n\t\t/[A-Z]+(?![a-z])|[A-Z]/g,\n\t\t( $, ofs ) => ( ofs ? '-' : '' ) + $.toLowerCase()\n\t);\n\nfunction colorRampCSS( ramp: RampResult, prefix: string ): Entry[] {\n\treturn [ ...Object.entries( ramp.ramp ) ].map(\n\t\t( [ tokenName, tokenValue ] ) => [\n\t\t\t`${ prefix }${ toKebabCase( tokenName ) }`,\n\t\t\ttokenValue.color,\n\t\t]\n\t);\n}\n\nfunction generateStyles( {\n\tprimary,\n\tcomputedColorRamps,\n}: {\n\tprimary: string;\n\tcomputedColorRamps: Map< string, RampResult >;\n} ): CSSProperties {\n\treturn Object.fromEntries(\n\t\t[\n\t\t\t// Primitive tokens\n\t\t\tArray.from( computedColorRamps )\n\t\t\t\t.map( ( [ rampName, computedColorRamp ] ) => [\n\t\t\t\t\tcolorRampCSS(\n\t\t\t\t\t\tcomputedColorRamp,\n\t\t\t\t\t\t`--wpds-color-private-${ rampName }-`\n\t\t\t\t\t),\n\t\t\t\t] )\n\t\t\t\t.flat( 2 ),\n\t\t\t// Semantic color tokens (other semantic tokens for now are static)\n\t\t\tsemanticTokensCSS( ( [ key ] ) => /color/.test( key ) ),\n\t\t\t// Legacy overrides\n\t\t\tlegacyWpAdminThemeOverridesCSS( primary ),\n\t\t\tlegacyWpComponentsOverridesCSS,\n\t\t].flat()\n\t);\n}\n\nexport function useThemeProviderStyles( {\n\tcolor = {},\n}: {\n\tcolor?: ThemeProviderProps[ 'color' ];\n} = {} ) {\n\tconst { resolvedSettings: inheritedSettings } = useContext( ThemeContext );\n\n\t// Compute settings:\n\t// - used provided prop value;\n\t// - otherwise, use inherited value from parent instance;\n\t// - otherwise, use fallback value (where applicable).\n\tconst primary =\n\t\tcolor.primary ??\n\t\tinheritedSettings.color?.primary ??\n\t\tDEFAULT_SEED_COLORS.primary;\n\tconst bg =\n\t\tcolor.bg ?? inheritedSettings.color?.bg ?? DEFAULT_SEED_COLORS.bg;\n\n\tconst resolvedSettings = useMemo(\n\t\t() => ( {\n\t\t\tcolor: {\n\t\t\t\tprimary,\n\t\t\t\tbg,\n\t\t\t},\n\t\t} ),\n\t\t[ primary, bg ]\n\t);\n\n\tconst themeProviderStyles = useMemo( () => {\n\t\t// Determine which seeds are needed for generating ramps.\n\t\tconst seeds = {\n\t\t\t...DEFAULT_SEED_COLORS,\n\t\t\tbg,\n\t\t\tprimary,\n\t\t};\n\n\t\t// Generate ramps.\n\t\tconst computedColorRamps = new Map< string, RampResult >();\n\t\tconst bgRamp = buildBgRamp( { seed: seeds.bg } );\n\t\tObject.entries( seeds ).forEach( ( [ rampName, seed ] ) => {\n\t\t\tif ( rampName === 'bg' ) {\n\t\t\t\tcomputedColorRamps.set( rampName, bgRamp );\n\t\t\t} else {\n\t\t\t\tcomputedColorRamps.set(\n\t\t\t\t\trampName,\n\t\t\t\t\tbuildAccentRamp( {\n\t\t\t\t\t\tseed,\n\t\t\t\t\t\tbgRamp,\n\t\t\t\t\t} )\n\t\t\t\t);\n\t\t\t}\n\t\t} );\n\n\t\treturn generateStyles( {\n\t\t\tprimary: seeds.primary,\n\t\t\tcomputedColorRamps,\n\t\t} );\n\t}, [ primary, bg ] );\n\n\treturn {\n\t\tresolvedSettings,\n\t\tthemeProviderStyles,\n\t};\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["Color", "semanticVariables"]
7
+ }
@@ -0,0 +1,95 @@
1
+ import Color from "colorjs.io";
2
+ import { buildRamp } from "./lib/index";
3
+ import { clampAccentScaleReferenceLightness } from "./lib/utils";
4
+ import { BG_RAMP_CONFIG, ACCENT_RAMP_CONFIG } from "./lib/ramp-configs";
5
+ import { getCachedContrast } from "./lib/cache-utils";
6
+ import { CONTRAST_COMBINATIONS } from "./lib/constants";
7
+ import { DEFAULT_SEED_COLORS } from "./lib/constants";
8
+ function buildBgRamp({
9
+ seed,
10
+ debug
11
+ }) {
12
+ if (typeof seed !== "string" || seed.trim() === "") {
13
+ throw new Error("Seed color must be a non-empty string");
14
+ }
15
+ return buildRamp(seed, BG_RAMP_CONFIG, { debug });
16
+ }
17
+ const STEP_TO_PIN = "surface2";
18
+ function getBgRampInfo(ramp) {
19
+ return {
20
+ mainDirection: ramp.direction,
21
+ pinLightness: {
22
+ stepName: STEP_TO_PIN,
23
+ value: clampAccentScaleReferenceLightness(
24
+ new Color(ramp.ramp[STEP_TO_PIN].color).oklch.l,
25
+ ramp.direction
26
+ )
27
+ }
28
+ };
29
+ }
30
+ function buildAccentRamp({
31
+ seed,
32
+ bgRamp,
33
+ debug
34
+ }) {
35
+ if (typeof seed !== "string" || seed.trim() === "") {
36
+ throw new Error("Seed color must be a non-empty string");
37
+ }
38
+ const bgRampInfo = bgRamp ? getBgRampInfo(bgRamp) : void 0;
39
+ return buildRamp(seed, ACCENT_RAMP_CONFIG, {
40
+ ...bgRampInfo,
41
+ debug
42
+ });
43
+ }
44
+ function checkAccessibleCombinations({
45
+ bgRamp,
46
+ accentRamps = []
47
+ }) {
48
+ const unmetTargets = [];
49
+ [bgRamp, ...accentRamps].forEach((ramp) => {
50
+ CONTRAST_COMBINATIONS.forEach(({ bgs, fgs, target }) => {
51
+ for (const bg of bgs) {
52
+ for (const fg of fgs) {
53
+ const bgColor = new Color(ramp.ramp[bg].color);
54
+ const fgColor = new Color(ramp.ramp[fg].color);
55
+ if (getCachedContrast(bgColor, fgColor) < target) {
56
+ unmetTargets.push({
57
+ bgName: bg,
58
+ bgColor: bgColor.toString(),
59
+ fgName: fg,
60
+ fgColor: fgColor.toString(),
61
+ unmetContrast: target
62
+ });
63
+ }
64
+ }
65
+ }
66
+ });
67
+ });
68
+ accentRamps.forEach((ramp) => {
69
+ CONTRAST_COMBINATIONS.forEach(({ bgs, fgs, target }) => {
70
+ for (const bg of bgs) {
71
+ for (const fg of fgs) {
72
+ const bgColor = new Color(bgRamp.ramp[bg].color);
73
+ const fgColor = new Color(ramp.ramp[fg].color);
74
+ if (getCachedContrast(bgColor, fgColor) < target) {
75
+ unmetTargets.push({
76
+ bgName: bg,
77
+ bgColor: bgColor.toString(),
78
+ fgName: fg,
79
+ fgColor: fgColor.toString(),
80
+ unmetContrast: target
81
+ });
82
+ }
83
+ }
84
+ }
85
+ });
86
+ });
87
+ return unmetTargets;
88
+ }
89
+ export {
90
+ DEFAULT_SEED_COLORS,
91
+ buildAccentRamp,
92
+ buildBgRamp,
93
+ checkAccessibleCombinations
94
+ };
95
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/color-ramps/index.ts"],
4
+ "sourcesContent": ["/**\n * External dependencies\n */\nimport Color from 'colorjs.io';\n\n/**\n * Internal dependencies\n */\nimport { buildRamp } from './lib/index';\nimport { clampAccentScaleReferenceLightness } from './lib/utils';\nimport { BG_RAMP_CONFIG, ACCENT_RAMP_CONFIG } from './lib/ramp-configs';\nimport type {\n\tRampResult as InternalRampResult,\n\tRampDirection,\n\tRamp,\n} from './lib/types';\nimport { getCachedContrast } from './lib/cache-utils';\nimport { CONTRAST_COMBINATIONS } from './lib/constants';\nexport { DEFAULT_SEED_COLORS } from './lib/constants';\n\n/**\n * Creates a background ramp.\n * @param params\n * @param params.seed\n * @param params.debug\n */\nexport function buildBgRamp( {\n\tseed,\n\tdebug,\n}: {\n\tseed: string;\n\tdebug?: boolean;\n} ): InternalRampResult {\n\tif ( typeof seed !== 'string' || seed.trim() === '' ) {\n\t\tthrow new Error( 'Seed color must be a non-empty string' );\n\t}\n\n\treturn buildRamp( seed, BG_RAMP_CONFIG, { debug } );\n}\n\nconst STEP_TO_PIN = 'surface2';\nfunction getBgRampInfo( ramp: InternalRampResult ): {\n\tmainDirection: RampDirection;\n\tpinLightness: {\n\t\tstepName: keyof Ramp;\n\t\tvalue: number;\n\t};\n} {\n\treturn {\n\t\tmainDirection: ramp.direction,\n\t\tpinLightness: {\n\t\t\tstepName: STEP_TO_PIN,\n\t\t\tvalue: clampAccentScaleReferenceLightness(\n\t\t\t\tnew Color( ramp.ramp[ STEP_TO_PIN ].color ).oklch.l,\n\t\t\t\tramp.direction\n\t\t\t),\n\t\t},\n\t};\n}\n\n/**\n * Creates an accent ramp (ie used by primary, success, info, warning and error\n * ramps).\n * @param params\n * @param params.seed\n * @param params.bgRamp\n * @param params.debug\n */\nexport function buildAccentRamp( {\n\tseed,\n\tbgRamp,\n\tdebug,\n}: {\n\tseed: string;\n\tbgRamp?: InternalRampResult;\n\tdebug?: boolean;\n} ): InternalRampResult {\n\tif ( typeof seed !== 'string' || seed.trim() === '' ) {\n\t\tthrow new Error( 'Seed color must be a non-empty string' );\n\t}\n\n\tconst bgRampInfo = bgRamp ? getBgRampInfo( bgRamp ) : undefined;\n\treturn buildRamp( seed, ACCENT_RAMP_CONFIG, {\n\t\t...bgRampInfo,\n\t\tdebug,\n\t} );\n}\n\n/**\n * Checks that all bg/fg combinations generated by the ramps meet contrast\n * targets.\n * @param params\n * @param params.bgRamp\n * @param params.accentRamps\n */\nexport function checkAccessibleCombinations( {\n\tbgRamp,\n\taccentRamps = [],\n}: {\n\tbgRamp: InternalRampResult;\n\taccentRamps?: InternalRampResult[];\n} ) {\n\tconst unmetTargets: {\n\t\tbgName: keyof Ramp;\n\t\tbgColor: string;\n\t\tfgName: keyof Ramp;\n\t\tfgColor: string;\n\t\tunmetContrast: number;\n\t}[] = [];\n\n\t// Assess combinations within each ramp\n\t[ bgRamp, ...accentRamps ].forEach( ( ramp ) => {\n\t\tCONTRAST_COMBINATIONS.forEach( ( { bgs, fgs, target } ) => {\n\t\t\tfor ( const bg of bgs ) {\n\t\t\t\tfor ( const fg of fgs ) {\n\t\t\t\t\tconst bgColor = new Color( ramp.ramp[ bg ].color );\n\t\t\t\t\tconst fgColor = new Color( ramp.ramp[ fg ].color );\n\t\t\t\t\tif ( getCachedContrast( bgColor, fgColor ) < target ) {\n\t\t\t\t\t\tunmetTargets.push( {\n\t\t\t\t\t\t\tbgName: bg,\n\t\t\t\t\t\t\tbgColor: bgColor.toString(),\n\t\t\t\t\t\t\tfgName: fg,\n\t\t\t\t\t\t\tfgColor: fgColor.toString(),\n\t\t\t\t\t\t\tunmetContrast: target,\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t} );\n\t// Assess each accent ramp's fg color against bg ramp\n\taccentRamps.forEach( ( ramp ) => {\n\t\tCONTRAST_COMBINATIONS.forEach( ( { bgs, fgs, target } ) => {\n\t\t\tfor ( const bg of bgs ) {\n\t\t\t\tfor ( const fg of fgs ) {\n\t\t\t\t\tconst bgColor = new Color( bgRamp.ramp[ bg ].color );\n\t\t\t\t\tconst fgColor = new Color( ramp.ramp[ fg ].color );\n\t\t\t\t\tif ( getCachedContrast( bgColor, fgColor ) < target ) {\n\t\t\t\t\t\tunmetTargets.push( {\n\t\t\t\t\t\t\tbgName: bg,\n\t\t\t\t\t\t\tbgColor: bgColor.toString(),\n\t\t\t\t\t\t\tfgName: fg,\n\t\t\t\t\t\t\tfgColor: fgColor.toString(),\n\t\t\t\t\t\t\tunmetContrast: target,\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t} );\n\n\treturn unmetTargets;\n}\n\nexport type RampResult = InternalRampResult;\n"],
5
+ "mappings": "AAGA,OAAO,WAAW;AAKlB,SAAS,iBAAiB;AAC1B,SAAS,0CAA0C;AACnD,SAAS,gBAAgB,0BAA0B;AAMnD,SAAS,yBAAyB;AAClC,SAAS,6BAA6B;AACtC,SAAS,2BAA2B;AAQ7B,SAAS,YAAa;AAAA,EAC5B;AAAA,EACA;AACD,GAGwB;AACvB,MAAK,OAAO,SAAS,YAAY,KAAK,KAAK,MAAM,IAAK;AACrD,UAAM,IAAI,MAAO,uCAAwC;AAAA,EAC1D;AAEA,SAAO,UAAW,MAAM,gBAAgB,EAAE,MAAM,CAAE;AACnD;AAEA,MAAM,cAAc;AACpB,SAAS,cAAe,MAMtB;AACD,SAAO;AAAA,IACN,eAAe,KAAK;AAAA,IACpB,cAAc;AAAA,MACb,UAAU;AAAA,MACV,OAAO;AAAA,QACN,IAAI,MAAO,KAAK,KAAM,WAAY,EAAE,KAAM,EAAE,MAAM;AAAA,QAClD,KAAK;AAAA,MACN;AAAA,IACD;AAAA,EACD;AACD;AAUO,SAAS,gBAAiB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AACD,GAIwB;AACvB,MAAK,OAAO,SAAS,YAAY,KAAK,KAAK,MAAM,IAAK;AACrD,UAAM,IAAI,MAAO,uCAAwC;AAAA,EAC1D;AAEA,QAAM,aAAa,SAAS,cAAe,MAAO,IAAI;AACtD,SAAO,UAAW,MAAM,oBAAoB;AAAA,IAC3C,GAAG;AAAA,IACH;AAAA,EACD,CAAE;AACH;AASO,SAAS,4BAA6B;AAAA,EAC5C;AAAA,EACA,cAAc,CAAC;AAChB,GAGI;AACH,QAAM,eAMA,CAAC;AAGP,GAAE,QAAQ,GAAG,WAAY,EAAE,QAAS,CAAE,SAAU;AAC/C,0BAAsB,QAAS,CAAE,EAAE,KAAK,KAAK,OAAO,MAAO;AAC1D,iBAAY,MAAM,KAAM;AACvB,mBAAY,MAAM,KAAM;AACvB,gBAAM,UAAU,IAAI,MAAO,KAAK,KAAM,EAAG,EAAE,KAAM;AACjD,gBAAM,UAAU,IAAI,MAAO,KAAK,KAAM,EAAG,EAAE,KAAM;AACjD,cAAK,kBAAmB,SAAS,OAAQ,IAAI,QAAS;AACrD,yBAAa,KAAM;AAAA,cAClB,QAAQ;AAAA,cACR,SAAS,QAAQ,SAAS;AAAA,cAC1B,QAAQ;AAAA,cACR,SAAS,QAAQ,SAAS;AAAA,cAC1B,eAAe;AAAA,YAChB,CAAE;AAAA,UACH;AAAA,QACD;AAAA,MACD;AAAA,IACD,CAAE;AAAA,EACH,CAAE;AAEF,cAAY,QAAS,CAAE,SAAU;AAChC,0BAAsB,QAAS,CAAE,EAAE,KAAK,KAAK,OAAO,MAAO;AAC1D,iBAAY,MAAM,KAAM;AACvB,mBAAY,MAAM,KAAM;AACvB,gBAAM,UAAU,IAAI,MAAO,OAAO,KAAM,EAAG,EAAE,KAAM;AACnD,gBAAM,UAAU,IAAI,MAAO,KAAK,KAAM,EAAG,EAAE,KAAM;AACjD,cAAK,kBAAmB,SAAS,OAAQ,IAAI,QAAS;AACrD,yBAAa,KAAM;AAAA,cAClB,QAAQ;AAAA,cACR,SAAS,QAAQ,SAAS;AAAA,cAC1B,QAAQ;AAAA,cACR,SAAS,QAAQ,SAAS;AAAA,cAC1B,eAAe;AAAA,YAChB,CAAE;AAAA,UACH;AAAA,QACD;AAAA,MACD;AAAA,IACD,CAAE;AAAA,EACH,CAAE;AAEF,SAAO;AACR;",
6
+ "names": []
7
+ }
@@ -0,0 +1,31 @@
1
+ const contrastCache = /* @__PURE__ */ new Map();
2
+ const colorStringCache = /* @__PURE__ */ new Map();
3
+ function getColorString(color) {
4
+ let str = colorStringCache.get(color);
5
+ if (str === void 0) {
6
+ str = color.to("srgb").toString({ format: "hex", inGamut: true });
7
+ colorStringCache.set(color, str);
8
+ }
9
+ return str;
10
+ }
11
+ function getCachedContrast(colorA, colorB) {
12
+ const keyA = getColorString(colorA);
13
+ const keyB = getColorString(colorB);
14
+ const cacheKey = keyA < keyB ? `${keyA}|${keyB}` : `${keyB}|${keyA}`;
15
+ let contrast = contrastCache.get(cacheKey);
16
+ if (contrast === void 0) {
17
+ contrast = colorA.contrastWCAG21(colorB);
18
+ contrastCache.set(cacheKey, contrast);
19
+ }
20
+ return contrast;
21
+ }
22
+ function clearCaches() {
23
+ contrastCache.clear();
24
+ colorStringCache.clear();
25
+ }
26
+ export {
27
+ clearCaches,
28
+ getCachedContrast,
29
+ getColorString
30
+ };
31
+ //# sourceMappingURL=cache-utils.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/color-ramps/lib/cache-utils.ts"],
4
+ "sourcesContent": ["/**\n * External dependencies\n */\nimport type Color from 'colorjs.io';\n\n/**\n * Cache for WCAG contrast calculations\n */\nconst contrastCache = new Map< string, number >();\n\n/**\n * Cache for color string representations\n */\nconst colorStringCache = new Map< Color, string >();\n\n/**\n * Get cached string representation of a color\n * @param color - Color object to stringify\n * @return Cached string representation\n */\nexport function getColorString( color: Color ): string {\n\tlet str = colorStringCache.get( color );\n\tif ( str === undefined ) {\n\t\tstr = color.to( 'srgb' ).toString( { format: 'hex', inGamut: true } );\n\t\tcolorStringCache.set( color, str );\n\t}\n\treturn str;\n}\n\n/**\n * Get cached contrast calculation between two colors\n * @param colorA - First color\n * @param colorB - Second color\n * @return WCAG 2.1 contrast ratio\n */\nexport function getCachedContrast( colorA: Color, colorB: Color ): number {\n\tconst keyA = getColorString( colorA );\n\tconst keyB = getColorString( colorB );\n\tconst cacheKey =\n\t\tkeyA < keyB ? `${ keyA }|${ keyB }` : `${ keyB }|${ keyA }`;\n\n\tlet contrast = contrastCache.get( cacheKey );\n\tif ( contrast === undefined ) {\n\t\tcontrast = colorA.contrastWCAG21( colorB );\n\t\tcontrastCache.set( cacheKey, contrast );\n\t}\n\treturn contrast;\n}\n\n/**\n * Clear all caches - useful for memory management or testing\n */\nexport function clearCaches(): void {\n\tcontrastCache.clear();\n\tcolorStringCache.clear();\n}\n"],
5
+ "mappings": "AAQA,MAAM,gBAAgB,oBAAI,IAAsB;AAKhD,MAAM,mBAAmB,oBAAI,IAAqB;AAO3C,SAAS,eAAgB,OAAuB;AACtD,MAAI,MAAM,iBAAiB,IAAK,KAAM;AACtC,MAAK,QAAQ,QAAY;AACxB,UAAM,MAAM,GAAI,MAAO,EAAE,SAAU,EAAE,QAAQ,OAAO,SAAS,KAAK,CAAE;AACpE,qBAAiB,IAAK,OAAO,GAAI;AAAA,EAClC;AACA,SAAO;AACR;AAQO,SAAS,kBAAmB,QAAe,QAAwB;AACzE,QAAM,OAAO,eAAgB,MAAO;AACpC,QAAM,OAAO,eAAgB,MAAO;AACpC,QAAM,WACL,OAAO,OAAO,GAAI,IAAK,IAAK,IAAK,KAAK,GAAI,IAAK,IAAK,IAAK;AAE1D,MAAI,WAAW,cAAc,IAAK,QAAS;AAC3C,MAAK,aAAa,QAAY;AAC7B,eAAW,OAAO,eAAgB,MAAO;AACzC,kBAAc,IAAK,UAAU,QAAS;AAAA,EACvC;AACA,SAAO;AACR;AAKO,SAAS,cAAoB;AACnC,gBAAc,MAAM;AACpB,mBAAiB,MAAM;AACxB;",
6
+ "names": []
7
+ }
@@ -0,0 +1,63 @@
1
+ import Color from "colorjs.io";
2
+ const WHITE = new Color("#fff").to("oklch");
3
+ const BLACK = new Color("#000").to("oklch");
4
+ const UNIVERSAL_CONTRAST_TOPUP = 0.05;
5
+ const WHITE_TEXT_CONTRAST_MARGIN = 3.1;
6
+ const ACCENT_SCALE_BASE_LIGHTNESS_THRESHOLDS = {
7
+ lighter: { min: 0.2, max: 0.4 },
8
+ darker: { min: 0.75, max: 0.98 }
9
+ };
10
+ const LIGHTNESS_EPSILON = 1e-3;
11
+ const MAX_BISECTION_ITERATIONS = 25;
12
+ const CONTRAST_COMBINATIONS = [
13
+ {
14
+ bgs: ["surface1", "surface2", "surface3"],
15
+ fgs: ["fgSurface3", "fgSurface4"],
16
+ target: 4.5
17
+ },
18
+ {
19
+ bgs: ["surface4", "surface5"],
20
+ fgs: ["fgSurface4"],
21
+ target: 4.5
22
+ },
23
+ {
24
+ bgs: ["bgFill1"],
25
+ fgs: ["fgFill"],
26
+ target: 4.5
27
+ },
28
+ {
29
+ bgs: ["bgFillInverted1"],
30
+ fgs: ["fgFillInverted"],
31
+ target: 4.5
32
+ },
33
+ {
34
+ bgs: ["bgFillInverted1"],
35
+ fgs: ["fgFillInverted"],
36
+ target: 4.5
37
+ },
38
+ {
39
+ bgs: ["surface1", "surface2", "surface3"],
40
+ fgs: ["stroke3"],
41
+ target: 3
42
+ }
43
+ ];
44
+ const DEFAULT_SEED_COLORS = {
45
+ bg: "#f8f8f8",
46
+ primary: "#3858e9",
47
+ info: "#0090ff",
48
+ success: "#4ab866",
49
+ warning: "#f0b849",
50
+ error: "#cc1818"
51
+ };
52
+ export {
53
+ ACCENT_SCALE_BASE_LIGHTNESS_THRESHOLDS,
54
+ BLACK,
55
+ CONTRAST_COMBINATIONS,
56
+ DEFAULT_SEED_COLORS,
57
+ LIGHTNESS_EPSILON,
58
+ MAX_BISECTION_ITERATIONS,
59
+ UNIVERSAL_CONTRAST_TOPUP,
60
+ WHITE,
61
+ WHITE_TEXT_CONTRAST_MARGIN
62
+ };
63
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/color-ramps/lib/constants.ts"],
4
+ "sourcesContent": ["/**\n * External dependencies\n */\nimport Color from 'colorjs.io';\n\n/**\n * Internal dependencies\n */\nimport type { Ramp } from './types';\n\nexport const WHITE = new Color( '#fff' ).to( 'oklch' );\nexport const BLACK = new Color( '#000' ).to( 'oklch' );\n\n// Margin added to target contrasts to counter for algorithm approximations\n// and rounding errors.\nexport const UNIVERSAL_CONTRAST_TOPUP = 0.05;\n\n// When enabling \"lighter direction\" bias, this is the amount by which\n// black text contrast needs to be greater than white text contrast.\n// The higher the value, the stronger the preference for white text.\n// The current value has been determined empirically as the highest value\n// that won't cause the algo not to be able to correctly solve all contrasts.\nexport const WHITE_TEXT_CONTRAST_MARGIN = 3.1;\n\n// These values are used as thresholds when trying to match the background\n// ramp's lightness while calculating an accent ramp. They prevent the accent\n// scale from being pinned to lightness values in the middle of the range,\n// which would cause the algorithm to struggle to satisfy the accent scale\n// constraints and therefore produce unexpected results.\nexport const ACCENT_SCALE_BASE_LIGHTNESS_THRESHOLDS = {\n\tlighter: { min: 0.2, max: 0.4 },\n\tdarker: { min: 0.75, max: 0.98 },\n} as const;\n\n// Minimum lightness difference noticed by the algorithm.\nexport const LIGHTNESS_EPSILON = 1e-3;\n\nexport const MAX_BISECTION_ITERATIONS = 25;\n\nexport const CONTRAST_COMBINATIONS: {\n\tbgs: ( keyof Ramp )[];\n\tfgs: ( keyof Ramp )[];\n\ttarget: number;\n}[] = [\n\t{\n\t\tbgs: [ 'surface1', 'surface2', 'surface3' ],\n\t\tfgs: [ 'fgSurface3', 'fgSurface4' ],\n\t\ttarget: 4.5,\n\t},\n\t{\n\t\tbgs: [ 'surface4', 'surface5' ],\n\t\tfgs: [ 'fgSurface4' ],\n\t\ttarget: 4.5,\n\t},\n\t{\n\t\tbgs: [ 'bgFill1' ],\n\t\tfgs: [ 'fgFill' ],\n\t\ttarget: 4.5,\n\t},\n\t{\n\t\tbgs: [ 'bgFillInverted1' ],\n\t\tfgs: [ 'fgFillInverted' ],\n\t\ttarget: 4.5,\n\t},\n\t{\n\t\tbgs: [ 'bgFillInverted1' ],\n\t\tfgs: [ 'fgFillInverted' ],\n\t\ttarget: 4.5,\n\t},\n\t{\n\t\tbgs: [ 'surface1', 'surface2', 'surface3' ],\n\t\tfgs: [ 'stroke3' ],\n\t\ttarget: 3,\n\t},\n];\n\n// Used when generating the DTCG tokens and the static color ramps.\nexport const DEFAULT_SEED_COLORS = {\n\tbg: '#f8f8f8',\n\tprimary: '#3858e9',\n\tinfo: '#0090ff',\n\tsuccess: '#4ab866',\n\twarning: '#f0b849',\n\terror: '#cc1818',\n};\n"],
5
+ "mappings": "AAGA,OAAO,WAAW;AAOX,MAAM,QAAQ,IAAI,MAAO,MAAO,EAAE,GAAI,OAAQ;AAC9C,MAAM,QAAQ,IAAI,MAAO,MAAO,EAAE,GAAI,OAAQ;AAI9C,MAAM,2BAA2B;AAOjC,MAAM,6BAA6B;AAOnC,MAAM,yCAAyC;AAAA,EACrD,SAAS,EAAE,KAAK,KAAK,KAAK,IAAI;AAAA,EAC9B,QAAQ,EAAE,KAAK,MAAM,KAAK,KAAK;AAChC;AAGO,MAAM,oBAAoB;AAE1B,MAAM,2BAA2B;AAEjC,MAAM,wBAIP;AAAA,EACL;AAAA,IACC,KAAK,CAAE,YAAY,YAAY,UAAW;AAAA,IAC1C,KAAK,CAAE,cAAc,YAAa;AAAA,IAClC,QAAQ;AAAA,EACT;AAAA,EACA;AAAA,IACC,KAAK,CAAE,YAAY,UAAW;AAAA,IAC9B,KAAK,CAAE,YAAa;AAAA,IACpB,QAAQ;AAAA,EACT;AAAA,EACA;AAAA,IACC,KAAK,CAAE,SAAU;AAAA,IACjB,KAAK,CAAE,QAAS;AAAA,IAChB,QAAQ;AAAA,EACT;AAAA,EACA;AAAA,IACC,KAAK,CAAE,iBAAkB;AAAA,IACzB,KAAK,CAAE,gBAAiB;AAAA,IACxB,QAAQ;AAAA,EACT;AAAA,EACA;AAAA,IACC,KAAK,CAAE,iBAAkB;AAAA,IACzB,KAAK,CAAE,gBAAiB;AAAA,IACxB,QAAQ;AAAA,EACT;AAAA,EACA;AAAA,IACC,KAAK,CAAE,YAAY,YAAY,UAAW;AAAA,IAC1C,KAAK,CAAE,SAAU;AAAA,IACjB,QAAQ;AAAA,EACT;AACD;AAGO,MAAM,sBAAsB;AAAA,EAClC,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AACR;",
6
+ "names": []
7
+ }
@@ -0,0 +1,112 @@
1
+ import Color from "colorjs.io";
2
+ import { clampToGamut } from "./utils";
3
+ import {
4
+ WHITE,
5
+ BLACK,
6
+ LIGHTNESS_EPSILON,
7
+ MAX_BISECTION_ITERATIONS
8
+ } from "./constants";
9
+ import { getCachedContrast } from "./cache-utils";
10
+ import { taperChroma } from "./taper-chroma";
11
+ function findColorMeetingRequirements(reference, seed, target, direction, {
12
+ lightnessConstraint,
13
+ taperChromaOptions,
14
+ strict = true,
15
+ debug = false
16
+ } = {}) {
17
+ if (target <= 1) {
18
+ return { color: seed.clone(), reached: true, achieved: 1 };
19
+ }
20
+ if (lightnessConstraint) {
21
+ let newL = lightnessConstraint.value;
22
+ let newC = seed.oklch.c;
23
+ if (taperChromaOptions) {
24
+ ({ l: newL, c: newC } = taperChroma(
25
+ seed,
26
+ newL,
27
+ taperChromaOptions
28
+ ));
29
+ }
30
+ const colorWithExactL = clampToGamut(
31
+ new Color("oklch", [newL, newC, seed.oklch.h])
32
+ );
33
+ const exactLContrast = getCachedContrast(reference, colorWithExactL);
34
+ if (debug) {
35
+ console.log(
36
+ `Succeeded with ${lightnessConstraint.type} lightness`,
37
+ lightnessConstraint.value,
38
+ colorWithExactL.oklch.l
39
+ );
40
+ }
41
+ if (lightnessConstraint.type === "force" || exactLContrast >= target) {
42
+ return {
43
+ color: colorWithExactL,
44
+ reached: exactLContrast >= target,
45
+ achieved: exactLContrast
46
+ };
47
+ }
48
+ }
49
+ const mostContrastingL = direction === "lighter" ? 1 : 0;
50
+ const mostContrastingColor = direction === "lighter" ? WHITE : BLACK;
51
+ const highestPossibleContrast = getCachedContrast(
52
+ reference,
53
+ mostContrastingColor
54
+ );
55
+ if (highestPossibleContrast < target) {
56
+ if (strict) {
57
+ throw new Error(
58
+ `Contrast target ${target.toFixed(
59
+ 2
60
+ )}:1 unreachable in ${direction} direction against ${mostContrastingColor.toString()}(boundary achieves ${highestPossibleContrast.toFixed(
61
+ 3
62
+ )}:1).`
63
+ );
64
+ }
65
+ if (debug) {
66
+ console.log(
67
+ "Did not succeeded because it reached the limit",
68
+ mostContrastingL
69
+ );
70
+ }
71
+ return {
72
+ color: mostContrastingColor,
73
+ reached: false,
74
+ achieved: highestPossibleContrast
75
+ };
76
+ }
77
+ let worseL = reference.oklch.l;
78
+ let betterL = mostContrastingL;
79
+ let bestContrastFound = highestPossibleContrast;
80
+ let resultingColor = mostContrastingColor;
81
+ for (let i = 0; i < MAX_BISECTION_ITERATIONS && Math.abs(betterL - worseL) > LIGHTNESS_EPSILON; i++) {
82
+ let newL = (worseL + betterL) / 2;
83
+ let newC = seed.oklch.c;
84
+ if (taperChromaOptions) {
85
+ ({ l: newL, c: newC } = taperChroma(
86
+ seed,
87
+ newL,
88
+ taperChromaOptions
89
+ ));
90
+ }
91
+ const newColor = clampToGamut(
92
+ new Color("oklch", [newL, newC, seed.oklch.h])
93
+ );
94
+ const newContrast = getCachedContrast(reference, newColor);
95
+ if (newContrast >= target) {
96
+ betterL = newL;
97
+ bestContrastFound = newContrast;
98
+ resultingColor = newColor;
99
+ } else {
100
+ worseL = newL;
101
+ }
102
+ }
103
+ return {
104
+ color: resultingColor,
105
+ reached: true,
106
+ achieved: bestContrastFound
107
+ };
108
+ }
109
+ export {
110
+ findColorMeetingRequirements
111
+ };
112
+ //# sourceMappingURL=find-color-with-constraints.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/color-ramps/lib/find-color-with-constraints.ts"],
4
+ "sourcesContent": ["/**\n * External dependencies\n */\nimport Color from 'colorjs.io';\n\n/**\n * Internal dependencies\n */\nimport { clampToGamut } from './utils';\nimport {\n\tWHITE,\n\tBLACK,\n\tLIGHTNESS_EPSILON,\n\tMAX_BISECTION_ITERATIONS,\n} from './constants';\nimport { getCachedContrast } from './cache-utils';\nimport { type TaperChromaOptions, taperChroma } from './taper-chroma';\n\n/**\n * Solve for L such that:\n * - the L applied to the seed meets the contrast target against the reference\n * - the search is performed in one direction (ie lighter / darker)\n * - more constraints can be applied around lightness\n * - chroma could be tapered\n * @param reference\n * @param seed\n * @param target\n * @param direction\n * @param options\n * @param options.strict\n * @param options.debug\n * @param options.lightnessConstraint\n * @param options.lightnessConstraint.type\n * @param options.lightnessConstraint.value\n * @param options.taperChromaOptions\n */\nexport function findColorMeetingRequirements(\n\treference: Color,\n\tseed: Color,\n\ttarget: number,\n\tdirection: 'lighter' | 'darker',\n\t{\n\t\tlightnessConstraint,\n\t\ttaperChromaOptions,\n\t\tstrict = true,\n\t\tdebug = false,\n\t}: {\n\t\tlightnessConstraint?: {\n\t\t\ttype: 'force' | 'onlyIfSucceeds';\n\t\t\tvalue: number;\n\t\t};\n\t\ttaperChromaOptions?: TaperChromaOptions;\n\t\tstrict?: boolean;\n\t\tdebug?: boolean;\n\t} = {}\n): { color: Color; reached: boolean; achieved: number } {\n\t// A target of 1 means same color.\n\t// A target lower than 1 doesn't make sense.\n\tif ( target <= 1 ) {\n\t\treturn { color: seed.clone(), reached: true, achieved: 1 };\n\t}\n\n\tif ( lightnessConstraint ) {\n\t\t// Apply a specific L value.\n\t\t// Useful when pinning a step to a specific lightness, of to specify\n\t\t// min/max L values.\n\t\tlet newL = lightnessConstraint.value;\n\t\tlet newC = seed.oklch.c;\n\n\t\tif ( taperChromaOptions ) {\n\t\t\t( { l: newL, c: newC } = taperChroma(\n\t\t\t\tseed,\n\t\t\t\tnewL,\n\t\t\t\ttaperChromaOptions\n\t\t\t) );\n\t\t}\n\n\t\tconst colorWithExactL = clampToGamut(\n\t\t\tnew Color( 'oklch', [ newL, newC, seed.oklch.h ] )\n\t\t);\n\t\tconst exactLContrast = getCachedContrast( reference, colorWithExactL );\n\n\t\tif ( debug ) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.log(\n\t\t\t\t`Succeeded with ${ lightnessConstraint.type } lightness`,\n\t\t\t\tlightnessConstraint.value,\n\t\t\t\tcolorWithExactL.oklch.l\n\t\t\t);\n\t\t}\n\n\t\t// If the L constraint is of \"force\" type, apply it even when it doesn't\n\t\t// meet the contrast target.\n\t\tif (\n\t\t\tlightnessConstraint.type === 'force' ||\n\t\t\texactLContrast >= target\n\t\t) {\n\t\t\treturn {\n\t\t\t\tcolor: colorWithExactL,\n\t\t\t\treached: exactLContrast >= target,\n\t\t\t\tachieved: exactLContrast,\n\t\t\t};\n\t\t}\n\t}\n\n\t// Set the boundary based on the direction.\n\tconst mostContrastingL = direction === 'lighter' ? 1 : 0;\n\tconst mostContrastingColor = direction === 'lighter' ? WHITE : BLACK;\n\tconst highestPossibleContrast = getCachedContrast(\n\t\treference,\n\t\tmostContrastingColor\n\t);\n\n\t// If even the most contrasting color can't reach the target,\n\t// the target is unreachable.\n\tif ( highestPossibleContrast < target ) {\n\t\tif ( strict ) {\n\t\t\tthrow new Error(\n\t\t\t\t`Contrast target ${ target.toFixed(\n\t\t\t\t\t2\n\t\t\t\t) }:1 unreachable in ${ direction } direction against ${ mostContrastingColor.toString() }` +\n\t\t\t\t\t`(boundary achieves ${ highestPossibleContrast.toFixed(\n\t\t\t\t\t\t3\n\t\t\t\t\t) }:1).`\n\t\t\t);\n\t\t}\n\n\t\tif ( debug ) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.log(\n\t\t\t\t'Did not succeeded because it reached the limit',\n\t\t\t\tmostContrastingL\n\t\t\t);\n\t\t}\n\t\treturn {\n\t\t\tcolor: mostContrastingColor,\n\t\t\treached: false,\n\t\t\tachieved: highestPossibleContrast,\n\t\t};\n\t}\n\n\t// Bracket: low fails, high meets.\n\t// Originally this was seed.oklch.l \u2014 although it's an assumption that works\n\t// only when we know for sure the direction of the search.\n\t// TODO: can we bring this back to seed.oklch.l ?\n\tlet worseL = reference.oklch.l;\n\tlet betterL = mostContrastingL;\n\n\tlet bestContrastFound = highestPossibleContrast;\n\tlet resultingColor = mostContrastingColor;\n\n\tfor (\n\t\tlet i = 0;\n\t\ti < MAX_BISECTION_ITERATIONS &&\n\t\tMath.abs( betterL - worseL ) > LIGHTNESS_EPSILON;\n\t\ti++\n\t) {\n\t\tlet newL = ( worseL + betterL ) / 2;\n\t\tlet newC = seed.oklch.c;\n\n\t\tif ( taperChromaOptions ) {\n\t\t\t( { l: newL, c: newC } = taperChroma(\n\t\t\t\tseed,\n\t\t\t\tnewL,\n\t\t\t\ttaperChromaOptions\n\t\t\t) );\n\t\t}\n\n\t\tconst newColor = clampToGamut(\n\t\t\tnew Color( 'oklch', [ newL, newC, seed.oklch.h ] )\n\t\t);\n\t\tconst newContrast = getCachedContrast( reference, newColor );\n\n\t\tif ( newContrast >= target ) {\n\t\t\tbetterL = newL;\n\t\t\t// Only update the resulting color when the target is met, this ensuring\n\t\t\t// at the end of the search the target is always met.\n\t\t\tbestContrastFound = newContrast;\n\t\t\tresultingColor = newColor;\n\t\t} else {\n\t\t\tworseL = newL;\n\t\t}\n\t}\n\n\treturn {\n\t\tcolor: resultingColor,\n\t\treached: true,\n\t\tachieved: bestContrastFound,\n\t};\n}\n"],
5
+ "mappings": "AAGA,OAAO,WAAW;AAKlB,SAAS,oBAAoB;AAC7B;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,yBAAyB;AAClC,SAAkC,mBAAmB;AAoB9C,SAAS,6BACf,WACA,MACA,QACA,WACA;AAAA,EACC;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,QAAQ;AACT,IAQI,CAAC,GACkD;AAGvD,MAAK,UAAU,GAAI;AAClB,WAAO,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,MAAM,UAAU,EAAE;AAAA,EAC1D;AAEA,MAAK,qBAAsB;AAI1B,QAAI,OAAO,oBAAoB;AAC/B,QAAI,OAAO,KAAK,MAAM;AAEtB,QAAK,oBAAqB;AACzB,OAAE,EAAE,GAAG,MAAM,GAAG,KAAK,IAAI;AAAA,QACxB;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAAA,IACD;AAEA,UAAM,kBAAkB;AAAA,MACvB,IAAI,MAAO,SAAS,CAAE,MAAM,MAAM,KAAK,MAAM,CAAE,CAAE;AAAA,IAClD;AACA,UAAM,iBAAiB,kBAAmB,WAAW,eAAgB;AAErE,QAAK,OAAQ;AAEZ,cAAQ;AAAA,QACP,kBAAmB,oBAAoB,IAAK;AAAA,QAC5C,oBAAoB;AAAA,QACpB,gBAAgB,MAAM;AAAA,MACvB;AAAA,IACD;AAIA,QACC,oBAAoB,SAAS,WAC7B,kBAAkB,QACjB;AACD,aAAO;AAAA,QACN,OAAO;AAAA,QACP,SAAS,kBAAkB;AAAA,QAC3B,UAAU;AAAA,MACX;AAAA,IACD;AAAA,EACD;AAGA,QAAM,mBAAmB,cAAc,YAAY,IAAI;AACvD,QAAM,uBAAuB,cAAc,YAAY,QAAQ;AAC/D,QAAM,0BAA0B;AAAA,IAC/B;AAAA,IACA;AAAA,EACD;AAIA,MAAK,0BAA0B,QAAS;AACvC,QAAK,QAAS;AACb,YAAM,IAAI;AAAA,QACT,mBAAoB,OAAO;AAAA,UAC1B;AAAA,QACD,CAAE,qBAAsB,SAAU,sBAAuB,qBAAqB,SAAS,CAAE,sBACjE,wBAAwB;AAAA,UAC9C;AAAA,QACD,CAAE;AAAA,MACJ;AAAA,IACD;AAEA,QAAK,OAAQ;AAEZ,cAAQ;AAAA,QACP;AAAA,QACA;AAAA,MACD;AAAA,IACD;AACA,WAAO;AAAA,MACN,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,IACX;AAAA,EACD;AAMA,MAAI,SAAS,UAAU,MAAM;AAC7B,MAAI,UAAU;AAEd,MAAI,oBAAoB;AACxB,MAAI,iBAAiB;AAErB,WACK,IAAI,GACR,IAAI,4BACJ,KAAK,IAAK,UAAU,MAAO,IAAI,mBAC/B,KACC;AACD,QAAI,QAAS,SAAS,WAAY;AAClC,QAAI,OAAO,KAAK,MAAM;AAEtB,QAAK,oBAAqB;AACzB,OAAE,EAAE,GAAG,MAAM,GAAG,KAAK,IAAI;AAAA,QACxB;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAAA,IACD;AAEA,UAAM,WAAW;AAAA,MAChB,IAAI,MAAO,SAAS,CAAE,MAAM,MAAM,KAAK,MAAM,CAAE,CAAE;AAAA,IAClD;AACA,UAAM,cAAc,kBAAmB,WAAW,QAAS;AAE3D,QAAK,eAAe,QAAS;AAC5B,gBAAU;AAGV,0BAAoB;AACpB,uBAAiB;AAAA,IAClB,OAAO;AACN,eAAS;AAAA,IACV;AAAA,EACD;AAEA,SAAO;AAAA,IACN,OAAO;AAAA,IACP,SAAS;AAAA,IACT,UAAU;AAAA,EACX;AACD;",
6
+ "names": []
7
+ }