@multiplatform.one/components 7.8.0 → 7.10.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 (426) hide show
  1. package/dist/cjs/Accordion/index.cjs +3 -3
  2. package/dist/cjs/Accordion/index.native.js +4 -4
  3. package/dist/cjs/Accordion/index.native.js.map +1 -1
  4. package/dist/cjs/Chip/index.cjs +1 -1
  5. package/dist/cjs/Chip/index.native.js +1 -1
  6. package/dist/cjs/Chip/index.native.js.map +1 -1
  7. package/dist/cjs/ContextMenu/index.cjs +3 -3
  8. package/dist/cjs/ContextMenu/index.native.js +3 -3
  9. package/dist/cjs/ContextMenu/index.native.js.map +1 -1
  10. package/dist/cjs/DropdownMenu/index.cjs +3 -3
  11. package/dist/cjs/DropdownMenu/index.native.js +3 -3
  12. package/dist/cjs/DropdownMenu/index.native.js.map +1 -1
  13. package/dist/cjs/Meter/index.cjs +3 -2
  14. package/dist/cjs/Meter/index.native.js +3 -2
  15. package/dist/cjs/Meter/index.native.js.map +1 -1
  16. package/dist/cjs/Meter/meter.cjs +1 -2
  17. package/dist/cjs/Meter/meter.native.js +1 -2
  18. package/dist/cjs/Meter/meter.native.js.map +1 -1
  19. package/dist/cjs/Pagination.cjs +2 -2
  20. package/dist/cjs/Pagination.native.js +2 -2
  21. package/dist/cjs/Pagination.native.js.map +1 -1
  22. package/dist/cjs/ProgressSteps/index.cjs +3 -3
  23. package/dist/cjs/ProgressSteps/index.native.js +3 -3
  24. package/dist/cjs/ProgressSteps/index.native.js.map +1 -1
  25. package/dist/cjs/Quote/index.cjs +1 -2
  26. package/dist/cjs/Quote/index.native.js +1 -2
  27. package/dist/cjs/Quote/index.native.js.map +1 -1
  28. package/dist/cjs/Tabs/index.cjs +1 -1
  29. package/dist/cjs/Tabs/index.native.js +1 -1
  30. package/dist/cjs/Tabs/index.native.js.map +1 -1
  31. package/dist/cjs/Toast/index.cjs +4 -5
  32. package/dist/cjs/Toast/index.native.js +4 -5
  33. package/dist/cjs/Toast/index.native.js.map +1 -1
  34. package/dist/cjs/TreeSelect/index.cjs +46 -7
  35. package/dist/cjs/TreeSelect/index.native.js +58 -7
  36. package/dist/cjs/TreeSelect/index.native.js.map +1 -1
  37. package/dist/cjs/charts/PieChart.cjs +1 -2
  38. package/dist/cjs/charts/PieChart.native.js +1 -2
  39. package/dist/cjs/charts/PieChart.native.js.map +1 -1
  40. package/dist/cjs/code/HighlightedCode/index.cjs +1 -1
  41. package/dist/cjs/code/HighlightedCode/index.native.js +1 -1
  42. package/dist/cjs/code/HighlightedCode/index.native.js.map +1 -1
  43. package/dist/cjs/componentColors.cjs +6 -4
  44. package/dist/cjs/componentColors.native.js +6 -4
  45. package/dist/cjs/componentColors.native.js.map +1 -1
  46. package/dist/cjs/images/Image/ImageFrame.cjs +4 -2
  47. package/dist/cjs/images/Image/ImageFrame.native.js +4 -2
  48. package/dist/cjs/images/Image/ImageFrame.native.js.map +1 -1
  49. package/dist/cjs/layouts/AsyncBoundary.cjs +1 -2
  50. package/dist/cjs/layouts/AsyncBoundary.native.js +1 -2
  51. package/dist/cjs/layouts/AsyncBoundary.native.js.map +1 -1
  52. package/dist/cjs/layouts/EmptyState.cjs +6 -2
  53. package/dist/cjs/layouts/EmptyState.native.js +10 -6
  54. package/dist/cjs/layouts/EmptyState.native.js.map +1 -1
  55. package/dist/cjs/layouts/attachments.cjs +4 -4
  56. package/dist/cjs/layouts/attachments.native.js +4 -4
  57. package/dist/cjs/layouts/attachments.native.js.map +1 -1
  58. package/dist/cjs/layouts/breadcrumbs.cjs +1 -2
  59. package/dist/cjs/layouts/breadcrumbs.native.js +1 -2
  60. package/dist/cjs/layouts/breadcrumbs.native.js.map +1 -1
  61. package/dist/cjs/layouts/page.cjs +2 -2
  62. package/dist/cjs/layouts/page.native.js +2 -2
  63. package/dist/cjs/layouts/page.native.js.map +1 -1
  64. package/dist/cjs/layouts/sidebar.cjs +2 -2
  65. package/dist/cjs/layouts/sidebar.native.js +2 -2
  66. package/dist/cjs/layouts/sidebar.native.js.map +1 -1
  67. package/dist/cjs/layouts/tags.cjs +6 -7
  68. package/dist/cjs/layouts/tags.native.js +6 -9
  69. package/dist/cjs/layouts/tags.native.js.map +1 -1
  70. package/dist/cjs/layouts/timeline.cjs +5 -5
  71. package/dist/cjs/layouts/timeline.native.js +5 -5
  72. package/dist/cjs/layouts/timeline.native.js.map +1 -1
  73. package/dist/cjs/surfaces.cjs +1 -0
  74. package/dist/cjs/surfaces.native.js +1 -0
  75. package/dist/cjs/surfaces.native.js.map +1 -1
  76. package/dist/cjs/views/Calendar.cjs +11 -8
  77. package/dist/cjs/views/Calendar.native.js +11 -8
  78. package/dist/cjs/views/Calendar.native.js.map +1 -1
  79. package/dist/cjs/views/Dashboard.cjs +6 -6
  80. package/dist/cjs/views/Dashboard.native.js +7 -7
  81. package/dist/cjs/views/Dashboard.native.js.map +1 -1
  82. package/dist/cjs/views/Gantt.cjs +3 -3
  83. package/dist/cjs/views/Gantt.native.js +3 -3
  84. package/dist/cjs/views/Gantt.native.js.map +1 -1
  85. package/dist/cjs/views/Kanban.cjs +2 -2
  86. package/dist/cjs/views/Kanban.native.js +2 -2
  87. package/dist/cjs/views/Kanban.native.js.map +1 -1
  88. package/dist/cjs/views/ReportBuilder.cjs +4 -4
  89. package/dist/cjs/views/ReportBuilder.native.js +4 -4
  90. package/dist/cjs/views/ReportBuilder.native.js.map +1 -1
  91. package/dist/cjs/views/TreeView.cjs +103 -6
  92. package/dist/cjs/views/TreeView.native.js +115 -6
  93. package/dist/cjs/views/TreeView.native.js.map +1 -1
  94. package/dist/cjs/views/treeViewReveal.cjs +55 -0
  95. package/dist/cjs/views/treeViewReveal.native.js +80 -0
  96. package/dist/cjs/views/treeViewReveal.native.js.map +1 -0
  97. package/dist/esm/Accordion/index.mjs +3 -3
  98. package/dist/esm/Accordion/index.mjs.map +1 -1
  99. package/dist/esm/Accordion/index.native.js +4 -4
  100. package/dist/esm/Accordion/index.native.js.map +1 -1
  101. package/dist/esm/Chip/index.mjs +1 -1
  102. package/dist/esm/Chip/index.mjs.map +1 -1
  103. package/dist/esm/Chip/index.native.js +1 -1
  104. package/dist/esm/Chip/index.native.js.map +1 -1
  105. package/dist/esm/ContextMenu/index.mjs +3 -3
  106. package/dist/esm/ContextMenu/index.mjs.map +1 -1
  107. package/dist/esm/ContextMenu/index.native.js +3 -3
  108. package/dist/esm/ContextMenu/index.native.js.map +1 -1
  109. package/dist/esm/DropdownMenu/index.mjs +3 -3
  110. package/dist/esm/DropdownMenu/index.mjs.map +1 -1
  111. package/dist/esm/DropdownMenu/index.native.js +3 -3
  112. package/dist/esm/DropdownMenu/index.native.js.map +1 -1
  113. package/dist/esm/Meter/index.mjs +3 -2
  114. package/dist/esm/Meter/index.mjs.map +1 -1
  115. package/dist/esm/Meter/index.native.js +3 -2
  116. package/dist/esm/Meter/index.native.js.map +1 -1
  117. package/dist/esm/Meter/meter.mjs +1 -2
  118. package/dist/esm/Meter/meter.mjs.map +1 -1
  119. package/dist/esm/Meter/meter.native.js +1 -2
  120. package/dist/esm/Meter/meter.native.js.map +1 -1
  121. package/dist/esm/Pagination.mjs +2 -2
  122. package/dist/esm/Pagination.mjs.map +1 -1
  123. package/dist/esm/Pagination.native.js +2 -2
  124. package/dist/esm/Pagination.native.js.map +1 -1
  125. package/dist/esm/ProgressSteps/index.mjs +3 -3
  126. package/dist/esm/ProgressSteps/index.mjs.map +1 -1
  127. package/dist/esm/ProgressSteps/index.native.js +3 -3
  128. package/dist/esm/ProgressSteps/index.native.js.map +1 -1
  129. package/dist/esm/Quote/index.mjs +1 -2
  130. package/dist/esm/Quote/index.mjs.map +1 -1
  131. package/dist/esm/Quote/index.native.js +1 -2
  132. package/dist/esm/Quote/index.native.js.map +1 -1
  133. package/dist/esm/Tabs/index.mjs +1 -1
  134. package/dist/esm/Tabs/index.mjs.map +1 -1
  135. package/dist/esm/Tabs/index.native.js +1 -1
  136. package/dist/esm/Tabs/index.native.js.map +1 -1
  137. package/dist/esm/Toast/index.mjs +4 -5
  138. package/dist/esm/Toast/index.mjs.map +1 -1
  139. package/dist/esm/Toast/index.native.js +4 -5
  140. package/dist/esm/Toast/index.native.js.map +1 -1
  141. package/dist/esm/TreeSelect/index.mjs +46 -7
  142. package/dist/esm/TreeSelect/index.mjs.map +1 -1
  143. package/dist/esm/TreeSelect/index.native.js +58 -7
  144. package/dist/esm/TreeSelect/index.native.js.map +1 -1
  145. package/dist/esm/charts/PieChart.mjs +1 -2
  146. package/dist/esm/charts/PieChart.mjs.map +1 -1
  147. package/dist/esm/charts/PieChart.native.js +1 -2
  148. package/dist/esm/charts/PieChart.native.js.map +1 -1
  149. package/dist/esm/code/HighlightedCode/index.mjs +1 -1
  150. package/dist/esm/code/HighlightedCode/index.mjs.map +1 -1
  151. package/dist/esm/code/HighlightedCode/index.native.js +1 -1
  152. package/dist/esm/code/HighlightedCode/index.native.js.map +1 -1
  153. package/dist/esm/componentColors.mjs +6 -4
  154. package/dist/esm/componentColors.mjs.map +1 -1
  155. package/dist/esm/componentColors.native.js +6 -4
  156. package/dist/esm/componentColors.native.js.map +1 -1
  157. package/dist/esm/images/Image/ImageFrame.mjs +4 -2
  158. package/dist/esm/images/Image/ImageFrame.mjs.map +1 -1
  159. package/dist/esm/images/Image/ImageFrame.native.js +4 -2
  160. package/dist/esm/images/Image/ImageFrame.native.js.map +1 -1
  161. package/dist/esm/layouts/AsyncBoundary.mjs +1 -2
  162. package/dist/esm/layouts/AsyncBoundary.mjs.map +1 -1
  163. package/dist/esm/layouts/AsyncBoundary.native.js +1 -2
  164. package/dist/esm/layouts/AsyncBoundary.native.js.map +1 -1
  165. package/dist/esm/layouts/EmptyState.mjs +7 -3
  166. package/dist/esm/layouts/EmptyState.mjs.map +1 -1
  167. package/dist/esm/layouts/EmptyState.native.js +11 -7
  168. package/dist/esm/layouts/EmptyState.native.js.map +1 -1
  169. package/dist/esm/layouts/attachments.mjs +4 -4
  170. package/dist/esm/layouts/attachments.mjs.map +1 -1
  171. package/dist/esm/layouts/attachments.native.js +4 -4
  172. package/dist/esm/layouts/attachments.native.js.map +1 -1
  173. package/dist/esm/layouts/breadcrumbs.mjs +1 -2
  174. package/dist/esm/layouts/breadcrumbs.mjs.map +1 -1
  175. package/dist/esm/layouts/breadcrumbs.native.js +1 -2
  176. package/dist/esm/layouts/breadcrumbs.native.js.map +1 -1
  177. package/dist/esm/layouts/page.mjs +2 -2
  178. package/dist/esm/layouts/page.mjs.map +1 -1
  179. package/dist/esm/layouts/page.native.js +2 -2
  180. package/dist/esm/layouts/page.native.js.map +1 -1
  181. package/dist/esm/layouts/sidebar.mjs +2 -2
  182. package/dist/esm/layouts/sidebar.mjs.map +1 -1
  183. package/dist/esm/layouts/sidebar.native.js +2 -2
  184. package/dist/esm/layouts/sidebar.native.js.map +1 -1
  185. package/dist/esm/layouts/tags.mjs +6 -7
  186. package/dist/esm/layouts/tags.mjs.map +1 -1
  187. package/dist/esm/layouts/tags.native.js +6 -9
  188. package/dist/esm/layouts/tags.native.js.map +1 -1
  189. package/dist/esm/layouts/timeline.mjs +5 -5
  190. package/dist/esm/layouts/timeline.mjs.map +1 -1
  191. package/dist/esm/layouts/timeline.native.js +5 -5
  192. package/dist/esm/layouts/timeline.native.js.map +1 -1
  193. package/dist/esm/surfaces.mjs +1 -0
  194. package/dist/esm/surfaces.mjs.map +1 -1
  195. package/dist/esm/surfaces.native.js +1 -0
  196. package/dist/esm/surfaces.native.js.map +1 -1
  197. package/dist/esm/views/Calendar.mjs +11 -8
  198. package/dist/esm/views/Calendar.mjs.map +1 -1
  199. package/dist/esm/views/Calendar.native.js +11 -8
  200. package/dist/esm/views/Calendar.native.js.map +1 -1
  201. package/dist/esm/views/Dashboard.mjs +6 -6
  202. package/dist/esm/views/Dashboard.mjs.map +1 -1
  203. package/dist/esm/views/Dashboard.native.js +7 -7
  204. package/dist/esm/views/Dashboard.native.js.map +1 -1
  205. package/dist/esm/views/Gantt.mjs +3 -3
  206. package/dist/esm/views/Gantt.mjs.map +1 -1
  207. package/dist/esm/views/Gantt.native.js +3 -3
  208. package/dist/esm/views/Gantt.native.js.map +1 -1
  209. package/dist/esm/views/Kanban.mjs +2 -2
  210. package/dist/esm/views/Kanban.mjs.map +1 -1
  211. package/dist/esm/views/Kanban.native.js +2 -2
  212. package/dist/esm/views/Kanban.native.js.map +1 -1
  213. package/dist/esm/views/ReportBuilder.mjs +4 -4
  214. package/dist/esm/views/ReportBuilder.mjs.map +1 -1
  215. package/dist/esm/views/ReportBuilder.native.js +4 -4
  216. package/dist/esm/views/ReportBuilder.native.js.map +1 -1
  217. package/dist/esm/views/TreeView.mjs +104 -7
  218. package/dist/esm/views/TreeView.mjs.map +1 -1
  219. package/dist/esm/views/TreeView.native.js +116 -7
  220. package/dist/esm/views/TreeView.native.js.map +1 -1
  221. package/dist/esm/views/treeViewReveal.mjs +29 -0
  222. package/dist/esm/views/treeViewReveal.mjs.map +1 -0
  223. package/dist/esm/views/treeViewReveal.native.js +51 -0
  224. package/dist/esm/views/treeViewReveal.native.js.map +1 -0
  225. package/dist/jsx/Accordion/index.mjs +3 -3
  226. package/dist/jsx/Accordion/index.mjs.map +1 -1
  227. package/dist/jsx/Accordion/index.native.js +4 -4
  228. package/dist/jsx/Accordion/index.native.js.map +1 -1
  229. package/dist/jsx/Chip/index.mjs +1 -1
  230. package/dist/jsx/Chip/index.mjs.map +1 -1
  231. package/dist/jsx/Chip/index.native.js +1 -1
  232. package/dist/jsx/Chip/index.native.js.map +1 -1
  233. package/dist/jsx/ContextMenu/index.mjs +3 -3
  234. package/dist/jsx/ContextMenu/index.mjs.map +1 -1
  235. package/dist/jsx/ContextMenu/index.native.js +3 -3
  236. package/dist/jsx/ContextMenu/index.native.js.map +1 -1
  237. package/dist/jsx/DropdownMenu/index.mjs +3 -3
  238. package/dist/jsx/DropdownMenu/index.mjs.map +1 -1
  239. package/dist/jsx/DropdownMenu/index.native.js +3 -3
  240. package/dist/jsx/DropdownMenu/index.native.js.map +1 -1
  241. package/dist/jsx/Meter/index.mjs +3 -2
  242. package/dist/jsx/Meter/index.mjs.map +1 -1
  243. package/dist/jsx/Meter/index.native.js +3 -2
  244. package/dist/jsx/Meter/index.native.js.map +1 -1
  245. package/dist/jsx/Meter/meter.mjs +1 -2
  246. package/dist/jsx/Meter/meter.mjs.map +1 -1
  247. package/dist/jsx/Meter/meter.native.js +1 -2
  248. package/dist/jsx/Meter/meter.native.js.map +1 -1
  249. package/dist/jsx/Pagination.mjs +2 -2
  250. package/dist/jsx/Pagination.mjs.map +1 -1
  251. package/dist/jsx/Pagination.native.js +2 -2
  252. package/dist/jsx/Pagination.native.js.map +1 -1
  253. package/dist/jsx/ProgressSteps/index.mjs +3 -3
  254. package/dist/jsx/ProgressSteps/index.mjs.map +1 -1
  255. package/dist/jsx/ProgressSteps/index.native.js +3 -3
  256. package/dist/jsx/ProgressSteps/index.native.js.map +1 -1
  257. package/dist/jsx/Quote/index.mjs +1 -2
  258. package/dist/jsx/Quote/index.mjs.map +1 -1
  259. package/dist/jsx/Quote/index.native.js +1 -2
  260. package/dist/jsx/Quote/index.native.js.map +1 -1
  261. package/dist/jsx/Tabs/index.mjs +1 -1
  262. package/dist/jsx/Tabs/index.mjs.map +1 -1
  263. package/dist/jsx/Tabs/index.native.js +1 -1
  264. package/dist/jsx/Tabs/index.native.js.map +1 -1
  265. package/dist/jsx/Toast/index.mjs +4 -5
  266. package/dist/jsx/Toast/index.mjs.map +1 -1
  267. package/dist/jsx/Toast/index.native.js +4 -5
  268. package/dist/jsx/Toast/index.native.js.map +1 -1
  269. package/dist/jsx/TreeSelect/index.mjs +46 -7
  270. package/dist/jsx/TreeSelect/index.mjs.map +1 -1
  271. package/dist/jsx/TreeSelect/index.native.js +58 -7
  272. package/dist/jsx/TreeSelect/index.native.js.map +1 -1
  273. package/dist/jsx/charts/PieChart.mjs +1 -2
  274. package/dist/jsx/charts/PieChart.mjs.map +1 -1
  275. package/dist/jsx/charts/PieChart.native.js +1 -2
  276. package/dist/jsx/charts/PieChart.native.js.map +1 -1
  277. package/dist/jsx/code/HighlightedCode/index.mjs +1 -1
  278. package/dist/jsx/code/HighlightedCode/index.mjs.map +1 -1
  279. package/dist/jsx/code/HighlightedCode/index.native.js +1 -1
  280. package/dist/jsx/code/HighlightedCode/index.native.js.map +1 -1
  281. package/dist/jsx/componentColors.mjs +6 -4
  282. package/dist/jsx/componentColors.mjs.map +1 -1
  283. package/dist/jsx/componentColors.native.js +6 -4
  284. package/dist/jsx/componentColors.native.js.map +1 -1
  285. package/dist/jsx/images/Image/ImageFrame.mjs +4 -2
  286. package/dist/jsx/images/Image/ImageFrame.mjs.map +1 -1
  287. package/dist/jsx/images/Image/ImageFrame.native.js +4 -2
  288. package/dist/jsx/images/Image/ImageFrame.native.js.map +1 -1
  289. package/dist/jsx/layouts/AsyncBoundary.mjs +1 -2
  290. package/dist/jsx/layouts/AsyncBoundary.mjs.map +1 -1
  291. package/dist/jsx/layouts/AsyncBoundary.native.js +1 -2
  292. package/dist/jsx/layouts/AsyncBoundary.native.js.map +1 -1
  293. package/dist/jsx/layouts/EmptyState.mjs +7 -3
  294. package/dist/jsx/layouts/EmptyState.mjs.map +1 -1
  295. package/dist/jsx/layouts/EmptyState.native.js +10 -6
  296. package/dist/jsx/layouts/EmptyState.native.js.map +1 -1
  297. package/dist/jsx/layouts/attachments.mjs +4 -4
  298. package/dist/jsx/layouts/attachments.mjs.map +1 -1
  299. package/dist/jsx/layouts/attachments.native.js +4 -4
  300. package/dist/jsx/layouts/attachments.native.js.map +1 -1
  301. package/dist/jsx/layouts/breadcrumbs.mjs +1 -2
  302. package/dist/jsx/layouts/breadcrumbs.mjs.map +1 -1
  303. package/dist/jsx/layouts/breadcrumbs.native.js +1 -2
  304. package/dist/jsx/layouts/breadcrumbs.native.js.map +1 -1
  305. package/dist/jsx/layouts/page.mjs +2 -2
  306. package/dist/jsx/layouts/page.mjs.map +1 -1
  307. package/dist/jsx/layouts/page.native.js +2 -2
  308. package/dist/jsx/layouts/page.native.js.map +1 -1
  309. package/dist/jsx/layouts/sidebar.mjs +2 -2
  310. package/dist/jsx/layouts/sidebar.mjs.map +1 -1
  311. package/dist/jsx/layouts/sidebar.native.js +2 -2
  312. package/dist/jsx/layouts/sidebar.native.js.map +1 -1
  313. package/dist/jsx/layouts/tags.mjs +6 -7
  314. package/dist/jsx/layouts/tags.mjs.map +1 -1
  315. package/dist/jsx/layouts/tags.native.js +6 -9
  316. package/dist/jsx/layouts/tags.native.js.map +1 -1
  317. package/dist/jsx/layouts/timeline.mjs +5 -5
  318. package/dist/jsx/layouts/timeline.mjs.map +1 -1
  319. package/dist/jsx/layouts/timeline.native.js +5 -5
  320. package/dist/jsx/layouts/timeline.native.js.map +1 -1
  321. package/dist/jsx/surfaces.mjs +1 -0
  322. package/dist/jsx/surfaces.mjs.map +1 -1
  323. package/dist/jsx/surfaces.native.js +1 -0
  324. package/dist/jsx/surfaces.native.js.map +1 -1
  325. package/dist/jsx/views/Calendar.mjs +11 -8
  326. package/dist/jsx/views/Calendar.mjs.map +1 -1
  327. package/dist/jsx/views/Calendar.native.js +11 -8
  328. package/dist/jsx/views/Calendar.native.js.map +1 -1
  329. package/dist/jsx/views/Dashboard.mjs +6 -6
  330. package/dist/jsx/views/Dashboard.mjs.map +1 -1
  331. package/dist/jsx/views/Dashboard.native.js +7 -7
  332. package/dist/jsx/views/Dashboard.native.js.map +1 -1
  333. package/dist/jsx/views/Gantt.mjs +3 -3
  334. package/dist/jsx/views/Gantt.mjs.map +1 -1
  335. package/dist/jsx/views/Gantt.native.js +3 -3
  336. package/dist/jsx/views/Gantt.native.js.map +1 -1
  337. package/dist/jsx/views/Kanban.mjs +2 -2
  338. package/dist/jsx/views/Kanban.mjs.map +1 -1
  339. package/dist/jsx/views/Kanban.native.js +2 -2
  340. package/dist/jsx/views/Kanban.native.js.map +1 -1
  341. package/dist/jsx/views/ReportBuilder.mjs +4 -4
  342. package/dist/jsx/views/ReportBuilder.mjs.map +1 -1
  343. package/dist/jsx/views/ReportBuilder.native.js +4 -4
  344. package/dist/jsx/views/ReportBuilder.native.js.map +1 -1
  345. package/dist/jsx/views/TreeView.mjs +104 -7
  346. package/dist/jsx/views/TreeView.mjs.map +1 -1
  347. package/dist/jsx/views/TreeView.native.js +115 -6
  348. package/dist/jsx/views/TreeView.native.js.map +1 -1
  349. package/dist/jsx/views/treeViewReveal.mjs +29 -0
  350. package/dist/jsx/views/treeViewReveal.mjs.map +1 -0
  351. package/dist/jsx/views/treeViewReveal.native.js +80 -0
  352. package/dist/jsx/views/treeViewReveal.native.js.map +1 -0
  353. package/package.json +9 -9
  354. package/src/Accordion/index.tsx +4 -6
  355. package/src/Chip/index.tsx +1 -1
  356. package/src/ContextMenu/index.tsx +3 -3
  357. package/src/DropdownMenu/index.tsx +3 -3
  358. package/src/Meter/Meter.spec.tsx +12 -4
  359. package/src/Meter/index.tsx +3 -2
  360. package/src/Meter/meter.ts +6 -1
  361. package/src/Pagination.tsx +2 -2
  362. package/src/ProgressSteps/index.tsx +3 -3
  363. package/src/Quote/index.tsx +1 -3
  364. package/src/Tabs/index.tsx +2 -2
  365. package/src/Toast/Toast.spec.tsx +120 -48
  366. package/src/Toast/index.tsx +5 -3
  367. package/src/TreeSelect/index.tsx +61 -1
  368. package/src/charts/PieChart.tsx +1 -2
  369. package/src/code/HighlightedCode/index.tsx +1 -1
  370. package/src/componentColors.ts +6 -4
  371. package/src/images/Image/ImageFrame.tsx +2 -2
  372. package/src/layouts/AsyncBoundary.tsx +1 -2
  373. package/src/layouts/EmptyState.spec.tsx +58 -1
  374. package/src/layouts/EmptyState.tsx +11 -7
  375. package/src/layouts/KeyboardAvoidingWrapper/KeyboardAvoidingWrapper.stories.tsx +3 -3
  376. package/src/layouts/PaneScaffold.stories.tsx +3 -8
  377. package/src/layouts/SafeAreaWrapper/SafeAreaWrapper.stories.tsx +3 -3
  378. package/src/layouts/attachments.tsx +4 -4
  379. package/src/layouts/breadcrumbs.tsx +1 -2
  380. package/src/layouts/page.tsx +2 -2
  381. package/src/layouts/sidebar.tsx +2 -2
  382. package/src/layouts/tags-trigger.spec.tsx +32 -0
  383. package/src/layouts/tags.tsx +6 -9
  384. package/src/layouts/timeline.tsx +5 -5
  385. package/src/surfaces.spec.tsx +97 -3
  386. package/src/surfaces.tsx +4 -2
  387. package/src/textAccentSecondary.spec.tsx +187 -0
  388. package/src/views/Calendar.tsx +9 -8
  389. package/src/views/Dashboard.tsx +13 -8
  390. package/src/views/Gantt.tsx +3 -3
  391. package/src/views/Kanban.native.tsx +2 -2
  392. package/src/views/Kanban.tsx +2 -2
  393. package/src/views/ReportBuilder.tsx +4 -4
  394. package/src/views/TreeView.reveal.spec.tsx +167 -0
  395. package/src/views/TreeView.reveal.stories.tsx +115 -0
  396. package/src/views/TreeView.scroll.spec.tsx +196 -0
  397. package/src/views/TreeView.spec.tsx +1 -1
  398. package/src/views/TreeView.tsx +159 -16
  399. package/src/views/treeViewReveal.spec.ts +83 -0
  400. package/src/views/treeViewReveal.ts +45 -0
  401. package/src/views/views.spec.tsx +13 -12
  402. package/types/Accordion/index.d.ts.map +1 -1
  403. package/types/Meter/index.d.ts.map +1 -1
  404. package/types/Meter/meter.d.ts +5 -1
  405. package/types/Meter/meter.d.ts.map +1 -1
  406. package/types/Quote/index.d.ts.map +1 -1
  407. package/types/Tabs/index.d.ts.map +1 -1
  408. package/types/Toast/index.d.ts.map +1 -1
  409. package/types/TreeSelect/index.d.ts +9 -1
  410. package/types/TreeSelect/index.d.ts.map +1 -1
  411. package/types/charts/PieChart.d.ts.map +1 -1
  412. package/types/componentColors.d.ts +1 -4
  413. package/types/componentColors.d.ts.map +1 -1
  414. package/types/images/Image/ImageFrame.d.ts.map +1 -1
  415. package/types/layouts/AsyncBoundary.d.ts.map +1 -1
  416. package/types/layouts/EmptyState.d.ts.map +1 -1
  417. package/types/layouts/breadcrumbs.d.ts.map +1 -1
  418. package/types/layouts/tags.d.ts.map +1 -1
  419. package/types/surfaces.d.ts.map +1 -1
  420. package/types/views/Calendar.d.ts.map +1 -1
  421. package/types/views/Dashboard.d.ts +7 -3
  422. package/types/views/Dashboard.d.ts.map +1 -1
  423. package/types/views/TreeView.d.ts +10 -1
  424. package/types/views/TreeView.d.ts.map +1 -1
  425. package/types/views/treeViewReveal.d.ts +11 -0
  426. package/types/views/treeViewReveal.d.ts.map +1 -0
