@ankhorage/surface 7.0.0 → 9.0.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 (498) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +1 -1
  3. package/dist/{surfaceColor.d.ts → constants/surfaceColor.d.ts} +0 -4
  4. package/dist/constants/surfaceColor.d.ts.map +1 -0
  5. package/dist/constants/surfaceColor.js.map +1 -0
  6. package/dist/features/app-bar/adapters/inbound/AppBar.d.ts.map +1 -1
  7. package/dist/features/app-bar/adapters/inbound/AppBar.js +1 -1
  8. package/dist/features/app-bar/adapters/inbound/AppBar.js.map +1 -1
  9. package/dist/features/badge/adapters/inbound/Badge.d.ts.map +1 -1
  10. package/dist/features/badge/adapters/inbound/Badge.js +1 -1
  11. package/dist/features/badge/adapters/inbound/Badge.js.map +1 -1
  12. package/dist/features/button/adapters/inbound/Button.d.ts.map +1 -1
  13. package/dist/features/button/adapters/inbound/Button.js +6 -6
  14. package/dist/features/button/adapters/inbound/Button.js.map +1 -1
  15. package/dist/features/button/adapters/inbound/IconButton.d.ts.map +1 -1
  16. package/dist/features/button/adapters/inbound/IconButton.js +4 -4
  17. package/dist/features/button/adapters/inbound/IconButton.js.map +1 -1
  18. package/dist/features/card/adapters/inbound/Card.d.ts.map +1 -1
  19. package/dist/features/card/adapters/inbound/Card.js +4 -4
  20. package/dist/features/card/adapters/inbound/Card.js.map +1 -1
  21. package/dist/features/font/adapters/inbound/FontProvider.d.ts +4 -0
  22. package/dist/features/font/adapters/inbound/FontProvider.d.ts.map +1 -0
  23. package/dist/features/font/adapters/inbound/FontProvider.js +16 -0
  24. package/dist/features/font/adapters/inbound/FontProvider.js.map +1 -0
  25. package/dist/features/font/adapters/inbound/FontRuntimeContext.d.ts +4 -0
  26. package/dist/features/font/adapters/inbound/FontRuntimeContext.d.ts.map +1 -0
  27. package/dist/features/font/adapters/inbound/FontRuntimeContext.js +9 -0
  28. package/dist/features/font/adapters/inbound/FontRuntimeContext.js.map +1 -0
  29. package/dist/features/font/adapters/inbound/useFontRuntime.d.ts +4 -0
  30. package/dist/features/font/adapters/inbound/useFontRuntime.d.ts.map +1 -0
  31. package/dist/features/font/adapters/inbound/useFontRuntime.js +7 -0
  32. package/dist/features/font/adapters/inbound/useFontRuntime.js.map +1 -0
  33. package/dist/features/font/public.d.ts +3 -0
  34. package/dist/features/font/public.d.ts.map +1 -0
  35. package/dist/features/font/public.js +2 -0
  36. package/dist/features/font/public.js.map +1 -0
  37. package/dist/features/form/checkbox/adapters/inbound/Checkbox.d.ts.map +1 -1
  38. package/dist/features/form/checkbox/adapters/inbound/Checkbox.js +4 -4
  39. package/dist/features/form/checkbox/adapters/inbound/Checkbox.js.map +1 -1
  40. package/dist/features/form/radio/adapters/inbound/Radio.d.ts.map +1 -1
  41. package/dist/features/form/radio/adapters/inbound/Radio.js +4 -4
  42. package/dist/features/form/radio/adapters/inbound/Radio.js.map +1 -1
  43. package/dist/features/form/switch/adapters/inbound/Switch.d.ts.map +1 -1
  44. package/dist/features/form/switch/adapters/inbound/Switch.js +4 -4
  45. package/dist/features/form/switch/adapters/inbound/Switch.js.map +1 -1
  46. package/dist/features/form/text-input/adapters/inbound/TextInput.d.ts.map +1 -1
  47. package/dist/features/form/text-input/adapters/inbound/TextInput.js +1 -1
  48. package/dist/features/form/text-input/adapters/inbound/TextInput.js.map +1 -1
  49. package/dist/features/form/text-input/utils/resolveTextInputPresentation.d.ts +1 -1
  50. package/dist/features/form/text-input/utils/resolveTextInputPresentation.d.ts.map +1 -1
  51. package/dist/features/form/text-input/utils/resolveTextInputPresentation.js.map +1 -1
  52. package/dist/features/icon/adapters/inbound/Icon.d.ts.map +1 -1
  53. package/dist/features/icon/adapters/inbound/Icon.js +2 -2
  54. package/dist/features/icon/adapters/inbound/Icon.js.map +1 -1
  55. package/dist/features/image/adapters/inbound/Image.d.ts.map +1 -1
  56. package/dist/features/image/adapters/inbound/Image.js +1 -1
  57. package/dist/features/image/adapters/inbound/Image.js.map +1 -1
  58. package/dist/features/image/utils/resolveImageStyle.d.ts +1 -1
  59. package/dist/features/image/utils/resolveImageStyle.d.ts.map +1 -1
  60. package/dist/features/image/utils/resolveImageStyle.js +1 -1
  61. package/dist/features/image/utils/resolveImageStyle.js.map +1 -1
  62. package/dist/features/layout/adapters/inbound/Grid.d.ts.map +1 -1
  63. package/dist/features/layout/adapters/inbound/Grid.js +1 -1
  64. package/dist/features/layout/adapters/inbound/Grid.js.map +1 -1
  65. package/dist/features/layout/adapters/inbound/ScrollView.d.ts.map +1 -1
  66. package/dist/features/layout/adapters/inbound/ScrollView.js +1 -1
  67. package/dist/features/layout/adapters/inbound/ScrollView.js.map +1 -1
  68. package/dist/features/layout/adapters/inbound/View.d.ts.map +1 -1
  69. package/dist/features/layout/adapters/inbound/View.js +1 -1
  70. package/dist/features/layout/adapters/inbound/View.js.map +1 -1
  71. package/dist/features/list/adapters/inbound/ListItem.d.ts.map +1 -1
  72. package/dist/features/list/adapters/inbound/ListItem.js +4 -4
  73. package/dist/features/list/adapters/inbound/ListItem.js.map +1 -1
  74. package/dist/features/modal/adapters/inbound/Modal.d.ts.map +1 -1
  75. package/dist/features/modal/adapters/inbound/Modal.js +1 -1
  76. package/dist/features/modal/adapters/inbound/Modal.js.map +1 -1
  77. package/dist/features/popover-menu/adapters/inbound/PopoverMenu.d.ts.map +1 -1
  78. package/dist/features/popover-menu/adapters/inbound/PopoverMenu.js +1 -1
  79. package/dist/features/popover-menu/adapters/inbound/PopoverMenu.js.map +1 -1
  80. package/dist/features/pressable/adapters/inbound/Pressable.d.ts +5 -0
  81. package/dist/features/pressable/adapters/inbound/Pressable.d.ts.map +1 -0
  82. package/dist/features/pressable/adapters/inbound/Pressable.js +48 -0
  83. package/dist/features/pressable/adapters/inbound/Pressable.js.map +1 -0
  84. package/dist/features/pressable/public.d.ts +3 -0
  85. package/dist/features/pressable/public.d.ts.map +1 -0
  86. package/dist/features/pressable/public.js +2 -0
  87. package/dist/features/pressable/public.js.map +1 -0
  88. package/dist/features/surface/adapters/inbound/Surface.d.ts.map +1 -1
  89. package/dist/features/surface/adapters/inbound/Surface.js +1 -1
  90. package/dist/features/surface/adapters/inbound/Surface.js.map +1 -1
  91. package/dist/features/tabs/adapters/inbound/Tab.d.ts.map +1 -1
  92. package/dist/features/tabs/adapters/inbound/Tab.js +1 -1
  93. package/dist/features/tabs/adapters/inbound/Tab.js.map +1 -1
  94. package/dist/features/theme/adapters/inbound/ThemeProvider.d.ts +4 -0
  95. package/dist/features/theme/adapters/inbound/ThemeProvider.d.ts.map +1 -0
  96. package/dist/features/theme/adapters/inbound/ThemeProvider.js +27 -0
  97. package/dist/features/theme/adapters/inbound/ThemeProvider.js.map +1 -0
  98. package/dist/features/theme/adapters/inbound/ThemeRuntimeContext.d.ts +4 -0
  99. package/dist/features/theme/adapters/inbound/ThemeRuntimeContext.d.ts.map +1 -0
  100. package/dist/features/theme/adapters/inbound/ThemeRuntimeContext.js +11 -0
  101. package/dist/features/theme/adapters/inbound/ThemeRuntimeContext.js.map +1 -0
  102. package/dist/features/theme/adapters/inbound/ThemeScope.d.ts +4 -0
  103. package/dist/features/theme/adapters/inbound/ThemeScope.d.ts.map +1 -0
  104. package/dist/features/theme/adapters/inbound/ThemeScope.js +17 -0
  105. package/dist/features/theme/adapters/inbound/ThemeScope.js.map +1 -0
  106. package/dist/features/theme/adapters/inbound/useTheme.d.ts +4 -0
  107. package/dist/features/theme/adapters/inbound/useTheme.d.ts.map +1 -0
  108. package/dist/features/theme/adapters/inbound/useTheme.js +7 -0
  109. package/dist/features/theme/adapters/inbound/useTheme.js.map +1 -0
  110. package/dist/features/theme/application/use-cases/createTheme.d.ts +5 -0
  111. package/dist/features/theme/application/use-cases/createTheme.d.ts.map +1 -0
  112. package/dist/features/theme/application/use-cases/createTheme.js +56 -0
  113. package/dist/features/theme/application/use-cases/createTheme.js.map +1 -0
  114. package/dist/features/theme/constants.d.ts +10 -0
  115. package/dist/features/theme/constants.d.ts.map +1 -0
  116. package/dist/{theme/defaultTokens.js → features/theme/constants.js} +9 -2
  117. package/dist/features/theme/constants.js.map +1 -0
  118. package/dist/{theme → features/theme/domain}/createSurfaceColorDiagnosticCollector.d.ts +1 -1
  119. package/dist/features/theme/domain/createSurfaceColorDiagnosticCollector.d.ts.map +1 -0
  120. package/dist/features/theme/domain/createSurfaceColorDiagnosticCollector.js.map +1 -0
  121. package/dist/{theme → features/theme/domain}/createSurfaceSemanticPolicy.d.ts +1 -1
  122. package/dist/features/theme/domain/createSurfaceSemanticPolicy.d.ts.map +1 -0
  123. package/dist/{theme → features/theme/domain}/createSurfaceSemanticPolicy.js +1 -1
  124. package/dist/features/theme/domain/createSurfaceSemanticPolicy.js.map +1 -0
  125. package/dist/features/theme/domain/generatePalette.d.ts +10 -0
  126. package/dist/features/theme/domain/generatePalette.d.ts.map +1 -0
  127. package/dist/{theme/colorEngine.js → features/theme/domain/generatePalette.js} +2 -10
  128. package/dist/features/theme/domain/generatePalette.js.map +1 -0
  129. package/dist/{theme → features/theme/domain}/resolveRoleSemantics.d.ts +1 -1
  130. package/dist/features/theme/domain/resolveRoleSemantics.d.ts.map +1 -0
  131. package/dist/{theme → features/theme/domain}/resolveRoleSemantics.js +1 -1
  132. package/dist/features/theme/domain/resolveRoleSemantics.js.map +1 -0
  133. package/dist/features/theme/domain/resolveSemanticColors.d.ts +4 -0
  134. package/dist/features/theme/domain/resolveSemanticColors.d.ts.map +1 -0
  135. package/dist/features/theme/domain/resolveSemanticColors.js +10 -0
  136. package/dist/features/theme/domain/resolveSemanticColors.js.map +1 -0
  137. package/dist/{theme → features/theme/domain}/resolveSurfaceSemanticModel.d.ts +1 -1
  138. package/dist/features/theme/domain/resolveSurfaceSemanticModel.d.ts.map +1 -0
  139. package/dist/features/theme/domain/resolveSurfaceSemanticModel.js.map +1 -0
  140. package/dist/features/theme/public.d.ts +3 -0
  141. package/dist/features/theme/public.d.ts.map +1 -0
  142. package/dist/features/theme/public.js +2 -0
  143. package/dist/features/theme/public.js.map +1 -0
  144. package/dist/features/theme/runtime.d.ts +5 -0
  145. package/dist/features/theme/runtime.d.ts.map +1 -0
  146. package/dist/features/theme/runtime.js +4 -0
  147. package/dist/features/theme/runtime.js.map +1 -0
  148. package/dist/{theme → features/theme/utils}/resolveGlobalTokens.d.ts +1 -1
  149. package/dist/features/theme/utils/resolveGlobalTokens.d.ts.map +1 -0
  150. package/dist/{theme → features/theme/utils}/resolveGlobalTokens.js +1 -1
  151. package/dist/features/theme/utils/resolveGlobalTokens.js.map +1 -0
  152. package/dist/{theme → features/theme/utils}/resolveHeadingTokenOverrides.d.ts +1 -1
  153. package/dist/features/theme/utils/resolveHeadingTokenOverrides.d.ts.map +1 -0
  154. package/dist/features/theme/utils/resolveHeadingTokenOverrides.js.map +1 -0
  155. package/dist/features/theme/utils/resolveNumericTokenOverrides.d.ts.map +1 -0
  156. package/dist/features/theme/utils/resolveNumericTokenOverrides.js.map +1 -0
  157. package/dist/{theme → features/theme/utils}/resolveToken.d.ts +2 -8
  158. package/dist/features/theme/utils/resolveToken.d.ts.map +1 -0
  159. package/dist/features/theme/utils/resolveToken.js +10 -0
  160. package/dist/features/theme/utils/resolveToken.js.map +1 -0
  161. package/dist/{theme → features/theme/utils}/resolveWeightTokenOverrides.d.ts +1 -1
  162. package/dist/features/theme/utils/resolveWeightTokenOverrides.d.ts.map +1 -0
  163. package/dist/{theme → features/theme/utils}/resolveWeightTokenOverrides.js +3 -5
  164. package/dist/features/theme/utils/resolveWeightTokenOverrides.js.map +1 -0
  165. package/dist/features/toast/adapters/inbound/Toast.d.ts.map +1 -1
  166. package/dist/features/toast/adapters/inbound/Toast.js +1 -1
  167. package/dist/features/toast/adapters/inbound/Toast.js.map +1 -1
  168. package/dist/features/tooltip/adapters/inbound/Tooltip.d.ts.map +1 -1
  169. package/dist/features/tooltip/adapters/inbound/Tooltip.js +1 -1
  170. package/dist/features/tooltip/adapters/inbound/Tooltip.js.map +1 -1
  171. package/dist/features/typography/adapters/inbound/Heading.d.ts +2 -2
  172. package/dist/features/typography/adapters/inbound/Heading.d.ts.map +1 -1
  173. package/dist/features/typography/adapters/inbound/Heading.js +4 -20
  174. package/dist/features/typography/adapters/inbound/Heading.js.map +1 -1
  175. package/dist/features/typography/adapters/inbound/Text.d.ts +1 -1
  176. package/dist/features/typography/adapters/inbound/Text.d.ts.map +1 -1
  177. package/dist/features/typography/adapters/inbound/Text.js +3 -20
  178. package/dist/features/typography/adapters/inbound/Text.js.map +1 -1
  179. package/dist/features/typography/utils/resolveHeadingTextStyle.d.ts +2 -2
  180. package/dist/features/typography/utils/resolveHeadingTextStyle.d.ts.map +1 -1
  181. package/dist/features/typography/utils/resolveHeadingTextStyle.js.map +1 -1
  182. package/dist/index.d.ts +11 -12
  183. package/dist/index.d.ts.map +1 -1
  184. package/dist/index.js +5 -7
  185. package/dist/index.js.map +1 -1
  186. package/dist/internal/resolvers/resolveControlSize.d.ts +1 -1
  187. package/dist/internal/resolvers/resolveControlSize.js.map +1 -1
  188. package/dist/internal/resolvers/resolveFieldPresentation.d.ts +1 -1
  189. package/dist/internal/resolvers/resolveFieldPresentation.d.ts.map +1 -1
  190. package/dist/internal/resolvers/resolveFieldPresentation.js.map +1 -1
  191. package/dist/internal/resolvers/resolveIconSize.d.ts +1 -1
  192. package/dist/internal/resolvers/resolveIconSize.js.map +1 -1
  193. package/dist/internal/resolvers/resolveInteractiveColors.d.ts +2 -2
  194. package/dist/internal/resolvers/resolveInteractiveColors.d.ts.map +1 -1
  195. package/dist/internal/resolvers/resolveInteractiveColors.js.map +1 -1
  196. package/dist/internal/resolvers/resolveSelectionControlColors.d.ts +2 -2
  197. package/dist/internal/resolvers/resolveSelectionControlColors.d.ts.map +1 -1
  198. package/dist/internal/resolvers/resolveSelectionControlColors.js.map +1 -1
  199. package/dist/internal/resolvers/resolveSurfaceColor.d.ts +2 -2
  200. package/dist/internal/resolvers/resolveSurfaceColor.d.ts.map +1 -1
  201. package/dist/internal/resolvers/resolveSurfaceColor.js.map +1 -1
  202. package/dist/internal/resolvers/resolveTextColor.d.ts +2 -2
  203. package/dist/internal/resolvers/resolveTextColor.d.ts.map +1 -1
  204. package/dist/internal/resolvers/resolveTextColor.js.map +1 -1
  205. package/dist/internal/resolvers/resolveTextStyles.d.ts +1 -1
  206. package/dist/internal/resolvers/resolveTextStyles.js.map +1 -1
  207. package/dist/types/accordion.d.ts +1 -1
  208. package/dist/types/accordion.d.ts.map +1 -1
  209. package/dist/types/accordion.js.map +1 -1
  210. package/dist/types/badge.d.ts +1 -1
  211. package/dist/types/badge.d.ts.map +1 -1
  212. package/dist/types/badge.js.map +1 -1
  213. package/dist/types/button.d.ts +4 -4
  214. package/dist/types/button.d.ts.map +1 -1
  215. package/dist/types/button.js.map +1 -1
  216. package/dist/types/checkbox.d.ts +3 -3
  217. package/dist/types/checkbox.d.ts.map +1 -1
  218. package/dist/types/checkbox.js.map +1 -1
  219. package/dist/types/font.d.ts +13 -0
  220. package/dist/types/font.d.ts.map +1 -0
  221. package/dist/types/font.js +2 -0
  222. package/dist/types/font.js.map +1 -0
  223. package/dist/types/icon.d.ts +1 -1
  224. package/dist/types/icon.d.ts.map +1 -1
  225. package/dist/types/icon.js.map +1 -1
  226. package/dist/types/image.d.ts +1 -1
  227. package/dist/types/image.d.ts.map +1 -1
  228. package/dist/types/image.js.map +1 -1
  229. package/dist/types/interactionPolicy.d.ts.map +1 -0
  230. package/dist/types/interactionPolicy.js.map +1 -0
  231. package/dist/types/layout.d.ts +1 -1
  232. package/dist/types/layout.d.ts.map +1 -1
  233. package/dist/types/layout.js.map +1 -1
  234. package/dist/types/list.d.ts +1 -1
  235. package/dist/types/list.d.ts.map +1 -1
  236. package/dist/types/list.js.map +1 -1
  237. package/dist/types/modal.d.ts +1 -1
  238. package/dist/types/modal.d.ts.map +1 -1
  239. package/dist/types/modal.js.map +1 -1
  240. package/dist/types/popover.d.ts +1 -1
  241. package/dist/types/popover.d.ts.map +1 -1
  242. package/dist/types/popover.js.map +1 -1
  243. package/dist/types/popoverMenu.d.ts +1 -1
  244. package/dist/types/popoverMenu.d.ts.map +1 -1
  245. package/dist/types/popoverMenu.js.map +1 -1
  246. package/dist/{primitives/button-base/types.d.ts → types/pressable.d.ts} +5 -5
  247. package/dist/types/pressable.d.ts.map +1 -0
  248. package/dist/types/pressable.js +2 -0
  249. package/dist/types/pressable.js.map +1 -0
  250. package/dist/types/radio.d.ts +3 -3
  251. package/dist/types/radio.d.ts.map +1 -1
  252. package/dist/types/radio.js.map +1 -1
  253. package/dist/types/surfaceColor.d.ts +6 -0
  254. package/dist/types/surfaceColor.d.ts.map +1 -0
  255. package/dist/types/surfaceColor.js +2 -0
  256. package/dist/types/surfaceColor.js.map +1 -0
  257. package/dist/types/switch.d.ts +3 -3
  258. package/dist/types/switch.d.ts.map +1 -1
  259. package/dist/types/switch.js.map +1 -1
  260. package/dist/types/tabs.d.ts +1 -1
  261. package/dist/types/tabs.d.ts.map +1 -1
  262. package/dist/types/tabs.js.map +1 -1
  263. package/dist/types/text-input.d.ts +1 -1
  264. package/dist/types/text-input.d.ts.map +1 -1
  265. package/dist/types/text-input.js.map +1 -1
  266. package/dist/{theme/types.d.ts → types/theme.d.ts} +19 -3
  267. package/dist/types/theme.d.ts.map +1 -0
  268. package/dist/types/theme.js +2 -0
  269. package/dist/types/theme.js.map +1 -0
  270. package/dist/types/toast.d.ts +2 -2
  271. package/dist/types/toast.d.ts.map +1 -1
  272. package/dist/types/toast.js.map +1 -1
  273. package/dist/types/tooltip.d.ts +1 -1
  274. package/dist/types/tooltip.d.ts.map +1 -1
  275. package/dist/types/tooltip.js.map +1 -1
  276. package/dist/types/typography.d.ts +1 -1
  277. package/dist/types/typography.d.ts.map +1 -1
  278. package/dist/types/typography.js.map +1 -1
  279. package/dist/utils/resolveSpacing.d.ts +1 -1
  280. package/dist/utils/resolveSpacing.d.ts.map +1 -1
  281. package/dist/utils/resolveSpacing.js +1 -1
  282. package/dist/utils/resolveSpacing.js.map +1 -1
  283. package/dist/utils/resolveViewStyles.d.ts +1 -1
  284. package/dist/utils/resolveViewStyles.d.ts.map +1 -1
  285. package/dist/utils/resolveViewStyles.js +1 -1
  286. package/dist/utils/resolveViewStyles.js.map +1 -1
  287. package/package.json +8 -7
  288. package/src/constants/surfaceColor.test.ts +18 -0
  289. package/src/{surfaceColor.ts → constants/surfaceColor.ts} +0 -5
  290. package/src/features/app-bar/adapters/inbound/AppBar.tsx +1 -1
  291. package/src/features/badge/adapters/inbound/Badge.tsx +1 -1
  292. package/src/features/button/adapters/inbound/Button.tsx +8 -8
  293. package/src/features/button/adapters/inbound/IconButton.tsx +4 -4
  294. package/src/features/card/adapters/inbound/Card.tsx +4 -4
  295. package/src/features/font/adapters/inbound/FontProvider.tsx +27 -0
  296. package/src/features/font/adapters/inbound/FontRuntimeContext.tsx +12 -0
  297. package/src/features/font/adapters/inbound/useFontRuntime.ts +9 -0
  298. package/src/features/font/public.ts +2 -0
  299. package/src/features/form/checkbox/adapters/inbound/Checkbox.tsx +7 -7
  300. package/src/features/form/radio/adapters/inbound/Radio.tsx +7 -7
  301. package/src/features/form/switch/adapters/inbound/Switch.tsx +4 -4
  302. package/src/features/form/text-input/adapters/inbound/TextInput.tsx +1 -1
  303. package/src/features/form/text-input/utils/resolveTextInputPresentation.ts +1 -1
  304. package/src/features/icon/adapters/inbound/Icon.tsx +2 -2
  305. package/src/features/image/adapters/inbound/Image.tsx +1 -1
  306. package/src/features/image/utils/resolveImageProps.test.ts +1 -1
  307. package/src/features/image/utils/resolveImageStyle.ts +2 -2
  308. package/src/features/layout/adapters/inbound/Grid.tsx +1 -1
  309. package/src/features/layout/adapters/inbound/ScrollView.tsx +1 -1
  310. package/src/features/layout/adapters/inbound/View.tsx +1 -1
  311. package/src/features/list/adapters/inbound/ListItem.tsx +5 -5
  312. package/src/features/modal/adapters/inbound/Modal.tsx +1 -1
  313. package/src/features/popover-menu/adapters/inbound/PopoverMenu.tsx +1 -1
  314. package/src/{primitives/button-base/ButtonBase.tsx → features/pressable/adapters/inbound/Pressable.tsx} +45 -31
  315. package/src/features/pressable/public.ts +2 -0
  316. package/src/features/surface/adapters/inbound/Surface.tsx +1 -1
  317. package/src/features/tabs/adapters/inbound/Tab.tsx +1 -1
  318. package/src/features/theme/adapters/inbound/ThemeProvider.tsx +46 -0
  319. package/src/features/theme/adapters/inbound/ThemeRuntimeContext.tsx +14 -0
  320. package/src/features/theme/adapters/inbound/ThemeScope.test.tsx +52 -0
  321. package/src/features/theme/adapters/inbound/ThemeScope.tsx +29 -0
  322. package/src/features/theme/adapters/inbound/useTheme.ts +9 -0
  323. package/src/features/theme/application/use-cases/createTheme.ts +71 -0
  324. package/src/{theme → features/theme/application/use-cases}/createThemeOverrides.test.ts +8 -9
  325. package/src/{theme → features/theme/application/use-cases}/createThemeValidation.test.ts +4 -2
  326. package/src/features/theme/constants.ts +68 -0
  327. package/src/{theme → features/theme/domain}/createSurfaceColorDiagnosticCollector.ts +4 -1
  328. package/src/{theme → features/theme/domain}/createSurfaceSemanticPolicy.ts +2 -2
  329. package/src/features/theme/domain/generatePalette.test.ts +294 -0
  330. package/src/{theme/colorEngine.ts → features/theme/domain/generatePalette.ts} +3 -30
  331. package/src/{theme → features/theme/domain}/inverseSemantics.test.ts +1 -1
  332. package/src/{theme → features/theme/domain}/resolveRoleSemantics.ts +2 -2
  333. package/src/features/theme/domain/resolveSemanticColors.ts +23 -0
  334. package/src/{theme → features/theme/domain}/resolveSurfaceSemanticModel.ts +4 -4
  335. package/src/{theme → features/theme}/public.test.ts +1 -1
  336. package/src/features/theme/public.ts +18 -0
  337. package/src/features/theme/runtime.test.ts +13 -0
  338. package/src/features/theme/runtime.ts +4 -0
  339. package/src/{theme → features/theme/utils}/resolveGlobalTokens.ts +2 -2
  340. package/src/{theme → features/theme/utils}/resolveHeadingTokenOverrides.ts +1 -1
  341. package/src/features/theme/utils/resolveToken.ts +16 -0
  342. package/src/{theme → features/theme/utils}/resolveWeightTokenOverrides.ts +12 -12
  343. package/src/features/toast/adapters/inbound/Toast.tsx +3 -3
  344. package/src/features/tooltip/adapters/inbound/Tooltip.tsx +1 -1
  345. package/src/features/typography/adapters/inbound/Heading.tsx +3 -30
  346. package/src/features/typography/adapters/inbound/Text.tsx +3 -23
  347. package/src/features/typography/utils/resolveHeadingTextStyle.test.ts +1 -1
  348. package/src/features/typography/utils/resolveHeadingTextStyle.ts +2 -2
  349. package/src/index.test.ts +13 -9
  350. package/src/index.ts +32 -17
  351. package/src/internal/resolvers/resolveControlSize.test.ts +1 -1
  352. package/src/internal/resolvers/resolveControlSize.ts +1 -1
  353. package/src/internal/resolvers/resolveFieldPresentation.ts +1 -1
  354. package/src/internal/resolvers/resolveIconSize.ts +1 -1
  355. package/src/internal/resolvers/resolveInteractiveColors.test.ts +1 -1
  356. package/src/internal/resolvers/resolveInteractiveColors.ts +2 -2
  357. package/src/internal/resolvers/resolveSelectionControlColors.test.ts +1 -1
  358. package/src/internal/resolvers/resolveSelectionControlColors.ts +2 -2
  359. package/src/internal/resolvers/resolveSurfaceColor.test.ts +1 -1
  360. package/src/internal/resolvers/resolveSurfaceColor.ts +2 -2
  361. package/src/internal/resolvers/resolveTextColor.test.ts +1 -1
  362. package/src/internal/resolvers/resolveTextColor.ts +2 -2
  363. package/src/internal/resolvers/resolveTextStyles.test.ts +1 -1
  364. package/src/internal/resolvers/resolveTextStyles.ts +1 -1
  365. package/src/structureOwnership.test.ts +16 -0
  366. package/src/types/accordion.ts +1 -1
  367. package/src/types/badge.ts +1 -1
  368. package/src/types/button.ts +4 -4
  369. package/src/types/checkbox.ts +3 -3
  370. package/src/types/font.ts +14 -0
  371. package/src/types/icon.ts +1 -1
  372. package/src/types/image.ts +1 -1
  373. package/src/types/interactionPolicy.test.ts +30 -0
  374. package/src/types/layout.ts +1 -1
  375. package/src/types/list.ts +1 -1
  376. package/src/types/modal.ts +1 -1
  377. package/src/types/popover.ts +1 -1
  378. package/src/types/popoverMenu.ts +1 -1
  379. package/src/{primitives/button-base/types.ts → types/pressable.ts} +4 -4
  380. package/src/types/radio.ts +3 -3
  381. package/src/types/surfaceColor.test.ts +18 -0
  382. package/src/types/surfaceColor.ts +11 -0
  383. package/src/types/switch.ts +3 -3
  384. package/src/types/tabs.ts +1 -1
  385. package/src/types/text-input.ts +1 -1
  386. package/src/{theme/types.ts → types/theme.ts} +22 -13
  387. package/src/types/toast.ts +2 -2
  388. package/src/types/tooltip.ts +1 -1
  389. package/src/types/typography.ts +1 -1
  390. package/src/utils/resolveSpacing.ts +2 -2
  391. package/src/utils/resolveViewStyles.test.ts +1 -1
  392. package/src/utils/resolveViewStyles.ts +2 -2
  393. package/src/webAcceptance.test.tsx +1 -1
  394. package/dist/context/FontContext.d.ts +0 -20
  395. package/dist/context/FontContext.d.ts.map +0 -1
  396. package/dist/context/FontContext.js +0 -27
  397. package/dist/context/FontContext.js.map +0 -1
  398. package/dist/context/TranslationContext.d.ts +0 -22
  399. package/dist/context/TranslationContext.d.ts.map +0 -1
  400. package/dist/context/TranslationContext.js +0 -25
  401. package/dist/context/TranslationContext.js.map +0 -1
  402. package/dist/interactionPolicy.d.ts.map +0 -1
  403. package/dist/interactionPolicy.js.map +0 -1
  404. package/dist/primitives/button-base/ButtonBase.d.ts +0 -5
  405. package/dist/primitives/button-base/ButtonBase.d.ts.map +0 -1
  406. package/dist/primitives/button-base/ButtonBase.js +0 -42
  407. package/dist/primitives/button-base/ButtonBase.js.map +0 -1
  408. package/dist/primitives/button-base/index.d.ts +0 -3
  409. package/dist/primitives/button-base/index.d.ts.map +0 -1
  410. package/dist/primitives/button-base/index.js +0 -2
  411. package/dist/primitives/button-base/index.js.map +0 -1
  412. package/dist/primitives/button-base/types.d.ts.map +0 -1
  413. package/dist/primitives/button-base/types.js +0 -2
  414. package/dist/primitives/button-base/types.js.map +0 -1
  415. package/dist/surfaceColor.d.ts.map +0 -1
  416. package/dist/surfaceColor.js.map +0 -1
  417. package/dist/theme/ThemeContext.d.ts +0 -27
  418. package/dist/theme/ThemeContext.d.ts.map +0 -1
  419. package/dist/theme/ThemeContext.js +0 -59
  420. package/dist/theme/ThemeContext.js.map +0 -1
  421. package/dist/theme/colorEngine.d.ts +0 -16
  422. package/dist/theme/colorEngine.d.ts.map +0 -1
  423. package/dist/theme/colorEngine.js.map +0 -1
  424. package/dist/theme/createSurfaceColorDiagnosticCollector.d.ts.map +0 -1
  425. package/dist/theme/createSurfaceColorDiagnosticCollector.js.map +0 -1
  426. package/dist/theme/createSurfaceSemanticPolicy.d.ts.map +0 -1
  427. package/dist/theme/createSurfaceSemanticPolicy.js.map +0 -1
  428. package/dist/theme/createTheme.d.ts +0 -5
  429. package/dist/theme/createTheme.d.ts.map +0 -1
  430. package/dist/theme/createTheme.js +0 -49
  431. package/dist/theme/createTheme.js.map +0 -1
  432. package/dist/theme/defaultTokens.d.ts +0 -3
  433. package/dist/theme/defaultTokens.d.ts.map +0 -1
  434. package/dist/theme/defaultTokens.js.map +0 -1
  435. package/dist/theme/index.d.ts +0 -3
  436. package/dist/theme/index.d.ts.map +0 -1
  437. package/dist/theme/index.js +0 -3
  438. package/dist/theme/index.js.map +0 -1
  439. package/dist/theme/public.d.ts +0 -5
  440. package/dist/theme/public.d.ts.map +0 -1
  441. package/dist/theme/public.js +0 -5
  442. package/dist/theme/public.js.map +0 -1
  443. package/dist/theme/resolveGlobalTokens.d.ts.map +0 -1
  444. package/dist/theme/resolveGlobalTokens.js.map +0 -1
  445. package/dist/theme/resolveHeadingTokenOverrides.d.ts.map +0 -1
  446. package/dist/theme/resolveHeadingTokenOverrides.js.map +0 -1
  447. package/dist/theme/resolveNumericTokenOverrides.d.ts.map +0 -1
  448. package/dist/theme/resolveNumericTokenOverrides.js.map +0 -1
  449. package/dist/theme/resolveRoleSemantics.d.ts.map +0 -1
  450. package/dist/theme/resolveRoleSemantics.js.map +0 -1
  451. package/dist/theme/resolveSurfaceSemanticModel.d.ts.map +0 -1
  452. package/dist/theme/resolveSurfaceSemanticModel.js.map +0 -1
  453. package/dist/theme/resolveToken.d.ts.map +0 -1
  454. package/dist/theme/resolveToken.js +0 -19
  455. package/dist/theme/resolveToken.js.map +0 -1
  456. package/dist/theme/resolveWeightTokenOverrides.d.ts.map +0 -1
  457. package/dist/theme/resolveWeightTokenOverrides.js.map +0 -1
  458. package/dist/theme/surfaceColorPolicy.d.ts +0 -8
  459. package/dist/theme/surfaceColorPolicy.d.ts.map +0 -1
  460. package/dist/theme/surfaceColorPolicy.js +0 -8
  461. package/dist/theme/surfaceColorPolicy.js.map +0 -1
  462. package/dist/theme/types.d.ts.map +0 -1
  463. package/dist/theme/types.js +0 -2
  464. package/dist/theme/types.js.map +0 -1
  465. package/dist/utils/deepEqual.d.ts +0 -6
  466. package/dist/utils/deepEqual.d.ts.map +0 -1
  467. package/dist/utils/deepEqual.js +0 -36
  468. package/dist/utils/deepEqual.js.map +0 -1
  469. package/dist/utils/deepMerge.d.ts +0 -6
  470. package/dist/utils/deepMerge.d.ts.map +0 -1
  471. package/dist/utils/deepMerge.js +0 -26
  472. package/dist/utils/deepMerge.js.map +0 -1
  473. package/src/context/FontContext.tsx +0 -59
  474. package/src/context/TranslationContext.tsx +0 -50
  475. package/src/interactionPolicy.test.ts +0 -86
  476. package/src/primitives/button-base/index.ts +0 -2
  477. package/src/surfaceColor.test.ts +0 -44
  478. package/src/theme/ThemeContext.tsx +0 -94
  479. package/src/theme/colorEngine.test.ts +0 -302
  480. package/src/theme/createTheme.ts +0 -60
  481. package/src/theme/defaultTokens.ts +0 -61
  482. package/src/theme/index.ts +0 -2
  483. package/src/theme/public.ts +0 -4
  484. package/src/theme/resolveToken.ts +0 -32
  485. package/src/theme/surfaceColorPolicy.ts +0 -7
  486. package/src/utils/deepEqual.ts +0 -34
  487. package/src/utils/deepMerge.test.ts +0 -113
  488. package/src/utils/deepMerge.ts +0 -29
  489. /package/dist/{surfaceColor.js → constants/surfaceColor.js} +0 -0
  490. /package/dist/{theme → features/theme/domain}/createSurfaceColorDiagnosticCollector.js +0 -0
  491. /package/dist/{theme → features/theme/domain}/resolveSurfaceSemanticModel.js +0 -0
  492. /package/dist/{theme → features/theme/utils}/resolveHeadingTokenOverrides.js +0 -0
  493. /package/dist/{theme → features/theme/utils}/resolveNumericTokenOverrides.d.ts +0 -0
  494. /package/dist/{theme → features/theme/utils}/resolveNumericTokenOverrides.js +0 -0
  495. /package/dist/{interactionPolicy.d.ts → types/interactionPolicy.d.ts} +0 -0
  496. /package/dist/{interactionPolicy.js → types/interactionPolicy.js} +0 -0
  497. /package/src/{theme → features/theme/utils}/resolveNumericTokenOverrides.ts +0 -0
  498. /package/src/{interactionPolicy.ts → types/interactionPolicy.ts} +0 -0
