@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,6 @@
1
+ export type LabPoint = [number, number, number];
2
+ export declare function labFromInt(argb: number): LabPoint;
3
+ export declare function intFromLab(point: LabPoint): number;
4
+ /** Squared Euclidean distance in L*a*b* (cheaper than the real distance). */
5
+ export declare function labDistance(from: LabPoint, to: LabPoint): number;
6
+ //# sourceMappingURL=lab-point-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lab-point-provider.d.ts","sourceRoot":"","sources":["../../../../../src/theme/color-engine/lab-point-provider.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAEhD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAEjD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAElD;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,GAAG,MAAM,CAKhE"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Bloom colour engine — scalar/vector maths.
3
+ *
4
+ * Self-contained port of the Material Color Utilities maths helpers (the same
5
+ * primitives MaterialKolor uses), reimplemented in Bloom's own TypeScript so the
6
+ * theme has ZERO external colour dependencies. Algorithm © Google, Apache-2.0;
7
+ * this is a faithful derivative kept byte-compatible via golden tests.
8
+ */
9
+ /** 1 if `n > 0`, -1 if `n < 0`, 0 if `n === 0`. */
10
+ export declare function signum(n: number): number;
11
+ /** Linear interpolation: `start` at `amount = 0`, `stop` at `amount = 1`. */
12
+ export declare function lerp(start: number, stop: number, amount: number): number;
13
+ /** Clamp `input` into `[min, max]`. */
14
+ export declare function clampInt(min: number, max: number, input: number): number;
15
+ /** Clamp `input` into `[min, max]` (floating point). */
16
+ export declare function clampDouble(min: number, max: number, input: number): number;
17
+ /** Wrap a degree measure into `[0, 360)` as an integer. */
18
+ export declare function sanitizeDegreesInt(degrees: number): number;
19
+ /** Wrap a degree measure into `[0, 360)` as a float. */
20
+ export declare function sanitizeDegreesDouble(degrees: number): number;
21
+ /**
22
+ * Sign of the shortest rotation from `from` to `to` on a circle.
23
+ * @returns 1 if increasing `from` is shortest, -1 if decreasing is.
24
+ */
25
+ export declare function rotationDirection(from: number, to: number): number;
26
+ /** Shortest angular distance (degrees) between two hues. */
27
+ export declare function differenceDegrees(a: number, b: number): number;
28
+ /** Multiply a 1×3 row vector by a 3×3 matrix. */
29
+ export declare function matrixMultiply(row: [number, number, number], matrix: [
30
+ [
31
+ number,
32
+ number,
33
+ number
34
+ ],
35
+ [
36
+ number,
37
+ number,
38
+ number
39
+ ],
40
+ [
41
+ number,
42
+ number,
43
+ number
44
+ ]
45
+ ]): [number, number, number];
46
+ //# sourceMappingURL=math-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"math-utils.d.ts","sourceRoot":"","sources":["../../../../../src/theme/color-engine/math-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,mDAAmD;AACnD,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAExC;AAED,6EAA6E;AAC7E,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAExE;AAED,uCAAuC;AACvC,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAExE;AAED,wDAAwD;AACxD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3E;AAED,2DAA2D;AAC3D,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAG1D;AAED,wDAAwD;AACxD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAG7D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAGlE;AAED,4DAA4D;AAC5D,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,iDAAiD;AACjD,wBAAgB,cAAc,CAC5B,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAC7B,MAAM,EAAE;IACN;QAAC,MAAM;QAAE,MAAM;QAAE,MAAM;KAAC;IACxB;QAAC,MAAM;QAAE,MAAM;QAAE,MAAM;KAAC;IACxB;QAAC,MAAM;QAAE,MAAM;QAAE,MAAM;KAAC;CACzB,GACA,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAK1B"}
@@ -0,0 +1,3 @@
1
+ /** Count opaque pixels by exact ARGB. Fully-transparent pixels are dropped. */
2
+ export declare function countByColor(pixels: number[]): Map<number, number>;
3
+ //# sourceMappingURL=quantizer-map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quantizer-map.d.ts","sourceRoot":"","sources":["../../../../../src/theme/color-engine/quantizer-map.ts"],"names":[],"mappings":"AAQA,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAOlE"}
@@ -0,0 +1,3 @@
1
+ /** Wu-quantize `pixels` into at most `maxColors` representative ARGB colours. */
2
+ export declare function quantizeWu(pixels: number[], maxColors: number): number[];
3
+ //# sourceMappingURL=quantizer-wu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quantizer-wu.d.ts","sourceRoot":"","sources":["../../../../../src/theme/color-engine/quantizer-wu.ts"],"names":[],"mappings":"AAqDA,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAyQxE"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Bloom colour engine — scheme variants.
3
+ *
4
+ * How each variant derives its five tonal palettes from the seed HCT. Faithful
5
+ * port of Material Color Utilities' `Scheme*` families (Apache-2.0), expressed
6
+ * as plain builder functions (our style) rather than subclasses. Fidelity/
7
+ * Content are intentionally left out — they need the temperature-cache complement
8
+ * and aren't useful for Bloom's fixed brand seeds.
9
+ */
10
+ import { DynamicScheme } from './dynamic-scheme';
11
+ import type { Hct } from './hct';
12
+ export type SchemeVariant = 'vibrant' | 'expressive' | 'tonalSpot' | 'neutral';
13
+ /** Maxed-out colourfulness at each position of the primary palette. */
14
+ export declare function schemeVibrant(source: Hct, isDark: boolean, contrastLevel: number): DynamicScheme;
15
+ /** Playful, intentionally detached from the seed hue (primary rotated 240°). */
16
+ export declare function schemeExpressive(source: Hct, isDark: boolean, contrastLevel: number): DynamicScheme;
17
+ /** The Material You default — a calm, balanced treatment of the seed. */
18
+ export declare function schemeTonalSpot(source: Hct, isDark: boolean, contrastLevel: number): DynamicScheme;
19
+ /** Near-greyscale — the seed hue is present only as a whisper. */
20
+ export declare function schemeNeutral(source: Hct, isDark: boolean, contrastLevel: number): DynamicScheme;
21
+ /** Build a scheme by variant name. */
22
+ export declare function buildScheme(variant: SchemeVariant, source: Hct, isDark: boolean, contrastLevel?: number): DynamicScheme;
23
+ //# sourceMappingURL=scheme-variants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheme-variants.d.ts","sourceRoot":"","sources":["../../../../../src/theme/color-engine/scheme-variants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAKjC,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,YAAY,GAAG,WAAW,GAAG,SAAS,CAAC;AAU/E,uEAAuE;AACvE,wBAAgB,aAAa,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,GAAG,aAAa,CAkBhG;AAED,gFAAgF;AAChF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,GAAG,aAAa,CAkBnG;AAED,yEAAyE;AACzE,wBAAgB,eAAe,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,GAAG,aAAa,CAYlG;AAED,kEAAkE;AAClE,wBAAgB,aAAa,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,GAAG,aAAa,CAYhG;AASD,sCAAsC;AACtC,wBAAgB,WAAW,CACzB,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,GAAG,EACX,MAAM,EAAE,OAAO,EACf,aAAa,SAAI,GAChB,aAAa,CAEf"}
@@ -0,0 +1,8 @@
1
+ export interface ScoreOptions {
2
+ desired?: number;
3
+ fallbackColorARGB?: number;
4
+ filter?: boolean;
5
+ }
6
+ /** Rank quantized colours as theme seeds. Best first. */
7
+ export declare function score(colorsToPopulation: Map<number, number>, options?: ScoreOptions): number[];
8
+ //# sourceMappingURL=score.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"score.d.ts","sourceRoot":"","sources":["../../../../../src/theme/color-engine/score.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,yDAAyD;AACzD,wBAAgB,KAAK,CAAC,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAE,YAAiB,GAAG,MAAM,EAAE,CAwDnG"}
@@ -0,0 +1,13 @@
1
+ import { type ScoreOptions } from './score';
2
+ /**
3
+ * Quantize `pixels` to a representative palette with its populations. Uses Wu
4
+ * (deterministic) for the palette, then assigns every pixel to its nearest
5
+ * representative in L*a*b* — no randomness, so the same image always yields the
6
+ * same result.
7
+ */
8
+ export declare function quantizeImage(pixels: number[], maxColors?: number): Map<number, number>;
9
+ /** Ranked seed candidates (best first) extracted from an image's pixels (ARGB). */
10
+ export declare function seedsFromImagePixels(pixels: number[], options?: ScoreOptions): number[];
11
+ /** The single best seed colour from an image, as `#rrggbb`. */
12
+ export declare function seedHexFromImagePixels(pixels: number[]): string;
13
+ //# sourceMappingURL=seed-from-image.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed-from-image.d.ts","sourceRoot":"","sources":["../../../../../src/theme/color-engine/seed-from-image.ts"],"names":[],"mappings":"AAcA,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAEnD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,SAAS,SAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CA6BpF;AAED,mFAAmF;AACnF,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,EAAE,CAEvF;AAED,+DAA+D;AAC/D,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAI/D"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Bloom colour engine — tonal palettes.
3
+ *
4
+ * Faithful port of Material Color Utilities' `TonalPalette` (Apache-2.0). A
5
+ * palette holds a fixed hue + chroma and yields a colour for any tone (0–100).
6
+ * Schemes build primary/secondary/tertiary/neutral palettes and read specific
7
+ * tones per role.
8
+ */
9
+ import { Hct } from './hct';
10
+ export declare class TonalPalette {
11
+ readonly hue: number;
12
+ readonly chroma: number;
13
+ readonly keyColor: Hct;
14
+ private readonly cache;
15
+ private constructor();
16
+ static fromInt(argb: number): TonalPalette;
17
+ static fromHct(hct: Hct): TonalPalette;
18
+ static fromHueAndChroma(hue: number, chroma: number): TonalPalette;
19
+ /** ARGB of this palette at the given tone. */
20
+ tone(tone: number): number;
21
+ /** HCT of this palette at the given tone. */
22
+ getHct(tone: number): Hct;
23
+ }
24
+ //# sourceMappingURL=tonal-palette.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tonal-palette.d.ts","sourceRoot":"","sources":["../../../../../src/theme/color-engine/tonal-palette.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAE5B,qBAAa,YAAY;IAIrB,QAAQ,CAAC,GAAG,EAAE,MAAM;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,QAAQ,EAAE,GAAG;IALxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IAEnD,OAAO;IAMP,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY;IAI1C,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,YAAY;IAItC,MAAM,CAAC,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY;IAKlE,8CAA8C;IAC9C,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAS1B,6CAA6C;IAC7C,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG;CAG1B"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Bloom colour engine — tone-delta pair.
3
+ *
4
+ * Faithful port of Material Color Utilities' `ToneDeltaPair` (Apache-2.0).
5
+ * Constrains two related roles to keep a minimum tonal distance in a given
6
+ * direction (e.g. a fixed colour must stay lighter than its dim variant), so
7
+ * paired roles never collapse into each other.
8
+ */
9
+ import type { ColorRole } from './color-role';
10
+ export type TonePolarity = 'darker' | 'lighter' | 'nearer' | 'farther';
11
+ export declare class ToneDeltaPair {
12
+ readonly roleA: ColorRole;
13
+ readonly roleB: ColorRole;
14
+ readonly delta: number;
15
+ readonly polarity: TonePolarity;
16
+ readonly stayTogether: boolean;
17
+ constructor(roleA: ColorRole, roleB: ColorRole, delta: number, polarity: TonePolarity, stayTogether: boolean);
18
+ }
19
+ //# sourceMappingURL=tone-delta-pair.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tone-delta-pair.d.ts","sourceRoot":"","sources":["../../../../../src/theme/color-engine/tone-delta-pair.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEvE,qBAAa,aAAa;IAEtB,QAAQ,CAAC,KAAK,EAAE,SAAS;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM;IACtB,QAAQ,CAAC,QAAQ,EAAE,YAAY;IAC/B,QAAQ,CAAC,YAAY,EAAE,OAAO;gBAJrB,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,YAAY,EACtB,YAAY,EAAE,OAAO;CAEjC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Bloom colour engine — scheme variants.
3
+ *
4
+ * The families of dynamic-colour scheme supported by the engine. Bloom exposes
5
+ * the useful subset (Vibrant, Expressive, TonalSpot, Neutral, Fidelity); the
6
+ * numeric values match Material Color Utilities so ported scheme logic lines up.
7
+ */
8
+ export declare enum Variant {
9
+ MONOCHROME = 0,
10
+ NEUTRAL = 1,
11
+ TONAL_SPOT = 2,
12
+ VIBRANT = 3,
13
+ EXPRESSIVE = 4,
14
+ FIDELITY = 5,
15
+ CONTENT = 6,
16
+ RAINBOW = 7,
17
+ FRUIT_SALAD = 8
18
+ }
19
+ //# sourceMappingURL=variant.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"variant.d.ts","sourceRoot":"","sources":["../../../../../src/theme/color-engine/variant.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,oBAAY,OAAO;IACjB,UAAU,IAAI;IACd,OAAO,IAAI;IACX,UAAU,IAAI;IACd,OAAO,IAAI;IACX,UAAU,IAAI;IACd,QAAQ,IAAI;IACZ,OAAO,IAAI;IACX,OAAO,IAAI;IACX,WAAW,IAAI;CAChB"}
@@ -0,0 +1,18 @@
1
+ export declare class ViewingConditions {
2
+ readonly n: number;
3
+ readonly aw: number;
4
+ readonly nbb: number;
5
+ readonly ncb: number;
6
+ readonly c: number;
7
+ readonly nc: number;
8
+ readonly rgbD: [number, number, number];
9
+ readonly fl: number;
10
+ readonly fLRoot: number;
11
+ readonly z: number;
12
+ private static _default;
13
+ /** sRGB-like viewing conditions (the only ones Bloom uses). */
14
+ static get DEFAULT(): ViewingConditions;
15
+ private constructor();
16
+ static make(whitePoint?: [number, number, number], adaptingLuminance?: number, backgroundLstar?: number, surround?: number, discountingIlluminant?: boolean): ViewingConditions;
17
+ }
18
+ //# sourceMappingURL=viewing-conditions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewing-conditions.d.ts","sourceRoot":"","sources":["../../../../../src/theme/color-engine/viewing-conditions.ts"],"names":[],"mappings":"AAWA,qBAAa,iBAAiB;IAQ1B,QAAQ,CAAC,CAAC,EAAE,MAAM;IAClB,QAAQ,CAAC,EAAE,EAAE,MAAM;IACnB,QAAQ,CAAC,GAAG,EAAE,MAAM;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM;IACpB,QAAQ,CAAC,CAAC,EAAE,MAAM;IAClB,QAAQ,CAAC,EAAE,EAAE,MAAM;IACnB,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,EAAE,EAAE,MAAM;IACnB,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,CAAC,EAAE,MAAM;IAhBpB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAgC;IACvD,+DAA+D;IAC/D,MAAM,KAAK,OAAO,IAAI,iBAAiB,CAEtC;IAED,OAAO;IAaP,MAAM,CAAC,IAAI,CACT,UAAU,GAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAmB,EACtD,iBAAiB,GAAE,MAAuD,EAC1E,eAAe,SAAO,EACtB,QAAQ,SAAM,EACd,qBAAqB,UAAQ,GAC5B,iBAAiB;CAuCrB"}
@@ -1,35 +1,40 @@
1
+ import type { SchemeVariant } from './color-engine';
1
2
  export type AppColorName = 'teal' | 'blue' | 'green' | 'amber' | 'yellow' | 'red' | 'purple' | 'pink' | 'sky' | 'orange' | 'mint' | 'oxy' | 'faircoin';
