@multiplatform.one/components 7.7.6 → 7.8.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 (565) hide show
  1. package/dist/cjs/Button.native.js.map +1 -1
  2. package/dist/cjs/Card.cjs +7 -1
  3. package/dist/cjs/Card.native.js +11 -1
  4. package/dist/cjs/Card.native.js.map +1 -1
  5. package/dist/cjs/CardFooter.cjs +1 -0
  6. package/dist/cjs/CardFooter.native.js +1 -0
  7. package/dist/cjs/CardFooter.native.js.map +1 -1
  8. package/dist/cjs/CopyField/index.cjs +6 -1
  9. package/dist/cjs/CopyField/index.native.js +6 -1
  10. package/dist/cjs/CopyField/index.native.js.map +1 -1
  11. package/dist/cjs/DropdownMenu/index.cjs +31 -1
  12. package/dist/cjs/DropdownMenu/index.native.js +31 -1
  13. package/dist/cjs/DropdownMenu/index.native.js.map +1 -1
  14. package/dist/cjs/Meter/index.cjs +12 -5
  15. package/dist/cjs/Meter/index.native.js +12 -5
  16. package/dist/cjs/Meter/index.native.js.map +1 -1
  17. package/dist/cjs/Tabs/index.cjs +7 -6
  18. package/dist/cjs/Tabs/index.native.js +8 -7
  19. package/dist/cjs/Tabs/index.native.js.map +1 -1
  20. package/dist/cjs/Toast/index.cjs +53 -2
  21. package/dist/cjs/Toast/index.native.js +55 -2
  22. package/dist/cjs/Toast/index.native.js.map +1 -1
  23. package/dist/cjs/actions/DestructiveAction.cjs +7 -13
  24. package/dist/cjs/actions/DestructiveAction.native.js +7 -15
  25. package/dist/cjs/actions/DestructiveAction.native.js.map +1 -1
  26. package/dist/cjs/charts/Axis.cjs +5 -0
  27. package/dist/cjs/charts/Axis.native.js +5 -0
  28. package/dist/cjs/charts/Axis.native.js.map +1 -1
  29. package/dist/cjs/charts/BarChart.cjs +71 -57
  30. package/dist/cjs/charts/BarChart.native.js +81 -67
  31. package/dist/cjs/charts/BarChart.native.js.map +1 -1
  32. package/dist/cjs/charts/ChartDataView.cjs +212 -0
  33. package/dist/cjs/charts/ChartDataView.native.js +224 -0
  34. package/dist/cjs/charts/ChartDataView.native.js.map +1 -0
  35. package/dist/cjs/charts/ChartSurface.cjs +5 -1
  36. package/dist/cjs/charts/ChartSurface.native.js +5 -1
  37. package/dist/cjs/charts/ChartSurface.native.js.map +1 -1
  38. package/dist/cjs/charts/LineChart.cjs +81 -67
  39. package/dist/cjs/charts/LineChart.native.js +94 -80
  40. package/dist/cjs/charts/LineChart.native.js.map +1 -1
  41. package/dist/cjs/charts/PieChart.cjs +98 -73
  42. package/dist/cjs/charts/PieChart.native.js +109 -84
  43. package/dist/cjs/charts/PieChart.native.js.map +1 -1
  44. package/dist/cjs/charts/Sparkline.cjs +10 -1
  45. package/dist/cjs/charts/Sparkline.native.js +10 -1
  46. package/dist/cjs/charts/Sparkline.native.js.map +1 -1
  47. package/dist/cjs/charts/accessibility.cjs +4 -0
  48. package/dist/cjs/charts/accessibility.native.js +7 -0
  49. package/dist/cjs/charts/accessibility.native.js.map +1 -1
  50. package/dist/cjs/charts/index.cjs +3 -1
  51. package/dist/cjs/charts/index.native.js +2 -0
  52. package/dist/cjs/charts/index.native.js.map +1 -1
  53. package/dist/cjs/charts/math.cjs +16 -0
  54. package/dist/cjs/charts/math.native.js +18 -0
  55. package/dist/cjs/charts/math.native.js.map +1 -1
  56. package/dist/cjs/charts/series.cjs +49 -7
  57. package/dist/cjs/charts/series.native.js +53 -11
  58. package/dist/cjs/charts/series.native.js.map +1 -1
  59. package/dist/cjs/charts/svg.cjs +46 -3
  60. package/dist/cjs/charts/svg.native.js +46 -3
  61. package/dist/cjs/charts/svg.native.js.map +1 -1
  62. package/dist/cjs/code/CodeBlock/index.cjs +6 -1
  63. package/dist/cjs/code/CodeBlock/index.native.js +6 -1
  64. package/dist/cjs/code/CodeBlock/index.native.js.map +1 -1
  65. package/dist/cjs/feedback/ConfirmDialog.cjs +7 -21
  66. package/dist/cjs/feedback/ConfirmDialog.native.js +7 -22
  67. package/dist/cjs/feedback/ConfirmDialog.native.js.map +1 -1
  68. package/dist/cjs/feedback/NotifyHost.cjs +2 -1
  69. package/dist/cjs/feedback/NotifyHost.native.js +3 -2
  70. package/dist/cjs/feedback/NotifyHost.native.js.map +1 -1
  71. package/dist/cjs/feedback/copy.cjs +36 -4
  72. package/dist/cjs/feedback/copy.native.js +38 -4
  73. package/dist/cjs/feedback/copy.native.js.map +1 -1
  74. package/dist/cjs/feedback/index.cjs +1 -0
  75. package/dist/cjs/feedback/index.native.js +1 -0
  76. package/dist/cjs/feedback/index.native.js.map +1 -1
  77. package/dist/cjs/feedback/notify.cjs +1 -0
  78. package/dist/cjs/feedback/notify.native.js +1 -0
  79. package/dist/cjs/feedback/notify.native.js.map +1 -1
  80. package/dist/cjs/feedback/route.cjs +3 -0
  81. package/dist/cjs/feedback/route.native.js +3 -0
  82. package/dist/cjs/feedback/route.native.js.map +1 -1
  83. package/dist/cjs/feedback/store.cjs +6 -0
  84. package/dist/cjs/feedback/store.native.js +8 -0
  85. package/dist/cjs/feedback/store.native.js.map +1 -1
  86. package/dist/cjs/icons/lucide.cjs +2 -1
  87. package/dist/cjs/icons/lucide.native.js +2 -1
  88. package/dist/cjs/icons/lucide.native.js.map +1 -1
  89. package/dist/cjs/layouts/PaneScaffold.cjs +96 -41
  90. package/dist/cjs/layouts/PaneScaffold.native.js +97 -41
  91. package/dist/cjs/layouts/PaneScaffold.native.js.map +1 -1
  92. package/dist/cjs/layouts/index.cjs +2 -0
  93. package/dist/cjs/layouts/index.native.js +2 -0
  94. package/dist/cjs/layouts/index.native.js.map +1 -1
  95. package/dist/cjs/layouts/page.cjs +48 -7
  96. package/dist/cjs/layouts/page.native.js +50 -7
  97. package/dist/cjs/layouts/page.native.js.map +1 -1
  98. package/dist/cjs/shared/useKeyboardInset.cjs +1 -19
  99. package/dist/cjs/shared/useKeyboardInset.native.js +3 -3
  100. package/dist/cjs/shared/useKeyboardInset.native.js.map +1 -1
  101. package/dist/cjs/views/Dashboard.cjs +110 -17
  102. package/dist/cjs/views/Dashboard.native.js +151 -45
  103. package/dist/cjs/views/Dashboard.native.js.map +1 -1
  104. package/dist/cjs/views/Gantt.cjs +374 -91
  105. package/dist/cjs/views/Gantt.native.js +443 -94
  106. package/dist/cjs/views/Gantt.native.js.map +1 -1
  107. package/dist/cjs/views/ganttMath.cjs +91 -2
  108. package/dist/cjs/views/ganttMath.native.js +113 -3
  109. package/dist/cjs/views/ganttMath.native.js.map +1 -1
  110. package/dist/cjs/views/index.cjs +20 -1
  111. package/dist/cjs/views/index.native.js +20 -1
  112. package/dist/cjs/views/index.native.js.map +1 -1
  113. package/dist/esm/Button.mjs.map +1 -1
  114. package/dist/esm/Button.native.js.map +1 -1
  115. package/dist/esm/Card.mjs +8 -2
  116. package/dist/esm/Card.mjs.map +1 -1
  117. package/dist/esm/Card.native.js +12 -2
  118. package/dist/esm/Card.native.js.map +1 -1
  119. package/dist/esm/CardFooter.mjs +1 -0
  120. package/dist/esm/CardFooter.mjs.map +1 -1
  121. package/dist/esm/CardFooter.native.js +1 -0
  122. package/dist/esm/CardFooter.native.js.map +1 -1
  123. package/dist/esm/CopyField/index.mjs +7 -2
  124. package/dist/esm/CopyField/index.mjs.map +1 -1
  125. package/dist/esm/CopyField/index.native.js +7 -2
  126. package/dist/esm/CopyField/index.native.js.map +1 -1
  127. package/dist/esm/DropdownMenu/index.mjs +32 -2
  128. package/dist/esm/DropdownMenu/index.mjs.map +1 -1
  129. package/dist/esm/DropdownMenu/index.native.js +32 -2
  130. package/dist/esm/DropdownMenu/index.native.js.map +1 -1
  131. package/dist/esm/Meter/index.mjs +12 -5
  132. package/dist/esm/Meter/index.mjs.map +1 -1
  133. package/dist/esm/Meter/index.native.js +12 -5
  134. package/dist/esm/Meter/index.native.js.map +1 -1
  135. package/dist/esm/Tabs/index.mjs +7 -6
  136. package/dist/esm/Tabs/index.mjs.map +1 -1
  137. package/dist/esm/Tabs/index.native.js +8 -7
  138. package/dist/esm/Tabs/index.native.js.map +1 -1
  139. package/dist/esm/Toast/index.mjs +52 -3
  140. package/dist/esm/Toast/index.mjs.map +1 -1
  141. package/dist/esm/Toast/index.native.js +54 -3
  142. package/dist/esm/Toast/index.native.js.map +1 -1
  143. package/dist/esm/actions/DestructiveAction.mjs +8 -14
  144. package/dist/esm/actions/DestructiveAction.mjs.map +1 -1
  145. package/dist/esm/actions/DestructiveAction.native.js +8 -16
  146. package/dist/esm/actions/DestructiveAction.native.js.map +1 -1
  147. package/dist/esm/charts/Axis.mjs +6 -1
  148. package/dist/esm/charts/Axis.mjs.map +1 -1
  149. package/dist/esm/charts/Axis.native.js +6 -1
  150. package/dist/esm/charts/Axis.native.js.map +1 -1
  151. package/dist/esm/charts/BarChart.mjs +72 -58
  152. package/dist/esm/charts/BarChart.mjs.map +1 -1
  153. package/dist/esm/charts/BarChart.native.js +82 -68
  154. package/dist/esm/charts/BarChart.native.js.map +1 -1
  155. package/dist/esm/charts/ChartDataView.mjs +185 -0
  156. package/dist/esm/charts/ChartDataView.mjs.map +1 -0
  157. package/dist/esm/charts/ChartDataView.native.js +194 -0
  158. package/dist/esm/charts/ChartDataView.native.js.map +1 -0
  159. package/dist/esm/charts/ChartSurface.mjs +5 -1
  160. package/dist/esm/charts/ChartSurface.mjs.map +1 -1
  161. package/dist/esm/charts/ChartSurface.native.js +5 -1
  162. package/dist/esm/charts/ChartSurface.native.js.map +1 -1
  163. package/dist/esm/charts/LineChart.mjs +82 -68
  164. package/dist/esm/charts/LineChart.mjs.map +1 -1
  165. package/dist/esm/charts/LineChart.native.js +95 -81
  166. package/dist/esm/charts/LineChart.native.js.map +1 -1
  167. package/dist/esm/charts/PieChart.mjs +100 -75
  168. package/dist/esm/charts/PieChart.mjs.map +1 -1
  169. package/dist/esm/charts/PieChart.native.js +111 -86
  170. package/dist/esm/charts/PieChart.native.js.map +1 -1
  171. package/dist/esm/charts/Sparkline.mjs +11 -2
  172. package/dist/esm/charts/Sparkline.mjs.map +1 -1
  173. package/dist/esm/charts/Sparkline.native.js +11 -2
  174. package/dist/esm/charts/Sparkline.native.js.map +1 -1
  175. package/dist/esm/charts/accessibility.mjs +4 -1
  176. package/dist/esm/charts/accessibility.mjs.map +1 -1
  177. package/dist/esm/charts/accessibility.native.js +7 -1
  178. package/dist/esm/charts/accessibility.native.js.map +1 -1
  179. package/dist/esm/charts/index.mjs +2 -1
  180. package/dist/esm/charts/index.mjs.map +1 -1
  181. package/dist/esm/charts/index.native.js +2 -1
  182. package/dist/esm/charts/index.native.js.map +1 -1
  183. package/dist/esm/charts/math.mjs +16 -1
  184. package/dist/esm/charts/math.mjs.map +1 -1
  185. package/dist/esm/charts/math.native.js +18 -1
  186. package/dist/esm/charts/math.native.js.map +1 -1
  187. package/dist/esm/charts/series.mjs +51 -9
  188. package/dist/esm/charts/series.mjs.map +1 -1
  189. package/dist/esm/charts/series.native.js +55 -13
  190. package/dist/esm/charts/series.native.js.map +1 -1
  191. package/dist/esm/charts/svg.mjs +40 -4
  192. package/dist/esm/charts/svg.mjs.map +1 -1
  193. package/dist/esm/charts/svg.native.js +40 -4
  194. package/dist/esm/charts/svg.native.js.map +1 -1
  195. package/dist/esm/code/CodeBlock/index.mjs +7 -2
  196. package/dist/esm/code/CodeBlock/index.mjs.map +1 -1
  197. package/dist/esm/code/CodeBlock/index.native.js +7 -2
  198. package/dist/esm/code/CodeBlock/index.native.js.map +1 -1
  199. package/dist/esm/feedback/ConfirmDialog.mjs +8 -22
  200. package/dist/esm/feedback/ConfirmDialog.mjs.map +1 -1
  201. package/dist/esm/feedback/ConfirmDialog.native.js +8 -23
  202. package/dist/esm/feedback/ConfirmDialog.native.js.map +1 -1
  203. package/dist/esm/feedback/NotifyHost.mjs +2 -1
  204. package/dist/esm/feedback/NotifyHost.mjs.map +1 -1
  205. package/dist/esm/feedback/NotifyHost.native.js +3 -2
  206. package/dist/esm/feedback/NotifyHost.native.js.map +1 -1
  207. package/dist/esm/feedback/copy.mjs +35 -4
  208. package/dist/esm/feedback/copy.mjs.map +1 -1
  209. package/dist/esm/feedback/copy.native.js +37 -4
  210. package/dist/esm/feedback/copy.native.js.map +1 -1
  211. package/dist/esm/feedback/index.mjs +2 -2
  212. package/dist/esm/feedback/index.mjs.map +1 -1
  213. package/dist/esm/feedback/index.native.js +2 -2
  214. package/dist/esm/feedback/index.native.js.map +1 -1
  215. package/dist/esm/feedback/notify.mjs +1 -0
  216. package/dist/esm/feedback/notify.mjs.map +1 -1
  217. package/dist/esm/feedback/notify.native.js +1 -0
  218. package/dist/esm/feedback/notify.native.js.map +1 -1
  219. package/dist/esm/feedback/route.mjs +3 -0
  220. package/dist/esm/feedback/route.mjs.map +1 -1
  221. package/dist/esm/feedback/route.native.js +3 -0
  222. package/dist/esm/feedback/route.native.js.map +1 -1
  223. package/dist/esm/feedback/store.mjs +6 -1
  224. package/dist/esm/feedback/store.mjs.map +1 -1
  225. package/dist/esm/feedback/store.native.js +8 -1
  226. package/dist/esm/feedback/store.native.js.map +1 -1
  227. package/dist/esm/icons/lucide.mjs +2 -2
  228. package/dist/esm/icons/lucide.mjs.map +1 -1
  229. package/dist/esm/icons/lucide.native.js +2 -2
  230. package/dist/esm/icons/lucide.native.js.map +1 -1
  231. package/dist/esm/layouts/PaneScaffold.mjs +97 -42
  232. package/dist/esm/layouts/PaneScaffold.mjs.map +1 -1
  233. package/dist/esm/layouts/PaneScaffold.native.js +98 -42
  234. package/dist/esm/layouts/PaneScaffold.native.js.map +1 -1
  235. package/dist/esm/layouts/index.mjs +2 -1
  236. package/dist/esm/layouts/index.mjs.map +1 -1
  237. package/dist/esm/layouts/index.native.js +2 -1
  238. package/dist/esm/layouts/index.native.js.map +1 -1
  239. package/dist/esm/layouts/page.mjs +49 -8
  240. package/dist/esm/layouts/page.mjs.map +1 -1
  241. package/dist/esm/layouts/page.native.js +51 -8
  242. package/dist/esm/layouts/page.native.js.map +1 -1
  243. package/dist/esm/shared/useKeyboardInset.mjs +1 -19
  244. package/dist/esm/shared/useKeyboardInset.mjs.map +1 -1
  245. package/dist/esm/shared/useKeyboardInset.native.js.map +1 -1
  246. package/dist/esm/views/Dashboard.mjs +112 -19
  247. package/dist/esm/views/Dashboard.mjs.map +1 -1
  248. package/dist/esm/views/Dashboard.native.js +153 -47
  249. package/dist/esm/views/Dashboard.native.js.map +1 -1
  250. package/dist/esm/views/Gantt.mjs +376 -93
  251. package/dist/esm/views/Gantt.mjs.map +1 -1
  252. package/dist/esm/views/Gantt.native.js +445 -96
  253. package/dist/esm/views/Gantt.native.js.map +1 -1
  254. package/dist/esm/views/ganttMath.mjs +84 -3
  255. package/dist/esm/views/ganttMath.mjs.map +1 -1
  256. package/dist/esm/views/ganttMath.native.js +106 -4
  257. package/dist/esm/views/ganttMath.native.js.map +1 -1
  258. package/dist/esm/views/index.mjs +2 -2
  259. package/dist/esm/views/index.mjs.map +1 -1
  260. package/dist/esm/views/index.native.js +2 -2
  261. package/dist/esm/views/index.native.js.map +1 -1
  262. package/dist/jsx/Button.mjs.map +1 -1
  263. package/dist/jsx/Button.native.js.map +1 -1
  264. package/dist/jsx/Card.mjs +8 -2
  265. package/dist/jsx/Card.mjs.map +1 -1
  266. package/dist/jsx/Card.native.js +11 -1
  267. package/dist/jsx/Card.native.js.map +1 -1
  268. package/dist/jsx/CardFooter.mjs +1 -0
  269. package/dist/jsx/CardFooter.mjs.map +1 -1
  270. package/dist/jsx/CardFooter.native.js +1 -0
  271. package/dist/jsx/CardFooter.native.js.map +1 -1
  272. package/dist/jsx/CopyField/index.mjs +7 -2
  273. package/dist/jsx/CopyField/index.mjs.map +1 -1
  274. package/dist/jsx/CopyField/index.native.js +6 -1
  275. package/dist/jsx/CopyField/index.native.js.map +1 -1
  276. package/dist/jsx/DropdownMenu/index.mjs +32 -2
  277. package/dist/jsx/DropdownMenu/index.mjs.map +1 -1
  278. package/dist/jsx/DropdownMenu/index.native.js +31 -1
  279. package/dist/jsx/DropdownMenu/index.native.js.map +1 -1
  280. package/dist/jsx/Meter/index.mjs +12 -5
  281. package/dist/jsx/Meter/index.mjs.map +1 -1
  282. package/dist/jsx/Meter/index.native.js +12 -5
  283. package/dist/jsx/Meter/index.native.js.map +1 -1
  284. package/dist/jsx/Tabs/index.mjs +7 -6
  285. package/dist/jsx/Tabs/index.mjs.map +1 -1
  286. package/dist/jsx/Tabs/index.native.js +8 -7
  287. package/dist/jsx/Tabs/index.native.js.map +1 -1
  288. package/dist/jsx/Toast/index.mjs +52 -3
  289. package/dist/jsx/Toast/index.mjs.map +1 -1
  290. package/dist/jsx/Toast/index.native.js +55 -2
  291. package/dist/jsx/Toast/index.native.js.map +1 -1
  292. package/dist/jsx/actions/DestructiveAction.mjs +8 -14
  293. package/dist/jsx/actions/DestructiveAction.mjs.map +1 -1
  294. package/dist/jsx/actions/DestructiveAction.native.js +7 -15
  295. package/dist/jsx/actions/DestructiveAction.native.js.map +1 -1
  296. package/dist/jsx/charts/Axis.mjs +6 -1
  297. package/dist/jsx/charts/Axis.mjs.map +1 -1
  298. package/dist/jsx/charts/Axis.native.js +5 -0
  299. package/dist/jsx/charts/Axis.native.js.map +1 -1
  300. package/dist/jsx/charts/BarChart.mjs +72 -58
  301. package/dist/jsx/charts/BarChart.mjs.map +1 -1
  302. package/dist/jsx/charts/BarChart.native.js +81 -67
  303. package/dist/jsx/charts/BarChart.native.js.map +1 -1
  304. package/dist/jsx/charts/ChartDataView.mjs +185 -0
  305. package/dist/jsx/charts/ChartDataView.mjs.map +1 -0
  306. package/dist/jsx/charts/ChartDataView.native.js +224 -0
  307. package/dist/jsx/charts/ChartDataView.native.js.map +1 -0
  308. package/dist/jsx/charts/ChartSurface.mjs +5 -1
  309. package/dist/jsx/charts/ChartSurface.mjs.map +1 -1
  310. package/dist/jsx/charts/ChartSurface.native.js +5 -1
  311. package/dist/jsx/charts/ChartSurface.native.js.map +1 -1
  312. package/dist/jsx/charts/LineChart.mjs +82 -68
  313. package/dist/jsx/charts/LineChart.mjs.map +1 -1
  314. package/dist/jsx/charts/LineChart.native.js +94 -80
  315. package/dist/jsx/charts/LineChart.native.js.map +1 -1
  316. package/dist/jsx/charts/PieChart.mjs +100 -75
  317. package/dist/jsx/charts/PieChart.mjs.map +1 -1
  318. package/dist/jsx/charts/PieChart.native.js +109 -84
  319. package/dist/jsx/charts/PieChart.native.js.map +1 -1
  320. package/dist/jsx/charts/Sparkline.mjs +11 -2
  321. package/dist/jsx/charts/Sparkline.mjs.map +1 -1
  322. package/dist/jsx/charts/Sparkline.native.js +10 -1
  323. package/dist/jsx/charts/Sparkline.native.js.map +1 -1
  324. package/dist/jsx/charts/accessibility.mjs +4 -1
  325. package/dist/jsx/charts/accessibility.mjs.map +1 -1
  326. package/dist/jsx/charts/accessibility.native.js +7 -0
  327. package/dist/jsx/charts/accessibility.native.js.map +1 -1
  328. package/dist/jsx/charts/index.mjs +2 -1
  329. package/dist/jsx/charts/index.mjs.map +1 -1
  330. package/dist/jsx/charts/index.native.js +2 -0
  331. package/dist/jsx/charts/index.native.js.map +1 -1
  332. package/dist/jsx/charts/math.mjs +16 -1
  333. package/dist/jsx/charts/math.mjs.map +1 -1
  334. package/dist/jsx/charts/math.native.js +18 -0
  335. package/dist/jsx/charts/math.native.js.map +1 -1
  336. package/dist/jsx/charts/series.mjs +51 -9
  337. package/dist/jsx/charts/series.mjs.map +1 -1
  338. package/dist/jsx/charts/series.native.js +53 -11
  339. package/dist/jsx/charts/series.native.js.map +1 -1
  340. package/dist/jsx/charts/svg.mjs +40 -4
  341. package/dist/jsx/charts/svg.mjs.map +1 -1
  342. package/dist/jsx/charts/svg.native.js +46 -3
  343. package/dist/jsx/charts/svg.native.js.map +1 -1
  344. package/dist/jsx/code/CodeBlock/index.mjs +7 -2
  345. package/dist/jsx/code/CodeBlock/index.mjs.map +1 -1
  346. package/dist/jsx/code/CodeBlock/index.native.js +6 -1
  347. package/dist/jsx/code/CodeBlock/index.native.js.map +1 -1
  348. package/dist/jsx/feedback/ConfirmDialog.mjs +8 -22
  349. package/dist/jsx/feedback/ConfirmDialog.mjs.map +1 -1
  350. package/dist/jsx/feedback/ConfirmDialog.native.js +7 -22
  351. package/dist/jsx/feedback/ConfirmDialog.native.js.map +1 -1
  352. package/dist/jsx/feedback/NotifyHost.mjs +2 -1
  353. package/dist/jsx/feedback/NotifyHost.mjs.map +1 -1
  354. package/dist/jsx/feedback/NotifyHost.native.js +3 -2
  355. package/dist/jsx/feedback/NotifyHost.native.js.map +1 -1
  356. package/dist/jsx/feedback/copy.mjs +35 -4
  357. package/dist/jsx/feedback/copy.mjs.map +1 -1
  358. package/dist/jsx/feedback/copy.native.js +38 -4
  359. package/dist/jsx/feedback/copy.native.js.map +1 -1
  360. package/dist/jsx/feedback/index.mjs +2 -2
  361. package/dist/jsx/feedback/index.mjs.map +1 -1
  362. package/dist/jsx/feedback/index.native.js +1 -0
  363. package/dist/jsx/feedback/index.native.js.map +1 -1
  364. package/dist/jsx/feedback/notify.mjs +1 -0
  365. package/dist/jsx/feedback/notify.mjs.map +1 -1
  366. package/dist/jsx/feedback/notify.native.js +1 -0
  367. package/dist/jsx/feedback/notify.native.js.map +1 -1
  368. package/dist/jsx/feedback/route.mjs +3 -0
  369. package/dist/jsx/feedback/route.mjs.map +1 -1
  370. package/dist/jsx/feedback/route.native.js +3 -0
  371. package/dist/jsx/feedback/route.native.js.map +1 -1
  372. package/dist/jsx/feedback/store.mjs +6 -1
  373. package/dist/jsx/feedback/store.mjs.map +1 -1
  374. package/dist/jsx/feedback/store.native.js +8 -0
  375. package/dist/jsx/feedback/store.native.js.map +1 -1
  376. package/dist/jsx/icons/lucide.mjs +2 -2
  377. package/dist/jsx/icons/lucide.mjs.map +1 -1
  378. package/dist/jsx/icons/lucide.native.js +2 -1
  379. package/dist/jsx/layouts/PaneScaffold.mjs +97 -42
  380. package/dist/jsx/layouts/PaneScaffold.mjs.map +1 -1
  381. package/dist/jsx/layouts/PaneScaffold.native.js +97 -41
  382. package/dist/jsx/layouts/PaneScaffold.native.js.map +1 -1
  383. package/dist/jsx/layouts/index.mjs +2 -1
  384. package/dist/jsx/layouts/index.mjs.map +1 -1
  385. package/dist/jsx/layouts/index.native.js +2 -0
  386. package/dist/jsx/layouts/index.native.js.map +1 -1
  387. package/dist/jsx/layouts/page.mjs +49 -8
  388. package/dist/jsx/layouts/page.mjs.map +1 -1
  389. package/dist/jsx/layouts/page.native.js +50 -7
  390. package/dist/jsx/layouts/page.native.js.map +1 -1
  391. package/dist/jsx/shared/useKeyboardInset.mjs +1 -19
  392. package/dist/jsx/shared/useKeyboardInset.mjs.map +1 -1
  393. package/dist/jsx/shared/useKeyboardInset.native.js +3 -3
  394. package/dist/jsx/shared/useKeyboardInset.native.js.map +1 -1
  395. package/dist/jsx/views/Dashboard.mjs +112 -19
  396. package/dist/jsx/views/Dashboard.mjs.map +1 -1
  397. package/dist/jsx/views/Dashboard.native.js +151 -45
  398. package/dist/jsx/views/Dashboard.native.js.map +1 -1
  399. package/dist/jsx/views/Gantt.mjs +376 -93
  400. package/dist/jsx/views/Gantt.mjs.map +1 -1
  401. package/dist/jsx/views/Gantt.native.js +443 -94
  402. package/dist/jsx/views/Gantt.native.js.map +1 -1
  403. package/dist/jsx/views/ganttMath.mjs +84 -3
  404. package/dist/jsx/views/ganttMath.mjs.map +1 -1
  405. package/dist/jsx/views/ganttMath.native.js +113 -3
  406. package/dist/jsx/views/ganttMath.native.js.map +1 -1
  407. package/dist/jsx/views/index.mjs +2 -2
  408. package/dist/jsx/views/index.mjs.map +1 -1
  409. package/dist/jsx/views/index.native.js +20 -1
  410. package/dist/jsx/views/index.native.js.map +1 -1
  411. package/package.json +11 -9
  412. package/src/Button.tsx +10 -2
  413. package/src/Card.spec.tsx +76 -3
  414. package/src/Card.stories.tsx +1 -1
  415. package/src/Card.tsx +13 -1
  416. package/src/CardFooter.stories.tsx +3 -7
  417. package/src/CardFooter.tsx +3 -1
  418. package/src/CardHeader.stories.tsx +1 -3
  419. package/src/Collapsible.stories.tsx +2 -2
  420. package/src/CopyField/CopyField.spec.tsx +66 -1
  421. package/src/CopyField/index.tsx +4 -3
  422. package/src/DropdownMenu/DropdownMenu.spec.tsx +112 -1
  423. package/src/DropdownMenu/DropdownMenu.stories.tsx +1 -3
  424. package/src/DropdownMenu/index.tsx +67 -6
  425. package/src/LinearGradient.stories.tsx +2 -2
  426. package/src/Meter/Meter.spec.tsx +59 -2
  427. package/src/Meter/Meter.stories.tsx +38 -0
  428. package/src/Meter/index.tsx +9 -4
  429. package/src/Panel.stories.tsx +1 -1
  430. package/src/SortableList/SortableList.spec.tsx +3 -3
  431. package/src/Tabs/Tabs.spec.tsx +43 -3
  432. package/src/Tabs/Tabs.stories.tsx +10 -1
  433. package/src/Tabs/index.tsx +19 -13
  434. package/src/Toast/Toast.spec.tsx +56 -1
  435. package/src/Toast/index.tsx +68 -3
  436. package/src/Unspaced.stories.tsx +2 -2
  437. package/src/VisuallyHidden.stories.tsx +2 -2
  438. package/src/actions/DestructiveAction.spec.tsx +19 -3
  439. package/src/actions/DestructiveAction.tsx +9 -14
  440. package/src/charts/Axis.tsx +6 -1
  441. package/src/charts/BarChart.tsx +82 -67
  442. package/src/charts/ChartDataView.spec.tsx +104 -0
  443. package/src/charts/ChartDataView.tsx +158 -0
  444. package/src/charts/ChartSurface.tsx +7 -2
  445. package/src/charts/Charts.stories.tsx +213 -9
  446. package/src/charts/LineChart.tsx +90 -75
  447. package/src/charts/PieChart.knobs.spec.tsx +25 -0
  448. package/src/charts/PieChart.tsx +51 -9
  449. package/src/charts/Sparkline.tsx +25 -3
  450. package/src/charts/accessibility.ts +8 -0
  451. package/src/charts/charts.spec.tsx +77 -3
  452. package/src/charts/index.ts +2 -0
  453. package/src/charts/math.spec.ts +19 -0
  454. package/src/charts/math.ts +36 -0
  455. package/src/charts/series.tsx +101 -21
  456. package/src/charts/svg.spec.ts +28 -0
  457. package/src/charts/svg.ts +56 -2
  458. package/src/code/CodeBlock/CodeBlock.copy.spec.tsx +23 -0
  459. package/src/code/CodeBlock/index.tsx +4 -3
  460. package/src/feedback/ConfirmDialog.nativeFocus.spec.tsx +52 -0
  461. package/src/feedback/ConfirmDialog.spec.tsx +20 -0
  462. package/src/feedback/ConfirmDialog.tsx +9 -15
  463. package/src/feedback/NotifyHost.tsx +11 -2
  464. package/src/feedback/copy.ts +36 -4
  465. package/src/feedback/index.ts +1 -0
  466. package/src/feedback/notify.spec.ts +15 -1
  467. package/src/feedback/notify.ts +1 -0
  468. package/src/feedback/route.ts +4 -0
  469. package/src/feedback/store.ts +7 -0
  470. package/src/icons/lucide.ts +1 -1
  471. package/src/images/SvgUri/index.native.ts +11 -3
  472. package/src/layouts/EmptyState.stories.tsx +2 -2
  473. package/src/layouts/Page.weight.spec.tsx +75 -0
  474. package/src/layouts/PageHeader.stories.tsx +4 -4
  475. package/src/layouts/PageTemplates.stories.tsx +2 -2
  476. package/src/layouts/PaneScaffold.spec.tsx +144 -4
  477. package/src/layouts/PaneScaffold.stories.tsx +58 -2
  478. package/src/layouts/PaneScaffold.tsx +156 -58
  479. package/src/layouts/ScreenToolbar.stories.tsx +6 -23
  480. package/src/layouts/index.tsx +11 -0
  481. package/src/layouts/layouts.spec.tsx +51 -0
  482. package/src/layouts/page.designLaw.spec.tsx +25 -0
  483. package/src/layouts/page.tsx +46 -9
  484. package/src/shared/useKeyboardInset.native.ts +43 -0
  485. package/src/shared/useKeyboardInset.ts +2 -41
  486. package/src/tamagui.spec.ts +63 -0
  487. package/src/views/Dashboard.stories.tsx +38 -1
  488. package/src/views/Dashboard.tsx +119 -21
  489. package/src/views/Gantt.scroll.spec.tsx +120 -0
  490. package/src/views/Gantt.spec.tsx +376 -0
  491. package/src/views/Gantt.stories.tsx +75 -2
  492. package/src/views/Gantt.tsx +564 -96
  493. package/src/views/Kanban.spec.tsx +11 -0
  494. package/src/views/ganttMath.ts +142 -4
  495. package/src/views/index.ts +44 -1
  496. package/src/views/views.spec.tsx +39 -0
  497. package/types/Button.d.ts +12 -2
  498. package/types/Button.d.ts.map +1 -1
  499. package/types/Card.d.ts.map +1 -1
  500. package/types/CardFooter.d.ts +2 -1
  501. package/types/CardFooter.d.ts.map +1 -1
  502. package/types/CopyField/index.d.ts.map +1 -1
  503. package/types/DropdownMenu/index.d.ts +22 -0
  504. package/types/DropdownMenu/index.d.ts.map +1 -1
  505. package/types/Meter/index.d.ts.map +1 -1
  506. package/types/Tabs/index.d.ts +1 -1
  507. package/types/Tabs/index.d.ts.map +1 -1
  508. package/types/Toast/index.d.ts +16 -0
  509. package/types/Toast/index.d.ts.map +1 -1
  510. package/types/actions/DestructiveAction.d.ts.map +1 -1
  511. package/types/charts/Axis.d.ts.map +1 -1
  512. package/types/charts/BarChart.d.ts.map +1 -1
  513. package/types/charts/ChartDataView.d.ts +22 -0
  514. package/types/charts/ChartDataView.d.ts.map +1 -0
  515. package/types/charts/ChartSurface.d.ts +4 -1
  516. package/types/charts/ChartSurface.d.ts.map +1 -1
  517. package/types/charts/LineChart.d.ts.map +1 -1
  518. package/types/charts/PieChart.d.ts +1 -1
  519. package/types/charts/PieChart.d.ts.map +1 -1
  520. package/types/charts/Sparkline.d.ts +3 -1
  521. package/types/charts/Sparkline.d.ts.map +1 -1
  522. package/types/charts/accessibility.d.ts +3 -0
  523. package/types/charts/accessibility.d.ts.map +1 -1
  524. package/types/charts/index.d.ts +1 -0
  525. package/types/charts/index.d.ts.map +1 -1
  526. package/types/charts/math.d.ts +12 -0
  527. package/types/charts/math.d.ts.map +1 -1
  528. package/types/charts/series.d.ts +1 -1
  529. package/types/charts/series.d.ts.map +1 -1
  530. package/types/charts/svg.d.ts +18 -2
  531. package/types/charts/svg.d.ts.map +1 -1
  532. package/types/code/CodeBlock/index.d.ts.map +1 -1
  533. package/types/feedback/ConfirmDialog.d.ts.map +1 -1
  534. package/types/feedback/NotifyHost.d.ts +3 -1
  535. package/types/feedback/NotifyHost.d.ts.map +1 -1
  536. package/types/feedback/copy.d.ts +12 -2
  537. package/types/feedback/copy.d.ts.map +1 -1
  538. package/types/feedback/index.d.ts +1 -1
  539. package/types/feedback/index.d.ts.map +1 -1
  540. package/types/feedback/notify.d.ts.map +1 -1
  541. package/types/feedback/route.d.ts +3 -0
  542. package/types/feedback/route.d.ts.map +1 -1
  543. package/types/feedback/store.d.ts +2 -0
  544. package/types/feedback/store.d.ts.map +1 -1
  545. package/types/icons/lucide.d.ts +1 -1
  546. package/types/icons/lucide.d.ts.map +1 -1
  547. package/types/images/SvgUri/index.native.d.ts +4 -3
  548. package/types/images/SvgUri/index.native.d.ts.map +1 -1
  549. package/types/layouts/PaneScaffold.d.ts +27 -5
  550. package/types/layouts/PaneScaffold.d.ts.map +1 -1
  551. package/types/layouts/index.d.ts +1 -0
  552. package/types/layouts/index.d.ts.map +1 -1
  553. package/types/layouts/page.d.ts +10 -5
  554. package/types/layouts/page.d.ts.map +1 -1
  555. package/types/shared/useKeyboardInset.d.ts +1 -14
  556. package/types/shared/useKeyboardInset.d.ts.map +1 -1
  557. package/types/shared/useKeyboardInset.native.d.ts +16 -0
  558. package/types/shared/useKeyboardInset.native.d.ts.map +1 -0
  559. package/types/views/Dashboard.d.ts.map +1 -1
  560. package/types/views/Gantt.d.ts +132 -13
  561. package/types/views/Gantt.d.ts.map +1 -1
  562. package/types/views/ganttMath.d.ts +73 -0
  563. package/types/views/ganttMath.d.ts.map +1 -1
  564. package/types/views/index.d.ts +2 -2
  565. package/types/views/index.d.ts.map +1 -1