@@ -0,0 +1,294 @@
1
+ import type { SemanticColorToken } from '@ankhorage/color-theory';
2
+ import {
3
+ COLOR_HARMONIES,
4
+ DARK_SEMANTIC_COLOR_REFERENCES,
5
+ DEFAULT_SEMANTIC_STATUS_COLOR_SEEDS,
6
+ LIGHT_SEMANTIC_COLOR_REFERENCES,
7
+ } from '@ankhorage/color-theory';
8
+ import type { ThemeConfig } from '@ankhorage/contracts';
9
+ import { isRecord, readOwnProperty } from '@ankhorage/utility/object';
10
+ import { expect, it } from 'bun:test';
11
+
12
+ import { generatePalette } from './generatePalette';
13
+ import { resolveSemanticColors } from './resolveSemanticColors';
14
+
15
+ const mockConfig: ThemeConfig = {
16
+ id: 'test',
17
+ name: 'Test Theme',
18
+ light: {
19
+ primaryColor: '#3B82F6',
20
+ harmony: 'triadic',
21
+ },
22
+ dark: {
23
+ primaryColor: '#3B82F6',
24
+ harmony: 'triadic',
25
+ },
26
+ };
27
+
28
+ function expectCompleteSemanticValues(value: unknown): void {
29
+ if (typeof value === 'string') {
30
+ expect(value.length).toBeGreaterThan(0);
31
+ return;
32
+ }
33
+ if (!isRecord(value)) return;
34
+ Object.values(value).forEach(expectCompleteSemanticValues);
35
+ }
36
+
37
+ it('generates a valid palette for light mode', () => {
38
+ const { colors, swatches, semantics } = generatePalette(mockConfig, 'light');
39
+
40
+ expect(colors.primary).toBeDefined();
41
+ expect(swatches.primary).toBeDefined();
42
+ expect(swatches.neutral).toBeDefined();
43
+ expect(Object.keys(swatches.primary)).toHaveLength(11);
44
+ expect(Object.keys(swatches.neutral)).toHaveLength(11);
45
+
46
+ // Surface semantic aliases
47
+ expect(semantics.surface.default).toBe(semantics.neutral.surface);
48
+ expect(semantics.content.muted).toBe(semantics.neutral.textMuted);
49
+ expect(semantics.border.focus).toBe(semantics.brand.outline);
50
+ expect(semantics.action.primary.base).toBe(semantics.brand.base);
51
+ expect(semantics.action.danger.base).toBe(semantics.danger.base);
52
+
53
+ // Surface runtime semantic aliases derived from ordinal swatches
54
+ expect(semantics.accent.base).toBeDefined();
55
+ expect(semantics.highlight.base).toBeDefined();
56
+ // accent/highlight are Surface semantic aliases (tertiary/quaternary fallback to primary when absent)
57
+ expect(semantics.accent.base).toBe(colors.accent);
58
+ expect(semantics.highlight.base).toBe(colors.highlight);
59
+ });
60
+
61
+ it('generates a valid palette for dark mode', () => {
62
+ const { colors, swatches, semantics } = generatePalette(mockConfig, 'dark');
63
+
64
+ expect(colors.background).toBe(semantics.neutral.bg);
65
+ expect(semantics.surface.inverse).toBe(swatches.neutral[50]);
66
+ expect(semantics.content.inverse).toBe(swatches.neutral[900]);
67
+ });
68
+
69
+ it('uses the Color Theory status owner independently from brand harmony', () => {
70
+ const statusConfig: ThemeConfig = {
71
+ ...mockConfig,
72
+ light: { primaryColor: '#dc2626', harmony: 'monochromatic' },
73
+ dark: { primaryColor: '#dc2626', harmony: 'monochromatic' },
74
+ };
75
+ const light = generatePalette(statusConfig, 'light');
76
+ const dark = generatePalette(statusConfig, 'dark');
77
+
78
+ expect(light.semantics.danger.base).toBe('#ef4444');
79
+ expect(light.semantics.success.base).toBe('#22c55e');
80
+ expect(light.semantics.warning.base).toBe('#f59e0b');
81
+ expect(light.semantics.error.base).toBe(light.semantics.danger.base);
82
+ expect(light.semantics.info.base).toBe(DEFAULT_SEMANTIC_STATUS_COLOR_SEEDS.info);
83
+ expect(light.semantics.info.base).not.toBe(light.semantics.brand.base);
84
+
85
+ expect(dark.semantics.danger.base).toBe('#ef4444');
86
+ expect(dark.semantics.success.base).toBe('#22c55e');
87
+ expect(dark.semantics.warning.base).toBe('#f59e0b');
88
+ expect(dark.semantics.error.base).toBe(dark.semantics.danger.base);
89
+ expect(dark.semantics.info.base).toBe(DEFAULT_SEMANTIC_STATUS_COLOR_SEEDS.info);
90
+ expect(dark.semantics.info.base).not.toBe(dark.semantics.brand.base);
91
+ expect(light.semantics.error).toBe(light.semantics.danger);
92
+ expect(dark.semantics.error).toBe(dark.semantics.danger);
93
+ });
94
+
95
+ it('uses mode-aware role semantics for dark mode soft states', () => {
96
+ const light = generatePalette(mockConfig, 'light');
97
+ const dark = generatePalette(mockConfig, 'dark');
98
+
99
+ expect(light.semantics.brand.softBg).toBe(light.swatches.primary[100]);
100
+ expect(light.semantics.brand.softHover).toBe(light.swatches.primary[200]);
101
+ expect(light.semantics.brand.softActive).toBe(light.swatches.primary[300]);
102
+ expect(dark.semantics.brand.softBg).toBe(dark.swatches.primary[900]);
103
+ expect(dark.semantics.brand.softHover).toBe(dark.swatches.primary[800]);
104
+ expect(dark.semantics.brand.softActive).toBe(dark.swatches.primary[700]);
105
+ });
106
+
107
+ it('preserves the primary color at swatch step 500 in light mode', () => {
108
+ const { swatches } = generatePalette(mockConfig, 'light');
109
+ expect(String(swatches.primary[500])).toBe(mockConfig.light.primaryColor);
110
+ });
111
+
112
+ it('preserves the primary color at swatch step 500 in dark mode', () => {
113
+ const { swatches } = generatePalette(mockConfig, 'dark');
114
+ expect(String(swatches.primary[500])).toBe(mockConfig.dark.primaryColor);
115
+ });
116
+
117
+ it('provides a neutral swatch with neutralKeyColor at step 500', () => {
118
+ const { swatches } = generatePalette(mockConfig, 'light');
119
+ // neutral swatch must have a step 500 entry
120
+ expect(swatches.neutral[500]).toBeDefined();
121
+ });
122
+
123
+ it('throws deterministically on invalid primary color', () => {
124
+ const config = {
125
+ ...mockConfig,
126
+ light: { ...mockConfig.light, primaryColor: 'not-a-hex-color' },
127
+ };
128
+ expect(() => generatePalette(config, 'light')).toThrow();
129
+ });
130
+
131
+ it('throws deterministically on invalid primary color in dark mode', () => {
132
+ const config = {
133
+ ...mockConfig,
134
+ dark: { ...mockConfig.dark, primaryColor: 'rgb(0,0,0)' },
135
+ };
136
+ expect(() => generatePalette(config, 'dark')).toThrow();
137
+ });
138
+
139
+ it('emits required semantic roles for all harmonies', () => {
140
+ for (const harmony of COLOR_HARMONIES) {
141
+ const config = {
142
+ ...mockConfig,
143
+ light: { ...mockConfig.light, harmony },
144
+ dark: { ...mockConfig.dark, harmony },
145
+ };
146
+ const light = generatePalette(config, 'light');
147
+ const dark = generatePalette(config, 'dark');
148
+ expectCompleteSemanticValues(light.semantics);
149
+ expectCompleteSemanticValues(dark.semantics);
150
+ }
151
+ });
152
+
153
+ it('resolves canonical semantic references and returns their selected steps', () => {
154
+ const light = generatePalette(mockConfig, 'light');
155
+ const dark = generatePalette(mockConfig, 'dark');
156
+
157
+ expect(light.colorDiagnostics.semanticReferences).toBe(LIGHT_SEMANTIC_COLOR_REFERENCES);
158
+ expect(dark.colorDiagnostics.semanticReferences).toBe(DARK_SEMANTIC_COLOR_REFERENCES);
159
+ expect(light.colorDiagnostics.generated.swatches).toBe(light.swatches);
160
+ expect(dark.colorDiagnostics.generated.swatches).toBe(dark.swatches);
161
+ });
162
+
163
+ it('returns measured selections and contrast diagnostics for both modes', () => {
164
+ for (const mode of ['light', 'dark'] as const) {
165
+ const palette = generatePalette(mockConfig, mode);
166
+
167
+ expect(palette.colorDiagnostics.selections.length).toBeGreaterThan(0);
168
+ expect(
169
+ palette.colorDiagnostics.selections.every(({ result }) => result.selected !== null),
170
+ ).toBe(true);
171
+ expect(palette.colorDiagnostics.contrasts.length).toBeGreaterThan(0);
172
+ expect(palette.colorDiagnostics.contrasts.every(({ passes }) => passes)).toBe(true);
173
+ expect(palette.colorDiagnostics.surfaceSeparation.length).toBeGreaterThan(0);
174
+ }
175
+ });
176
+
177
+ it('reports neutral and surface-separation evidence without hiding failed separation', () => {
178
+ const palette = generatePalette(mockConfig, 'light');
179
+ const failedSeparation = palette.colorDiagnostics.surfaceSeparation.find(({ passes }) => !passes);
180
+
181
+ expect(palette.colorDiagnostics.generated.neutral.neutralKeyColor).toBe(
182
+ palette.swatches.neutral[500],
183
+ );
184
+ expect(palette.colorDiagnostics.generated.neutral.diagnostics.isUsable).toBeBoolean();
185
+ expect(failedSeparation).toBeDefined();
186
+ expect(failedSeparation?.contrast).toBeLessThan(failedSeparation?.minimumContrast ?? 0);
187
+ });
188
+
189
+ it('preserves owner diagnostics for achromatic and low-chroma inputs', () => {
190
+ const achromaticConfig: ThemeConfig = {
191
+ ...mockConfig,
192
+ light: { primaryColor: '#777777', harmony: 'square' },
193
+ };
194
+ const palette = generatePalette(achromaticConfig, 'light');
195
+
196
+ expect(palette.colorDiagnostics.generated.harmonyRoleColors.diagnostics.isHueReliable).toBe(
197
+ false,
198
+ );
199
+ expect(
200
+ palette.colorDiagnostics.generated.harmonyRoleColors.diagnostics.warnings.length,
201
+ ).toBeGreaterThan(0);
202
+ expect(palette.colorDiagnostics.generated.neutral.diagnostics).toBeDefined();
203
+ });
204
+
205
+ it('generates ordinal chromatic role swatches (no accent/highlight as swatch keys)', () => {
206
+ const { swatches } = generatePalette(mockConfig, 'light');
207
+ const keys = Object.keys(swatches);
208
+ expect(keys).not.toContain('accent');
209
+ expect(keys).not.toContain('highlight');
210
+ expect(keys).not.toContain('surfaceTint');
211
+ expect(keys).not.toContain('base');
212
+ // ordinal roles are present
213
+ expect(keys).toContain('primary');
214
+ expect(keys).toContain('neutral');
215
+ });
216
+
217
+ it('semantic resolver maps all SemanticColorToken entries for light mode', () => {
218
+ const { swatches } = generatePalette(mockConfig, 'light');
219
+ // Build a minimal GeneratedThemeModeColors for resolver testing
220
+ const generated = {
221
+ harmonyRoleColors: {} as never,
222
+ swatches,
223
+ neutral: { neutralKeyColor: swatches.neutral[500], diagnostics: {} as never },
224
+ };
225
+ const resolved = resolveSemanticColors(generated, LIGHT_SEMANTIC_COLOR_REFERENCES);
226
+ const tokens: SemanticColorToken[] = [
227
+ 'background',
228
+ 'surface',
229
+ 'surfaceRaised',
230
+ 'border',
231
+ 'divider',
232
+ 'text',
233
+ 'textMuted',
234
+ 'disabledBg',
235
+ 'disabledText',
236
+ 'brand',
237
+ 'brandEmphasis',
238
+ 'action',
239
+ 'actionEmphasis',
240
+ ];
241
+ for (const token of tokens) {
242
+ expect(readOwnProperty(resolved, token)).toBeDefined();
243
+ expect(typeof readOwnProperty(resolved, token)).toBe('string');
244
+ }
245
+ });
246
+
247
+ it('semantic resolver maps all SemanticColorToken entries for dark mode', () => {
248
+ const { swatches } = generatePalette(mockConfig, 'dark');
249
+ const generated = {
250
+ harmonyRoleColors: {} as never,
251
+ swatches,
252
+ neutral: { neutralKeyColor: swatches.neutral[500], diagnostics: {} as never },
253
+ };
254
+ const resolved = resolveSemanticColors(generated, DARK_SEMANTIC_COLOR_REFERENCES);
255
+ const tokens: SemanticColorToken[] = [
256
+ 'background',
257
+ 'surface',
258
+ 'surfaceRaised',
259
+ 'border',
260
+ 'divider',
261
+ 'text',
262
+ 'textMuted',
263
+ 'disabledBg',
264
+ 'disabledText',
265
+ 'brand',
266
+ 'brandEmphasis',
267
+ 'action',
268
+ 'actionEmphasis',
269
+ ];
270
+ for (const token of tokens) {
271
+ expect(readOwnProperty(resolved, token)).toBeDefined();
272
+ }
273
+ });
274
+
275
+ it('neutral semantics power backgrounds, borders, text in light mode', () => {
276
+ const { semantics } = generatePalette(mockConfig, 'light');
277
+ expect(semantics.neutral.bg).toBeDefined();
278
+ expect(semantics.neutral.bgSubtle).toBeDefined();
279
+ expect(semantics.neutral.surface).toBeDefined();
280
+ expect(semantics.neutral.surfaceHover).toBeDefined();
281
+ expect(semantics.neutral.border).toBeDefined();
282
+ expect(semantics.neutral.borderStrong).toBeDefined();
283
+ expect(semantics.neutral.divider).toBeDefined();
284
+ expect(semantics.neutral.text).toBeDefined();
285
+ expect(semantics.neutral.textMuted).toBeDefined();
286
+ expect(semantics.neutral.textSubtle).toBeDefined();
287
+ });
288
+
289
+ it('readable foregrounds are generated for brand base in both modes', () => {
290
+ const light = generatePalette(mockConfig, 'light');
291
+ const dark = generatePalette(mockConfig, 'dark');
292
+ expect(light.semantics.brand.onSolidText).toMatch(/^#/);
293
+ expect(dark.semantics.brand.onSolidText).toMatch(/^#/);
294
+ });
@@ -1,11 +1,4 @@
1
- import type {
2
- GeneratedThemeModeColors,
3
- GeneratedThemeSwatches,
4
- HexColor,
5
- SemanticColorReferenceMap,
6
- SemanticColorToken,
7
- ThemeColorMode,
8
- } from '@ankhorage/color-theory';
1
+ import type { GeneratedThemeSwatches, ThemeColorMode } from '@ankhorage/color-theory';
9
2
  import {
10
3
  DARK_SEMANTIC_COLOR_REFERENCES,
11
4
  generateThemeModeColors,
@@ -14,29 +7,9 @@ import {
14
7
  } from '@ankhorage/color-theory';
15
8
  import type { ThemeConfig } from '@ankhorage/contracts';
16
9
 
10
+ import type { SurfaceColorDiagnostics, ThemeSemantics, ThemeTokens } from '../../../types/theme';
11
+ import { resolveSemanticColors } from './resolveSemanticColors';
17
12
  import { resolveSurfaceSemanticModel } from './resolveSurfaceSemanticModel';
18
- import type { SurfaceColorDiagnostics, ThemeSemantics, ThemeTokens } from './types';
19
-
20
- /**
21
- * Surface semantic resolver: maps color-theory SemanticColorToken references
22
- * to hex values from the generated swatches.
23
- */
24
- export type SurfaceSemanticColors = Record<SemanticColorToken, HexColor>;
25
-
26
- export function resolveSemanticColors(
27
- generated: GeneratedThemeModeColors,
28
- references: SemanticColorReferenceMap,
29
- ): SurfaceSemanticColors {
30
- return Object.fromEntries(
31
- Object.entries(references).map(([token, ref]) => {
32
- const swatch = generated.swatches[ref.role];
33
- if (!swatch) {
34
- throw new Error(`Missing swatch for role '${ref.role}' (token: '${token}')`);
35
- }
36
- return [token, swatch[ref.step]];
37
- }),
38
- ) as SurfaceSemanticColors;
39
- }
40
13
 
41
14
  export function generatePalette(
42
15
  config: ThemeConfig,
@@ -1,7 +1,7 @@
1
1
  import type { ThemeConfig } from '@ankhorage/contracts';
2
2
  import { describe, expect, it } from 'bun:test';
3
3
 
4
- import { generatePalette } from './colorEngine';
4
+ import { generatePalette } from './generatePalette';
5
5
 
6
6
  const config: ThemeConfig = {
7
7
  id: 'inverse-semantics-test',
@@ -1,7 +1,7 @@
1
1
  import type { ColorSwatch, HexColor } from '@ankhorage/color-theory';
2
2
 
3
- import { SURFACE_COLOR_POLICY } from './surfaceColorPolicy';
4
- import type { RoleSemantics } from './types';
3
+ import type { RoleSemantics } from '../../../types/theme';
4
+ import { SURFACE_COLOR_POLICY } from '../constants';
5
5
 
6
6
  interface ResolveRoleSemanticsInput {
7
7
  base?: HexColor;
@@ -0,0 +1,23 @@
1
+ import type {
2
+ GeneratedThemeModeColors,
3
+ HexColor,
4
+ SemanticColorReferenceMap,
5
+ SemanticColorToken,
6
+ } from '@ankhorage/color-theory';
7
+
8
+ export type SurfaceSemanticColors = Record<SemanticColorToken, HexColor>;
9
+
10
+ export function resolveSemanticColors(
11
+ generated: GeneratedThemeModeColors,
12
+ references: SemanticColorReferenceMap,
13
+ ): SurfaceSemanticColors {
14
+ return Object.fromEntries(
15
+ Object.entries(references).map(([token, ref]) => {
16
+ const swatch = generated.swatches[ref.role];
17
+ if (!swatch) {
18
+ throw new Error(`Missing swatch for role '${ref.role}' (token: '${token}')`);
19
+ }
20
+ return [token, swatch[ref.step]];
21
+ }),
22
+ ) as SurfaceSemanticColors;
23
+ }
@@ -10,16 +10,16 @@ import type {
10
10
  } from '@ankhorage/color-theory';
11
11
  import { createDefaultSemanticStatusSwatches } from '@ankhorage/color-theory';
12
12
 
13
- import { createSurfaceColorDiagnosticCollector } from './createSurfaceColorDiagnosticCollector';
14
- import { createSurfaceSemanticPolicy } from './createSurfaceSemanticPolicy';
15
- import { resolveRoleSemantics } from './resolveRoleSemantics';
16
13
  import type {
17
14
  BorderSemantics,
18
15
  ContentSemantics,
19
16
  RoleSemantics,
20
17
  SurfaceColorDiagnostics,
21
18
  ThemeSemantics,
22
- } from './types';
19
+ } from '../../../types/theme';
20
+ import { createSurfaceColorDiagnosticCollector } from './createSurfaceColorDiagnosticCollector';
21
+ import { createSurfaceSemanticPolicy } from './createSurfaceSemanticPolicy';
22
+ import { resolveRoleSemantics } from './resolveRoleSemantics';
23
23
 
24
24
  type ResolvedSemanticColors = Record<SemanticColorToken, HexColor>;
25
25
 
@@ -17,7 +17,7 @@ describe('public theme subpath', () => {
17
17
 
18
18
  expect(source).not.toContain('ThemeContext');
19
19
  expect(source).not.toMatch(/from ['"]react(?:-native)?['"]/);
20
- expect(source).toContain("export * from './createTheme';");
20
+ expect(source).toContain("export { createTheme } from './application/use-cases/createTheme';");
21
21
  });
22
22
 
23
23
  test('imports and executes through the package subpath in plain Bun', async () => {
@@ -0,0 +1,18 @@
1
+ export type {
2
+ ActionSemantics,
3
+ BorderSemantics,
4
+ ContentSemantics,
5
+ FontWeight,
6
+ NeutralSemantics,
7
+ RoleSemantics,
8
+ SelectionSemantics,
9
+ SurfaceColorDiagnostics,
10
+ SurfaceColorSelectionDiagnostic,
11
+ SurfaceContrastDiagnostic,
12
+ SurfaceSemantics,
13
+ SurfaceTheme,
14
+ ThemeMode,
15
+ ThemeSemantics,
16
+ ThemeTokens,
17
+ } from '../../types/theme';
18
+ export { createTheme } from './application/use-cases/createTheme';
@@ -0,0 +1,13 @@
1
+ import { readFileSync } from 'node:fs';
2
+
3
+ import { describe, expect, it } from 'bun:test';
4
+
5
+ describe('theme runtime ownership', () => {
6
+ it('keeps nested scopes on the Surface runtime boundary without exposing raw context', () => {
7
+ const root = readFileSync(new URL('../../index.ts', import.meta.url), 'utf8');
8
+ const runtime = readFileSync(new URL('./runtime.ts', import.meta.url), 'utf8');
9
+ expect(root).toContain('ThemeProvider, ThemeScope, useTheme');
10
+ expect(root).not.toContain('ThemeContext');
11
+ expect(runtime).not.toContain('ThemeRuntimeContext');
12
+ });
13
+ });
@@ -0,0 +1,4 @@
1
+ export type { ThemeProviderProps, ThemeRuntime, ThemeScopeProps } from '../../types/theme';
2
+ export { ThemeProvider } from './adapters/inbound/ThemeProvider';
3
+ export { ThemeScope } from './adapters/inbound/ThemeScope';
4
+ export { useTheme } from './adapters/inbound/useTheme';
@@ -1,10 +1,10 @@
1
1
  import type { ThemeGlobalTokenOverrides } from '@ankhorage/contracts';
2
2
 
3
- import { DEFAULT_TOKENS } from './defaultTokens';
3
+ import type { ThemeTokens } from '../../../types/theme';
4
+ import { DEFAULT_TOKENS } from '../constants';
4
5
  import { resolveHeadingTokenOverrides } from './resolveHeadingTokenOverrides';
5
6
  import { resolveNumericTokenOverrides } from './resolveNumericTokenOverrides';
6
7
  import { resolveWeightTokenOverrides } from './resolveWeightTokenOverrides';
7
- import type { ThemeTokens } from './types';
8
8
 
9
9
  type GlobalThemeTokens = Omit<
10
10
  ThemeTokens,
@@ -1,6 +1,6 @@
1
1
  import type { ThemeTypographyHeadingOverrides } from '@ankhorage/contracts';
2
2
 
3
- import type { ThemeTokens } from './types';
3
+ import type { ThemeTokens } from '../../../types/theme';
4
4
 
5
5
  type HeadingTokens = ThemeTokens['typography']['headings'];
6
6
  type HeadingToken = HeadingTokens[1];
@@ -0,0 +1,16 @@
1
+ /*** Resolve a theme token key through its map while preserving raw values. */
2
+ type ResolvedToken<TMap, TValue> = TValue extends keyof TMap ? TMap[TValue] : TValue;
3
+
4
+ /*** Resolve a mapped theme token or return the supplied raw value unchanged. */
5
+ export function resolveToken<
6
+ TMap extends Record<string | number, unknown>,
7
+ TValue extends string | number | undefined,
8
+ >(map: TMap, value: TValue): ResolvedToken<TMap, TValue> {
9
+ if (value === undefined) return undefined as ResolvedToken<TMap, TValue>;
10
+
11
+ if (Object.prototype.hasOwnProperty.call(map, value)) {
12
+ return map[value as keyof TMap] as ResolvedToken<TMap, TValue>;
13
+ }
14
+
15
+ return value as ResolvedToken<TMap, TValue>;
16
+ }
@@ -1,4 +1,4 @@
1
- import type { FontWeight } from './types';
1
+ import type { FontWeight } from '../../../types/theme';
2
2
 
3
3
  const WEIGHT_TOKEN_KEYS = new Set<string>([
4
4
  'thin',
@@ -30,17 +30,17 @@ export function resolveWeightTokenOverrides(
30
30
  ): Readonly<Record<string, FontWeight>> {
31
31
  if (overrides === undefined) return {};
32
32
 
33
- const resolved: Record<string, FontWeight> = {};
34
- for (const [token, value] of Object.entries(overrides)) {
35
- if (!WEIGHT_TOKEN_KEYS.has(token)) {
36
- throw new RangeError(`Unknown typography weight token: ${token}.`);
37
- }
38
- if (!isFontWeight(value)) {
39
- throw new RangeError(`Invalid font weight for typography.weights.${token}: ${value}.`);
40
- }
41
- resolved[token] = value;
42
- }
43
- return resolved;
33
+ return Object.fromEntries(
34
+ Object.entries(overrides).map(([token, value]) => {
35
+ if (!WEIGHT_TOKEN_KEYS.has(token)) {
36
+ throw new RangeError(`Unknown typography weight token: ${token}.`);
37
+ }
38
+ if (!isFontWeight(value)) {
39
+ throw new RangeError(`Invalid font weight for typography.weights.${token}: ${value}.`);
40
+ }
41
+ return [token, value] as const;
42
+ }),
43
+ );
44
44
  }
45
45
 
46
46
  function isFontWeight(value: string): value is FontWeight {
@@ -1,12 +1,12 @@
1
1
  import React from 'react';
2
2
  import { Pressable, StyleSheet, type ViewStyle } from 'react-native';
3
3
 
4
- import type { SurfaceColor } from '../../../../surfaceColor';
5
- import { useTheme } from '../../../../theme/ThemeContext';
6
- import type { SurfaceTheme } from '../../../../theme/types';
4
+ import type { SurfaceColor } from '../../../../types/surfaceColor';
5
+ import type { SurfaceTheme } from '../../../../types/theme';
7
6
  import type { ToastProps } from '../../../../types/toast';
8
7
  import { View } from '../../../layout/public';
9
8
  import { Surface } from '../../../surface/public';
9
+ import { useTheme } from '../../../theme/runtime';
10
10
  import { Text } from '../../../typography/public';
11
11
 
12
12
  /*** Renders one transient toast notification. */
@@ -1,10 +1,10 @@
1
1
  import React from 'react';
2
2
  import { Platform, Pressable, View } from 'react-native';
3
3
 
4
- import { useTheme } from '../../../../theme/ThemeContext';
5
4
  import type { TooltipProps } from '../../../../types/tooltip';
6
5
  import { Popover } from '../../../popover/public';
7
6
  import { Surface } from '../../../surface/public';
7
+ import { useTheme } from '../../../theme/runtime';
8
8
  import { Text } from '../../../typography/public';
9
9
  import { useTooltipVisibility } from '../../composition/useTooltipVisibility';
10
10
 
@@ -1,12 +1,11 @@
1
1
  import React from 'react';
2
2
  import { Text as ReactNativeText } from 'react-native';
3
3
 
4
- import { useTranslationContext } from '../../../../context/TranslationContext';
5
- import { useTheme } from '../../../../theme/ThemeContext';
6
4
  import type { HeadingProps } from '../../../../types/typography';
5
+ import { useTheme } from '../../../theme/runtime';
7
6
  import { resolveHeadingTextStyle } from '../../utils/resolveHeadingTextStyle';
8
7
 
9
- /*** Renders a semantic, translatable heading using Surface typography tokens. */
8
+ /*** Renders a semantic heading using Surface typography tokens. */
10
9
  export function Heading({
11
10
  text,
12
11
  children,
@@ -15,12 +14,10 @@ export function Heading({
15
14
  color,
16
15
  emphasis = 'default',
17
16
  numberOfLines,
18
- i18nKey,
19
17
  testID,
20
18
  }: HeadingProps) {
21
19
  const { theme } = useTheme();
22
- const { t } = useTranslationContext();
23
- const content = resolveHeadingContent({ text, children, i18nKey, translate: t });
20
+ const content = text ?? children;
24
21
 
25
22
  return (
26
23
  <ReactNativeText
@@ -33,27 +30,3 @@ export function Heading({
33
30
  </ReactNativeText>
34
31
  );
35
32
  }
36
-
37
- /*** Resolves authored or translated heading content without mutating source input. */
38
- function resolveHeadingContent({
39
- text,
40
- children,
41
- i18nKey,
42
- translate,
43
- }: {
44
- text: HeadingProps['text'];
45
- children: HeadingProps['children'];
46
- i18nKey: HeadingProps['i18nKey'];
47
- translate: (key: string) => string;
48
- }) {
49
- const content = text ?? children;
50
- if (!i18nKey) return content;
51
-
52
- try {
53
- const translated = translate(i18nKey);
54
- return translated && translated !== i18nKey ? translated : content;
55
- } catch (error) {
56
- console.warn('[Heading] Translation error:', error);
57
- return content;
58
- }
59
- }
@@ -1,12 +1,11 @@
1
1
  import React from 'react';
2
2
  import { Text as ReactNativeText } from 'react-native';
3
3
 
4
- import { useTranslationContext } from '../../../../context/TranslationContext';
5
4
  import { resolveTextColor, resolveTextStyles } from '../../../../internal/resolvers';
6
- import { useTheme } from '../../../../theme/ThemeContext';
7
5
  import type { TextProps } from '../../../../types/typography';
6
+ import { useTheme } from '../../../theme/runtime';
8
7
 
9
- /*** Renders translatable body text using Surface semantic typography. */
8
+ /*** Renders body text using Surface semantic typography. */
10
9
  export function Text({
11
10
  children,
12
11
  i18nKey,
@@ -20,8 +19,7 @@ export function Text({
20
19
  testID,
21
20
  }: TextProps) {
22
21
  const { theme } = useTheme();
23
- const { t } = useTranslationContext();
24
- const content = resolveTextContent(children, i18nKey, t);
22
+ const content = children ?? i18nKey ?? null;
25
23
 
26
24
  return (
27
25
  <ReactNativeText
@@ -36,21 +34,3 @@ export function Text({
36
34
  </ReactNativeText>
37
35
  );
38
36
  }
39
-
40
- /*** Resolves authored or translated Text content with a stable fallback. */
41
- function resolveTextContent(
42
- children: TextProps['children'],
43
- i18nKey: TextProps['i18nKey'],
44
- translate: (key: string) => string,
45
- ) {
46
- if (children !== undefined) return children;
47
- if (!i18nKey) return null;
48
-
49
- try {
50
- const translated = translate(i18nKey);
51
- return translated && translated !== i18nKey ? translated : i18nKey;
52
- } catch (error) {
53
- console.warn('[Text] Translation error:', error);
54
- return i18nKey;
55
- }
56
- }