2
3
  /**
3
- * Palette tokens for a single mode (light or dark) of a color preset.
4
+ * A single colour preset: a brand SEED colour plus the tonal scheme variant to
5
+ * derive its full role set with.
4
6
  *
5
- * Keys carry a leading `--` for historical reasons (shadcn-style CSS variable
6
- * names) keep in mind the values are platform-agnostic **raw HSL triples**
7
- * (e.g. `'185 100% 20%'` or `'185 100% 20% / 0.5'`), not CSS-resolved colors.
8
- * The single canonical resolver `getResolvedTokens` (in `token-registry.ts`)
9
- * converts this raw map to sRGB `rgb(...)` for every runtime write — the same
10
- * values drive BOTH layers:
11
- * - the web layer: `getResolvedTokens`'s `rgb(...)` strings are written to
12
- * `document.documentElement` / a `BloomColorScope` element, so `var(--x)` —
13
- * the form Tailwind v4 `@theme inline` compiles its color utilities to —
14
- * resolves to a valid color directly, and
15
- * - the native layer (`buildTheme` resolves the raw triples into `hsl(...)`
16
- * strings consumable by React Native styles; `native-root-vars.native.ts`
17
- * writes the same canonical `rgb(...)` values into react-native-css's
18
- * `rootVariables` family).
19
- *
20
- * The `--` prefix is an implementation detail we will drop in a future major.
7
+ * Every preset's palette is now GENERATED by Bloom's dependency-free colour
8
+ * engine (`color-engine/`) from this seed no hand-authored HSL triples. The
9
+ * engine's `generateRoleColors({ seed, variant, isDark })` yields the full
10
+ * Material-3 role set for light and dark; `getPresetVars` (in `preset-vars.ts`)
11
+ * maps those roles onto Bloom's canonical token names. A user-picked colour
12
+ * flows through the identical path — a preset is just a fixed seed.
21
13
  */
