@oxyhq/bloom 0.35.8 → 0.37.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 (310) hide show
  1. package/lib/commonjs/frosted-icon-button/FrostedIconButton.js +148 -0
  2. package/lib/commonjs/frosted-icon-button/FrostedIconButton.js.map +1 -0
  3. package/lib/commonjs/frosted-icon-button/FrostedIconButton.web.js +166 -0
  4. package/lib/commonjs/frosted-icon-button/FrostedIconButton.web.js.map +1 -0
  5. package/lib/commonjs/frosted-icon-button/index.js +13 -0
  6. package/lib/commonjs/frosted-icon-button/index.js.map +1 -0
  7. package/lib/commonjs/frosted-icon-button/index.web.js +13 -0
  8. package/lib/commonjs/frosted-icon-button/index.web.js.map +1 -0
  9. package/lib/commonjs/frosted-icon-button/shared.js +112 -0
  10. package/lib/commonjs/frosted-icon-button/shared.js.map +1 -0
  11. package/lib/commonjs/frosted-icon-button/types.js +6 -0
  12. package/lib/commonjs/frosted-icon-button/types.js.map +1 -0
  13. package/lib/commonjs/index.js +10 -1
  14. package/lib/commonjs/index.js.map +1 -1
  15. package/lib/commonjs/index.web.js +46 -37
  16. package/lib/commonjs/index.web.js.map +1 -1
  17. package/lib/commonjs/theme/build-theme.js +31 -43
  18. package/lib/commonjs/theme/build-theme.js.map +1 -1
  19. package/lib/commonjs/theme/color-engine/cam16.js +161 -0
  20. package/lib/commonjs/theme/color-engine/cam16.js.map +1 -0
  21. package/lib/commonjs/theme/color-engine/color-role.js +183 -0
  22. package/lib/commonjs/theme/color-engine/color-role.js.map +1 -0
  23. package/lib/commonjs/theme/color-engine/color-roles.js +416 -0
  24. package/lib/commonjs/theme/color-engine/color-roles.js.map +1 -0
  25. package/lib/commonjs/theme/color-engine/color-utils.js +157 -0
  26. package/lib/commonjs/theme/color-engine/color-utils.js.map +1 -0
  27. package/lib/commonjs/theme/color-engine/contrast-curve.js +32 -0
  28. package/lib/commonjs/theme/color-engine/contrast-curve.js.map +1 -0
  29. package/lib/commonjs/theme/color-engine/contrast.js +70 -0
  30. package/lib/commonjs/theme/color-engine/contrast.js.map +1 -0
  31. package/lib/commonjs/theme/color-engine/dislike-analyzer.js +26 -0
  32. package/lib/commonjs/theme/color-engine/dislike-analyzer.js.map +1 -0
  33. package/lib/commonjs/theme/color-engine/dynamic-scheme.js +70 -0
  34. package/lib/commonjs/theme/color-engine/dynamic-scheme.js.map +1 -0
  35. package/lib/commonjs/theme/color-engine/hct-solver.js +236 -0
  36. package/lib/commonjs/theme/color-engine/hct-solver.js.map +1 -0
  37. package/lib/commonjs/theme/color-engine/hct.js +67 -0
  38. package/lib/commonjs/theme/color-engine/hct.js.map +1 -0
  39. package/lib/commonjs/theme/color-engine/index.js +173 -0
  40. package/lib/commonjs/theme/color-engine/index.js.map +1 -0
  41. package/lib/commonjs/theme/color-engine/lab-point-provider.js +32 -0
  42. package/lib/commonjs/theme/color-engine/lab-point-provider.js.map +1 -0
  43. package/lib/commonjs/theme/color-engine/math-utils.js +77 -0
  44. package/lib/commonjs/theme/color-engine/math-utils.js.map +1 -0
  45. package/lib/commonjs/theme/color-engine/quantizer-map.js +24 -0
  46. package/lib/commonjs/theme/color-engine/quantizer-map.js.map +1 -0
  47. package/lib/commonjs/theme/color-engine/quantizer-wu.js +266 -0
  48. package/lib/commonjs/theme/color-engine/quantizer-wu.js.map +1 -0
  49. package/lib/commonjs/theme/color-engine/scheme-variants.js +102 -0
  50. package/lib/commonjs/theme/color-engine/scheme-variants.js.map +1 -0
  51. package/lib/commonjs/theme/color-engine/score.js +80 -0
  52. package/lib/commonjs/theme/color-engine/score.js.map +1 -0
  53. package/lib/commonjs/theme/color-engine/seed-from-image.js +73 -0
  54. package/lib/commonjs/theme/color-engine/seed-from-image.js.map +1 -0
  55. package/lib/commonjs/theme/color-engine/tonal-palette.js +95 -0
  56. package/lib/commonjs/theme/color-engine/tonal-palette.js.map +1 -0
  57. package/lib/commonjs/theme/color-engine/tone-delta-pair.js +26 -0
  58. package/lib/commonjs/theme/color-engine/tone-delta-pair.js.map +1 -0
  59. package/lib/commonjs/theme/color-engine/variant.js +26 -0
  60. package/lib/commonjs/theme/color-engine/variant.js.map +1 -0
  61. package/lib/commonjs/theme/color-engine/viewing-conditions.js +61 -0
  62. package/lib/commonjs/theme/color-engine/viewing-conditions.js.map +1 -0
  63. package/lib/commonjs/theme/color-presets.js +44 -572
  64. package/lib/commonjs/theme/color-presets.js.map +1 -1
  65. package/lib/commonjs/theme/preset-vars.js +64 -47
  66. package/lib/commonjs/theme/preset-vars.js.map +1 -1
  67. package/lib/module/frosted-icon-button/FrostedIconButton.js +143 -0
  68. package/lib/module/frosted-icon-button/FrostedIconButton.js.map +1 -0
  69. package/lib/module/frosted-icon-button/FrostedIconButton.web.js +161 -0
  70. package/lib/module/frosted-icon-button/FrostedIconButton.web.js.map +1 -0
  71. package/lib/module/frosted-icon-button/index.js +4 -0
  72. package/lib/module/frosted-icon-button/index.js.map +1 -0
  73. package/lib/module/frosted-icon-button/index.web.js +11 -0
  74. package/lib/module/frosted-icon-button/index.web.js.map +1 -0
  75. package/lib/module/frosted-icon-button/shared.js +107 -0
  76. package/lib/module/frosted-icon-button/shared.js.map +1 -0
  77. package/lib/module/frosted-icon-button/types.js +4 -0
  78. package/lib/module/frosted-icon-button/types.js.map +1 -0
  79. package/lib/module/index.js +1 -0
  80. package/lib/module/index.js.map +1 -1
  81. package/lib/module/index.web.js +1 -0
  82. package/lib/module/index.web.js.map +1 -1
  83. package/lib/module/theme/build-theme.js +32 -44
  84. package/lib/module/theme/build-theme.js.map +1 -1
  85. package/lib/module/theme/color-engine/cam16.js +155 -0
  86. package/lib/module/theme/color-engine/cam16.js.map +1 -0
  87. package/lib/module/theme/color-engine/color-role.js +177 -0
  88. package/lib/module/theme/color-engine/color-role.js.map +1 -0
  89. package/lib/module/theme/color-engine/color-roles.js +411 -0
  90. package/lib/module/theme/color-engine/color-roles.js.map +1 -0
  91. package/lib/module/theme/color-engine/color-utils.js +135 -0
  92. package/lib/module/theme/color-engine/color-utils.js.map +1 -0
  93. package/lib/module/theme/color-engine/contrast-curve.js +26 -0
  94. package/lib/module/theme/color-engine/contrast-curve.js.map +1 -0
  95. package/lib/module/theme/color-engine/contrast.js +61 -0
  96. package/lib/module/theme/color-engine/contrast.js.map +1 -0
  97. package/lib/module/theme/color-engine/dislike-analyzer.js +20 -0
  98. package/lib/module/theme/color-engine/dislike-analyzer.js.map +1 -0
  99. package/lib/module/theme/color-engine/dynamic-scheme.js +65 -0
  100. package/lib/module/theme/color-engine/dynamic-scheme.js.map +1 -0
  101. package/lib/module/theme/color-engine/hct-solver.js +231 -0
  102. package/lib/module/theme/color-engine/hct-solver.js.map +1 -0
  103. package/lib/module/theme/color-engine/hct.js +61 -0
  104. package/lib/module/theme/color-engine/hct.js.map +1 -0
  105. package/lib/module/theme/color-engine/index.js +57 -0
  106. package/lib/module/theme/color-engine/index.js.map +1 -0
  107. package/lib/module/theme/color-engine/lab-point-provider.js +25 -0
  108. package/lib/module/theme/color-engine/lab-point-provider.js.map +1 -0
  109. package/lib/module/theme/color-engine/math-utils.js +65 -0
  110. package/lib/module/theme/color-engine/math-utils.js.map +1 -0
  111. package/lib/module/theme/color-engine/quantizer-map.js +20 -0
  112. package/lib/module/theme/color-engine/quantizer-map.js.map +1 -0
  113. package/lib/module/theme/color-engine/quantizer-wu.js +261 -0
  114. package/lib/module/theme/color-engine/quantizer-wu.js.map +1 -0
  115. package/lib/module/theme/color-engine/scheme-variants.js +93 -0
  116. package/lib/module/theme/color-engine/scheme-variants.js.map +1 -0
  117. package/lib/module/theme/color-engine/score.js +75 -0
  118. package/lib/module/theme/color-engine/score.js.map +1 -0
  119. package/lib/module/theme/color-engine/seed-from-image.js +67 -0
  120. package/lib/module/theme/color-engine/seed-from-image.js.map +1 -0
  121. package/lib/module/theme/color-engine/tonal-palette.js +89 -0
  122. package/lib/module/theme/color-engine/tonal-palette.js.map +1 -0
  123. package/lib/module/theme/color-engine/tone-delta-pair.js +21 -0
  124. package/lib/module/theme/color-engine/tone-delta-pair.js.map +1 -0
  125. package/lib/module/theme/color-engine/variant.js +22 -0
  126. package/lib/module/theme/color-engine/variant.js.map +1 -0
  127. package/lib/module/theme/color-engine/viewing-conditions.js +55 -0
  128. package/lib/module/theme/color-engine/viewing-conditions.js.map +1 -0
  129. package/lib/module/theme/color-presets.js +44 -572
  130. package/lib/module/theme/color-presets.js.map +1 -1
  131. package/lib/module/theme/preset-vars.js +64 -46
  132. package/lib/module/theme/preset-vars.js.map +1 -1
  133. package/lib/typescript/commonjs/frosted-icon-button/FrostedIconButton.d.ts +5 -0
  134. package/lib/typescript/commonjs/frosted-icon-button/FrostedIconButton.d.ts.map +1 -0
  135. package/lib/typescript/commonjs/frosted-icon-button/FrostedIconButton.web.d.ts +5 -0
  136. package/lib/typescript/commonjs/frosted-icon-button/FrostedIconButton.web.d.ts.map +1 -0
  137. package/lib/typescript/commonjs/frosted-icon-button/index.d.ts +3 -0
  138. package/lib/typescript/commonjs/frosted-icon-button/index.d.ts.map +1 -0
  139. package/lib/typescript/commonjs/frosted-icon-button/index.web.d.ts +3 -0
  140. package/lib/typescript/commonjs/frosted-icon-button/index.web.d.ts.map +1 -0
  141. package/lib/typescript/commonjs/frosted-icon-button/shared.d.ts +60 -0
  142. package/lib/typescript/commonjs/frosted-icon-button/shared.d.ts.map +1 -0
  143. package/lib/typescript/commonjs/frosted-icon-button/types.d.ts +69 -0
  144. package/lib/typescript/commonjs/frosted-icon-button/types.d.ts.map +1 -0
  145. package/lib/typescript/commonjs/index.d.ts +2 -0
  146. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  147. package/lib/typescript/commonjs/index.web.d.ts +2 -0
  148. package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
  149. package/lib/typescript/commonjs/theme/build-theme.d.ts.map +1 -1
  150. package/lib/typescript/commonjs/theme/color-engine/cam16.d.ts +26 -0
  151. package/lib/typescript/commonjs/theme/color-engine/cam16.d.ts.map +1 -0
  152. package/lib/typescript/commonjs/theme/color-engine/color-role.d.ts +36 -0
  153. package/lib/typescript/commonjs/theme/color-engine/color-role.d.ts.map +1 -0
  154. package/lib/typescript/commonjs/theme/color-engine/color-roles.d.ts +58 -0
  155. package/lib/typescript/commonjs/theme/color-engine/color-roles.d.ts.map +1 -0
  156. package/lib/typescript/commonjs/theme/color-engine/color-utils.d.ts +32 -0
  157. package/lib/typescript/commonjs/theme/color-engine/color-utils.d.ts.map +1 -0
  158. package/lib/typescript/commonjs/theme/color-engine/contrast-curve.d.ts +9 -0
  159. package/lib/typescript/commonjs/theme/color-engine/contrast-curve.d.ts.map +1 -0
  160. package/lib/typescript/commonjs/theme/color-engine/contrast.d.ts +12 -0
  161. package/lib/typescript/commonjs/theme/color-engine/contrast.d.ts.map +1 -0
  162. package/lib/typescript/commonjs/theme/color-engine/dislike-analyzer.d.ts +11 -0
  163. package/lib/typescript/commonjs/theme/color-engine/dislike-analyzer.d.ts.map +1 -0
  164. package/lib/typescript/commonjs/theme/color-engine/dynamic-scheme.d.ts +47 -0
  165. package/lib/typescript/commonjs/theme/color-engine/dynamic-scheme.d.ts.map +1 -0
  166. package/lib/typescript/commonjs/theme/color-engine/hct-solver.d.ts +6 -0
  167. package/lib/typescript/commonjs/theme/color-engine/hct-solver.d.ts.map +1 -0
  168. package/lib/typescript/commonjs/theme/color-engine/hct.d.ts +20 -0
  169. package/lib/typescript/commonjs/theme/color-engine/hct.d.ts.map +1 -0
  170. package/lib/typescript/commonjs/theme/color-engine/index.d.ts +44 -0
  171. package/lib/typescript/commonjs/theme/color-engine/index.d.ts.map +1 -0
  172. package/lib/typescript/commonjs/theme/color-engine/lab-point-provider.d.ts +6 -0
  173. package/lib/typescript/commonjs/theme/color-engine/lab-point-provider.d.ts.map +1 -0
  174. package/lib/typescript/commonjs/theme/color-engine/math-utils.d.ts +46 -0
  175. package/lib/typescript/commonjs/theme/color-engine/math-utils.d.ts.map +1 -0
  176. package/lib/typescript/commonjs/theme/color-engine/quantizer-map.d.ts +3 -0
  177. package/lib/typescript/commonjs/theme/color-engine/quantizer-map.d.ts.map +1 -0
  178. package/lib/typescript/commonjs/theme/color-engine/quantizer-wu.d.ts +3 -0
  179. package/lib/typescript/commonjs/theme/color-engine/quantizer-wu.d.ts.map +1 -0
  180. package/lib/typescript/commonjs/theme/color-engine/scheme-variants.d.ts +23 -0
  181. package/lib/typescript/commonjs/theme/color-engine/scheme-variants.d.ts.map +1 -0
  182. package/lib/typescript/commonjs/theme/color-engine/score.d.ts +8 -0
  183. package/lib/typescript/commonjs/theme/color-engine/score.d.ts.map +1 -0
  184. package/lib/typescript/commonjs/theme/color-engine/seed-from-image.d.ts +13 -0
  185. package/lib/typescript/commonjs/theme/color-engine/seed-from-image.d.ts.map +1 -0
  186. package/lib/typescript/commonjs/theme/color-engine/tonal-palette.d.ts +24 -0
  187. package/lib/typescript/commonjs/theme/color-engine/tonal-palette.d.ts.map +1 -0
  188. package/lib/typescript/commonjs/theme/color-engine/tone-delta-pair.d.ts +19 -0
  189. package/lib/typescript/commonjs/theme/color-engine/tone-delta-pair.d.ts.map +1 -0
  190. package/lib/typescript/commonjs/theme/color-engine/variant.d.ts +19 -0
  191. package/lib/typescript/commonjs/theme/color-engine/variant.d.ts.map +1 -0
  192. package/lib/typescript/commonjs/theme/color-engine/viewing-conditions.d.ts +18 -0
  193. package/lib/typescript/commonjs/theme/color-engine/viewing-conditions.d.ts.map +1 -0
  194. package/lib/typescript/commonjs/theme/color-presets.d.ts +25 -20
  195. package/lib/typescript/commonjs/theme/color-presets.d.ts.map +1 -1
  196. package/lib/typescript/commonjs/theme/preset-vars.d.ts +16 -12
  197. package/lib/typescript/commonjs/theme/preset-vars.d.ts.map +1 -1
  198. package/lib/typescript/module/frosted-icon-button/FrostedIconButton.d.ts +5 -0
  199. package/lib/typescript/module/frosted-icon-button/FrostedIconButton.d.ts.map +1 -0
  200. package/lib/typescript/module/frosted-icon-button/FrostedIconButton.web.d.ts +5 -0
  201. package/lib/typescript/module/frosted-icon-button/FrostedIconButton.web.d.ts.map +1 -0
  202. package/lib/typescript/module/frosted-icon-button/index.d.ts +3 -0
  203. package/lib/typescript/module/frosted-icon-button/index.d.ts.map +1 -0
  204. package/lib/typescript/module/frosted-icon-button/index.web.d.ts +3 -0
  205. package/lib/typescript/module/frosted-icon-button/index.web.d.ts.map +1 -0
  206. package/lib/typescript/module/frosted-icon-button/shared.d.ts +60 -0
  207. package/lib/typescript/module/frosted-icon-button/shared.d.ts.map +1 -0
  208. package/lib/typescript/module/frosted-icon-button/types.d.ts +69 -0
  209. package/lib/typescript/module/frosted-icon-button/types.d.ts.map +1 -0
  210. package/lib/typescript/module/index.d.ts +2 -0
  211. package/lib/typescript/module/index.d.ts.map +1 -1
  212. package/lib/typescript/module/index.web.d.ts +2 -0
  213. package/lib/typescript/module/index.web.d.ts.map +1 -1
  214. package/lib/typescript/module/theme/build-theme.d.ts.map +1 -1
  215. package/lib/typescript/module/theme/color-engine/cam16.d.ts +26 -0
  216. package/lib/typescript/module/theme/color-engine/cam16.d.ts.map +1 -0
  217. package/lib/typescript/module/theme/color-engine/color-role.d.ts +36 -0
  218. package/lib/typescript/module/theme/color-engine/color-role.d.ts.map +1 -0
  219. package/lib/typescript/module/theme/color-engine/color-roles.d.ts +58 -0
  220. package/lib/typescript/module/theme/color-engine/color-roles.d.ts.map +1 -0
  221. package/lib/typescript/module/theme/color-engine/color-utils.d.ts +32 -0
  222. package/lib/typescript/module/theme/color-engine/color-utils.d.ts.map +1 -0
  223. package/lib/typescript/module/theme/color-engine/contrast-curve.d.ts +9 -0
  224. package/lib/typescript/module/theme/color-engine/contrast-curve.d.ts.map +1 -0
  225. package/lib/typescript/module/theme/color-engine/contrast.d.ts +12 -0
  226. package/lib/typescript/module/theme/color-engine/contrast.d.ts.map +1 -0
  227. package/lib/typescript/module/theme/color-engine/dislike-analyzer.d.ts +11 -0
  228. package/lib/typescript/module/theme/color-engine/dislike-analyzer.d.ts.map +1 -0
  229. package/lib/typescript/module/theme/color-engine/dynamic-scheme.d.ts +47 -0
  230. package/lib/typescript/module/theme/color-engine/dynamic-scheme.d.ts.map +1 -0
  231. package/lib/typescript/module/theme/color-engine/hct-solver.d.ts +6 -0
  232. package/lib/typescript/module/theme/color-engine/hct-solver.d.ts.map +1 -0
  233. package/lib/typescript/module/theme/color-engine/hct.d.ts +20 -0
  234. package/lib/typescript/module/theme/color-engine/hct.d.ts.map +1 -0
  235. package/lib/typescript/module/theme/color-engine/index.d.ts +44 -0
  236. package/lib/typescript/module/theme/color-engine/index.d.ts.map +1 -0
  237. package/lib/typescript/module/theme/color-engine/lab-point-provider.d.ts +6 -0
  238. package/lib/typescript/module/theme/color-engine/lab-point-provider.d.ts.map +1 -0
  239. package/lib/typescript/module/theme/color-engine/math-utils.d.ts +46 -0
  240. package/lib/typescript/module/theme/color-engine/math-utils.d.ts.map +1 -0
  241. package/lib/typescript/module/theme/color-engine/quantizer-map.d.ts +3 -0
  242. package/lib/typescript/module/theme/color-engine/quantizer-map.d.ts.map +1 -0
  243. package/lib/typescript/module/theme/color-engine/quantizer-wu.d.ts +3 -0
  244. package/lib/typescript/module/theme/color-engine/quantizer-wu.d.ts.map +1 -0
  245. package/lib/typescript/module/theme/color-engine/scheme-variants.d.ts +23 -0
  246. package/lib/typescript/module/theme/color-engine/scheme-variants.d.ts.map +1 -0
  247. package/lib/typescript/module/theme/color-engine/score.d.ts +8 -0
  248. package/lib/typescript/module/theme/color-engine/score.d.ts.map +1 -0
  249. package/lib/typescript/module/theme/color-engine/seed-from-image.d.ts +13 -0
  250. package/lib/typescript/module/theme/color-engine/seed-from-image.d.ts.map +1 -0
  251. package/lib/typescript/module/theme/color-engine/tonal-palette.d.ts +24 -0
  252. package/lib/typescript/module/theme/color-engine/tonal-palette.d.ts.map +1 -0
  253. package/lib/typescript/module/theme/color-engine/tone-delta-pair.d.ts +19 -0
  254. package/lib/typescript/module/theme/color-engine/tone-delta-pair.d.ts.map +1 -0
  255. package/lib/typescript/module/theme/color-engine/variant.d.ts +19 -0
  256. package/lib/typescript/module/theme/color-engine/variant.d.ts.map +1 -0
  257. package/lib/typescript/module/theme/color-engine/viewing-conditions.d.ts +18 -0
  258. package/lib/typescript/module/theme/color-engine/viewing-conditions.d.ts.map +1 -0
  259. package/lib/typescript/module/theme/color-presets.d.ts +25 -20
  260. package/lib/typescript/module/theme/color-presets.d.ts.map +1 -1
  261. package/lib/typescript/module/theme/preset-vars.d.ts +16 -12
  262. package/lib/typescript/module/theme/preset-vars.d.ts.map +1 -1
  263. package/package.json +17 -1
  264. package/src/__tests__/BloomThemeProvider.test.tsx +9 -4
  265. package/src/__tests__/FrostedIconButton.test.tsx +137 -0
  266. package/src/__tests__/FrostedIconButton.web.test.tsx +246 -0
  267. package/src/__tests__/native-root-vars.test.ts +8 -4
  268. package/src/__tests__/preset-vars.test.ts +66 -37
  269. package/src/__tests__/theme.test.ts +20 -12
  270. package/src/frosted-icon-button/FrostedIconButton.stories.tsx +65 -0
  271. package/src/frosted-icon-button/FrostedIconButton.tsx +156 -0
  272. package/src/frosted-icon-button/FrostedIconButton.web.tsx +207 -0
  273. package/src/frosted-icon-button/index.ts +2 -0
  274. package/src/frosted-icon-button/index.web.ts +9 -0
  275. package/src/frosted-icon-button/shared.ts +118 -0
  276. package/src/frosted-icon-button/types.ts +81 -0
  277. package/src/index.ts +2 -0
  278. package/src/index.web.ts +2 -0
  279. package/src/theme/__tests__/__fixtures__/golden-resolved-tokens.json +509 -509
  280. package/src/theme/__tests__/__snapshots__/visual-gallery.test.tsx.snap +613 -613
  281. package/src/theme/__tests__/color-engine-golden.test.ts +81 -0
  282. package/src/theme/__tests__/fixtures/color-engine-golden.json +1 -0
  283. package/src/theme/__tests__/golden-tokens.test.ts +6 -7
  284. package/src/theme/__tests__/runtime-contract.test.ts +8 -8
  285. package/src/theme/__tests__/theme-colors-parity.test.ts +44 -88
  286. package/src/theme/build-theme.ts +32 -44
  287. package/src/theme/color-engine/cam16.ts +179 -0
  288. package/src/theme/color-engine/color-role.ts +217 -0
  289. package/src/theme/color-engine/color-roles.ts +435 -0
  290. package/src/theme/color-engine/color-utils.ts +157 -0
  291. package/src/theme/color-engine/contrast-curve.ts +25 -0
  292. package/src/theme/color-engine/contrast.ts +59 -0
  293. package/src/theme/color-engine/dislike-analyzer.ts +19 -0
  294. package/src/theme/color-engine/dynamic-scheme.ts +90 -0
  295. package/src/theme/color-engine/hct-solver.ts +263 -0
  296. package/src/theme/color-engine/hct.ts +69 -0
  297. package/src/theme/color-engine/index.ts +73 -0
  298. package/src/theme/color-engine/lab-point-provider.ts +26 -0
  299. package/src/theme/color-engine/math-utils.ts +69 -0
  300. package/src/theme/color-engine/quantizer-map.ts +17 -0
  301. package/src/theme/color-engine/quantizer-wu.ts +320 -0
  302. package/src/theme/color-engine/scheme-variants.ts +113 -0
  303. package/src/theme/color-engine/score.ts +82 -0
  304. package/src/theme/color-engine/seed-from-image.ts +64 -0
  305. package/src/theme/color-engine/tonal-palette.ts +94 -0
  306. package/src/theme/color-engine/tone-delta-pair.ts +21 -0
  307. package/src/theme/color-engine/variant.ts +18 -0
  308. package/src/theme/color-engine/viewing-conditions.ts +77 -0
  309. package/src/theme/color-presets.ts +54 -631
  310. package/src/theme/preset-vars.ts +65 -49
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Bloom colour engine — CAM16 colour appearance model.
3
+ *
4
+ * Faithful port of Material Color Utilities' `Cam16` (Apache-2.0) into Bloom's
5
+ * own code. A colour is defined by its ARGB AND the viewing conditions; CAM16
6
+ * also exposes CAM16-UCS coordinates (jstar/astar/bstar) for perceptual
7
+ * distance. Underpins the HCT colour space.
8
+ */
9
+ import { argbFromXyz, linearized } from './color-utils';
10
+ import { signum } from './math-utils';
11
+ import { ViewingConditions } from './viewing-conditions';
12
+
13
+ export class Cam16 {
14
+ constructor(
15
+ readonly hue: number,
16
+ readonly chroma: number,
17
+ readonly j: number,
18
+ readonly q: number,
19
+ readonly m: number,
20
+ readonly s: number,
21
+ readonly jstar: number,
22
+ readonly astar: number,
23
+ readonly bstar: number,
24
+ ) {}
25
+
26
+ /** CAM16-UCS perceptual distance to another colour. */
27
+ distance(other: Cam16): number {
28
+ const dJ = this.jstar - other.jstar;
29
+ const dA = this.astar - other.astar;
30
+ const dB = this.bstar - other.bstar;
31
+ const dEPrime = Math.sqrt(dJ * dJ + dA * dA + dB * dB);
32
+ return 1.41 * Math.pow(dEPrime, 0.63);
33
+ }
34
+
35
+ static fromInt(argb: number): Cam16 {
36
+ return Cam16.fromIntInViewingConditions(argb, ViewingConditions.DEFAULT);
37
+ }
38
+
39
+ static fromIntInViewingConditions(argb: number, vc: ViewingConditions): Cam16 {
40
+ const red = (argb & 0x00ff0000) >> 16;
41
+ const green = (argb & 0x0000ff00) >> 8;
42
+ const blue = argb & 0x000000ff;
43
+ const redL = linearized(red);
44
+ const greenL = linearized(green);
45
+ const blueL = linearized(blue);
46
+ const x = 0.41233895 * redL + 0.35762064 * greenL + 0.18051042 * blueL;
47
+ const y = 0.2126 * redL + 0.7152 * greenL + 0.0722 * blueL;
48
+ const z = 0.01932141 * redL + 0.11916382 * greenL + 0.95034478 * blueL;
49
+ return Cam16.fromXyzInViewingConditions(x, y, z, vc);
50
+ }
51
+
52
+ static fromXyzInViewingConditions(
53
+ x: number,
54
+ y: number,
55
+ z: number,
56
+ vc: ViewingConditions,
57
+ ): Cam16 {
58
+ const rC = 0.401288 * x + 0.650173 * y - 0.051461 * z;
59
+ const gC = -0.250268 * x + 1.204414 * y + 0.045854 * z;
60
+ const bC = -0.002079 * x + 0.048952 * y + 0.953127 * z;
61
+ const rD = vc.rgbD[0] * rC;
62
+ const gD = vc.rgbD[1] * gC;
63
+ const bD = vc.rgbD[2] * bC;
64
+ const rAF = Math.pow((vc.fl * Math.abs(rD)) / 100.0, 0.42);
65
+ const gAF = Math.pow((vc.fl * Math.abs(gD)) / 100.0, 0.42);
66
+ const bAF = Math.pow((vc.fl * Math.abs(bD)) / 100.0, 0.42);
67
+ const rA = (signum(rD) * 400.0 * rAF) / (rAF + 27.13);
68
+ const gA = (signum(gD) * 400.0 * gAF) / (gAF + 27.13);
69
+ const bA = (signum(bD) * 400.0 * bAF) / (bAF + 27.13);
70
+ const a = (11.0 * rA + -12.0 * gA + bA) / 11.0;
71
+ const b = (rA + gA - 2.0 * bA) / 9.0;
72
+ const u = (20.0 * rA + 20.0 * gA + 21.0 * bA) / 20.0;
73
+ const p2 = (40.0 * rA + 20.0 * gA + bA) / 20.0;
74
+ const atan2 = Math.atan2(b, a);
75
+ const atanDegrees = (atan2 * 180.0) / Math.PI;
76
+ const hue =
77
+ atanDegrees < 0 ? atanDegrees + 360.0 : atanDegrees >= 360 ? atanDegrees - 360 : atanDegrees;
78
+ const hueRadians = (hue * Math.PI) / 180.0;
79
+ const ac = p2 * vc.nbb;
80
+ const J = 100.0 * Math.pow(ac / vc.aw, vc.c * vc.z);
81
+ const Q = (4.0 / vc.c) * Math.sqrt(J / 100.0) * (vc.aw + 4.0) * vc.fLRoot;
82
+ const huePrime = hue < 20.14 ? hue + 360 : hue;
83
+ const eHue = (1.0 / 4.0) * (Math.cos((huePrime * Math.PI) / 180.0 + 2.0) + 3.8);
84
+ const p1 = ((50000.0 / 13.0) * eHue * vc.nc * vc.ncb);
85
+ const t = (p1 * Math.sqrt(a * a + b * b)) / (u + 0.305);
86
+ const alpha = Math.pow(t, 0.9) * Math.pow(1.64 - Math.pow(0.29, vc.n), 0.73);
87
+ const C = alpha * Math.sqrt(J / 100.0);
88
+ const M = C * vc.fLRoot;
89
+ const s = 50.0 * Math.sqrt((alpha * vc.c) / (vc.aw + 4.0));
90
+ const jstar = ((1.0 + 100.0 * 0.007) * J) / (1.0 + 0.007 * J);
91
+ const mstar = Math.log(1.0 + 0.0228 * M) / 0.0228;
92
+ const astar = mstar * Math.cos(hueRadians);
93
+ const bstar = mstar * Math.sin(hueRadians);
94
+ return new Cam16(hue, C, J, Q, M, s, jstar, astar, bstar);
95
+ }
96
+
97
+ static fromJch(j: number, c: number, h: number): Cam16 {
98
+ return Cam16.fromJchInViewingConditions(j, c, h, ViewingConditions.DEFAULT);
99
+ }
100
+
101
+ static fromJchInViewingConditions(
102
+ j: number,
103
+ c: number,
104
+ h: number,
105
+ vc: ViewingConditions,
106
+ ): Cam16 {
107
+ const q = (4.0 / vc.c) * Math.sqrt(j / 100.0) * (vc.aw + 4.0) * vc.fLRoot;
108
+ const m = c * vc.fLRoot;
109
+ const alpha = c / Math.sqrt(j / 100.0);
110
+ const s = 50.0 * Math.sqrt((alpha * vc.c) / (vc.aw + 4.0));
111
+ const hueRadians = (h * Math.PI) / 180.0;
112
+ const jstar = ((1.0 + 100.0 * 0.007) * j) / (1.0 + 0.007 * j);
113
+ const mstar = (1.0 / 0.0228) * Math.log(1.0 + 0.0228 * m);
114
+ const astar = mstar * Math.cos(hueRadians);
115
+ const bstar = mstar * Math.sin(hueRadians);
116
+ return new Cam16(h, c, j, q, m, s, jstar, astar, bstar);
117
+ }
118
+
119
+ static fromUcs(jstar: number, astar: number, bstar: number): Cam16 {
120
+ return Cam16.fromUcsInViewingConditions(jstar, astar, bstar, ViewingConditions.DEFAULT);
121
+ }
122
+
123
+ static fromUcsInViewingConditions(
124
+ jstar: number,
125
+ astar: number,
126
+ bstar: number,
127
+ vc: ViewingConditions,
128
+ ): Cam16 {
129
+ const a = astar;
130
+ const b = bstar;
131
+ const m = Math.sqrt(a * a + b * b);
132
+ const M = (Math.exp(m * 0.0228) - 1.0) / 0.0228;
133
+ const c = M / vc.fLRoot;
134
+ let h = Math.atan2(b, a) * (180.0 / Math.PI);
135
+ if (h < 0.0) h += 360.0;
136
+ const j = jstar / (1 - (jstar - 100) * 0.007);
137
+ return Cam16.fromJchInViewingConditions(j, c, h, vc);
138
+ }
139
+
140
+ toInt(): number {
141
+ return this.viewed(ViewingConditions.DEFAULT);
142
+ }
143
+
144
+ viewed(vc: ViewingConditions): number {
145
+ const xyz = this.xyzInViewingConditions(vc);
146
+ return argbFromXyz(xyz[0], xyz[1], xyz[2]);
147
+ }
148
+
149
+ xyzInViewingConditions(vc: ViewingConditions): [number, number, number] {
150
+ const alpha = this.chroma === 0.0 || this.j === 0.0 ? 0.0 : this.chroma / Math.sqrt(this.j / 100.0);
151
+ const t = Math.pow(alpha / Math.pow(1.64 - Math.pow(0.29, vc.n), 0.73), 1.0 / 0.9);
152
+ const hRad = (this.hue * Math.PI) / 180.0;
153
+ const eHue = 0.25 * (Math.cos(hRad + 2.0) + 3.8);
154
+ const ac = vc.aw * Math.pow(this.j / 100.0, 1.0 / vc.c / vc.z);
155
+ const p1 = eHue * (50000.0 / 13.0) * vc.nc * vc.ncb;
156
+ const p2 = ac / vc.nbb;
157
+ const hSin = Math.sin(hRad);
158
+ const hCos = Math.cos(hRad);
159
+ const gamma = (23.0 * (p2 + 0.305) * t) / (23.0 * p1 + 11.0 * t * hCos + 108.0 * t * hSin);
160
+ const a = gamma * hCos;
161
+ const b = gamma * hSin;
162
+ const rA = (460.0 * p2 + 451.0 * a + 288.0 * b) / 1403.0;
163
+ const gA = (460.0 * p2 - 891.0 * a - 261.0 * b) / 1403.0;
164
+ const bA = (460.0 * p2 - 220.0 * a - 6300.0 * b) / 1403.0;
165
+ const rCBase = Math.max(0, (27.13 * Math.abs(rA)) / (400.0 - Math.abs(rA)));
166
+ const rC = signum(rA) * (100.0 / vc.fl) * Math.pow(rCBase, 1.0 / 0.42);
167
+ const gCBase = Math.max(0, (27.13 * Math.abs(gA)) / (400.0 - Math.abs(gA)));
168
+ const gC = signum(gA) * (100.0 / vc.fl) * Math.pow(gCBase, 1.0 / 0.42);
169
+ const bCBase = Math.max(0, (27.13 * Math.abs(bA)) / (400.0 - Math.abs(bA)));
170
+ const bC = signum(bA) * (100.0 / vc.fl) * Math.pow(bCBase, 1.0 / 0.42);
171
+ const rF = rC / vc.rgbD[0];
172
+ const gF = gC / vc.rgbD[1];
173
+ const bF = bC / vc.rgbD[2];
174
+ const x = 1.86206786 * rF - 1.01125463 * gF + 0.14918677 * bF;
175
+ const y = 0.38752654 * rF + 0.62144744 * gF - 0.00897398 * bF;
176
+ const z = -0.0158415 * rF - 0.03412294 * gF + 1.04996444 * bF;
177
+ return [x, y, z];
178
+ }
179
+ }
@@ -0,0 +1,217 @@
1
+ /**
2
+ * Bloom colour engine — a colour role.
3
+ *
4
+ * Faithful port of Material Color Utilities' `DynamicColor` (Apache-2.0),
5
+ * renamed to Bloom's own `ColorRole`. A role is a *recipe*, not a fixed colour:
6
+ * a palette + a base tone + (optionally) a background to contrast against and a
7
+ * paired role to keep tonal distance from. `getArgb(scheme)` resolves the recipe
8
+ * against a scheme's palettes, dark mode and contrast level into a concrete
9
+ * colour — guaranteeing legibility. This is the heart of the system.
10
+ */
11
+ import { darker, darkerUnsafe, lighter, lighterUnsafe, ratioOfTones } from './contrast';
12
+ import type { ContrastCurve } from './contrast-curve';
13
+ import type { DynamicScheme } from './dynamic-scheme';
14
+ import { Hct } from './hct';
15
+ import { clampDouble } from './math-utils';
16
+ import type { TonalPalette } from './tonal-palette';
17
+ import type { ToneDeltaPair } from './tone-delta-pair';
18
+
19
+ export interface ColorRoleArgs {
20
+ name?: string;
21
+ palette: (scheme: DynamicScheme) => TonalPalette;
22
+ tone: (scheme: DynamicScheme) => number;
23
+ isBackground?: boolean;
24
+ background?: (scheme: DynamicScheme) => ColorRole | undefined;
25
+ secondBackground?: (scheme: DynamicScheme) => ColorRole | undefined;
26
+ contrastCurve?: ContrastCurve;
27
+ toneDeltaPair?: (scheme: DynamicScheme) => ToneDeltaPair;
28
+ }
29
+
30
+ export class ColorRole {
31
+ readonly name: string;
32
+ readonly palette: (scheme: DynamicScheme) => TonalPalette;
33
+ readonly tone: (scheme: DynamicScheme) => number;
34
+ readonly isBackground: boolean;
35
+ readonly background?: (scheme: DynamicScheme) => ColorRole | undefined;
36
+ readonly secondBackground?: (scheme: DynamicScheme) => ColorRole | undefined;
37
+ readonly contrastCurve?: ContrastCurve;
38
+ readonly toneDeltaPair?: (scheme: DynamicScheme) => ToneDeltaPair;
39
+ private readonly hctCache = new Map<DynamicScheme, Hct>();
40
+
41
+ static fromPalette(args: ColorRoleArgs): ColorRole {
42
+ return new ColorRole(args);
43
+ }
44
+
45
+ constructor(args: ColorRoleArgs) {
46
+ this.name = args.name ?? '';
47
+ this.palette = args.palette;
48
+ this.tone = args.tone;
49
+ this.isBackground = args.isBackground ?? false;
50
+ this.background = args.background;
51
+ this.secondBackground = args.secondBackground;
52
+ this.contrastCurve = args.contrastCurve;
53
+ this.toneDeltaPair = args.toneDeltaPair;
54
+ if (!args.background && args.secondBackground) {
55
+ throw new Error(`Color ${this.name} has secondBackground defined, but background is not.`);
56
+ }
57
+ if (!args.background && args.contrastCurve) {
58
+ throw new Error(`Color ${this.name} has contrastCurve defined, but background is not.`);
59
+ }
60
+ if (args.background && !args.contrastCurve) {
61
+ throw new Error(`Color ${this.name} has background defined, but contrastCurve is not.`);
62
+ }
63
+ }
64
+
65
+ getArgb(scheme: DynamicScheme): number {
66
+ return this.getHct(scheme).toInt();
67
+ }
68
+
69
+ getHct(scheme: DynamicScheme): Hct {
70
+ const cached = this.hctCache.get(scheme);
71
+ if (cached != null) return cached;
72
+ const tone = this.getTone(scheme);
73
+ const answer = this.palette(scheme).getHct(tone);
74
+ if (this.hctCache.size > 4) this.hctCache.clear();
75
+ this.hctCache.set(scheme, answer);
76
+ return answer;
77
+ }
78
+
79
+ getTone(scheme: DynamicScheme): number {
80
+ const decreasingContrast = scheme.contrastLevel < 0;
81
+ if (this.toneDeltaPair) {
82
+ const pair = this.toneDeltaPair(scheme);
83
+ const { roleA, roleB, delta, polarity, stayTogether } = pair;
84
+ const bg = this.background!(scheme)!;
85
+ const bgTone = bg.getTone(scheme);
86
+ const aIsNearer =
87
+ polarity === 'nearer' ||
88
+ (polarity === 'lighter' && !scheme.isDark) ||
89
+ (polarity === 'darker' && scheme.isDark);
90
+ const nearer = aIsNearer ? roleA : roleB;
91
+ const farther = aIsNearer ? roleB : roleA;
92
+ const amNearer = this.name === nearer.name;
93
+ const expansionDir = scheme.isDark ? 1 : -1;
94
+ const nContrast = nearer.contrastCurve!.get(scheme.contrastLevel);
95
+ const fContrast = farther.contrastCurve!.get(scheme.contrastLevel);
96
+ const nInitialTone = nearer.tone(scheme);
97
+ let nTone =
98
+ ratioOfTones(bgTone, nInitialTone) >= nContrast
99
+ ? nInitialTone
100
+ : ColorRole.foregroundTone(bgTone, nContrast);
101
+ const fInitialTone = farther.tone(scheme);
102
+ let fTone =
103
+ ratioOfTones(bgTone, fInitialTone) >= fContrast
104
+ ? fInitialTone
105
+ : ColorRole.foregroundTone(bgTone, fContrast);
106
+ if (decreasingContrast) {
107
+ nTone = ColorRole.foregroundTone(bgTone, nContrast);
108
+ fTone = ColorRole.foregroundTone(bgTone, fContrast);
109
+ }
110
+ if ((fTone - nTone) * expansionDir >= delta) {
111
+ // constraint already satisfied
112
+ } else {
113
+ fTone = clampDouble(0, 100, nTone + delta * expansionDir);
114
+ if ((fTone - nTone) * expansionDir >= delta) {
115
+ // satisfied after expanding farther
116
+ } else {
117
+ nTone = clampDouble(0, 100, fTone - delta * expansionDir);
118
+ }
119
+ }
120
+ if (50 <= nTone && nTone < 60) {
121
+ if (expansionDir > 0) {
122
+ nTone = 60;
123
+ fTone = Math.max(fTone, nTone + delta * expansionDir);
124
+ } else {
125
+ nTone = 49;
126
+ fTone = Math.min(fTone, nTone + delta * expansionDir);
127
+ }
128
+ } else if (50 <= fTone && fTone < 60) {
129
+ if (stayTogether) {
130
+ if (expansionDir > 0) {
131
+ nTone = 60;
132
+ fTone = Math.max(fTone, nTone + delta * expansionDir);
133
+ } else {
134
+ nTone = 49;
135
+ fTone = Math.min(fTone, nTone + delta * expansionDir);
136
+ }
137
+ } else if (expansionDir > 0) {
138
+ fTone = 60;
139
+ } else {
140
+ fTone = 49;
141
+ }
142
+ }
143
+ return amNearer ? nTone : fTone;
144
+ }
145
+
146
+ let answer = this.tone(scheme);
147
+ if (this.background == null) return answer;
148
+ const bgTone = this.background(scheme)!.getTone(scheme);
149
+ const desiredRatio = this.contrastCurve!.get(scheme.contrastLevel);
150
+ if (ratioOfTones(bgTone, answer) >= desiredRatio) {
151
+ // already contrasts enough
152
+ } else {
153
+ answer = ColorRole.foregroundTone(bgTone, desiredRatio);
154
+ }
155
+ if (decreasingContrast) {
156
+ answer = ColorRole.foregroundTone(bgTone, desiredRatio);
157
+ }
158
+ if (this.isBackground && 50 <= answer && answer < 60) {
159
+ answer = ratioOfTones(49, bgTone) >= desiredRatio ? 49 : 60;
160
+ }
161
+ if (this.secondBackground) {
162
+ const bg1 = this.background;
163
+ const bg2 = this.secondBackground;
164
+ const bgTone1 = bg1(scheme)!.getTone(scheme);
165
+ const bgTone2 = bg2(scheme)!.getTone(scheme);
166
+ const upper = Math.max(bgTone1, bgTone2);
167
+ const lower = Math.min(bgTone1, bgTone2);
168
+ if (ratioOfTones(upper, answer) >= desiredRatio && ratioOfTones(lower, answer) >= desiredRatio) {
169
+ return answer;
170
+ }
171
+ const lightOption = lighter(upper, desiredRatio);
172
+ const darkOption = darker(lower, desiredRatio);
173
+ const availables: number[] = [];
174
+ if (lightOption !== -1) availables.push(lightOption);
175
+ if (darkOption !== -1) availables.push(darkOption);
176
+ const prefersLight =
177
+ ColorRole.tonePrefersLightForeground(bgTone1) ||
178
+ ColorRole.tonePrefersLightForeground(bgTone2);
179
+ if (prefersLight) return lightOption < 0 ? 100 : lightOption;
180
+ const onlyAvailable = availables[0];
181
+ if (availables.length === 1 && onlyAvailable !== undefined) return onlyAvailable;
182
+ return darkOption < 0 ? 0 : darkOption;
183
+ }
184
+ return answer;
185
+ }
186
+
187
+ static foregroundTone(bgTone: number, ratio: number): number {
188
+ const lighterTone = lighterUnsafe(bgTone, ratio);
189
+ const darkerTone = darkerUnsafe(bgTone, ratio);
190
+ const lighterRatio = ratioOfTones(lighterTone, bgTone);
191
+ const darkerRatio = ratioOfTones(darkerTone, bgTone);
192
+ const preferLighter = ColorRole.tonePrefersLightForeground(bgTone);
193
+ if (preferLighter) {
194
+ const negligibleDifference =
195
+ Math.abs(lighterRatio - darkerRatio) < 0.1 && lighterRatio < ratio && darkerRatio < ratio;
196
+ return lighterRatio >= ratio || lighterRatio >= darkerRatio || negligibleDifference
197
+ ? lighterTone
198
+ : darkerTone;
199
+ }
200
+ return darkerRatio >= ratio || darkerRatio >= lighterRatio ? darkerTone : lighterTone;
201
+ }
202
+
203
+ static tonePrefersLightForeground(tone: number): boolean {
204
+ return Math.round(tone) < 60.0;
205
+ }
206
+
207
+ static toneAllowsLightForeground(tone: number): boolean {
208
+ return Math.round(tone) <= 49.0;
209
+ }
210
+
211
+ static enableLightForeground(tone: number): number {
212
+ if (ColorRole.tonePrefersLightForeground(tone) && !ColorRole.toneAllowsLightForeground(tone)) {
213
+ return 49.0;
214
+ }
215
+ return tone;
216
+ }
217
+ }