@@ -23,6 +23,7 @@ import {
23
23
  useCallback,
24
24
  useContext,
25
25
  useEffect,
26
+ useLayoutEffect,
26
27
  useMemo,
27
28
  useRef,
28
29
  useState,
@@ -290,10 +291,38 @@ function DropdownMenuRoot({
290
291
  });
291
292
  const pendingFocusRef = useRef<"first" | "last">("first");
292
293
 
294
+ // Content's onCloseAutoFocus, read off the Content child below during the
295
+ // same render. A ref because the child scan happens after these callbacks
296
+ // are defined, and both close paths have to reach the same handler.
297
+ const closeAutoFocusRef = useRef<DropdownMenuContentProps["onCloseAutoFocus"]>(undefined);
298
+ // Notify on the actual state transition, including parent-controlled closes.
299
+ // A rejected controlled close request must not move focus out of an open menu.
300
+ const wasOpenRef = useRef(false);
301
+ const skipReturnFocusRef = useRef(false);
302
+
303
+ const fireCloseAutoFocus = useCallback(() => {
304
+ const handler = closeAutoFocusRef.current;
305
+ if (!handler) return;
306
+ handler({
307
+ preventDefault: () => {
308
+ skipReturnFocusRef.current = true;
309
+ },
310
+ get defaultPrevented() {
311
+ return skipReturnFocusRef.current;
312
+ },
313
+ });
314
+ }, []);
315
+
293
316
  const close = useCallback(() => {
294
317
  setOpen(false);
295
318
  }, [setOpen]);
296
319
 
320
+ useLayoutEffect(() => {
321
+ if (wasOpenRef.current && !open) fireCloseAutoFocus();
322
+ wasOpenRef.current = !!open;
323
+ if (open) skipReturnFocusRef.current = false;
324
+ }, [open, fireCloseAutoFocus]);
325
+
297
326
  const ctx = useMemo<DropdownMenuContextValue>(
298
327
  () => ({ open, setOpen, close, closeOnSelect, pendingFocusRef }),
299
328
  [open, setOpen, close, closeOnSelect],
@@ -311,6 +340,8 @@ function DropdownMenuRoot({
311
340
  let body: ReactNode = null;
312
341
  let contentMaxHeight = maxHeight;
313
342
  let contentMaxWidth: number | undefined;
343
+ let contentAriaLabel: string | undefined;
344
+ closeAutoFocusRef.current = undefined;
314
345
  if (items) {
315
346
  body = renderEntries(items);
316
347
  } else if (Array.isArray(children) || isValidElement(children)) {
@@ -326,14 +357,13 @@ function DropdownMenuRoot({
326
357
  if (type === DropdownMenuTrigger) {
327
358
  triggerParts.push((child.props as { children?: ReactNode }).children);
328
359
  } else if (type === DropdownMenuContent) {
329
- const contentProps = child.props as {
330
- children?: ReactNode;
331
- maxHeight?: number;
332
- maxWidth?: number;
333
- };
360
+ const contentProps = child.props as DropdownMenuContentProps;
334
361
  contentParts.push(contentProps.children);
335
362
  if (contentProps.maxHeight != null) contentMaxHeight = contentProps.maxHeight;
336
363
  if (contentProps.maxWidth != null) contentMaxWidth = contentProps.maxWidth;
364
+ if (contentProps.onCloseAutoFocus)
365
+ closeAutoFocusRef.current = contentProps.onCloseAutoFocus;
366
+ if (contentProps["aria-label"] != null) contentAriaLabel = contentProps["aria-label"];
337
367
  } else {
338
368
  triggerParts.push(child);
339
369
  }
@@ -347,12 +377,17 @@ function DropdownMenuRoot({
347
377
  <FloatingPanel
348
378
  open={open}
349
379
  onOpenChange={setOpen}
380
+ skipReturnFocusRef={skipReturnFocusRef}
350
381
  trigger={decorateTrigger(trigger, open, onArrow)}
351
382
  contentPadding="none"
352
383
  {...coverContract}
353
384
  {...(placement ? { placement } : {})}
354
385
  >
355
- <DropdownMenuList maxHeight={contentMaxHeight} maxWidth={contentMaxWidth}>
386
+ <DropdownMenuList
387
+ maxHeight={contentMaxHeight}
388
+ maxWidth={contentMaxWidth}
389
+ aria-label={contentAriaLabel}
390
+ >
356
391
  {body}
357
392
  </DropdownMenuList>
358
393
  </FloatingPanel>
@@ -387,6 +422,29 @@ export interface DropdownMenuContentProps {
387
422
  * owns this now — kept so existing callers type-check.
388
423
  */
389
424
  minWidth?: number;
425
+ /**
426
+ * Fired as the menu closes, before focus would return to the trigger.
427
+ * Call `preventDefault()` to keep the trigger from taking focus back —
428
+ * the rich-text toolbars do exactly that and hand focus to the editor
429
+ * instead, so the user can keep typing after picking a heading or a list.
430
+ */
431
+ onCloseAutoFocus?: (event: DropdownMenuCloseAutoFocusEvent) => void;
432
+ /**
433
+ * Accessible name for the menu. Lands on the `role="menu"` element, which
434
+ * is the node a screen reader announces — a facet menu whose trigger is an
435
+ * icon has no other name. DataTableFacetMenu passes its column label.
436
+ */
437
+ "aria-label"?: string;
438
+ }
439
+
440
+ /**
441
+ * The minimal preventable event `onCloseAutoFocus` receives. Deliberately not
442
+ * a DOM event: the close can originate from a native sheet or a keyboard
443
+ * dismissal where there is no DOM event to forward.
444
+ */
445
+ export interface DropdownMenuCloseAutoFocusEvent {
446
+ preventDefault: () => void;
447
+ readonly defaultPrevented: boolean;
390
448
  }
391
449
 
392
450
  function DropdownMenuContent({ children }: DropdownMenuContentProps) {
@@ -397,10 +455,12 @@ function DropdownMenuList({
397
455
  children,
398
456
  maxHeight,
399
457
  maxWidth,
458
+ "aria-label": ariaLabel,
400
459
  }: {
401
460
  children?: ReactNode;
402
461
  maxHeight?: number;
403
462
  maxWidth?: number;
463
+ "aria-label"?: string;
404
464
  }) {
405
465
  const ctx = useDropdownMenuContext("Content");
406
466
  const innerRef = useRef<TamaguiElement | null>(null);
@@ -494,6 +554,7 @@ function DropdownMenuList({
494
554
  <YStack
495
555
  ref={innerRef}
496
556
  role="menu"
557
+ {...(ariaLabel ? { "aria-label": ariaLabel } : {})}
497
558
  data-dismiss-class="commit"
498
559
  data-mp-width-mode="at-least-trigger"
499
560
  width="100%"
@@ -1,6 +1,6 @@
1
1
  import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
2
- import { Text, YStack } from "tamagui";
3
- import { LinearGradient } from "./tamagui";
2
+ import { Text } from "./Text";
3
+ import { LinearGradient, YStack } from "./tamagui";
4
4
 
5
5
  const meta: Meta<typeof LinearGradient> = {
6
6
  title: "Components/LinearGradient",
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import { cleanup, screen } from "@testing-library/react";
10
10
  import { renderWithProviders } from "@multiplatform.one/test-utils";
11
- import { Preset, resolveRadiusClass } from "@multiplatform.one/theme";
11
+ import { Preset, resolveRadiusClass, type Knobs } from "@multiplatform.one/theme";
12
12
  import type { ReactElement } from "react";
13
13
  import { Theme } from "tamagui";
14
14
  import { afterEach, describe, expect, it } from "vitest";
@@ -36,7 +36,7 @@ const BATTERY = { min: 0, max: 100, low: 10, high: 20, optimum: 100 } as const;
36
36
  function renderMeter(
37
37
  ui: ReactElement,
38
38
  scheme: "light" | "dark" = "light",
39
- knobs?: { borderRadius?: "none" | "small" | "medium" | "large" | "full" },
39
+ knobs?: Partial<Pick<Knobs, "borderRadius" | "fillStyle" | "borderWidth">>,
40
40
  ) {
41
41
  return renderWithProviders(
42
42
  <Theme name={scheme}>
@@ -192,6 +192,63 @@ describe("Meter a11y and the Progress semantic line", () => {
192
192
  expect(formatMeterValue({ value: 78, min: 0, max: 100, format: "percent" })).toMatch(/%$/);
193
193
  expect(formatMeterValue({ value: undefined, min: 0, max: 8, format: "number" })).toBe("\u2014");
194
194
  });
195
+
196
+ it("outlined chrome spreads inputSurface — borderWidth is the knob, not a hardcoded 1", () => {
197
+ const { container: filled } = renderMeter(
198
+ <Meter label="Disk" value={5} min={0} max={8} />,
199
+ "light",
200
+ { fillStyle: "filled", borderWidth: "large" },
201
+ );
202
+ expect(rail(filled).getAttribute("data-meter-border-width")).toBe("0");
203
+
204
+ cleanup();
205
+ const { container: hairline } = renderMeter(
206
+ <Meter label="Disk" value={5} min={0} max={8} />,
207
+ "light",
208
+ { fillStyle: "outlined", borderWidth: "none" },
209
+ );
210
+ // LC-86: outlined + none still draws the small hairline, not 0.
211
+ expect(rail(hairline).getAttribute("data-meter-border-width")).toBe("0.5");
212
+
213
+ cleanup();
214
+ const { container: large } = renderMeter(
215
+ <Meter label="Disk" value={5} min={0} max={8} />,
216
+ "light",
217
+ { fillStyle: "outlined", borderWidth: "large" },
218
+ );
219
+ expect(rail(large).getAttribute("data-meter-border-width")).toBe("2");
220
+ });
221
+
222
+ it("loading is a skeleton, not an indeterminate meter", () => {
223
+ const { container } = renderMeter(<Meter label="Disk usage" min={0} max={8} loading />);
224
+ expect(container.querySelector("[role='meter']")).toBeNull();
225
+ expect(container.querySelector("[role='progressbar']")).toBeNull();
226
+ });
227
+
228
+ for (const discrete of [0, 5]) {
229
+ for (const [borderWidth, expected] of [
230
+ ["none", "0.5px"],
231
+ ["small", "0.5px"],
232
+ ["large", "2px"],
233
+ ] as const) {
234
+ it(`paints ${borderWidth} outline on ${discrete ? "every segment" : "the continuous rail"}`, () => {
235
+ const { container } = renderMeter(
236
+ <Meter label="Disk" value={5} min={0} max={8} segments={discrete} />,
237
+ "light",
238
+ { fillStyle: "outlined", borderWidth },
239
+ );
240
+ const parts = discrete
241
+ ? Array.from(container.querySelector("[data-meter-segments]")!.children)
242
+ : [rail(container)];
243
+ expect(parts).toHaveLength(discrete || 1);
244
+ for (const part of parts) expect(getComputedStyle(part).borderTopWidth).toBe(expected);
245
+ if (discrete) {
246
+ expect(getComputedStyle(parts[0]).backgroundColor).not.toBe("transparent");
247
+ expect(getComputedStyle(parts.at(-1)!).backgroundColor).toBe("transparent");
248
+ }
249
+ });
250
+ }
251
+ }
195
252
  });
196
253
 
197
254
  describe("barrel exports (the ProgressCard export gap)", () => {
@@ -117,3 +117,41 @@ export const Unknown: Story = {
117
117
  unit: "GB",
118
118
  },
119
119
  };
120
+
121
+ export const Loading: Story = {
122
+ args: {
123
+ label: "Disk usage",
124
+ min: 0,
125
+ max: 8,
126
+ unit: "GB",
127
+ loading: true,
128
+ },
129
+ };
130
+
131
+ export const Disabled: Story = {
132
+ args: {
133
+ label: "Disk usage",
134
+ value: 6.2,
135
+ min: 0,
136
+ max: 8,
137
+ low: 6.4,
138
+ high: 7.6,
139
+ optimum: 0,
140
+ unit: "GB",
141
+ disabled: true,
142
+ },
143
+ };
144
+
145
+ export const Inline: Story = {
146
+ args: {
147
+ label: "Disk usage",
148
+ value: 6.2,
149
+ min: 0,
150
+ max: 8,
151
+ low: 6.4,
152
+ high: 7.6,
153
+ optimum: 0,
154
+ format: "percent",
155
+ layout: "inline",
156
+ },
157
+ };
@@ -149,6 +149,11 @@ export function Meter({
149
149
  const outlined = knobProps.outlined;
150
150
  const trackH = meterTrackHeightPx(size);
151
151
  const railRadius = resolveMeterRailRadius(stop);
152
+ // Spread the fragment (AGENTS.md). Hardcoded 1px ignored the borderWidth knob.
153
+ const outlineChrome = outlined
154
+ ? { ...knobProps.inputSurface, borderColor: "$color6" as const }
155
+ : { borderWidth: 0 };
156
+ const paintedBorder = outlined ? knobProps.inputSurface.borderWidth : 0;
152
157
  const known = value != null && Number.isFinite(value);
153
158
  const zone = known
154
159
  ? resolveMeterZone({ value: value as number, min, max, low, high, optimum })
@@ -209,9 +214,8 @@ export function Meter({
209
214
  width={19}
210
215
  height={trackH}
211
216
  borderRadius={railRadius}
217
+ {...outlineChrome}
212
218
  backgroundColor={i < filledCount ? paint.fill : outlined ? "transparent" : METER_TRACK}
213
- borderWidth={outlined ? 1 : 0}
214
- borderColor={outlined ? "$color6" : undefined}
215
219
  />
216
220
  ))}
217
221
  </XStack>
@@ -220,9 +224,8 @@ export function Meter({
220
224
  height={trackH}
221
225
  minHeight={trackH}
222
226
  borderRadius={railRadius}
227
+ {...outlineChrome}
223
228
  backgroundColor={outlined ? "transparent" : METER_TRACK}
224
- borderWidth={outlined ? 1 : 0}
225
- borderColor={outlined ? "$color6" : undefined}
226
229
  opacity={disabled ? 0.5 : 1}
227
230
  role="meter"
228
231
  aria-label={label}
@@ -232,6 +235,7 @@ export function Meter({
232
235
  aria-valuetext={valuetext}
233
236
  data-meter-radius-class={METER_RADIUS_CLASS}
234
237
  data-meter-rail-radius={railRadius}
238
+ data-meter-border-width={paintedBorder}
235
239
  data-meter-zone={zone}
236
240
  data-meter-fill={known && ratio != null ? paint.fill : undefined}
237
241
  data-meter-track-height={trackH}
@@ -261,6 +265,7 @@ export function Meter({
261
265
  aria-valuetext={valuetext}
262
266
  data-meter-radius-class={METER_RADIUS_CLASS}
263
267
  data-meter-rail-radius={railRadius}
268
+ data-meter-border-width={paintedBorder}
264
269
  data-meter-zone={zone}
265
270
  data-meter-fill={known ? paint.fill : undefined}
266
271
  data-meter-track-height={trackH}
@@ -52,7 +52,7 @@ export const InteractiveContent: Story = {
52
52
  <SizableText fontWeight="600">Interactive content</SizableText>
53
53
  <Input placeholder="Focus me" inputProps={{ "aria-label": "Focus demo" }} />
54
54
  <XStack gap="$2">
55
- <Button variant="outlined">Cancel</Button>
55
+ <Button>Cancel</Button>
56
56
  <Button>Submit</Button>
57
57
  </XStack>
58
58
  </Panel>
@@ -138,10 +138,10 @@ describe("SortableList", () => {
138
138
 
139
139
  it("renders emptyMessage when there are no rows (board 04)", () => {
140
140
  const { container } = renderWithProviders(
141
- <SortableList
141
+ <SortableList<{ id: string; label: string }>
142
142
  items={[]}
143
- getId={(item: { id: string }) => item.id}
144
- getLabel={(item: { label: string }) => item.label}
143
+ getId={(item) => item.id}
144
+ getLabel={(item) => item.label}
145
145
  emptyMessage="No rows yet"
146
146
  />,
147
147
  );
@@ -246,6 +246,48 @@ describe("Tabs", () => {
246
246
  expect(two).toHaveAttribute("aria-selected", "true");
247
247
  });
248
248
 
249
+ it("selects the focused tab automatically when navigating with arrows", async () => {
250
+ renderWithProviders(<Tabs items={items} variant="band" />);
251
+ const one = screen.getByRole("tab", { name: "One" });
252
+ const two = screen.getByRole("tab", { name: "Two" });
253
+ one.focus();
254
+ fireEvent.keyDown(one, { key: "ArrowRight" });
255
+ await waitFor(() => expect(two).toHaveFocus());
256
+ expect(two).toHaveAttribute("aria-selected", "true");
257
+ expect(screen.getByText("Panel two")).toBeVisible();
258
+ });
259
+
260
+ it("reverses horizontal arrow navigation in RTL", async () => {
261
+ document.documentElement.dir = "rtl";
262
+ renderWithProviders(<Tabs items={items} defaultValue="two" />);
263
+ const two = screen.getByRole("tab", { name: "Two" });
264
+ const one = screen.getByRole("tab", { name: "One" });
265
+ two.focus();
266
+ fireEvent.keyDown(two, { key: "ArrowRight" });
267
+ await waitFor(() => expect(one).toHaveFocus());
268
+ expect(one).toHaveAttribute("aria-selected", "true");
269
+ });
270
+
271
+ it("stops at the last enabled tab when looping is disabled", async () => {
272
+ renderWithProviders(<Tabs items={items} loop={false} />);
273
+ const one = screen.getByRole("tab", { name: "One" });
274
+ const two = screen.getByRole("tab", { name: "Two" });
275
+ one.focus();
276
+ fireEvent.keyDown(one, { key: "End" });
277
+ await waitFor(() => expect(two).toHaveFocus());
278
+ fireEvent.keyDown(two, { key: "ArrowRight" });
279
+ expect(two).toHaveFocus();
280
+ expect(two).toHaveAttribute("aria-selected", "true");
281
+ });
282
+
283
+ it("removes every tab from the page tab order when the strip is disabled", () => {
284
+ renderWithProviders(<Tabs items={items} disabled />);
285
+ for (const tab of screen.getAllByRole("tab")) {
286
+ expect(tab.tabIndex).toBe(-1);
287
+ expect(tab).toHaveAttribute("aria-disabled", "true");
288
+ }
289
+ });
290
+
249
291
  it("keeps an enabled entry point when the selected tab is disabled", () => {
250
292
  renderWithProviders(<Tabs items={items} value="three" />);
251
293
  const stops = screen.getAllByRole("tab").filter((tab) => tab.tabIndex === 0);
@@ -261,13 +303,11 @@ describe("Tabs", () => {
261
303
  expect(container.querySelector("[data-tabs-indicator]")).toBeNull();
262
304
  });
263
305
 
264
- it("lets equal-band chrome shrink inside each allocated tab without horizontal insets", () => {
306
+ it("lets equal-band chrome shrink inside each allocated tab", () => {
265
307
  renderWithProviders(<Tabs items={items} variant="band" />);
266
308
  const chrome = screen.getByRole("tab", { name: "One" }).firstElementChild!;
267
309
  expect(chrome.className).toContain("_fs-1");
268
310
  expect(chrome.className).toContain("_fb-0px");
269
- expect(chrome.className).toContain("_pl-0px");
270
- expect(chrome.className).toContain("_pr-0px");
271
311
  });
272
312
 
273
313
  it("ariaLabel overrides the default tablist name", () => {
@@ -27,6 +27,7 @@ const meta: Meta<typeof Tabs> = {
27
27
  },
28
28
  argTypes: {
29
29
  variant: { control: "select", options: ["underline", "contained", "band"] },
30
+ distribution: { control: "select", options: ["content", "equal"] },
30
31
  size: { control: "select", options: ["$2", "$3", "$4", "$5"] },
31
32
  accent: { control: "boolean" },
32
33
  error: { control: "boolean" },
@@ -348,8 +349,16 @@ export const EqualBand: Story = {
348
349
 
349
350
  export const IntrinsicHorizontalHost: Story = {
350
351
  render: () => (
351
- <ScrollView horizontal width={390}>
352
+ <ScrollView horizontal width={390} maxWidth="100%">
352
353
  <Tabs items={baseItems} ariaLabel="Intrinsic tabs" />
353
354
  </ScrollView>
354
355
  ),
355
356
  };
357
+
358
+ export const EqualSmall: Story = {
359
+ render: () => (
360
+ <YStack width={390} maxWidth="100%">
361
+ <Tabs items={baseItems} distribution="equal" size="$2" ariaLabel="Compact equal sections" />
362
+ </YStack>
363
+ ),
364
+ };
@@ -534,6 +534,12 @@ function TabsRoot({
534
534
  item.value === anchorValue &&
535
535
  itemIndex === items.findIndex((i) => i.value === anchorValue);
536
536
  const kbRing = kbFocusValue === item.value;
537
+ const feedbackBackground =
538
+ pressValue === item.value
539
+ ? componentColors.interactive.hover
540
+ : hoverValue === item.value
541
+ ? componentColors.interactive.background
542
+ : "transparent";
537
543
  return (
538
544
  <Trigger
539
545
  key={item.value}
@@ -545,7 +551,7 @@ function TabsRoot({
545
551
  }}
546
552
  flex={equalDistribution ? 1 : undefined}
547
553
  minWidth={0}
548
- minHeight={isBand ? MIN_PRESS_TARGET : undefined}
554
+ minHeight={equalDistribution ? MIN_PRESS_TARGET : undefined}
549
555
  borderEndWidth={isBand && itemIndex < items.length - 1 ? 1 : 0}
550
556
  borderColor={isBand ? componentColors.surface.border : undefined}
551
557
  disabled={isDisabled}
@@ -573,7 +579,13 @@ function TabsRoot({
573
579
  onInteraction={handleInteraction}
574
580
  cursor={isDisabled ? "not-allowed" : "pointer"}
575
581
  backgroundColor={
576
- isBand && isActive ? componentColors.surface.background : "transparent"
582
+ isBand
583
+ ? isActive
584
+ ? componentColors.surface.background
585
+ : isDisabled
586
+ ? "transparent"
587
+ : feedbackBackground
588
+ : "transparent"
577
589
  }
578
590
  borderRadius={0}
579
591
  {...(isDisabled
@@ -608,8 +620,8 @@ function TabsRoot({
608
620
  // (spreading the recipe there too doubled the horizontal
609
621
  // padding).
610
622
  {...knobProps.control}
611
- // Equal columns own band spacing; extra inset can exceed a narrow column.
612
- paddingHorizontal={isBand ? 0 : knobProps.control.paddingHorizontal}
623
+ // Band columns share width; a minimal inset keeps labels off the edges.
624
+ paddingHorizontal={isBand ? "$1" : knobProps.control.paddingHorizontal}
613
625
  alignSelf="stretch"
614
626
  flexGrow={equalDistribution ? 1 : undefined}
615
627
  flexShrink={equalDistribution ? 1 : undefined}
@@ -619,21 +631,15 @@ function TabsRoot({
619
631
  alignItems="center"
620
632
  justifyContent="center"
621
633
  backgroundColor={
622
- isActive || isDisabled
623
- ? "transparent"
624
- : pressValue === item.value
625
- ? componentColors.interactive.hover
626
- : hoverValue === item.value
627
- ? componentColors.interactive.background
628
- : "transparent"
634
+ isBand || isActive || isDisabled ? "transparent" : feedbackBackground
629
635
  }
630
636
  {...(kbRing ? keyboardFocusRingProps : undefined)}
631
637
  >
632
638
  {item.icon}
633
639
  <TabLabel
634
- minWidth={equalDistribution ? 0 : undefined}
635
- flexShrink={equalDistribution ? 1 : undefined}
636
640
  active={isActive}
641
+ flexShrink={1}
642
+ minWidth={0}
637
643
  {...knobProps.controlType}
638
644
  fontFamily={knobProps.label.fontFamily}
639
645
  fontWeight={!isBand && isActive ? "700" : knobProps.label.fontWeight}
@@ -12,7 +12,7 @@ import {
12
12
  relativeLuminance,
13
13
  useAccentOnSurface,
14
14
  } from "@multiplatform.one/theme";
15
- import { Toast, ToastViewport, useToast } from "./index";
15
+ import { Toast, ToastViewport, useToast, nativeToastA11y, nativeToastControlA11y } from "./index";
16
16
  import {
17
17
  __resetToastViewportRegistry,
18
18
  dismissToast,
@@ -39,6 +39,40 @@ function Trigger(props: Parameters<ReturnType<typeof useToast>["show"]>[0]) {
39
39
  return <Button onPress={() => toast.show(props)}>fire</Button>;
40
40
  }
41
41
 
42
+ describe("native toast accessibility", () => {
43
+ it("groups text-only content while leaving action and dismiss controls reachable", () => {
44
+ expect(nativeToastA11y("Saved", false, false)).toEqual({
45
+ accessible: true,
46
+ accessibilityLabel: "Saved",
47
+ });
48
+ expect(nativeToastA11y("Saved", true, false)).toEqual({ accessible: false });
49
+ });
50
+
51
+ it("does not wire a second native announcement channel or web grouping", () => {
52
+ expect(nativeToastA11y("Saved", false, false)).not.toHaveProperty("accessibilityLiveRegion");
53
+ expect(nativeToastA11y("Saved", false, false)).not.toHaveProperty("aria-live");
54
+ expect(nativeToastA11y("Saved", false, true)).toEqual({});
55
+ expect(nativeToastA11y(undefined, false, false)).toEqual({ accessible: false });
56
+ });
57
+
58
+ it("makes native action and dismiss controls accessibility elements without leaking to web", () => {
59
+ expect(nativeToastControlA11y(false)).toEqual({ accessible: true });
60
+ expect(nativeToastControlA11y(true)).toEqual({});
61
+ });
62
+
63
+ it("records the library grouping default and keeps native control props off the DOM", () => {
64
+ renderWithProviders(
65
+ <>
66
+ <Trigger title="Saved" dismissible />
67
+ <ToastViewport />
68
+ </>,
69
+ );
70
+ fireEvent.click(screen.getByText("fire"));
71
+ expect(screen.getByTestId("toast")).toHaveAttribute("tabindex", "0");
72
+ expect(screen.getByLabelText("Dismiss notification")).not.toHaveAttribute("accessible");
73
+ });
74
+ });
75
+
42
76
  describe("Toast (standalone)", () => {
43
77
  it("renders title, description and role=status", () => {
44
78
  renderWithProviders(
@@ -49,6 +83,15 @@ describe("Toast (standalone)", () => {
49
83
  expect(screen.getByRole("status")).toBeInTheDocument();
50
84
  });
51
85
 
86
+ it("names CopyField confirm for assistive tech (DG-FB-03)", () => {
87
+ renderWithProviders(<Toast title="Copied to clipboard." intent="success" />);
88
+ const status = screen.getByRole("status");
89
+ expect(status).toHaveAttribute("aria-live", "polite");
90
+ expect(status).toHaveAttribute("aria-label", "Copied to clipboard.");
91
+ expect(status).toHaveTextContent("Copied to clipboard.");
92
+ expect(status).toHaveAttribute("aria-atomic");
93
+ });
94
+
52
95
  it("fires onDismiss from the close button", () => {
53
96
  const onDismiss = vi.fn();
54
97
  renderWithProviders(<Toast title="Saved" onDismiss={onDismiss} />);
@@ -198,6 +241,18 @@ describe("useToast + ToastViewport (imperative)", () => {
198
241
  expect(getToasts()).toHaveLength(2);
199
242
  });
200
243
 
244
+ it("viewport announce region carries Copied to clipboard.", async () => {
245
+ renderWithProviders(<ToastViewport />);
246
+ act(() => {
247
+ showToast({ title: "Copied to clipboard.", intent: "success" });
248
+ });
249
+ expect(await screen.findByText("Copied to clipboard.")).toBeInTheDocument();
250
+ await vi.waitFor(() => {
251
+ const live = document.querySelector("[aria-live]:not([aria-live='off'])");
252
+ expect(live?.textContent ?? "").toMatch(/Copied to clipboard/);
253
+ });
254
+ });
255
+
201
256
  it("dismisses via the close button", async () => {
202
257
  vi.useFakeTimers();
203
258
  try {