22
- export type PresetTokens = Record<string, string>;
23
14
  export interface AppColorPreset {
24
15
  name: AppColorName;
16
+ /** The brand seed colour, `#rrggbb`. Also the value the colour picker matches. */
25
17
  hex: string;
26
- light: PresetTokens;
27
- dark: PresetTokens;
18
+ /** The tonal scheme variant the engine derives roles with. */
19
+ variant: SchemeVariant;
28
20
  }
21
+ /**
22
+ * Historically each preset carried a full light/dark map of raw HSL triples.
23
+ * That map is gone — the engine derives every role from {@link AppColorPreset.hex}.
24
+ * The type alias is retained for the public `PresetTokens` export shape (the
25
+ * resolved `--token -> value` record that `getPresetVars` produces).
26
+ */
27
+ export type PresetTokens = Record<string, string>;
29
28
  export declare const APP_COLOR_NAMES: readonly AppColorName[];
30
29
  /** Premium-exclusive presets, hidden from the standard color picker. */
31
30
  export declare const PREMIUM_COLOR_NAMES: readonly AppColorName[];
32
31
  export declare const HEX_TO_APP_COLOR: Record<string, AppColorName>;
33
32
  export declare function hexToAppColorName(hex: string): AppColorName;
33
+ /**
34
+ * The 13 named presets, each a brand seed + scheme variant. The engine derives
35
+ * the full role set (light + dark) from the seed. Seeds are the brand hex of
36
+ * each preset; `oxy` reads most faithfully as `vibrant`, everything else keeps a
37
+ * bold `vibrant` derivation to match the prior saturated palette.
38
+ */
34
39
  export declare const APP_COLOR_PRESETS: Record<AppColorName, AppColorPreset>;