@@ -66,8 +66,6 @@ export function Quote({ children, cite, compact, ...props }: QuoteProps) {
66
66
  compact === undefined ? { component: "Quote" } : { component: "Quote", compact },
67
67
  );
68
68
  const railWidth = quoteRailWidth(knobProps.borderRadius.borderWidth);
69
- const citeColor =
70
- knobProps.textAccentColor === "$color" ? componentColors.text.muted : knobProps.textAccentColor;
71
69
 
72
70
  return (
73
71
  <QuoteFrame
@@ -106,7 +104,7 @@ export function Quote({ children, cite, compact, ...props }: QuoteProps) {
106
104
  key={key}
107
105
  render="cite"
108
106
  {...knobProps.label}
109
- color={citeColor}
107
+ color={knobProps.textAccentColor}
110
108
  fontStyle="normal"
111
109
  >
112
110
  — {label}
@@ -645,12 +645,12 @@ function TabsRoot({
645
645
  fontWeight={!isBand && isActive ? "700" : knobProps.label.fontWeight}
646
646
  color={
647
647
  isDisabled
648
- ? componentColors.text.muted
648
+ ? disabledState.textKnobProps.color
649
649
  : isActive
650
650
  ? variant === "contained" && onSelectedTint
651
651
  ? onSelectedTint
652
652
  : componentColors.text.primary
653
- : componentColors.text.secondary
653
+ : knobProps.textAccentColor
654
654
  }
655
655
  >
656
656
  {wrapBareTextChildren(item.label, (label) => label)}
@@ -1,15 +1,19 @@
1
1
  import { fireEvent, screen, act, cleanup } from "@testing-library/react";
2
- import type { ReactElement } from "react";
2
+ import type { ReactElement, ReactNode } from "react";
3
3
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
4
4
  import { renderWithProviders } from "@multiplatform.one/test-utils";
5
- import { Button, SizableText, Theme, useTheme, YStack } from "tamagui";
5
+ import { Button, SizableText, TamaguiProvider, useTheme, YStack } from "tamagui";
6
6
  import {
7
7
  __resetDevWarnSeen,
8
8
  aaTextContrastRatio,
9
- contrastRatio,
9
+ createDefaultThemeConfig,
10
+ createThemesBuilder,
11
+ defaultAccentTheme,
12
+ defaultBaseTheme,
13
+ defaultBuilderOptions,
14
+ measureContrast,
10
15
  normalizeToHex,
11
16
  Preset,
12
- relativeLuminance,
13
17
  useAccentOnSurface,
14
18
  } from "@multiplatform.one/theme";
15
19
  import { Toast, ToastViewport, useToast, nativeToastA11y, nativeToastControlA11y } from "./index";
@@ -514,35 +518,91 @@ function tokenVal(theme: ReturnType<typeof useTheme>, key: string): string {
514
518
  return typeof raw === "string" ? raw : "";
515
519
  }
516
520
 
517
- function ContrastProbe({ intent }: { intent: "accent" | "success" | "warning" | "error" }) {
518
- const onSurface = useAccentOnSurface();
519
- const theme = useTheme();
520
- const paper = tokenVal(theme, "background") || tokenVal(theme, "color1");
521
- const color11 = tokenVal(theme, "color11");
522
- const fg =
523
- intent === "accent"
524
- ? onSurface.startsWith("$")
525
- ? tokenVal(theme, onSurface.slice(1)) || onSurface
526
- : onSurface
527
- : color11;
521
+ const TOAST_INTENTS = ["accent", "success", "warning", "error"] as const;
522
+ const CONTRAST_SCHEMES = ["light", "dark"] as const;
523
+
524
+ const houseConfig = createDefaultThemeConfig();
525
+ const houseThemes = createThemesBuilder(
526
+ defaultBaseTheme,
527
+ defaultAccentTheme,
528
+ defaultBuilderOptions,
529
+ ).themes() as Record<string, Record<string, string>>;
530
+
531
+ /**
532
+ * The HOUSE config, not the stock one `renderWithProviders` mounts. The
533
+ * intent sub-themes the Toast wraps in (`light_warning`, ...) exist only
534
+ * there; under stock the wrap falls back to the base ramp and the arm
535
+ * certifies a pair the product never paints.
536
+ */
537
+ function ContrastScheme({
538
+ scheme,
539
+ children,
540
+ }: {
541
+ scheme: (typeof CONTRAST_SCHEMES)[number];
542
+ children: ReactNode;
543
+ }) {
528
544
  return (
529
- <>
530
- <span data-testid="contrast-probe" data-fg={fg} data-bg={paper} />
531
- <Toast
532
- title="Archived"
533
- intent={intent}
534
- action={{ label: ACTION, onPress: () => {} }}
535
- onDismiss={() => {}}
536
- />
537
- </>
545
+ <TamaguiProvider config={houseConfig.tamagui} defaultTheme={scheme} disableInjectCSS>
546
+ <YStack backgroundColor="$background">{children}</YStack>
547
+ </TamaguiProvider>
538
548
  );
539
549
  }
540
550
 
541
- function measuredRatio(fg: string, bg: string): number {
542
- const f = normalizeToHex(fg);
543
- const b = normalizeToHex(bg);
544
- if (!f || !b) return Number.NaN;
545
- return contrastRatio(relativeLuminance(f), relativeLuminance(b));
551
+ /**
552
+ * Accent toasts stay on the BASE theme and take their ink from
553
+ * `useAccentOnSurface()` -- a picked value, not a token the label can name in
554
+ * a class. Stamp it from inside the theme the Toast mounts in.
555
+ */
556
+ function AccentInkProbe() {
557
+ const onSurface = useAccentOnSurface();
558
+ const theme = useTheme();
559
+ const ink = onSurface.startsWith("$")
560
+ ? tokenVal(theme, onSurface.slice(1)) || onSurface
561
+ : onSurface;
562
+ return <span data-testid="accent-ink" data-fg={ink} />;
563
+ }
564
+
565
+ /**
566
+ * The RESTING atom for a prefix. Tamagui spells state atoms `_o-0hover-1` /
567
+ * `_bg-0active-color5`, so a bare prefix read picks up hover paint and
568
+ * certifies a surface nobody rests on.
569
+ */
570
+ function restAtom(node: Element, prefix: string): string | undefined {
571
+ for (const cls of Array.from(node.classList)) {
572
+ if (!cls.startsWith(prefix)) continue;
573
+ const value = cls.slice(prefix.length);
574
+ if (/^\d*(hover|active|focus|press|disabled)/.test(value)) continue;
575
+ return value;
576
+ }
577
+ return undefined;
578
+ }
579
+
580
+ /** `_o-0--9` is Tamagui's atom for 0.9; no resting atom means no rest dim. */
581
+ function restOpacity(node: Element): number {
582
+ const atom = restAtom(node, "_o-");
583
+ if (atom === undefined) return 1;
584
+ const value = Number(atom.replaceAll("--", "."));
585
+ return Number.isFinite(value) ? value : 1;
586
+ }
587
+
588
+ /**
589
+ * The ink as PAINTED. An opacity on the press target multiplies the label
590
+ * toward the fill under it, so the token pair is not what a reader sees:
591
+ * MPO-128's warning action measures 4.66:1 as tokens and 3.88:1 as pixels.
592
+ */
593
+ function paintedInk(ink: string, ground: string, alpha: number): string {
594
+ const f = normalizeToHex(ink);
595
+ const b = normalizeToHex(ground);
596
+ if (!f || !b) return ink;
597
+ if (alpha >= 1) return f;
598
+ const channel = (offset: number) =>
599
+ Math.round(
600
+ Number.parseInt(f.slice(offset, offset + 2), 16) * alpha +
601
+ Number.parseInt(b.slice(offset, offset + 2), 16) * (1 - alpha),
602
+ )
603
+ .toString(16)
604
+ .padStart(2, "0");
605
+ return `#${channel(1)}${channel(3)}${channel(5)}`;
546
606
  }
547
607
 
548
608
  describe("Toast overlay shadow (standalone === viewport)", () => {
@@ -694,28 +754,40 @@ describe("Toast action label weight and contrast (TEXT NODE)", () => {
694
754
  expect(screen.getByTestId("toast").contains(textNode)).toBe(true);
695
755
  });
696
756
 
697
- it.each(["accent", "success", "warning", "error"] as const)(
698
- "%s action label clears 4.5:1 vs its pill in light and dark",
757
+ it.each(TOAST_INTENTS)(
758
+ "%s action label clears the AA floor AS PAINTED, in light and dark",
699
759
  (intent) => {
700
- for (const scheme of ["light", "dark"] as const) {
760
+ for (const scheme of CONTRAST_SCHEMES) {
701
761
  renderWithProviders(
702
- <Theme name={scheme}>
703
- <ContrastProbe intent={intent} />
704
- </Theme>,
705
- );
706
- const probe = screen.getByTestId("contrast-probe");
707
- const fg = probe.getAttribute("data-fg") ?? "";
708
- const bg = probe.getAttribute("data-bg") ?? "";
709
- const label = screen.getByText(ACTION);
710
- const pill = label.parentElement as HTMLElement;
711
- const labelColor = (label as HTMLElement).style.color;
712
- const pillBg = (pill as HTMLElement).style.backgroundColor;
713
- const fromProbe = measuredRatio(fg, bg);
714
- const fromNodes = measuredRatio(labelColor || fg, pillBg || bg);
715
- const ratio = Number.isFinite(fromNodes) ? fromNodes : fromProbe;
716
- expect(ratio, `${scheme} ${intent} ${fg} on ${bg}`).toBeGreaterThanOrEqual(
717
- aaTextContrastRatio,
762
+ <ContrastScheme scheme={scheme}>
763
+ <AccentInkProbe />
764
+ <Toast
765
+ title="Archived"
766
+ intent={intent}
767
+ action={{ label: ACTION, onPress: () => {} }}
768
+ onDismiss={() => {}}
769
+ />
770
+ </ContrastScheme>,
718
771
  );
772
+ // Non-accent intents ride their hue sub-theme; accent stays on base.
773
+ const theme = houseThemes[intent === "accent" ? scheme : `${scheme}_${intent}`];
774
+ const groundToken = restAtom(screen.getByTestId("toast"), "_bg-");
775
+ const inkToken = restAtom(screen.getByText(ACTION), "_col-");
776
+ const ground = theme?.[groundToken ?? ""] ?? "";
777
+ const ink =
778
+ intent === "accent"
779
+ ? (screen.getByTestId("accent-ink").getAttribute("data-fg") ?? "")
780
+ : (theme?.[inkToken ?? ""] ?? "");
781
+ const where = `${scheme} ${intent}: ${inkToken ?? "?"} on ${groundToken ?? "?"}`;
782
+ expect(ground, `${where} -- the toast frame paints no resting fill`).toBeTruthy();
783
+ expect(ink, `${where} -- the action label emits no resting ink`).toBeTruthy();
784
+ const alpha = restOpacity(screen.getByLabelText(ACTION));
785
+ const report = measureContrast({
786
+ foreground: paintedInk(ink, ground, alpha),
787
+ background: ground,
788
+ label: `${where} at rest opacity ${alpha}`,
789
+ });
790
+ expect(report.ratio, report.label).toBeGreaterThanOrEqual(aaTextContrastRatio);
719
791
  cleanup();
720
792
  }
721
793
  },
@@ -283,12 +283,14 @@ const ToastActionTarget = styled(View, {
283
283
  alignItems: "center",
284
284
  justifyContent: "center",
285
285
  flexShrink: 0,
286
- opacity: 0.9,
286
+ // No REST dim. The label is $color11 — the lowest AA-safe step of the hue —
287
+ // sitting straight on the toast fill, so it carries no headroom for a
288
+ // multiplier: 0.9 composited every light intent under 4.5 (MPO-128). Hover
289
+ // and press read off the pill's own fill instead.
287
290
  outlineWidth: 0,
288
- hoverStyle: { opacity: 1 },
289
291
  pressStyle: { opacity: 0.95 },
290
292
  focusStyle: { outlineWidth: 0 },
291
- focusVisibleStyle: { opacity: 1, outlineWidth: 0 },
293
+ focusVisibleStyle: { outlineWidth: 0 },
292
294
  });
293
295
 
294
296
  const ToastActionPill = styled(View, {
@@ -66,6 +66,14 @@ export interface TreeSelectProps extends Omit<GetProps<typeof YStack>, "children
66
66
  open?: boolean;
67
67
  onOpenChange?: (open: boolean) => void;
68
68
  defaultExpandedIds?: string[];
69
+ /**
70
+ * MPO-283 — accessible name for the trigger. `GetProps<typeof YStack>`
71
+ * already admitted this prop, but it landed on the outer wrapper, which is
72
+ * not an accessibility element on iOS, so nothing read it. It is routed to
73
+ * the trigger now. `aria-label` is accepted as an alias.
74
+ */
75
+ accessibilityLabel?: string;
76
+ "aria-label"?: string;
69
77
  }
70
78
 
71
79
  function defaultNodeIcon(hasChildren: boolean, isExpanded: boolean, iconSize: number) {
@@ -134,6 +142,24 @@ function TreeSelectRows({
134
142
  aria-expanded={hasChildren ? isExpanded : undefined}
135
143
  aria-selected={isSelected}
136
144
  aria-level={depth + 1}
145
+ // MPO-283: the aria-* above are web-only. Without the RN spellings
146
+ // a row is not an accessibility element on iOS, so the whole tree
147
+ // came back as loose StaticText with no role and no selected state.
148
+ // `role` is overridden too: RN prefers it over accessibilityRole,
149
+ // and `treeitem` leaves the element out of the iOS tree the same
150
+ // way `radio` does (measured, iOS 26.2).
151
+ {...(!isWeb
152
+ ? {
153
+ accessible: true,
154
+ role: "button" as const,
155
+ accessibilityRole: "button" as const,
156
+ accessibilityLabel: node.label,
157
+ accessibilityState: {
158
+ selected: isSelected,
159
+ ...(hasChildren ? { expanded: isExpanded } : undefined),
160
+ },
161
+ }
162
+ : undefined)}
137
163
  data-treeselect-row={node.id}
138
164
  data-treeselect-index={String(index)}
139
165
  data-depth={String(depth)}
@@ -181,6 +207,16 @@ function TreeSelectRows({
181
207
  ? t("Collapse {{label}}", { label: node.label })
182
208
  : t("Expand {{label}}", { label: node.label })
183
209
  }
210
+ // MPO-283: the aria-label above never reaches native.
211
+ {...(!isWeb
212
+ ? {
213
+ accessible: true,
214
+ accessibilityRole: "button" as const,
215
+ accessibilityLabel: isExpanded
216
+ ? t("Collapse {{label}}", { label: node.label })
217
+ : t("Expand {{label}}", { label: node.label }),
218
+ }
219
+ : undefined)}
184
220
  width={expandIconSize}
185
221
  height={expandIconSize}
186
222
  alignItems="center"
@@ -321,6 +357,7 @@ function Trigger({
321
357
  triggerRef,
322
358
  sizeToken,
323
359
  borderRadius,
360
+ accessibilityLabel,
324
361
  }: {
325
362
  display?: string;
326
363
  placeholder: string;
@@ -328,6 +365,7 @@ function Trigger({
328
365
  disabled: boolean;
329
366
  id?: string;
330
367
  labelled: boolean;
368
+ accessibilityLabel?: string;
331
369
  onToggle: () => void;
332
370
  triggerRef: (node: HTMLElement | null) => void;
333
371
  sizeToken: string;
@@ -349,8 +387,21 @@ function Trigger({
349
387
  role="combobox"
350
388
  aria-haspopup="tree"
351
389
  aria-expanded={open}
352
- aria-label={labelled ? undefined : placeholder}
390
+ aria-label={accessibilityLabel ?? (labelled ? undefined : placeholder)}
353
391
  id={id}
392
+ // MPO-283 (same family as ToggleGroup / RadioGroup): every semantic on
393
+ // this trigger above is a web attribute, and tamagui does not map any
394
+ // of them onto React Native, so on iOS the control reached the
395
+ // accessibility tree with no role, no name and no expanded state.
396
+ {...(!isWeb
397
+ ? {
398
+ accessible: true,
399
+ role: "button" as const,
400
+ accessibilityRole: "button" as const,
401
+ accessibilityLabel: accessibilityLabel ?? display ?? placeholder,
402
+ accessibilityState: { disabled, expanded: open },
403
+ }
404
+ : undefined)}
354
405
  tabIndex={disabled || open ? -1 : 0}
355
406
  disabled={disabled}
356
407
  cursor={disabled ? "not-allowed" : "pointer"}
@@ -582,6 +633,7 @@ function FloatingTreeSelect({
582
633
  sizeToken,
583
634
  borderRadius,
584
635
  loading,
636
+ accessibilityLabel,
585
637
  }: {
586
638
  nodes: TreeNode[];
587
639
  value?: string;
@@ -599,6 +651,7 @@ function FloatingTreeSelect({
599
651
  sizeToken: string;
600
652
  borderRadius: number | string;
601
653
  loading?: boolean;
654
+ accessibilityLabel?: string;
602
655
  }) {
603
656
  const treeId = useId();
604
657
  const searchRef = useRef<HTMLInputElement | null>(null);
@@ -695,6 +748,7 @@ function FloatingTreeSelect({
695
748
  triggerRef={panel.setReferenceRef}
696
749
  sizeToken={sizeToken}
697
750
  borderRadius={borderRadius}
751
+ accessibilityLabel={accessibilityLabel}
698
752
  />
699
753
  {panel.mounted && (
700
754
  <FloatingFocusManager context={panel.context} modal={false} initialFocus={-1}>
@@ -772,6 +826,7 @@ function SheetTreeSelect({
772
826
  sizeToken,
773
827
  borderRadius,
774
828
  loading,
829
+ accessibilityLabel,
775
830
  }: {
776
831
  nodes: TreeNode[];
777
832
  value?: string;
@@ -789,6 +844,7 @@ function SheetTreeSelect({
789
844
  sizeToken: string;
790
845
  borderRadius: number | string;
791
846
  loading?: boolean;
847
+ accessibilityLabel?: string;
792
848
  }) {
793
849
  const treeId = useId();
794
850
  const searchRef = useRef<HTMLInputElement | null>(null);
@@ -844,6 +900,7 @@ function SheetTreeSelect({
844
900
  }}
845
901
  sizeToken={sizeToken}
846
902
  borderRadius={borderRadius}
903
+ accessibilityLabel={accessibilityLabel}
847
904
  />
848
905
  }
849
906
  header={
@@ -902,6 +959,8 @@ export function TreeSelect({
902
959
  onOpenChange,
903
960
  defaultExpandedIds,
904
961
  id: idProp,
962
+ accessibilityLabel,
963
+ "aria-label": ariaLabel,
905
964
  ...stackProps
906
965
  }: TreeSelectProps) {
907
966
  if (isWeb) ensureKeyboardModalityTracking();
@@ -965,6 +1024,7 @@ export function TreeSelect({
965
1024
  sizeToken: String(knobProps.sizeToken),
966
1025
  borderRadius: knobProps.borderRadius.borderRadius,
967
1026
  loading,
1027
+ accessibilityLabel: accessibilityLabel ?? ariaLabel,
968
1028
  };
969
1029
 
970
1030
  const core = shouldUseSheet ? (
@@ -1,7 +1,6 @@
1
1
  import { useResolvedKnobs } from "@multiplatform.one/theme";
2
2
  import { useTranslation } from "../shared/i18n";
3
3
  import { Text, XStack, YStack, type YStackProps } from "tamagui";
4
- import { componentColors } from "../componentColors";
5
4
  import { ChartDataFrame } from "./ChartDataView";
6
5
  import { ChartSurface } from "./ChartSurface";
7
6
  import { chartDatumText, describeChart, describeDatum } from "./accessibility";
@@ -169,7 +168,7 @@ export function PieChart({
169
168
  {...chartWebProps({ "data-mpo-chart-datum-label": "true" })}
170
169
  {...knobProps.body}
171
170
  fontSize="$2"
172
- color={componentColors.text.muted}
171
+ color={knobProps.textAccentColor}
173
172
  flex={1}
174
173
  numberOfLines={1}
175
174
  >
@@ -77,7 +77,7 @@ export function HighlightedCode({
77
77
  >
78
78
  {showLineNumbers && (
79
79
  <Text
80
- color={componentColors.text.secondary}
80
+ color={knobProps.textAccentColor}
81
81
  fontSize={resolvedFontSize}
82
82
  width={gutterWidth}
83
83
  data-line-number=""
@@ -30,15 +30,17 @@ export const componentColors = {
30
30
  border: "$color7",
31
31
  },
32
32
 
33
- /** Text color levels. muted sits on the $color11 tier — the lowest ramp
34
- * step that keeps secondary text AA-readable on color1/2 surfaces. */
33
+ /** Text color levels. */
35
34
  text: {
36
35
  // MPO-19 X5: was `$color12`, a second answer to what `resolveKnobs`'
37
36
  // `textAccent: high` already resolves to. `$color` IS the theme's ink,
38
37
  // and it tracks a sub-theme where the raw ramp step does not.
39
38
  primary: "$color",
40
- secondary: "$color11",
41
- muted: "$color11",
39
+ // MPO-154: `secondary` and `muted` were the same mistake one tier down —
40
+ // a static `$color11` read into 85 `color` props, which pinned every
41
+ // helper, caption and inactive label dim at `textAccent: high`. Secondary
42
+ // text takes `useResolvedKnobs().knobProps.textAccentColor`, which is
43
+ // `$color11` at low/medium (the AA floor) and `$color` at high.
42
44
  subtle: "$color8",
43
45
  },
44
46
 
@@ -11,7 +11,6 @@ import {
11
11
  type GroupPosition,
12
12
  } from "@multiplatform.one/theme";
13
13
  import { Image as TamaguiImage, View, isWeb } from "tamagui";
14
- import { componentColors } from "../../componentColors";
15
14
  import { Skeleton } from "../../Skeleton";
16
15
  import { isThumbnailSize, thumbnailPx as resolveThumbnailPx } from "./shared";
17
16
  import type { ImagePlaceholder, ImageProps } from "./types";
@@ -51,6 +50,7 @@ function glyphSize(px: number): number {
51
50
  }
52
51
 
53
52
  function DefaultFallback({ px }: { px: number }) {
53
+ const { knobProps } = useResolvedKnobs();
54
54
  return (
55
55
  <View
56
56
  data-image-fallback=""
@@ -61,7 +61,7 @@ function DefaultFallback({ px }: { px: number }) {
61
61
  justifyContent="center"
62
62
  backgroundColor="$color3"
63
63
  >
64
- <ImageIcon size={glyphSize(px)} color={componentColors.text.muted} />
64
+ <ImageIcon size={glyphSize(px)} color={knobProps.textAccentColor} />
65
65
  </View>
66
66
  );
67
67
  }
@@ -18,7 +18,6 @@ import { createContext, useContext, useEffect, useRef, type ReactNode } from "re
18
18
  import { useTranslation } from "../shared/i18n";
19
19
  import { XStack, YStack, type YStackProps } from "tamagui";
20
20
  import { Alert } from "../Alert";
21
- import { componentColors } from "../componentColors";
22
21
  import { Skeleton } from "../Skeleton";
23
22
  import { Text } from "../Text";
24
23
  import { EmptyState } from "./page";
@@ -320,7 +319,7 @@ function AsyncPendingBar() {
320
319
  {...knobProps.gap}
321
320
  >
322
321
  <Spinner size="small" aria-hidden />
323
- <Text {...knobProps.label} color={componentColors.text.muted}>
322
+ <Text {...knobProps.label} color={knobProps.textAccentColor}>
324
323
  {t("Updating...")}
325
324
  </Text>
326
325
  </XStack>
@@ -1,6 +1,20 @@
1
+ import { cleanup, screen } from "@testing-library/react";
1
2
  import { renderWithProviders } from "@multiplatform.one/test-utils";
2
- import { describe, expect, it } from "vitest";
3
+ import { Preset } from "@multiplatform.one/theme";
4
+ import { afterEach, describe, expect, it } from "vitest";
3
5
  import { EmptyState } from "./EmptyState";
6
+ import { KPICard } from "../views/Dashboard";
7
+
8
+ afterEach(cleanup);
9
+
10
+ const RADIUS_STOPS = ["none", "small", "medium", "large", "full"] as const;
11
+
12
+ function radiusAtoms(el: Element): string[] {
13
+ return String(el.className || "")
14
+ .split(" ")
15
+ .filter((c) => /^_(btlr|btrr|bbrr|bblr)-/.test(c))
16
+ .sort();
17
+ }
4
18
 
5
19
  describe("EmptyState", () => {
6
20
  it("does not pin compact, so the density knob restyles the frame", () => {
@@ -28,3 +42,46 @@ describe("EmptyState", () => {
28
42
  expect(container.textContent).toContain("Records you add will show up here.");
29
43
  });
30
44
  });
45
+
46
+ /**
47
+ * RULINGS-2026-08-28 R2e (MPO-106 D4): an icon well rides the radius scale
48
+ * (DEFAULT); R-PILL is reserved for a well that IS a count badge. EmptyState
49
+ * declared R-PILL and painted 1000, so its well stayed a circle at every
50
+ * stop while KPICard's well — the dialect the ruling picked — rode the scale.
51
+ */
52
+ describe("EmptyState icon well radius (R2e)", () => {
53
+ it.each(RADIUS_STOPS)("at radius %s the well matches KPICard's well", (borderRadius) => {
54
+ renderWithProviders(
55
+ <Preset overrides={{ borderRadius }}>
56
+ <>
57
+ <EmptyState title="Nothing here" icon={<span data-testid="empty-icon">i</span>} />
58
+ <KPICard
59
+ config={{ id: "k", title: "K", value: 1, icon: <span data-testid="kpi-icon">i</span> }}
60
+ />
61
+ </>
62
+ </Preset>,
63
+ );
64
+ const emptyWell = screen.getByTestId("empty-icon").parentElement as HTMLElement;
65
+ const kpiWell = screen.getByTestId("kpi-icon").parentElement as HTMLElement;
66
+ expect(radiusAtoms(emptyWell)).not.toHaveLength(0);
67
+ expect(radiusAtoms(emptyWell)).toEqual(radiusAtoms(kpiWell));
68
+ // A knob-immunity declaration is what licensed the circle; the well is
69
+ // not immune, so it must carry none.
70
+ expect(emptyWell.getAttribute("data-radius-class")).toBeNull();
71
+ });
72
+
73
+ it("squares at radius none rather than staying a circle", () => {
74
+ renderWithProviders(
75
+ <Preset overrides={{ borderRadius: "none" }}>
76
+ <EmptyState title="Nothing here" icon={<span data-testid="empty-icon">i</span>} />
77
+ </Preset>,
78
+ );
79
+ const well = screen.getByTestId("empty-icon").parentElement as HTMLElement;
80
+ expect(radiusAtoms(well)).toEqual([
81
+ "_bblr-t-radius-0",
82
+ "_bbrr-t-radius-0",
83
+ "_btlr-t-radius-0",
84
+ "_btrr-t-radius-0",
85
+ ]);
86
+ });
87
+ });
@@ -9,7 +9,6 @@
9
9
  */
10
10
  import {
11
11
  Intent,
12
- radiusClassProps,
13
12
  readingWidthStyle,
14
13
  useResolvedKnobs,
15
14
  warnBannedErrorWords,
@@ -69,18 +68,23 @@ export function EmptyState({
69
68
  warnBannedErrorWords(description, { component: "EmptyState" });
70
69
  }
71
70
 
71
+ const {
72
+ borderColor: _wellEdgeColor,
73
+ borderWidth: _wellEdgeWidth,
74
+ ...wellRadius
75
+ } = knobProps.borderRadius;
76
+
72
77
  const well = icon ? (
73
78
  <YStack
74
79
  alignItems="center"
75
80
  justifyContent="center"
76
81
  backgroundColor={componentColors.interactive.background}
77
- // R-PILL icon well: always a circle; its inset scales with the
78
- // size knob (spec: empty icon well consumes sizeToken). Declared so
79
- // the `radius:none` sweep licenses the circle instead of guessing
80
- // from its geometry (D-09 / LC-60).
81
- {...radiusClassProps("R-PILL", "empty icon well")}
82
+ // R2e: an icon well rides the radius scale (DEFAULT), the same
83
+ // resolution KPICard's well takes. Only the radius half of the
84
+ // fragment applies — the well paints no edge. Its inset still scales
85
+ // with the size knob (spec: empty icon well consumes sizeToken).
86
+ {...wellRadius}
82
87
  padding={knobProps.sizeToken as any}
83
- borderRadius={1000}
84
88
  aria-hidden
85
89
  {...(!isWeb ? { accessibilityElementsHidden: true } : null)}
86
90
  >
@@ -1,7 +1,7 @@
1
1
  import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
2
2
  import { Input } from "@multiplatform.one/forms";
3
3
  import { Paragraph, YStack } from "tamagui";
4
- import { componentColors } from "../../componentColors";
4
+ import { Text } from "../../Text";
5
5
  import { KeyboardAvoidingWrapper } from "./index";
6
6
 
7
7
  const meta: Meta<typeof KeyboardAvoidingWrapper> = {
@@ -27,10 +27,10 @@ export const Default: Story = {
27
27
  <KeyboardAvoidingWrapper>
28
28
  <YStack>
29
29
  <Paragraph>Content inside KeyboardAvoidingWrapper</Paragraph>
30
- <Paragraph color={componentColors.text.muted}>
30
+ <Text>
31
31
  On native, this shifts content when the keyboard appears. On web, it is a simple
32
32
  passthrough wrapper.
33
- </Paragraph>
33
+ </Text>
34
34
  <Input label="Test input" placeholder="Focus to test keyboard avoidance" />
35
35
  </YStack>
36
36
  </KeyboardAvoidingWrapper>
@@ -8,6 +8,7 @@ import {
8
8
  } from "@multiplatform.one/theme";
9
9
  import type { ReactNode } from "react";
10
10
  import { Paragraph, Text, YStack } from "tamagui";
11
+ import { Text as HouseText } from "../Text";
11
12
  import { componentColors } from "../componentColors";
12
13
  import {
13
14
  FeedLayout,
@@ -43,11 +44,7 @@ function PaneFill({ label, hint, muted }: { label: string; hint?: string; muted?
43
44
  gap="$2"
44
45
  >
45
46
  <Paragraph fontWeight="600">{label}</Paragraph>
46
- {hint ? (
47
- <Text color={componentColors.text.muted} fontSize="$2">
48
- {hint}
49
- </Text>
50
- ) : null}
47
+ {hint ? <HouseText fontSize="$2">{hint}</HouseText> : null}
51
48
  </YStack>
52
49
  );
53
50
  }
@@ -274,9 +271,7 @@ export const ProseReadingWidth: StoryObj<typeof ReadingWidth> = {
274
271
  </Paragraph>
275
272
  </ReadingWidth>
276
273
  <ReadingWidth measure="none">
277
- <Paragraph color={componentColors.text.muted}>
278
- Ejected measure (full width of parent).
279
- </Paragraph>
274
+ <HouseText>Ejected measure (full width of parent).</HouseText>
280
275
  </ReadingWidth>
281
276
  </YStack>
282
277
  ),