@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
package/src/charts/svg.ts CHANGED
@@ -19,8 +19,10 @@
19
19
 
20
20
  import {
21
21
  Circle as TCircle,
22
+ Defs as TDefs,
22
23
  G as TG,
23
24
  Line as TLine,
25
+ Mask as TMask,
24
26
  Path as TPath,
25
27
  Rect as TRect,
26
28
  Svg as TSvg,
@@ -29,8 +31,10 @@ import {
29
31
  import { isWeb } from "@multiplatform.one/platform";
30
32
  import type {
31
33
  Circle as RNCircle,
34
+ Defs as RNDefs,
32
35
  G as RNG,
33
36
  Line as RNLine,
37
+ Mask as RNMask,
34
38
  Path as RNPath,
35
39
  Rect as RNRect,
36
40
  Svg as RNSvg,
@@ -38,6 +42,8 @@ import type {
38
42
  } from "react-native-svg";
39
43
 
40
44
  export const Svg = TSvg as unknown as typeof RNSvg;
45
+ export const Defs = TDefs as unknown as typeof RNDefs;
46
+ export const Mask = TMask as unknown as typeof RNMask;
41
47
  export const G = TG as unknown as typeof RNG;
42
48
  export const Rect = TRect as unknown as typeof RNRect;
43
49
  export const Circle = TCircle as unknown as typeof RNCircle;
@@ -46,11 +52,59 @@ export const Path = TPath as unknown as typeof RNPath;
46
52
  export const SvgText = TSvgText as unknown as typeof RNSvgText;
47
53
 
48
54
  /** Accessible-image props for the chart root (Axiom 12). */
49
- export function chartRootA11yProps(label: string): Record<string, unknown> {
50
- if (isWeb) return { role: "img", "aria-label": label };
55
+ export interface ChartProofDeclaration {
56
+ kind: "bar" | "pie" | "donut" | "line" | "area";
57
+ separated: boolean;
58
+ datumText: boolean;
59
+ datumCount: number;
60
+ datumValues?: Array<[string, string]>;
61
+ }
62
+
63
+ export function chartRootA11yProps(
64
+ label: string,
65
+ proof?: ChartProofDeclaration,
66
+ ): Record<string, unknown> {
67
+ if (isWeb)
68
+ return {
69
+ role: "img",
70
+ "aria-label": label,
71
+ ...(proof
72
+ ? {
73
+ "data-mpo-chart": proof.kind,
74
+ "data-mpo-chart-separated": String(proof.separated),
75
+ "data-mpo-chart-datum-text": String(proof.datumText),
76
+ "data-mpo-chart-datum-count": proof.datumCount,
77
+ ...(proof.datumValues
78
+ ? { "data-mpo-chart-data-expected": JSON.stringify(proof.datumValues) }
79
+ : {}),
80
+ }
81
+ : {}),
82
+ };
51
83
  return { accessible: true, accessibilityRole: "image", accessibilityLabel: label };
52
84
  }
53
85
 
86
+ /** Audit declarations carry no paint and are never sent to native SVG. */
87
+ export function chartMarkProps(label: string): Record<string, unknown> {
88
+ return isWeb ? { "data-mpo-chart-mark": label } : {};
89
+ }
90
+
91
+ export function chartChromeProps(kind: "axis" | "grid"): Record<string, unknown> {
92
+ return isWeb ? { "data-mpo-chart-chrome": kind } : {};
93
+ }
94
+
95
+ export function chartDatumTextProps(index: number): Record<string, unknown> {
96
+ return isWeb ? { "data-mpo-chart-datum-text": String(index) } : {};
97
+ }
98
+
99
+ export function chartWebProps(props: Record<string, unknown>): Record<string, unknown> {
100
+ return isWeb ? props : {};
101
+ }
102
+
103
+ /** SVG's web presentation attribute and RNSVG's explicit native prop. */
104
+ export function luminanceMaskProps(): Record<string, unknown> {
105
+ return isWeb ? { "mask-type": "luminance" } : { maskType: "luminance" };
106
+ }
107
+
54
108
  export interface DatumTargetInput {
55
109
  /** Per-datum accessible name (describeDatum output). */
56
110
  label?: string;
@@ -105,4 +105,27 @@ describe("CodeBlock copy (Input.Button + notify)", () => {
105
105
  expect(getFeedback()[0]?.scope).toBe("field");
106
106
  expect(getFeedback()[0]?.surface).toBe("alert");
107
107
  });
108
+
109
+ it("keeps failures with their block and clears them on a successful retry", async () => {
110
+ const result = renderWithProviders(
111
+ <>
112
+ <div data-testid="first-code">
113
+ <CodeBlock>{"const first = 1;"}</CodeBlock>
114
+ </div>
115
+ <div data-testid="second-code">
116
+ <CodeBlock>{"const second = 2;"}</CodeBlock>
117
+ </div>
118
+ </>,
119
+ );
120
+ const first = result.getByTestId("first-code");
121
+ const second = result.getByTestId("second-code");
122
+ writeText.mockRejectedValueOnce(new Error("Denied"));
123
+ fireEvent.click(copyOf(first)!);
124
+ await vi.waitFor(() => expect(first.textContent).toContain("Copy failed."));
125
+ expect(second.textContent).not.toContain("Copy failed.");
126
+ fireEvent.click(copyOf(first)!);
127
+ await vi.waitFor(() => expect(first.textContent).not.toContain("Copy failed."));
128
+ expect(getFeedback()).toHaveLength(0);
129
+ expect(getToasts()).toHaveLength(1);
130
+ });
108
131
  });
@@ -24,7 +24,7 @@ import { Spacer, XStack, YStack } from "tamagui";
24
24
  import { settleMs } from "../../AnimateHeight";
25
25
  import { ErrorBoundary } from "../../ErrorBoundary";
26
26
  import { NotifyRegion } from "../../feedback/NotifyHost";
27
- import { copyAndNotify } from "../../feedback/copy";
27
+ import { useCopyFeedback } from "../../feedback/copy";
28
28
  import { Code } from "../Code";
29
29
  import { HighlightedCode } from "../HighlightedCode";
30
30
  import { useShikiTokens } from "../Highlighter";
@@ -72,6 +72,7 @@ export function CodeBlock({
72
72
  disableCopy,
73
73
  size,
74
74
  }: CodeBlockProps) {
75
+ const { region, copy } = useCopyFeedback();
75
76
  const { t } = useTranslation();
76
77
  const { knobProps } = useResolvedKnobs();
77
78
  // Content type scale follows the size knob (T-VALUE via sizeToken, LC-18);
@@ -123,7 +124,7 @@ export function CodeBlock({
123
124
  // (DG-FB-01 — the D-copyfield verdict replaces TooltipSimple + icon-swap).
124
125
  const showCopy = Boolean(codeText) && !disableCopy;
125
126
  const activateCopy = () => {
126
- void copyAndNotify(codeText);
127
+ void copy(codeText);
127
128
  };
128
129
  const capSquare = sizeRecipeForToken(String(codeSize), { touch: isTouchSurface() }).height;
129
130
 
@@ -211,7 +212,7 @@ export function CodeBlock({
211
212
  )}
212
213
  </YStack>
213
214
  </ErrorBoundary>
214
- <NotifyRegion scope="field" compact />
215
+ <NotifyRegion scope="field" region={region} compact />
215
216
  </YStack>
216
217
  );
217
218
  }
@@ -0,0 +1,52 @@
1
+ import { renderWithProviders } from "@multiplatform.one/test-utils";
2
+ import { describe, expect, it, vi } from "vitest";
3
+
4
+ const nativeHost = vi.hoisted(() => ({
5
+ query: vi.fn(() => []),
6
+ focus: vi.fn(),
7
+ preventDefault: vi.fn(),
8
+ }));
9
+
10
+ vi.mock("tamagui", async (original) => ({
11
+ ...(await original<typeof import("tamagui")>()),
12
+ isWeb: false,
13
+ }));
14
+
15
+ vi.mock("../surfaces", async (original) => {
16
+ const React = await import("react");
17
+ return {
18
+ ...(await original<typeof import("../surfaces")>()),
19
+ DialogContent: React.forwardRef(function NativeContent(
20
+ {
21
+ children,
22
+ onOpenAutoFocus,
23
+ }: { children?: React.ReactNode; onOpenAutoFocus?: (event: Event) => void },
24
+ ref,
25
+ ) {
26
+ React.useImperativeHandle(ref, () => {
27
+ // RN 0.83 exposes HTMLElement for native host refs, without web focus APIs.
28
+ const host = Object.create(HTMLElement.prototype);
29
+ host.querySelectorAll = nativeHost.query;
30
+ host.focus = nativeHost.focus;
31
+ return host;
32
+ }, []);
33
+ React.useEffect(() => {
34
+ onOpenAutoFocus?.({ preventDefault: nativeHost.preventDefault } as unknown as Event);
35
+ }, [onOpenAutoFocus]);
36
+ return <div>{children}</div>;
37
+ }),
38
+ };
39
+ });
40
+
41
+ import { ConfirmDialog } from "./ConfirmDialog";
42
+
43
+ describe("ConfirmDialog native focus ownership", () => {
44
+ it("leaves native host refs and open focus to the platform", () => {
45
+ renderWithProviders(
46
+ <ConfirmDialog open title="Delete project?" body="This cannot be undone." />,
47
+ );
48
+ expect(nativeHost.query).not.toHaveBeenCalled();
49
+ expect(nativeHost.focus).not.toHaveBeenCalled();
50
+ expect(nativeHost.preventDefault).not.toHaveBeenCalled();
51
+ });
52
+ });
@@ -31,6 +31,26 @@ function alertdialog(): Element | null {
31
31
  }
32
32
 
33
33
  describe("ConfirmDialog", () => {
34
+ it("keeps a disabled destructive label on Button's readable text tier", () => {
35
+ renderWithProviders(
36
+ <ConfirmDialog
37
+ open
38
+ destructive
39
+ confirmDisabled
40
+ confirmDisabledReason="Type the project name"
41
+ title="Delete project?"
42
+ confirmLabel="Delete"
43
+ />,
44
+ );
45
+ const button = buttonByLabel("Delete");
46
+ const label = Array.from(button.querySelectorAll("span")).find(
47
+ (node) => node.textContent === "Delete",
48
+ );
49
+ expect(label).toBeTruthy();
50
+ expect(label?.className).toContain("_col-color11");
51
+ expect(label?.className).toContain("_fow-400");
52
+ });
53
+
34
54
  it("renders title, body, confirm, and cancel", () => {
35
55
  renderWithProviders(
36
56
  <ConfirmDialog
@@ -27,9 +27,10 @@ import {
27
27
  } from "@multiplatform.one/theme";
28
28
  import { useCallback, useEffect, useRef, type ReactNode } from "react";
29
29
  import { useTranslation } from "../shared/i18n";
30
- import { Dialog, Paragraph, SizableText, XStack, YStack, type TamaguiElement } from "tamagui";
30
+ import { Dialog, Paragraph, XStack, YStack, isWeb, type TamaguiElement } from "tamagui";
31
31
  import { countActionsInTree } from "../shared/actionScan";
32
32
  import { useReturnFocusOnClose } from "../shared/useReturnFocusOnClose";
33
+ import { useKeyboardInset } from "../shared/useKeyboardInset";
33
34
  import { DialogContent, DialogOverlay } from "../surfaces";
34
35
 
35
36
  const TAB_STOPS =
@@ -55,16 +56,6 @@ function isTextEntry(el: HTMLElement): boolean {
55
56
  return Boolean(el.querySelector("input, textarea, [contenteditable='true']"));
56
57
  }
57
58
 
58
- /** R7 / §6.1: action labels are weight 400 on the TEXT NODE, never 500/600. */
59
- function ActionLabel({ children }: { children: string }) {
60
- const { knobProps } = useResolvedKnobs();
61
- return (
62
- <SizableText {...knobProps.body} {...knobProps.label} fontWeight="400" userSelect="none">
63
- {children}
64
- </SizableText>
65
- );
66
- }
67
-
68
59
  function firstTabStop(root: HTMLElement): HTMLElement | null {
69
60
  const nodes = root.querySelectorAll<HTMLElement>(TAB_STOPS);
70
61
  for (const el of nodes) {
@@ -155,6 +146,7 @@ export function ConfirmDialog({
155
146
  const { t } = useTranslation();
156
147
  const { knobProps } = useResolvedKnobs();
157
148
  const confirmLabel = confirmLabelProp ?? t("Confirm");
149
+ const keyboardInset = useKeyboardInset();
158
150
  const cancelLabel = cancelLabelProp ?? t("Cancel");
159
151
  const description = body ?? children;
160
152
  const contentRef = useRef<TamaguiElement | null>(null);
@@ -195,6 +187,7 @@ export function ConfirmDialog({
195
187
  };
196
188
 
197
189
  const handleOpenAutoFocus = useCallback((event: Event) => {
190
+ if (!isWeb) return;
198
191
  event.preventDefault();
199
192
  const panel = panelNode(contentRef.current);
200
193
  if (panel) applyOpenFocus(panel);
@@ -203,7 +196,8 @@ export function ConfirmDialog({
203
196
  // Radix onOpenAutoFocus is the web path; this effect covers jsdom and the
204
197
  // frame where the portal ref is not ready in the auto-focus callback.
205
198
  useEffect(() => {
206
- if (!open) return;
199
+ // RN 0.83 also exposes HTMLElement, but native refs have no DOM query API.
200
+ if (!open || !isWeb) return;
207
201
  let cancelled = false;
208
202
  let frames = 0;
209
203
  const run = () => {
@@ -223,7 +217,7 @@ export function ConfirmDialog({
223
217
 
224
218
  return (
225
219
  <Dialog modal open={open} onOpenChange={handleOpenChange}>
226
- <Dialog.Portal>
220
+ <Dialog.Portal paddingBottom={keyboardInset || undefined}>
227
221
  <DialogOverlay key="overlay" />
228
222
  <DialogContent
229
223
  ref={contentRef}
@@ -279,7 +273,7 @@ export function ConfirmDialog({
279
273
  handleOpenChange(false);
280
274
  }}
281
275
  >
282
- <ActionLabel>{cancelLabel}</ActionLabel>
276
+ {cancelLabel}
283
277
  </Button>
284
278
  <Button
285
279
  compact
@@ -300,7 +294,7 @@ export function ConfirmDialog({
300
294
  handleOpenChange(false);
301
295
  }}
302
296
  >
303
- <ActionLabel>{confirmLabel}</ActionLabel>
297
+ {confirmLabel}
304
298
  </Button>
305
299
  </XStack>
306
300
  </DialogContent>
@@ -120,17 +120,26 @@ function FeedbackDialog({ entry }: { entry: FeedbackEntry | undefined }) {
120
120
  */
121
121
  export function NotifyRegion({
122
122
  scope,
123
+ region,
123
124
  compact,
124
125
  }: {
125
126
  scope: "section" | "field";
127
+ /** Match one target; omitted regions display only untargeted feedback. */
128
+ region?: string;
126
129
  compact?: boolean;
127
130
  }) {
128
131
  const all = useFeedbackEntries();
129
132
  // SP-GAP (LC-18): inline alert stacking rides the space knob.
130
133
  const { knobProps } = useResolvedKnobs();
131
134
  const entries = useMemo(
132
- () => all.filter((e) => e.surface === "alert" && e.scope === scope),
133
- [all, scope],
135
+ () =>
136
+ all.filter(
137
+ (e) =>
138
+ e.surface === "alert" &&
139
+ e.scope === scope &&
140
+ (region != null ? e.region === region : e.region == null),
141
+ ),
142
+ [all, scope, region],
134
143
  );
135
144
  if (entries.length === 0) return null;
136
145
  return (
@@ -4,20 +4,52 @@
4
4
  */
5
5
  import { copyToClipboard } from "../hooks/useClipboard";
6
6
  import { notify } from "./notify";
7
+ import { useCallback, useEffect, useId, useRef } from "react";
8
+ import { dismissFeedbackByRegion } from "./store";
7
9
 
8
10
  export const COPY_OK = "Copied to clipboard.";
9
11
  export const COPY_FAIL = "Copy failed.";
10
12
 
11
- export function reportCopy(ok: boolean): void {
13
+ export function reportCopy(ok: boolean, options?: { region?: string }): void {
14
+ const region = options?.region;
15
+ if (region != null) dismissFeedbackByRegion(region);
12
16
  if (ok) {
13
17
  notify({ severity: "success", scope: "page", body: COPY_OK });
14
18
  return;
15
19
  }
16
- notify({ severity: "error", scope: "field", body: COPY_FAIL });
20
+ notify({ severity: "error", scope: "field", region, body: COPY_FAIL });
17
21
  }
18
22
 
19
- export async function copyAndNotify(text: string): Promise<boolean> {
23
+ export async function copyAndNotify(text: string, options?: { region?: string }): Promise<boolean> {
20
24
  const ok = await copyToClipboard(text).catch(() => false);
21
- reportCopy(ok);
25
+ reportCopy(ok, options);
22
26
  return ok;
23
27
  }
28
+
29
+ /** Keeps copy failures beside their owner, including asynchronous clipboard results. */
30
+ export function useCopyFeedback() {
31
+ const region = useId();
32
+ const mounted = useRef(true);
33
+ useEffect(() => {
34
+ mounted.current = true;
35
+ return () => {
36
+ mounted.current = false;
37
+ dismissFeedbackByRegion(region);
38
+ };
39
+ }, [region]);
40
+ const report = useCallback(
41
+ (ok: boolean) => {
42
+ if (mounted.current) reportCopy(ok, { region });
43
+ },
44
+ [region],
45
+ );
46
+ const copy = useCallback(
47
+ async (text: string) => {
48
+ const ok = await copyToClipboard(text).catch(() => false);
49
+ report(ok);
50
+ return ok;
51
+ },
52
+ [report],
53
+ );
54
+ return { region, report, copy };
55
+ }
@@ -13,6 +13,7 @@ export { NotifyHost, NotifyRegion, type NotifyHostProps } from "./NotifyHost";
13
13
  export { ConfirmDialog, type ConfirmDialogProps } from "./ConfirmDialog";
14
14
  export {
15
15
  dismissFeedback,
16
+ dismissFeedbackByRegion,
16
17
  dismissFeedbackBySurface,
17
18
  getFeedback,
18
19
  pushFeedback,
@@ -2,7 +2,7 @@ import { afterEach, describe, expect, it, vi } from "vitest";
2
2
  import { getToasts, resetToasts, TOAST_ACTION_MIN_MS } from "../Toast/store";
3
3
  import { notify } from "./notify";
4
4
  import { routeNotify, type NotifyEvent } from "./route";
5
- import { getFeedback, resetFeedback } from "./store";
5
+ import { dismissFeedbackByRegion, getFeedback, resetFeedback } from "./store";
6
6
 
7
7
  afterEach(() => {
8
8
  resetToasts();
@@ -103,6 +103,20 @@ describe("routeNotify (DG-FB-01 routing table)", () => {
103
103
  });
104
104
 
105
105
  describe("notify() delivery", () => {
106
+ it("targets and clears one inline region without disturbing another", () => {
107
+ const route = notify({
108
+ severity: "error",
109
+ scope: "field",
110
+ region: "first",
111
+ body: "First failed",
112
+ });
113
+ notify({ severity: "error", scope: "field", region: "second", body: "Second failed" });
114
+ expect(route.region).toBe("first");
115
+ expect(getFeedback().map((entry) => entry.region)).toEqual(["first", "second"]);
116
+ dismissFeedbackByRegion("first");
117
+ expect(getFeedback().map((entry) => entry.region)).toEqual(["second"]);
118
+ });
119
+
106
120
  it("success path shows a one-liner toast", () => {
107
121
  const route = notify({
108
122
  severity: "success",
@@ -45,6 +45,7 @@ export function notify(event: NotifyEvent): NotifyRoute {
45
45
  surface: route.surface,
46
46
  severity: route.severity,
47
47
  scope: route.scope,
48
+ region: route.region,
48
49
  title: route.title,
49
50
  body: route.body,
50
51
  action: route.action,
@@ -20,6 +20,8 @@ export interface NotifyAction {
20
20
  export interface NotifyEvent {
21
21
  severity: NotifySeverity;
22
22
  scope: NotifyScope;
23
+ /** Target one inline region instead of broadcasting to every region of the scope. */
24
+ region?: string;
23
25
  /** Escalate to a blocking dialog (error/warning only). Ignored for info/success. */
24
26
  blocking?: boolean;
25
27
  action?: NotifyAction;
@@ -40,6 +42,7 @@ export interface NotifyRoute {
40
42
  surface: NotifySurface;
41
43
  severity: NotifySeverity;
42
44
  scope: NotifyScope;
45
+ region?: string;
43
46
  /** Toast intent (info → accent). Banner/alert/dialog use `severity` as Alert intent. */
44
47
  toastIntent: NotifyToastIntent;
45
48
  title?: string;
@@ -81,6 +84,7 @@ export function routeNotify(event: NotifyEvent): NotifyRoute {
81
84
  const base = {
82
85
  severity,
83
86
  scope,
87
+ ...(event.region != null ? { region: event.region } : {}),
84
88
  toastIntent,
85
89
  title,
86
90
  body,
@@ -10,6 +10,7 @@ export interface FeedbackEntry {
10
10
  surface: Exclude<NotifySurface, "toast">;
11
11
  severity: NotifySeverity;
12
12
  scope: NotifyScope;
13
+ region?: string;
13
14
  title?: string;
14
15
  body: string;
15
16
  action?: NotifyAction;
@@ -64,6 +65,12 @@ export function dismissFeedbackBySurface(surface: FeedbackEntry["surface"]): voi
64
65
  if (entries.length !== before) emit();
65
66
  }
66
67
 
68
+ export function dismissFeedbackByRegion(region: string): void {
69
+ const before = entries.length;
70
+ entries = entries.filter((entry) => entry.region !== region);
71
+ if (entries.length !== before) emit();
72
+ }
73
+
67
74
  /** Hard-reset (tests / story decorators). */
68
75
  export function resetFeedback(): void {
69
76
  entries = [];
@@ -1,5 +1,5 @@
1
1
  /** Thin re-export so apps/packages/features never import @tamagui/lucide-icons-2. */
2
- export { Eye, EyeOff, Github, Info, Mail } from "@tamagui/lucide-icons-2";
2
+ export { Eye, EyeOff, Github, Info, Mail, Pencil } from "@tamagui/lucide-icons-2";
3
3
  // Aliased: bare `Menu` is the lucide hamburger. Tamagui Menu / create-menu
4
4
  // are unused leftovers and are not house barrel names (R9 G7). Package
5
5
  // root re-exports this as `Menu` after the curated tamagui surface.
@@ -1,6 +1,14 @@
1
- import { SvgUri as RNSvgUri } from "react-native-svg";
2
- import { styled } from "tamagui";
1
+ import { SvgUri as RNSvgUri, type UriProps } from "react-native-svg";
2
+ import { styled, type TamaguiComponent } from "tamagui";
3
+ import type { StackStyleBase, TamaDefer, TamaguiComponentPropsBaseBase } from "@tamagui/core";
3
4
 
4
- export const SvgUri = styled(RNSvgUri, { name: "SvgUri", uri: null, color: "$color" });
5
+ export const SvgUri: TamaguiComponent<
6
+ TamaDefer,
7
+ unknown,
8
+ TamaguiComponentPropsBaseBase & UriProps,
9
+ StackStyleBase,
10
+ {},
11
+ {}
12
+ > = styled(RNSvgUri, { name: "SvgUri", uri: null, color: "$color" });
5
13
 
6
14
  export type SvgUriProps = React.ComponentProps<typeof SvgUri>;
@@ -77,7 +77,7 @@ export const MultipleActions: Story = {
77
77
  action={
78
78
  <>
79
79
  <Button>Create record</Button>
80
- <Button variant="outlined">Learn more</Button>
80
+ <Button>Learn more</Button>
81
81
  </>
82
82
  }
83
83
  />
@@ -132,7 +132,7 @@ export const NoResults: Story = {
132
132
  <EmptyState
133
133
  {...args}
134
134
  icon={<MagnifyingGlassIcon size={40} />}
135
- action={<Button variant="outlined">Clear filters</Button>}
135
+ action={<Button>Clear filters</Button>}
136
136
  />
137
137
  </PageCanvas>
138
138
  ),
@@ -0,0 +1,75 @@
1
+ import { defaultConfig } from "@tamagui/config/v5";
2
+ import { createTamagui, TamaguiProvider } from "tamagui";
3
+ import type { ReactElement } from "react";
4
+ import { defaultHeadingFont, Preset } from "@multiplatform.one/theme";
5
+ import { cleanup, render, screen } from "@testing-library/react";
6
+ import { afterEach, describe, expect, it } from "vitest";
7
+ import { PageHeader } from "./page";
8
+
9
+ const config = createTamagui({
10
+ ...defaultConfig,
11
+ fonts: { ...defaultConfig.fonts, heading: defaultHeadingFont },
12
+ });
13
+ function renderWithProviders(node: ReactElement) {
14
+ return render(
15
+ <TamaguiProvider config={config} defaultTheme="light">
16
+ {node}
17
+ </TamaguiProvider>,
18
+ );
19
+ }
20
+ afterEach(cleanup);
21
+
22
+ describe("PageHeader rendered Tamagui title recipes", () => {
23
+ for (const scale of ["moderate", "display"] as const) {
24
+ for (const weight of ["regular", "bold"] as const) {
25
+ it(`${scale} preserves ${weight} independently of size`, () => {
26
+ renderWithProviders(
27
+ <Preset overrides={{ pageTitleScale: scale, fontWeight: weight }}>
28
+ <PageHeader title="Measured title" />
29
+ </Preset>,
30
+ );
31
+ const title = screen.getByRole("heading", { name: "Measured title" });
32
+ expect(getComputedStyle(title).fontSize).toBe(scale === "moderate" ? "26px" : "40px");
33
+ expect(getComputedStyle(title).fontWeight).toBe(weight === "regular" ? "400" : "700");
34
+ expect(title.tagName).toBe("H1");
35
+ expect(title).toHaveAttribute("data-font-weight-knob", weight);
36
+ expect(title.className).toContain("font_heading");
37
+ });
38
+
39
+ it(`${scale}/${weight} survives nested overrides and a titleScale eject`, () => {
40
+ renderWithProviders(
41
+ <Preset
42
+ overrides={{
43
+ pageTitleScale: scale,
44
+ fontWeight: weight === "bold" ? "regular" : "bold",
45
+ }}
46
+ >
47
+ <Preset overrides={{ fontWeight: weight }}>
48
+ <PageHeader
49
+ title="Nested title"
50
+ headingLevel={2}
51
+ titleScale={scale === "moderate" ? "display" : "moderate"}
52
+ />
53
+ </Preset>
54
+ </Preset>,
55
+ );
56
+ const title = screen.getByRole("heading", { name: "Nested title" });
57
+ expect(getComputedStyle(title).fontSize).toBe(scale === "moderate" ? "40px" : "26px");
58
+ expect(getComputedStyle(title).fontWeight).toBe(weight === "regular" ? "400" : "700");
59
+ expect(title.tagName).toBe("H2");
60
+ });
61
+ }
62
+ }
63
+
64
+ it("preserves the consumer heading eject and wrapper props", () => {
65
+ renderWithProviders(
66
+ <PageHeader
67
+ heading={<h3 style={{ fontWeight: 600 }}>Custom</h3>}
68
+ data-testid="eject"
69
+ padding={7}
70
+ />,
71
+ );
72
+ expect(getComputedStyle(screen.getByRole("heading")).fontWeight).toBe("600");
73
+ expect(getComputedStyle(screen.getByTestId("eject")).paddingTop).toBe("7px");
74
+ });
75
+ });
@@ -67,7 +67,7 @@ export const WithActions: Story = {
67
67
  {...args}
68
68
  actions={
69
69
  <>
70
- <Button variant="outlined">Secondary</Button>
70
+ <Button>Secondary</Button>
71
71
  <Button>Primary</Button>
72
72
  </>
73
73
  }
@@ -83,7 +83,7 @@ export const WithNav: Story = {
83
83
  {...args}
84
84
  actions={
85
85
  <>
86
- <Button variant="outlined">Secondary</Button>
86
+ <Button>Secondary</Button>
87
87
  <Button>Primary</Button>
88
88
  </>
89
89
  }
@@ -155,8 +155,8 @@ export const LongTitleNarrow: Story = {
155
155
  actions={
156
156
  <>
157
157
  <Button>First action</Button>
158
- <Button variant="outlined">Second action</Button>
159
- <Button variant="outlined">Third action</Button>
158
+ <Button>Second action</Button>
159
+ <Button>Third action</Button>
160
160
  </>
161
161
  }
162
162
  />
@@ -68,7 +68,7 @@ export const DetailPage: StoryObj<typeof DetailPageLayout> = {
68
68
  sizeClass="expanded"
69
69
  title="Bulbasaur"
70
70
  subtitle="Pokemon · #0001"
71
- toolbarLeading={<Button variant="outlined">Back</Button>}
71
+ toolbarLeading={<Button>Back</Button>}
72
72
  toolbarTrailing={<Button theme="accent">Edit</Button>}
73
73
  aside={<ContentBox label="Aside (meta / timeline) ⅓" minHeight={240} />}
74
74
  >
@@ -82,7 +82,7 @@ export const DetailPageCompact: StoryObj<typeof DetailPageLayout> = {
82
82
  <DetailPageLayout
83
83
  sizeClass="compact"
84
84
  title="Bulbasaur"
85
- toolbarLeading={<Button variant="outlined">Back</Button>}
85
+ toolbarLeading={<Button>Back</Button>}
86
86
  aside={<ContentBox label="Aside — stacked below, never hidden" minHeight={140} />}
87
87
  >
88
88
  <ContentBox label="Main content" minHeight={200} />