35
40
  //# sourceMappingURL=color-presets.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"color-presets.d.ts","sourceRoot":"","sources":["../../../../src/theme/color-presets.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,UAAU,CAAC;AAEvJ;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAElD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,YAAY,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,YAAY,CAAC;IACpB,IAAI,EAAE,YAAY,CAAC;CACpB;AAED,eAAO,MAAM,eAAe,EAAE,SAAS,YAAY,EAAsH,CAAC;AAE1K,wEAAwE;AACxE,eAAO,MAAM,mBAAmB,EAAE,SAAS,YAAY,EAAwB,CAAC;AAEhF,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAczD,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAE3D;AAED,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,YAAY,EAAE,cAAc,CAkmBlE,CAAC"}
1
+ {"version":3,"file":"color-presets.d.ts","sourceRoot":"","sources":["../../../../src/theme/color-presets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,MAAM,MAAM,YAAY,GACpB,MAAM,GACN,MAAM,GACN,OAAO,GACP,OAAO,GACP,QAAQ,GACR,KAAK,GACL,QAAQ,GACR,MAAM,GACN,KAAK,GACL,QAAQ,GACR,MAAM,GACN,KAAK,GACL,UAAU,CAAC;AAEf;;;;;;;;;;GAUG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,YAAY,CAAC;IACnB,kFAAkF;IAClF,GAAG,EAAE,MAAM,CAAC;IACZ,8DAA8D;IAC9D,OAAO,EAAE,aAAa,CAAC;CACxB;AAED;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAElD,eAAO,MAAM,eAAe,EAAE,SAAS,YAAY,EAAsH,CAAC;AAE1K,wEAAwE;AACxE,eAAO,MAAM,mBAAmB,EAAE,SAAS,YAAY,EAAwB,CAAC;AAEhF,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAczD,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAE3D;AAED;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,YAAY,EAAE,cAAc,CAclE,CAAC"}
@@ -1,16 +1,20 @@
1
1
  import { type AppColorName, type PresetTokens } from './color-presets';
2
2
  /**
3
- * Bloom's base preset tokens extended with the surface/card/chart/sidebar
4
- * tokens that apps layer on top of the core shadcn palette. Synthesized from
5
- * the preset's primary hue so every preset stays in sync automatically.
3
+ * Map a preset (seed + variant) and mode onto Bloom's canonical CSS-var token
4
+ * set, sourcing EVERY colour from the colour engine's Material-3 role output.
5
+ *
6
+ * This replaces the old hand-authored HSL triples: the engine derives a full,
7
+ * self-consistent, WCAG-legible role set from the seed for light and dark, and
8
+ * this function assigns those roles to Bloom's token names. The token NAMES are
9
+ * unchanged (see `CANONICAL_TOKENS` in `token-registry.ts`) — only the SOURCE of
10
+ * each colour moved to the engine, so every downstream consumer keeps working.
11
+ *
12
+ * Values are full `rgb(r g b)` strings straight from the engine. `getResolvedTokens`
13
+ * passes non-HSL-triple values through untouched, so these flow through the whole
14
+ * pipeline (web document writes, native `rootVariables`, JS `ThemeColors`) unchanged.
6
15
  *
7
16
  * This is the single source of truth for extended theming vars — consumer apps
8
17
  * must not redefine these per-app.
9
- *
10
- * Values are platform-agnostic **raw HSL triples** (`'185 100% 20%'`, optionally
11
- * with a `/ A` alpha tail). The single canonical resolver `getResolvedTokens`
12
- * (in `token-registry.ts`) converts these to sRGB `rgb(...)` for BOTH web and
13
- * native runtime writes — this function only produces the raw triple map.
14
18
  */
15
19
  export declare function getPresetVars(colorName: AppColorName, mode: 'light' | 'dark'): PresetTokens;
16
20
  /**
@@ -19,10 +23,10 @@ export declare function getPresetVars(colorName: AppColorName, mode: 'light' | '
19
23
  * call this only when an app needs the extended (card/chart/sidebar) tokens on
20
24
  * the document root.
21
25
  *
22
- * Tokens are resolved to sRGB `rgb(...)` via the single canonical
23
- * `getResolvedTokens` pipeline, so `var(--x)` — the form Tailwind v4
24
- * `@theme inline` compiles its color utilities to — resolves directly to a
25
- * valid color on web.
26
+ * Tokens are resolved via the single canonical `getResolvedTokens` pipeline
27
+ * (already full `rgb(...)` colours from the engine), so `var(--x)` — the form
28
+ * Tailwind v4 `@theme inline` compiles its color utilities to — resolves
29
+ * directly to a valid color on web.
26
30
  */
27
31
  export declare function applyPresetVarsToDocument(colorName: AppColorName, mode: 'light' | 'dark'): void;
28
32
  //# sourceMappingURL=preset-vars.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"preset-vars.d.ts","sourceRoot":"","sources":["../../../../src/theme/preset-vars.ts"],"names":[],"mappings":"AACA,OAAO,EAAqB,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAe1F;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,YAAY,EACvB,IAAI,EAAE,OAAO,GAAG,MAAM,GACrB,YAAY,CAiCd;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,YAAY,EACvB,IAAI,EAAE,OAAO,GAAG,MAAM,GACrB,IAAI,CAQN"}
1
+ {"version":3,"file":"preset-vars.d.ts","sourceRoot":"","sources":["../../../../src/theme/preset-vars.ts"],"names":[],"mappings":"AACA,OAAO,EAAqB,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAQ1F;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,YAAY,EACvB,IAAI,EAAE,OAAO,GAAG,MAAM,GACrB,YAAY,CAoDd;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,YAAY,EACvB,IAAI,EAAE,OAAO,GAAG,MAAM,GACrB,IAAI,CAQN"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxyhq/bloom",
3
- "version": "0.35.8",
3
+ "version": "0.37.0",
4
4
  "description": "Bloom UI — Oxy ecosystem component library for React Native + Expo + Web",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
@@ -158,6 +158,22 @@
158
158
  "default": "./lib/commonjs/fab/index.js"
159
159
  }
160
160
  },
161
+ "./frosted-icon-button": {
162
+ "react-native": "./src/frosted-icon-button/index.ts",
163
+ "browser": {
164
+ "types": "./lib/typescript/module/frosted-icon-button/index.web.d.ts",
165
+ "import": "./lib/module/frosted-icon-button/index.web.js",
166
+ "require": "./lib/commonjs/frosted-icon-button/index.web.js"
167
+ },
168
+ "import": {
169
+ "types": "./lib/typescript/module/frosted-icon-button/index.d.ts",
170
+ "default": "./lib/module/frosted-icon-button/index.js"
171
+ },
172
+ "require": {
173
+ "types": "./lib/typescript/commonjs/frosted-icon-button/index.d.ts",
174
+ "default": "./lib/commonjs/frosted-icon-button/index.js"
175
+ }
176
+ },
161
177
  "./grouped-buttons": {
162
178
  "react-native": "./src/grouped-buttons/index.ts",
163
179
  "import": {
@@ -4,6 +4,7 @@ import { render } from '@testing-library/react-native';
4
4
 
5
5
  import { BloomThemeProvider } from '../theme/BloomThemeProvider';
6
6
  import { useTheme, useThemeColor, useBloomTheme } from '../theme/use-theme';
7
+ import { buildTheme } from '../theme/build-theme';
7
8
  import type { AppColorName } from '../theme/color-presets';
8
9
 
9
10
  function ThemeDisplay() {
@@ -72,8 +73,10 @@ describe('BloomThemeProvider', () => {
72
73
  <ThemeDisplay />
73
74
  </BloomThemeProvider>,
74
75
  );
75
- // Blue preset primary is HSL(205, 87%, 53%) canonical sRGB rgb(31 153 239)
76
- expect(getByTestId('primary').props.children).toBe('rgb(31 153 239)');
76
+ // Blue preset primary is now engine-derived from the blue seed.
77
+ expect(getByTestId('primary').props.children).toBe(
78
+ buildTheme('blue', 'light').colors.primary,
79
+ );
77
80
  });
78
81
 
79
82
  it('generates different background colors for light and dark modes', () => {
@@ -135,8 +138,10 @@ describe('useThemeColor', () => {
135
138
  <ColorDisplay colorKey="primary" />
136
139
  </BloomThemeProvider>,
137
140
  );
138
- // teal preset primary HSL(185, 100%, 20%) canonical sRGB rgb(0 94 102)
139
- expect(getByTestId('color').props.children).toBe('rgb(0 94 102)');
141
+ // teal preset primary is now engine-derived from the teal seed.
142
+ expect(getByTestId('color').props.children).toBe(
143
+ buildTheme('teal', 'light').colors.primary,
144
+ );
140
145
  });
141
146
  });
142
147
 
@@ -0,0 +1,137 @@
1
+ import React from 'react';
2
+ import { Text, type ViewStyle } from 'react-native';
3
+ import { render, fireEvent } from '@testing-library/react-native';
4
+
5
+ import { BloomThemeProvider } from '../theme/BloomThemeProvider';
6
+ import { FrostedIconButton } from '../frosted-icon-button';
7
+ import { buildTheme } from '../theme/build-theme';
8
+ import { parseRgb } from '../theme/color-utils';
9
+ import { resolveFrostedPalette, resolveFrostedSize } from '../frosted-icon-button/shared';
10
+
11
+ function renderWithTheme(ui: React.ReactElement) {
12
+ return render(
13
+ <BloomThemeProvider mode="dark" colorPreset="blue">
14
+ {ui}
15
+ </BloomThemeProvider>,
16
+ );
17
+ }
18
+
19
+ function findGeometry(style: unknown): ViewStyle | undefined {
20
+ const arr = Array.isArray(style) ? style : [style];
21
+ return arr.find(
22
+ (s): s is ViewStyle => typeof s === 'object' && s !== null && 'width' in s,
23
+ );
24
+ }
25
+
26
+ /** A minimal icon element that accepts a `fill` prop (like a Bloom icon). */
27
+ function MockIcon({ fill, testID }: { fill?: string; testID?: string }) {
28
+ return React.createElement('MockIcon', { fill, testID });
29
+ }
30
+
31
+ describe('FrostedIconButton (native)', () => {
32
+ it('renders its icon content', () => {
33
+ const { getByText } = renderWithTheme(
34
+ <FrostedIconButton accessibilityLabel="Back" icon={<Text>x</Text>} />,
35
+ );
36
+ expect(getByText('x')).toBeTruthy();
37
+ });
38
+
39
+ it('calls onPress when pressed', () => {
40
+ const onPress = jest.fn();
41
+ const { getByTestId } = renderWithTheme(
42
+ <FrostedIconButton testID="btn" accessibilityLabel="Back" onPress={onPress} icon={<Text>x</Text>} />,
43
+ );
44
+ fireEvent.press(getByTestId('btn'));
45
+ expect(onPress).toHaveBeenCalledTimes(1);
46
+ });
47
+
48
+ it('marks the disabled a11y state and drops the press handler', () => {
49
+ const onPress = jest.fn();
50
+ const { getByTestId } = renderWithTheme(
51
+ <FrostedIconButton testID="btn" disabled accessibilityLabel="Back" onPress={onPress} icon={<Text>x</Text>} />,
52
+ );
53
+ const btn = getByTestId('btn');
54
+ expect(btn.props.accessibilityState).toEqual({ disabled: true, selected: false });
55
+ expect(btn.props.onPress).toBeUndefined();
56
+ });
57
+
58
+ it('reports the selected a11y state when active', () => {
59
+ const { getByTestId } = renderWithTheme(
60
+ <FrostedIconButton testID="btn" active accessibilityLabel="Mute" icon={<Text>x</Text>} />,
61
+ );
62
+ expect(getByTestId('btn').props.accessibilityState).toEqual({ disabled: false, selected: true });
63
+ });
64
+
65
+ it('injects the theme icon color as a fallback fill on a bare icon', () => {
66
+ const { getByTestId } = renderWithTheme(
67
+ <FrostedIconButton accessibilityLabel="Back" icon={<MockIcon testID="ic" />} />,
68
+ );
69
+ // Frosted (rest) icon color === foreground token.
70
+ expect(getByTestId('ic').props.fill).toMatch(/^rgb/);
71
+ });
72
+
73
+ it('never overrides an explicit fill on the icon', () => {
74
+ const { getByTestId } = renderWithTheme(
75
+ <FrostedIconButton accessibilityLabel="Back" icon={<MockIcon testID="ic" fill="rgb(1, 2, 3)" />} />,
76
+ );
77
+ expect(getByTestId('ic').props.fill).toBe('rgb(1, 2, 3)');
78
+ });
79
+
80
+ it('resolves preset sizes to concrete geometry (md=36, sm=32)', () => {
81
+ const { getByTestId, rerender } = renderWithTheme(
82
+ <FrostedIconButton testID="btn" size="md" accessibilityLabel="Back" icon={<Text>x</Text>} />,
83
+ );
84
+ expect(findGeometry(getByTestId('btn').props.style)?.width).toBe(36);
85
+ rerender(
86
+ <BloomThemeProvider mode="dark" colorPreset="blue">
87
+ <FrostedIconButton testID="btn" size="sm" accessibilityLabel="Back" icon={<Text>x</Text>} />
88
+ </BloomThemeProvider>,
89
+ );
90
+ expect(findGeometry(getByTestId('btn').props.style)?.width).toBe(32);
91
+ });
92
+
93
+ it('accepts children as an icon alias', () => {
94
+ const { getByText } = renderWithTheme(
95
+ <FrostedIconButton accessibilityLabel="Back">
96
+ <Text>★</Text>
97
+ </FrostedIconButton>,
98
+ );
99
+ expect(getByText('★')).toBeTruthy();
100
+ });
101
+ });
102
+
103
+ // Browser-independent proof of the visual contract: the frosted surface is a
104
+ // LIGHT translucent tint on a dark theme (never a dark card fill), so it reads on
105
+ // a solid dark page. Pure token math — no renderer / platform involved.
106
+ describe('FrostedIconButton palette math', () => {
107
+ it('dark surface is a light low-opacity tint that composites lighter than the page', () => {
108
+ const theme = buildTheme('blue', 'dark');
109
+ const palette = resolveFrostedPalette(theme.colors, true);
110
+
111
+ const base = parseRgb(palette.surface);
112
+ expect(base).not.toBeNull();
113
+ if (!base) throw new Error('unreachable');
114
+ // Light base (foreground), not a dark card.
115
+ expect(base.r).toBeGreaterThanOrEqual(200);
116
+
117
+ // Low opacity → composited over rgb(11,11,15) it is clearly lighter.
118
+ expect(palette.surface).toMatch(/, 0\.14\)$/);
119
+ const a = 0.14;
120
+ const page = 11;
121
+ const composite = Math.round(page * (1 - a) + base.r * a);
122
+ expect(composite - page).toBeGreaterThanOrEqual(15);
123
+ });
124
+
125
+ it('active surface is the opaque primary token (solid on-state, no alpha)', () => {
126
+ const theme = buildTheme('blue', 'dark');
127
+ const palette = resolveFrostedPalette(theme.colors, true);
128
+ expect(palette.activeSurface).toBe(theme.colors.primary);
129
+ expect(palette.activeSurface).toMatch(/^rgb\(/);
130
+ });
131
+
132
+ it('scales a numeric size to a concrete diameter + icon box', () => {
133
+ const geo = resolveFrostedSize(44);
134
+ expect(geo.diameter).toBe(44);
135
+ expect(geo.iconBox).toBe(Math.round(44 * 0.56));
136
+ });
137
+ });