@multiplatform.one/components 7.78.0 → 7.79.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 (466) hide show
  1. package/dist/cjs/Accordion/index.native.js +1 -1
  2. package/dist/cjs/Accordion/index.native.js.map +1 -1
  3. package/dist/cjs/Alert/index.native.js.map +1 -1
  4. package/dist/cjs/AnimateHeight/index.native.js.map +1 -1
  5. package/dist/cjs/Avatar/getInitials.native.js.map +1 -1
  6. package/dist/cjs/Avatar/index.native.js.map +1 -1
  7. package/dist/cjs/Badge/index.native.js.map +1 -1
  8. package/dist/cjs/Button.native.js.map +1 -1
  9. package/dist/cjs/Card.native.js.map +1 -1
  10. package/dist/cjs/CardFooter.native.js.map +1 -1
  11. package/dist/cjs/CardHeader.native.js.map +1 -1
  12. package/dist/cjs/Carousel/index.native.js +3 -3
  13. package/dist/cjs/Carousel/index.native.js.map +1 -1
  14. package/dist/cjs/Chip/index.native.js.map +1 -1
  15. package/dist/cjs/Collapsible.native.js.map +1 -1
  16. package/dist/cjs/ContextMenu/index.native.js.map +1 -1
  17. package/dist/cjs/CopyField/CopyMenuButton.native.js +1 -1
  18. package/dist/cjs/CopyField/CopyMenuButton.native.js.map +1 -1
  19. package/dist/cjs/CopyField/index.native.js.map +1 -1
  20. package/dist/cjs/Dialog.native.js.map +1 -1
  21. package/dist/cjs/Diff/diff.cjs +84 -0
  22. package/dist/cjs/Diff/diff.native.js +108 -0
  23. package/dist/cjs/Diff/diff.native.js.map +1 -0
  24. package/dist/cjs/Diff/index.cjs +174 -0
  25. package/dist/cjs/Diff/index.native.js +181 -0
  26. package/dist/cjs/Diff/index.native.js.map +1 -0
  27. package/dist/cjs/DotIndicator/index.native.js.map +1 -1
  28. package/dist/cjs/DropdownMenu/index.native.js.map +1 -1
  29. package/dist/cjs/DropdownMenu/menuSettle.native.js.map +1 -1
  30. package/dist/cjs/ElapsedProgress/index.cjs +102 -0
  31. package/dist/cjs/ElapsedProgress/index.native.js +112 -0
  32. package/dist/cjs/ElapsedProgress/index.native.js.map +1 -0
  33. package/dist/cjs/ErrorBoundary/index.native.js.map +1 -1
  34. package/dist/cjs/Heading.native.js.map +1 -1
  35. package/dist/cjs/Kbd/index.native.js.map +1 -1
  36. package/dist/cjs/Kbd/keys.native.js.map +1 -1
  37. package/dist/cjs/Lightbox/MediaControl.native.js.map +1 -1
  38. package/dist/cjs/Lightbox/index.gnome.native.js.map +1 -1
  39. package/dist/cjs/Lightbox/index.native.js +1 -1
  40. package/dist/cjs/Lightbox/shared.native.js.map +1 -1
  41. package/dist/cjs/Lightbox/useLightbox.native.js.map +1 -1
  42. package/dist/cjs/MachineLiteral/index.cjs +98 -0
  43. package/dist/cjs/MachineLiteral/index.native.js +102 -0
  44. package/dist/cjs/MachineLiteral/index.native.js.map +1 -0
  45. package/dist/cjs/Material/blur.cjs +34 -0
  46. package/dist/cjs/Material/blur.native.js +100 -0
  47. package/dist/cjs/Material/blur.native.js.map +1 -0
  48. package/dist/cjs/Material/index.cjs +9 -3
  49. package/dist/cjs/Material/index.native.js +9 -3
  50. package/dist/cjs/Material/index.native.js.map +1 -1
  51. package/dist/cjs/Meter/index.cjs +3 -1
  52. package/dist/cjs/Meter/index.native.js +4 -2
  53. package/dist/cjs/Meter/index.native.js.map +1 -1
  54. package/dist/cjs/Meter/meter.native.js.map +1 -1
  55. package/dist/cjs/OverflowRow/index.native.js +1 -1
  56. package/dist/cjs/OverflowRow/index.native.js.map +1 -1
  57. package/dist/cjs/Pagination.native.js +1 -1
  58. package/dist/cjs/Pagination.native.js.map +1 -1
  59. package/dist/cjs/Popover.native.js +1 -1
  60. package/dist/cjs/Popover.native.js.map +1 -1
  61. package/dist/cjs/ProgressSteps/index.native.js.map +1 -1
  62. package/dist/cjs/Quote/index.native.js.map +1 -1
  63. package/dist/cjs/SchemeToggle/index.native.js +1 -1
  64. package/dist/cjs/SchemeToggle/index.native.js.map +1 -1
  65. package/dist/cjs/ScrollView/revealFocusedField.native.js.map +1 -1
  66. package/dist/cjs/Separator/index.native.js.map +1 -1
  67. package/dist/cjs/Sheet.native.js.map +1 -1
  68. package/dist/cjs/SheetModal/SheetHeader.native.js.map +1 -1
  69. package/dist/cjs/SheetModal/SheetNavigation.native.js.map +1 -1
  70. package/dist/cjs/SheetModal/detents.native.js.map +1 -1
  71. package/dist/cjs/SheetModal/useSheetFrameFocus.native.js.map +1 -1
  72. package/dist/cjs/Skeleton/index.native.js.map +1 -1
  73. package/dist/cjs/SkipLink/index.native.js.map +1 -1
  74. package/dist/cjs/SortableList/SortableHandle.native.js.map +1 -1
  75. package/dist/cjs/SortableList/index.cjs +4 -1
  76. package/dist/cjs/SortableList/index.native.js +4 -1
  77. package/dist/cjs/SortableList/index.native.js.map +1 -1
  78. package/dist/cjs/SortableList/useSortableRows.native.js.map +1 -1
  79. package/dist/cjs/SortableList/useUserOrder.cjs +84 -0
  80. package/dist/cjs/SortableList/useUserOrder.native.js +107 -0
  81. package/dist/cjs/SortableList/useUserOrder.native.js.map +1 -0
  82. package/dist/cjs/Tabs/index.native.js +1 -1
  83. package/dist/cjs/Tabs/index.native.js.map +1 -1
  84. package/dist/cjs/Text.native.js.map +1 -1
  85. package/dist/cjs/ThemePresetPicker/index.native.js +2 -2
  86. package/dist/cjs/ThemePresetPicker/index.native.js.map +1 -1
  87. package/dist/cjs/Toast/index.native.js.map +1 -1
  88. package/dist/cjs/Toast/store.native.js.map +1 -1
  89. package/dist/cjs/Tooltip/nativePress.native.js.map +1 -1
  90. package/dist/cjs/Tooltip/tooltipShared.native.js.map +1 -1
  91. package/dist/cjs/TreeSelect/index.cjs +7 -1
  92. package/dist/cjs/TreeSelect/index.native.js +8 -2
  93. package/dist/cjs/TreeSelect/index.native.js.map +1 -1
  94. package/dist/cjs/TreeSelect/treeSelectModel.native.js.map +1 -1
  95. package/dist/cjs/Video/PlayerChrome.native.js.map +1 -1
  96. package/dist/cjs/Video/VideoFrame.native.js.map +1 -1
  97. package/dist/cjs/Video/types.native.js.map +1 -1
  98. package/dist/cjs/Wheel/index.native.js.map +1 -1
  99. package/dist/cjs/Wizard/index.native.js +2 -2
  100. package/dist/cjs/Wizard/index.native.js.map +1 -1
  101. package/dist/cjs/actions/ActionBar.native.js.map +1 -1
  102. package/dist/cjs/actions/DangerSection.native.js.map +1 -1
  103. package/dist/cjs/actions/DestructiveAction.native.js.map +1 -1
  104. package/dist/cjs/actions/HeaderActions.native.js +2 -2
  105. package/dist/cjs/actions/HeaderActions.native.js.map +1 -1
  106. package/dist/cjs/actions/StandardAction.native.js +1 -1
  107. package/dist/cjs/actions/StandardAction.native.js.map +1 -1
  108. package/dist/cjs/actions/devWarn.native.js.map +1 -1
  109. package/dist/cjs/actions/index.native.js.map +1 -1
  110. package/dist/cjs/actions/severity.native.js.map +1 -1
  111. package/dist/cjs/appShell/Dock.native.js.map +1 -1
  112. package/dist/cjs/appShell/MpoTabHost.native.js.map +1 -1
  113. package/dist/cjs/appShell/ScopeMenu.native.js.map +1 -1
  114. package/dist/cjs/appShell/SettingsSplit.native.js +1 -1
  115. package/dist/cjs/appShell/SettingsSplit.native.js.map +1 -1
  116. package/dist/cjs/appShell/Springboard.native.js +1 -1
  117. package/dist/cjs/appShell/Springboard.native.js.map +1 -1
  118. package/dist/cjs/appShell/SystemBar.native.js.map +1 -1
  119. package/dist/cjs/appShell/TabBar.cjs +10 -5
  120. package/dist/cjs/appShell/TabBar.native.js +11 -6
  121. package/dist/cjs/appShell/TabBar.native.js.map +1 -1
  122. package/dist/cjs/appShell/appTile.native.js +1 -1
  123. package/dist/cjs/appShell/appTile.native.js.map +1 -1
  124. package/dist/cjs/appShell/bottomChrome.native.js.map +1 -1
  125. package/dist/cjs/appShell/index.native.js.map +1 -1
  126. package/dist/cjs/charts/Axis.native.js.map +1 -1
  127. package/dist/cjs/charts/BarChart.native.js.map +1 -1
  128. package/dist/cjs/charts/ChartDataView.native.js +1 -1
  129. package/dist/cjs/charts/ChartDataView.native.js.map +1 -1
  130. package/dist/cjs/charts/ChartSurface.native.js.map +1 -1
  131. package/dist/cjs/charts/LineChart.native.js.map +1 -1
  132. package/dist/cjs/charts/PieChart.native.js.map +1 -1
  133. package/dist/cjs/charts/Sparkline.cjs +1 -1
  134. package/dist/cjs/charts/Sparkline.native.js +1 -1
  135. package/dist/cjs/charts/Sparkline.native.js.map +1 -1
  136. package/dist/cjs/charts/accessibility.native.js.map +1 -1
  137. package/dist/cjs/charts/chartHeight.native.js.map +1 -1
  138. package/dist/cjs/charts/composeChart.native.js.map +1 -1
  139. package/dist/cjs/charts/index.native.js.map +1 -1
  140. package/dist/cjs/charts/math.native.js.map +1 -1
  141. package/dist/cjs/charts/series.native.js.map +1 -1
  142. package/dist/cjs/charts/svg.native.js.map +1 -1
  143. package/dist/cjs/charts/types.native.js.map +1 -1
  144. package/dist/cjs/charts/useChartTheme.native.js.map +1 -1
  145. package/dist/cjs/code/Code/index.native.js.map +1 -1
  146. package/dist/cjs/code/CodeBlock/index.native.js +7 -7
  147. package/dist/cjs/code/CodeBlock/index.native.js.map +1 -1
  148. package/dist/cjs/code/HighlightedCode/index.native.js.map +1 -1
  149. package/dist/cjs/code/Highlighter/houseSyntaxTheme.native.js.map +1 -1
  150. package/dist/cjs/code/Highlighter/index.native.js.map +1 -1
  151. package/dist/cjs/code/Highlighter/namedGroupMatchAll.native.js.map +1 -1
  152. package/dist/cjs/code/Pre/index.native.js.map +1 -1
  153. package/dist/cjs/code/index.native.js +5 -5
  154. package/dist/cjs/code/index.native.js.map +1 -1
  155. package/dist/cjs/componentColors.native.js.map +1 -1
  156. package/dist/cjs/feedback/ConfirmDialog.native.js.map +1 -1
  157. package/dist/cjs/feedback/NotifyHost.native.js +2 -2
  158. package/dist/cjs/feedback/NotifyHost.native.js.map +1 -1
  159. package/dist/cjs/feedback/copy.native.js.map +1 -1
  160. package/dist/cjs/feedback/index.native.js.map +1 -1
  161. package/dist/cjs/feedback/notify.native.js.map +1 -1
  162. package/dist/cjs/feedback/route.native.js.map +1 -1
  163. package/dist/cjs/feedback/store.native.js.map +1 -1
  164. package/dist/cjs/formLayouts/FormLayouts.native.js +1 -1
  165. package/dist/cjs/formLayouts/FormLayouts.native.js.map +1 -1
  166. package/dist/cjs/formLayouts/PreferencePanel.native.js +2 -2
  167. package/dist/cjs/formLayouts/PreferencePanel.native.js.map +1 -1
  168. package/dist/cjs/formLayouts/index.native.js.map +1 -1
  169. package/dist/cjs/hooks/index.native.js +1 -1
  170. package/dist/cjs/hooks/index.native.js.map +1 -1
  171. package/dist/cjs/hooks/useClipboard.native.js.map +1 -1
  172. package/dist/cjs/hooks/useDocumentTitle.native.js.map +1 -1
  173. package/dist/cjs/hooks/useHoldCue.native.js.map +1 -1
  174. package/dist/cjs/icons/CheckRegular.native.js.map +1 -1
  175. package/dist/cjs/icons/MinusRegular.native.js.map +1 -1
  176. package/dist/cjs/icons/index.native.js.map +1 -1
  177. package/dist/cjs/icons/lucide.native.js.map +1 -1
  178. package/dist/cjs/icons/themed.native.js.map +1 -1
  179. package/dist/cjs/images/Image/ImageFrame.native.js +1 -1
  180. package/dist/cjs/images/Image/ImageFrame.native.js.map +1 -1
  181. package/dist/cjs/images/Image/framing.native.js.map +1 -1
  182. package/dist/cjs/images/Image/index.native.js +1 -1
  183. package/dist/cjs/images/Image/mediaRadius.native.js.map +1 -1
  184. package/dist/cjs/images/Image/shared.native.js +1 -1
  185. package/dist/cjs/images/Image/shared.native.js.map +1 -1
  186. package/dist/cjs/images/Image/types.native.js.map +1 -1
  187. package/dist/cjs/images/index.native.js.map +1 -1
  188. package/dist/cjs/index.cjs +6 -1
  189. package/dist/cjs/index.native.js +42 -37
  190. package/dist/cjs/index.native.js.map +1 -1
  191. package/dist/cjs/knobImmuneExports.native.js.map +1 -1
  192. package/dist/cjs/layouts/AsyncBoundary.native.js +2 -2
  193. package/dist/cjs/layouts/AsyncBoundary.native.js.map +1 -1
  194. package/dist/cjs/layouts/Debug/index.native.js.map +1 -1
  195. package/dist/cjs/layouts/EmptyState.native.js.map +1 -1
  196. package/dist/cjs/layouts/IdentityPlate.native.js.map +1 -1
  197. package/dist/cjs/layouts/KeyboardAvoidingWrapper/behavior.native.js.map +1 -1
  198. package/dist/cjs/layouts/PageTemplates.native.js.map +1 -1
  199. package/dist/cjs/layouts/PaneScaffold.native.js.map +1 -1
  200. package/dist/cjs/layouts/SafeAreaWrapper/insets.native.js.map +1 -1
  201. package/dist/cjs/layouts/StatusDot.native.js.map +1 -1
  202. package/dist/cjs/layouts/StatusGlyphStrip.native.js +1 -1
  203. package/dist/cjs/layouts/StatusGlyphStrip.native.js.map +1 -1
  204. package/dist/cjs/layouts/ViewSwitcher.native.js.map +1 -1
  205. package/dist/cjs/layouts/attachments.native.js +1 -1
  206. package/dist/cjs/layouts/attachments.native.js.map +1 -1
  207. package/dist/cjs/layouts/bottomAccessory.native.js.map +1 -1
  208. package/dist/cjs/layouts/breadcrumbs.native.js.map +1 -1
  209. package/dist/cjs/layouts/index.native.js +3 -3
  210. package/dist/cjs/layouts/index.native.js.map +1 -1
  211. package/dist/cjs/layouts/page.native.js +2 -2
  212. package/dist/cjs/layouts/page.native.js.map +1 -1
  213. package/dist/cjs/layouts/pageHeadingScope.native.js.map +1 -1
  214. package/dist/cjs/layouts/screenScroll.native.js.map +1 -1
  215. package/dist/cjs/layouts/shellSidebarSlot.native.js.map +1 -1
  216. package/dist/cjs/layouts/sidebar.native.js +1 -1
  217. package/dist/cjs/layouts/sidebar.native.js.map +1 -1
  218. package/dist/cjs/layouts/tags.native.js +2 -2
  219. package/dist/cjs/layouts/tags.native.js.map +1 -1
  220. package/dist/cjs/layouts/timeline.native.js +2 -2
  221. package/dist/cjs/layouts/timeline.native.js.map +1 -1
  222. package/dist/cjs/layouts/toolbar.native.js +1 -1
  223. package/dist/cjs/layouts/toolbar.native.js.map +1 -1
  224. package/dist/cjs/shared/actionScan.native.js.map +1 -1
  225. package/dist/cjs/shared/i18n.native.js.map +1 -1
  226. package/dist/cjs/shared/restoreRetries.native.js.map +1 -1
  227. package/dist/cjs/shared/t.native.js.map +1 -1
  228. package/dist/cjs/shared/textRidesText.native.js.map +1 -1
  229. package/dist/cjs/shared/useReturnFocusOnClose.native.js.map +1 -1
  230. package/dist/cjs/surfaces.native.js +1 -1
  231. package/dist/cjs/surfaces.native.js.map +1 -1
  232. package/dist/cjs/tamagui.native.js +1 -1
  233. package/dist/cjs/tamagui.native.js.map +1 -1
  234. package/dist/cjs/testSetup.native.js.map +1 -1
  235. package/dist/cjs/utils/setTinted.native.js.map +1 -1
  236. package/dist/cjs/utils/unwrapText.native.js.map +1 -1
  237. package/dist/cjs/views/Calendar.native.js +1 -1
  238. package/dist/cjs/views/Calendar.native.js.map +1 -1
  239. package/dist/cjs/views/Dashboard.native.js +2 -2
  240. package/dist/cjs/views/Dashboard.native.js.map +1 -1
  241. package/dist/cjs/views/Gantt.native.js +2 -2
  242. package/dist/cjs/views/Gantt.native.js.map +1 -1
  243. package/dist/cjs/views/GanttDateGrip.native.js.map +1 -1
  244. package/dist/cjs/views/ImageGrid.native.js +2 -2
  245. package/dist/cjs/views/ImageGrid.native.js.map +1 -1
  246. package/dist/cjs/views/Kanban.native.js +1 -1
  247. package/dist/cjs/views/List.native.js.map +1 -1
  248. package/dist/cjs/views/ListGroup.native.js.map +1 -1
  249. package/dist/cjs/views/ListRow.native.js.map +1 -1
  250. package/dist/cjs/views/Matrix.native.js +2 -2
  251. package/dist/cjs/views/Matrix.native.js.map +1 -1
  252. package/dist/cjs/views/ReportBuilder.cjs +3 -3
  253. package/dist/cjs/views/ReportBuilder.native.js +5 -5
  254. package/dist/cjs/views/ReportBuilder.native.js.map +1 -1
  255. package/dist/cjs/views/ShortcutCard.native.js.map +1 -1
  256. package/dist/cjs/views/TreeView.native.js.map +1 -1
  257. package/dist/cjs/views/calendarMath.native.js.map +1 -1
  258. package/dist/cjs/views/ganttIntervals.native.js.map +1 -1
  259. package/dist/cjs/views/ganttMath.native.js.map +1 -1
  260. package/dist/cjs/views/index.cjs +3 -1
  261. package/dist/cjs/views/index.native.js +3 -1
  262. package/dist/cjs/views/index.native.js.map +1 -1
  263. package/dist/cjs/views/kanbanDnd.native.js.map +1 -1
  264. package/dist/cjs/views/matrixMath.native.js.map +1 -1
  265. package/dist/cjs/views/sameNameScope.cjs +39 -0
  266. package/dist/cjs/views/sameNameScope.native.js +63 -0
  267. package/dist/cjs/views/sameNameScope.native.js.map +1 -0
  268. package/dist/cjs/views/treeViewDnd.native.js.map +1 -1
  269. package/dist/cjs/views/treeViewLayout.native.js.map +1 -1
  270. package/dist/cjs/views/treeViewMotion.native.js.map +1 -1
  271. package/dist/cjs/views/treeViewReveal.native.js.map +1 -1
  272. package/dist/cjs/views/usePageFlowLoadMore.native.js.map +1 -1
  273. package/dist/cjs/views/widgetChrome.native.js.map +1 -1
  274. package/dist/esm/Diff/diff.mjs +58 -0
  275. package/dist/esm/Diff/diff.mjs.map +1 -0
  276. package/dist/esm/Diff/diff.native.js +79 -0
  277. package/dist/esm/Diff/diff.native.js.map +1 -0
  278. package/dist/esm/Diff/index.mjs +147 -0
  279. package/dist/esm/Diff/index.mjs.map +1 -0
  280. package/dist/esm/Diff/index.native.js +151 -0
  281. package/dist/esm/Diff/index.native.js.map +1 -0
  282. package/dist/esm/ElapsedProgress/index.mjs +76 -0
  283. package/dist/esm/ElapsedProgress/index.mjs.map +1 -0
  284. package/dist/esm/ElapsedProgress/index.native.js +83 -0
  285. package/dist/esm/ElapsedProgress/index.native.js.map +1 -0
  286. package/dist/esm/MachineLiteral/index.mjs +73 -0
  287. package/dist/esm/MachineLiteral/index.mjs.map +1 -0
  288. package/dist/esm/MachineLiteral/index.native.js +74 -0
  289. package/dist/esm/MachineLiteral/index.native.js.map +1 -0
  290. package/dist/esm/Material/blur.mjs +8 -0
  291. package/dist/esm/Material/blur.mjs.map +1 -0
  292. package/dist/esm/Material/blur.native.js +67 -0
  293. package/dist/esm/Material/blur.native.js.map +1 -0
  294. package/dist/esm/Material/index.mjs +10 -4
  295. package/dist/esm/Material/index.mjs.map +1 -1
  296. package/dist/esm/Material/index.native.js +10 -4
  297. package/dist/esm/Material/index.native.js.map +1 -1
  298. package/dist/esm/Meter/index.mjs +4 -3
  299. package/dist/esm/Meter/index.mjs.map +1 -1
  300. package/dist/esm/Meter/index.native.js +4 -3
  301. package/dist/esm/Meter/index.native.js.map +1 -1
  302. package/dist/esm/SortableList/index.mjs +2 -1
  303. package/dist/esm/SortableList/index.mjs.map +1 -1
  304. package/dist/esm/SortableList/index.native.js +2 -1
  305. package/dist/esm/SortableList/index.native.js.map +1 -1
  306. package/dist/esm/SortableList/useUserOrder.mjs +58 -0
  307. package/dist/esm/SortableList/useUserOrder.mjs.map +1 -0
  308. package/dist/esm/SortableList/useUserOrder.native.js +78 -0
  309. package/dist/esm/SortableList/useUserOrder.native.js.map +1 -0
  310. package/dist/esm/TreeSelect/index.mjs +8 -2
  311. package/dist/esm/TreeSelect/index.mjs.map +1 -1
  312. package/dist/esm/TreeSelect/index.native.js +8 -2
  313. package/dist/esm/TreeSelect/index.native.js.map +1 -1
  314. package/dist/esm/appShell/TabBar.mjs +10 -5
  315. package/dist/esm/appShell/TabBar.mjs.map +1 -1
  316. package/dist/esm/appShell/TabBar.native.js +10 -5
  317. package/dist/esm/appShell/TabBar.native.js.map +1 -1
  318. package/dist/esm/charts/Sparkline.mjs +1 -1
  319. package/dist/esm/charts/Sparkline.mjs.map +1 -1
  320. package/dist/esm/charts/Sparkline.native.js +1 -1
  321. package/dist/esm/charts/Sparkline.native.js.map +1 -1
  322. package/dist/esm/index.mjs +5 -2
  323. package/dist/esm/index.mjs.map +1 -1
  324. package/dist/esm/index.native.js +5 -2
  325. package/dist/esm/index.native.js.map +1 -1
  326. package/dist/esm/views/ReportBuilder.mjs +4 -4
  327. package/dist/esm/views/ReportBuilder.mjs.map +1 -1
  328. package/dist/esm/views/ReportBuilder.native.js +4 -4
  329. package/dist/esm/views/ReportBuilder.native.js.map +1 -1
  330. package/dist/esm/views/index.mjs +2 -1
  331. package/dist/esm/views/index.mjs.map +1 -1
  332. package/dist/esm/views/index.native.js +2 -1
  333. package/dist/esm/views/index.native.js.map +1 -1
  334. package/dist/esm/views/sameNameScope.mjs +14 -0
  335. package/dist/esm/views/sameNameScope.mjs.map +1 -0
  336. package/dist/esm/views/sameNameScope.native.js +35 -0
  337. package/dist/esm/views/sameNameScope.native.js.map +1 -0
  338. package/dist/jsx/Diff/diff.mjs +58 -0
  339. package/dist/jsx/Diff/diff.mjs.map +1 -0
  340. package/dist/jsx/Diff/diff.native.js +108 -0
  341. package/dist/jsx/Diff/diff.native.js.map +1 -0
  342. package/dist/jsx/Diff/index.mjs +147 -0
  343. package/dist/jsx/Diff/index.mjs.map +1 -0
  344. package/dist/jsx/Diff/index.native.js +181 -0
  345. package/dist/jsx/Diff/index.native.js.map +1 -0
  346. package/dist/jsx/ElapsedProgress/index.mjs +76 -0
  347. package/dist/jsx/ElapsedProgress/index.mjs.map +1 -0
  348. package/dist/jsx/ElapsedProgress/index.native.js +112 -0
  349. package/dist/jsx/ElapsedProgress/index.native.js.map +1 -0
  350. package/dist/jsx/MachineLiteral/index.mjs +73 -0
  351. package/dist/jsx/MachineLiteral/index.mjs.map +1 -0
  352. package/dist/jsx/MachineLiteral/index.native.js +102 -0
  353. package/dist/jsx/MachineLiteral/index.native.js.map +1 -0
  354. package/dist/jsx/Material/blur.mjs +8 -0
  355. package/dist/jsx/Material/blur.mjs.map +1 -0
  356. package/dist/jsx/Material/blur.native.js +100 -0
  357. package/dist/jsx/Material/blur.native.js.map +1 -0
  358. package/dist/jsx/Material/index.mjs +10 -4
  359. package/dist/jsx/Material/index.mjs.map +1 -1
  360. package/dist/jsx/Material/index.native.js +9 -3
  361. package/dist/jsx/Material/index.native.js.map +1 -1
  362. package/dist/jsx/Meter/index.mjs +4 -3
  363. package/dist/jsx/Meter/index.mjs.map +1 -1
  364. package/dist/jsx/Meter/index.native.js +3 -1
  365. package/dist/jsx/Meter/index.native.js.map +1 -1
  366. package/dist/jsx/SortableList/index.mjs +2 -1
  367. package/dist/jsx/SortableList/index.mjs.map +1 -1
  368. package/dist/jsx/SortableList/index.native.js +4 -1
  369. package/dist/jsx/SortableList/index.native.js.map +1 -1
  370. package/dist/jsx/SortableList/useUserOrder.mjs +58 -0
  371. package/dist/jsx/SortableList/useUserOrder.mjs.map +1 -0
  372. package/dist/jsx/SortableList/useUserOrder.native.js +107 -0
  373. package/dist/jsx/SortableList/useUserOrder.native.js.map +1 -0
  374. package/dist/jsx/TreeSelect/index.mjs +8 -2
  375. package/dist/jsx/TreeSelect/index.mjs.map +1 -1
  376. package/dist/jsx/TreeSelect/index.native.js +7 -1
  377. package/dist/jsx/TreeSelect/index.native.js.map +1 -1
  378. package/dist/jsx/appShell/TabBar.mjs +10 -5
  379. package/dist/jsx/appShell/TabBar.mjs.map +1 -1
  380. package/dist/jsx/appShell/TabBar.native.js +10 -5
  381. package/dist/jsx/appShell/TabBar.native.js.map +1 -1
  382. package/dist/jsx/charts/Sparkline.mjs +1 -1
  383. package/dist/jsx/charts/Sparkline.mjs.map +1 -1
  384. package/dist/jsx/charts/Sparkline.native.js +1 -1
  385. package/dist/jsx/charts/Sparkline.native.js.map +1 -1
  386. package/dist/jsx/feedback/NotifyHost.native.js +1 -1
  387. package/dist/jsx/formLayouts/PreferencePanel.native.js +1 -1
  388. package/dist/jsx/index.js +5 -2
  389. package/dist/jsx/index.js.map +1 -1
  390. package/dist/jsx/index.mjs +5 -2
  391. package/dist/jsx/index.mjs.map +1 -1
  392. package/dist/jsx/index.native.js +7 -2
  393. package/dist/jsx/index.native.js.map +1 -1
  394. package/dist/jsx/layouts/AsyncBoundary.native.js +1 -1
  395. package/dist/jsx/layouts/AsyncBoundary.native.js.map +1 -1
  396. package/dist/jsx/views/ReportBuilder.mjs +4 -4
  397. package/dist/jsx/views/ReportBuilder.mjs.map +1 -1
  398. package/dist/jsx/views/ReportBuilder.native.js +3 -3
  399. package/dist/jsx/views/ReportBuilder.native.js.map +1 -1
  400. package/dist/jsx/views/index.mjs +2 -1
  401. package/dist/jsx/views/index.mjs.map +1 -1
  402. package/dist/jsx/views/index.native.js +2 -0
  403. package/dist/jsx/views/index.native.js.map +1 -1
  404. package/dist/jsx/views/sameNameScope.mjs +14 -0
  405. package/dist/jsx/views/sameNameScope.mjs.map +1 -0
  406. package/dist/jsx/views/sameNameScope.native.js +63 -0
  407. package/dist/jsx/views/sameNameScope.native.js.map +1 -0
  408. package/package.json +18 -9
  409. package/src/Diff/Diff.spec.tsx +105 -0
  410. package/src/Diff/Diff.stories.tsx +44 -0
  411. package/src/Diff/diff.ts +61 -0
  412. package/src/Diff/index.tsx +145 -0
  413. package/src/ElapsedProgress/ElapsedProgress.spec.tsx +66 -0
  414. package/src/ElapsedProgress/ElapsedProgress.stories.tsx +43 -0
  415. package/src/ElapsedProgress/index.tsx +89 -0
  416. package/src/MachineLiteral/MachineLiteral.spec.tsx +86 -0
  417. package/src/MachineLiteral/MachineLiteral.stories.tsx +44 -0
  418. package/src/MachineLiteral/index.tsx +75 -0
  419. package/src/Material/blur.native.spec.tsx +135 -0
  420. package/src/Material/blur.native.tsx +93 -0
  421. package/src/Material/blur.ts +11 -0
  422. package/src/Material/index.tsx +18 -6
  423. package/src/Meter/index.tsx +4 -2
  424. package/src/SortableList/index.tsx +2 -0
  425. package/src/SortableList/useUserOrder.spec.tsx +110 -0
  426. package/src/SortableList/useUserOrder.ts +96 -0
  427. package/src/TreeSelect/TreeSelect.rows.spec.tsx +44 -0
  428. package/src/TreeSelect/index.tsx +12 -1
  429. package/src/appShell/TabBar.tsx +3 -0
  430. package/src/charts/Sparkline.tsx +3 -3
  431. package/src/index.ts +7 -0
  432. package/src/presentationEmpty.spec.tsx +71 -0
  433. package/src/views/ReportBuilder.tsx +4 -3
  434. package/src/views/index.ts +1 -0
  435. package/src/views/sameNameScope.spec.tsx +55 -0
  436. package/src/views/sameNameScope.ts +22 -0
  437. package/types/Diff/diff.d.ts +17 -0
  438. package/types/Diff/diff.d.ts.map +1 -0
  439. package/types/Diff/index.d.ts +15 -0
  440. package/types/Diff/index.d.ts.map +1 -0
  441. package/types/ElapsedProgress/index.d.ts +15 -0
  442. package/types/ElapsedProgress/index.d.ts.map +1 -0
  443. package/types/MachineLiteral/index.d.ts +13 -0
  444. package/types/MachineLiteral/index.d.ts.map +1 -0
  445. package/types/Material/blur.d.ts +9 -0
  446. package/types/Material/blur.d.ts.map +1 -0
  447. package/types/Material/blur.native.d.ts +38 -0
  448. package/types/Material/blur.native.d.ts.map +1 -0
  449. package/types/Material/index.d.ts.map +1 -1
  450. package/types/Meter/index.d.ts +2 -0
  451. package/types/Meter/index.d.ts.map +1 -1
  452. package/types/SortableList/index.d.ts +2 -0
  453. package/types/SortableList/index.d.ts.map +1 -1
  454. package/types/SortableList/useUserOrder.d.ts +28 -0
  455. package/types/SortableList/useUserOrder.d.ts.map +1 -0
  456. package/types/TreeSelect/index.d.ts.map +1 -1
  457. package/types/appShell/TabBar.d.ts.map +1 -1
  458. package/types/charts/Sparkline.d.ts +2 -2
  459. package/types/charts/Sparkline.d.ts.map +1 -1
  460. package/types/index.d.ts +5 -2
  461. package/types/index.d.ts.map +1 -1
  462. package/types/views/ReportBuilder.d.ts.map +1 -1
  463. package/types/views/index.d.ts +1 -0
  464. package/types/views/index.d.ts.map +1 -1
  465. package/types/views/sameNameScope.d.ts +8 -0
  466. package/types/views/sameNameScope.d.ts.map +1 -0
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all) __defProp(target, name, {
9
+ get: all[name],
10
+ enumerable: true
11
+ });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
16
+ get: () => from[key],
17
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
18
+ });
19
+ }
20
+ return to;
21
+ };
22
+ var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
23
+ value: true
24
+ }), mod);
25
+ var sameNameScope_exports = {};
26
+ __export(sameNameScope_exports, {
27
+ scopedNames: () => scopedNames
28
+ });
29
+ module.exports = __toCommonJS(sameNameScope_exports);
30
+ function scopedNames(items, nameOf, scopeOf) {
31
+ var counts = /* @__PURE__ */new Map();
32
+ var _iteratorNormalCompletion = true,
33
+ _didIteratorError = false,
34
+ _iteratorError = void 0;
35
+ try {
36
+ for (var _iterator = items[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
37
+ var item = _step.value;
38
+ var _counts_get;
39
+ var name = nameOf(item);
40
+ counts.set(name, ((_counts_get = counts.get(name)) !== null && _counts_get !== void 0 ? _counts_get : 0) + 1);
41
+ }
42
+ } catch (err) {
43
+ _didIteratorError = true;
44
+ _iteratorError = err;
45
+ } finally {
46
+ try {
47
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
48
+ _iterator.return();
49
+ }
50
+ } finally {
51
+ if (_didIteratorError) {
52
+ throw _iteratorError;
53
+ }
54
+ }
55
+ }
56
+ return items.map(function (item2) {
57
+ var _counts_get2;
58
+ var name2 = nameOf(item2);
59
+ var scope = scopeOf(item2);
60
+ return ((_counts_get2 = counts.get(name2)) !== null && _counts_get2 !== void 0 ? _counts_get2 : 0) > 1 && scope ? `${name2} (${scope})` : name2;
61
+ });
62
+ }
63
+ //# sourceMappingURL=sameNameScope.native.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["__defProp","Object","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","__copyProps","to","from","except","desc","key"],"sources":["../../../src/views/sameNameScope.ts"],"sourcesContent":[null],"mappings":"AAMO,YAAS;;AAKd,IAAAA,SAAM,GAAAC,MAAS,CAAAC,cAAI;AACnB,IAAAC,gBAAW,GAAQF,MAAO,CAAAG,wBAAA;AACxB,IAAAC,iBAAa,GAAOJ,MAAI,CAAAK,mBAAA;AACxB,IAAAC,YAAW,GAAAN,MAAO,CAAAO,SAAW,CAAAC,cAAe;AAAA,IAC9CC,QAAA,GAAAA,CAAAC,MAAA,EAAAC,GAAA;EACA,SAAOC,IAAM,IAAID,GAAC,EAChBZ,SAAM,CAAAW,MAAO,EAAAE,IAAO,EAAI;IAAAC,GAAA,EAAAF,GAAA,CAAAC,IAAA;IAAAE,UAAA;EAAA;AACxB;AACA,IAAAC,WAAQ,GAAAA,CAAOC,EAAA,EAAIC,IAAI,EAAAC,MAAK,EAAKC,IAAA,KAAK;EACxC,IAACF,IAAA,WAAAA,IAAA,wBAAAA,IAAA;IACH,SAAAG,GAAA,IAAAhB,iBAAA,CAAAa,IAAA,G","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@multiplatform.one/components",
3
- "version": "7.78.0",
3
+ "version": "7.79.0",
4
4
  "description": "multiplatform.one ui components",
5
5
  "keywords": [
6
6
  "components",
@@ -58,11 +58,11 @@
58
58
  },
59
59
  "dependencies": {
60
60
  "@floating-ui/react": "^0.27.20",
61
- "@multiplatform.one/forms": "^7.78.0",
62
- "@multiplatform.one/i18n": "^7.78.0",
63
- "@multiplatform.one/platform": "^7.78.0",
64
- "@multiplatform.one/router": "^7.78.0",
65
- "@multiplatform.one/theme": "^7.78.0",
61
+ "@multiplatform.one/forms": "^7.79.0",
62
+ "@multiplatform.one/i18n": "^7.79.0",
63
+ "@multiplatform.one/platform": "^7.79.0",
64
+ "@multiplatform.one/router": "^7.79.0",
65
+ "@multiplatform.one/theme": "^7.79.0",
66
66
  "@phosphor-icons/react": "^2.1.10",
67
67
  "@shopify/flash-list": "^2.3.1",
68
68
  "@tamagui/colors": "2.7.6",
@@ -89,9 +89,9 @@
89
89
  "tamagui": "2.7.6"
90
90
  },
91
91
  "devDependencies": {
92
- "@multiplatform.one/config": "7.78.0",
93
- "@multiplatform.one/storybook": "7.78.0",
94
- "@multiplatform.one/test-utils": "7.78.0",
92
+ "@multiplatform.one/config": "7.79.0",
93
+ "@multiplatform.one/storybook": "7.79.0",
94
+ "@multiplatform.one/test-utils": "7.79.0",
95
95
  "@tamagui/build": "2.7.6",
96
96
  "@testing-library/jest-dom": "^7.0.1",
97
97
  "@testing-library/react": "^16.3.3",
@@ -99,6 +99,7 @@
99
99
  "@types/d3-shape": "^3.2.0",
100
100
  "@vitejs/plugin-react": "^6.1.2",
101
101
  "@vitest/coverage-v8": "^4.1.5",
102
+ "expo-blur": "~55.0.18",
102
103
  "expo-video": "~55.0.19",
103
104
  "matchmedia-polyfill": "^0.3.2",
104
105
  "moti": "^0.30.0",
@@ -115,6 +116,8 @@
115
116
  "@mdx-js/react": "^3.1.1",
116
117
  "@vxrn/color-scheme": "^1.0.0",
117
118
  "expo-asset": "*",
119
+ "expo-blur": "*",
120
+ "expo-modules-core": "*",
118
121
  "expo-video": "*",
119
122
  "gray-matter": "^4.0.3",
120
123
  "hast-util-to-html": "8.0.4",
@@ -149,6 +152,12 @@
149
152
  "expo-asset": {
150
153
  "optional": true
151
154
  },
155
+ "expo-blur": {
156
+ "optional": true
157
+ },
158
+ "expo-modules-core": {
159
+ "optional": true
160
+ },
152
161
  "expo-video": {
153
162
  "optional": true
154
163
  },
@@ -0,0 +1,105 @@
1
+ /**
2
+ * LC-190 CHANGE-POLARITY: a change view speaks insert and delete. The Main
3
+ * story marks added content <ins> and removed content <del>, says "added" and
4
+ * "removed" to assistive tech, puts the counts in the region's name, keeps the
5
+ * +/− gutter out of selection and out of the accessibility tree, and paints
6
+ * the success and error washes with neutral ink, never a border or solid.
7
+ */
8
+ import { renderWithProviders } from "@multiplatform.one/test-utils";
9
+ import { cleanup } from "@testing-library/react";
10
+ import { afterEach, describe, expect, it } from "vitest";
11
+ import meta, { Default, NoChanges, NoReading } from "./Diff.stories";
12
+ import { Diff, countDiff, diffLines, type DiffProps } from "./index";
13
+
14
+ afterEach(cleanup);
15
+
16
+ function mount(args: unknown) {
17
+ return renderWithProviders(<Diff {...(args as DiffProps)} />);
18
+ }
19
+
20
+ describe("diffLines", () => {
21
+ it("keeps common lines and orders a hunk removed before added", () => {
22
+ const lines = diffLines("a\nb\nc", "a\nB\nc\nd");
23
+ expect(lines.map((line) => `${line.kind}:${line.text}`)).toEqual([
24
+ "same:a",
25
+ "removed:b",
26
+ "added:B",
27
+ "same:c",
28
+ "added:d",
29
+ ]);
30
+ expect(countDiff(lines)).toEqual({ added: 2, removed: 1 });
31
+ expect(lines[2]).toMatchObject({ after: 2 });
32
+ expect(lines[1]).toMatchObject({ before: 2 });
33
+ });
34
+ });
35
+
36
+ describe("Diff (LC-190)", () => {
37
+ it("declares the Components/Diff title", () => {
38
+ expect(meta.title).toBe("Components/Diff");
39
+ });
40
+
41
+ it("marks content with ins and del and the hidden polarity words", () => {
42
+ const { container } = mount(Default.args);
43
+ const ins = [...container.querySelectorAll("ins")];
44
+ const del = [...container.querySelectorAll("del")];
45
+ expect(ins.map((node) => node.textContent)).toEqual([
46
+ "added: listen 443 ssl;",
47
+ "added: http2 on;",
48
+ ]);
49
+ expect(del.map((node) => node.textContent)).toEqual(["removed: listen 80;"]);
50
+ });
51
+
52
+ it("names the region with the counts", () => {
53
+ const { container } = mount(Default.args);
54
+ const region = container.querySelector("[role='region']");
55
+ expect(region?.getAttribute("aria-label")).toBe("nginx.conf: 2 added, 1 removed");
56
+ });
57
+
58
+ it("keeps the gutter out of selection and out of the accessibility tree", () => {
59
+ const { container } = mount(Default.args);
60
+ const gutters = [...container.querySelectorAll("[data-diff-gutter]")] as HTMLElement[];
61
+ expect(gutters.length).toBe(6);
62
+ for (const gutter of gutters) {
63
+ expect(gutter.getAttribute("aria-hidden")).toBe("true");
64
+ const inline = gutter.getAttribute("style") ?? "";
65
+ const unselectable =
66
+ /(?:^|\s)_(?:userSelect|ussl|ussel)-none(?:\s|$)/.test(gutter.className) ||
67
+ /user-select:\s*none/.test(inline) ||
68
+ getComputedStyle(gutter).userSelect === "none";
69
+ expect(unselectable, `${gutter.className} | ${inline}`).toBe(true);
70
+ }
71
+ const glyphs = gutters.map((gutter) => gutter.textContent?.slice(-1));
72
+ expect(glyphs.filter((glyph) => glyph === "+")).toHaveLength(2);
73
+ expect(glyphs.filter((glyph) => glyph === "−")).toHaveLength(1);
74
+ });
75
+
76
+ it("washes added and removed rows, neutral ink, no border or solid fill", () => {
77
+ const { container } = mount(Default.args);
78
+ for (const kind of ["added", "removed"] as const) {
79
+ for (const row of container.querySelectorAll(`[data-diff-line='${kind}']`)) {
80
+ const style = getComputedStyle(row as HTMLElement);
81
+ expect(style.borderTopWidth || "0px").toMatch(/^0/);
82
+ expect(row.className).not.toMatch(/_bw-|_btw-/);
83
+ }
84
+ }
85
+ expect(container.querySelectorAll("[data-diff-line='same']")).toHaveLength(3);
86
+ });
87
+
88
+ it("identical sides draw No changes, not a zero count", () => {
89
+ const { container } = mount(NoChanges.args);
90
+ expect(container.textContent).toContain("No changes");
91
+ expect(container.textContent).not.toMatch(/\b0\b/);
92
+ expect(container.querySelector("[role='region']")?.getAttribute("aria-label")).toBe(
93
+ "nginx.conf: no changes",
94
+ );
95
+ });
96
+
97
+ it("no reading draws the em dash and says so", () => {
98
+ const { container } = mount(NoReading.args);
99
+ expect(container.querySelector("[data-diff-empty='unknown']")?.textContent).toBe("—");
100
+ expect(container.textContent).not.toMatch(/\b0\b/);
101
+ expect(container.querySelector("[role='region']")?.getAttribute("aria-label")).toBe(
102
+ "nginx.conf: no reading",
103
+ );
104
+ });
105
+ });
@@ -0,0 +1,44 @@
1
+ import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
2
+ import { Diff } from "./index";
3
+
4
+ const meta: Meta<typeof Diff> = {
5
+ title: "Components/Diff",
6
+ component: Diff,
7
+ parameters: {
8
+ status: { type: "beta" },
9
+ docs: {
10
+ description: {
11
+ component:
12
+ "A change view (LC-190): added lines on the success wash, removed lines on the error wash, neutral ink, a +/− gutter that is never selected or read, <ins>/<del> with hidden polarity words on web, and the counts in the region's accessible name. No reading draws an em dash; identical sides draw No changes (LC-220).",
13
+ },
14
+ },
15
+ },
16
+ };
17
+ export default meta;
18
+
19
+ type Story = StoryObj<typeof Diff>;
20
+
21
+ export const Default: Story = {
22
+ name: "Main",
23
+ args: {
24
+ label: "nginx.conf",
25
+ before: "server {\n listen 80;\n root /srv/www;\n}",
26
+ after: "server {\n listen 443 ssl;\n root /srv/www;\n http2 on;\n}",
27
+ },
28
+ };
29
+
30
+ export const NoChanges: Story = {
31
+ args: {
32
+ label: "nginx.conf",
33
+ before: "server {\n listen 80;\n}",
34
+ after: "server {\n listen 80;\n}",
35
+ },
36
+ };
37
+
38
+ export const NoReading: Story = {
39
+ args: {
40
+ label: "nginx.conf",
41
+ before: null,
42
+ after: null,
43
+ },
44
+ };
@@ -0,0 +1,61 @@
1
+ export type DiffLineKind = "added" | "removed" | "same";
2
+
3
+ export interface DiffLine {
4
+ kind: DiffLineKind;
5
+ text: string;
6
+ /** 1-based line in the before text; absent on an added line. */
7
+ before?: number;
8
+ /** 1-based line in the after text; absent on a removed line. */
9
+ after?: number;
10
+ }
11
+
12
+ export interface DiffCounts {
13
+ added: number;
14
+ removed: number;
15
+ }
16
+
17
+ function splitLines(text: string): string[] {
18
+ return text === "" ? [] : text.replace(/\r\n/g, "\n").split("\n");
19
+ }
20
+
21
+ /** Line diff by longest common subsequence, removals before additions in a hunk. */
22
+ export function diffLines(before: string, after: string): DiffLine[] {
23
+ const a = splitLines(before);
24
+ const b = splitLines(after);
25
+ const lcs: number[][] = Array.from({ length: a.length + 1 }, () =>
26
+ new Array<number>(b.length + 1).fill(0),
27
+ );
28
+ for (let i = a.length - 1; i >= 0; i -= 1) {
29
+ for (let j = b.length - 1; j >= 0; j -= 1) {
30
+ lcs[i]![j] =
31
+ a[i] === b[j] ? lcs[i + 1]![j + 1]! + 1 : Math.max(lcs[i + 1]![j]!, lcs[i]![j + 1]!);
32
+ }
33
+ }
34
+ const lines: DiffLine[] = [];
35
+ let i = 0;
36
+ let j = 0;
37
+ while (i < a.length || j < b.length) {
38
+ if (i < a.length && j < b.length && a[i] === b[j]) {
39
+ lines.push({ kind: "same", text: a[i]!, before: i + 1, after: j + 1 });
40
+ i += 1;
41
+ j += 1;
42
+ } else if (j >= b.length || (i < a.length && lcs[i + 1]![j]! >= lcs[i]![j + 1]!)) {
43
+ lines.push({ kind: "removed", text: a[i]!, before: i + 1 });
44
+ i += 1;
45
+ } else {
46
+ lines.push({ kind: "added", text: b[j]!, after: j + 1 });
47
+ j += 1;
48
+ }
49
+ }
50
+ return lines;
51
+ }
52
+
53
+ export function countDiff(lines: readonly DiffLine[]): DiffCounts {
54
+ let added = 0;
55
+ let removed = 0;
56
+ for (const line of lines) {
57
+ if (line.kind === "added") added += 1;
58
+ else if (line.kind === "removed") removed += 1;
59
+ }
60
+ return { added, removed };
61
+ }
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Diff — a change view that speaks insert and delete (LC-190).
3
+ *
4
+ * Added lines sit on the success wash, removed lines on the error wash, both
5
+ * in neutral ink, with a +/− gutter glyph that is never selected or read.
6
+ * Web marks the content `<ins>`/`<del>` and prefixes the hidden words
7
+ * "added"/"removed"; native puts the same words in each row's label. The
8
+ * region's accessible name carries the counts.
9
+ *
10
+ * LC-220: no reading (either side missing) draws the em dash and says so;
11
+ * identical sides draw "No changes". Neither is a zero.
12
+ */
13
+ import { useResolvedKnobs } from "@multiplatform.one/theme";
14
+ import { useMemo } from "react";
15
+ import { Text, XStack, YStack, isWeb, type YStackProps } from "tamagui";
16
+ import { useTranslation } from "../shared/i18n";
17
+ import { withInterp } from "../shared/t";
18
+ import { countDiff, diffLines, type DiffLine } from "./diff";
19
+
20
+ export { countDiff, diffLines } from "./diff";
21
+ export type { DiffCounts, DiffLine, DiffLineKind } from "./diff";
22
+
23
+ export interface DiffProps extends Omit<YStackProps, "children"> {
24
+ /** The text before the change; null or undefined is no reading. */
25
+ before?: string | null;
26
+ /** The text after the change; null or undefined is no reading. */
27
+ after?: string | null;
28
+ /** What changed, the head of the region's accessible name ("nginx.conf"). */
29
+ label: string;
30
+ /** Show before/after line numbers in the gutter (default true). */
31
+ lineNumbers?: boolean;
32
+ }
33
+
34
+ const unknownMark = "—";
35
+ const glyphs = { added: "+", removed: "−", same: " " } as const;
36
+ const washes = { added: "$green3", removed: "$red3", same: undefined } as const;
37
+ const elements = { added: "ins", removed: "del", same: "span" } as const;
38
+
39
+ const hiddenWord = isWeb
40
+ ? ({
41
+ position: "absolute",
42
+ width: 1,
43
+ height: 1,
44
+ overflow: "hidden",
45
+ whiteSpace: "nowrap",
46
+ opacity: 0,
47
+ } as const)
48
+ : undefined;
49
+
50
+ export function Diff({ before, after, label, lineNumbers = true, ...frameProps }: DiffProps) {
51
+ const { t } = useTranslation();
52
+ const { knobProps } = useResolvedKnobs({ component: "Diff" });
53
+ const known = before != null && after != null;
54
+ const lines = useMemo(
55
+ () => (known ? diffLines(before as string, after as string) : []),
56
+ [known, before, after],
57
+ );
58
+ const counts = countDiff(lines);
59
+ const changed = counts.added + counts.removed > 0;
60
+ const state = !known ? "unknown" : changed ? "changed" : "same";
61
+ const summary =
62
+ state === "unknown"
63
+ ? withInterp(t("{{label}}: no reading", { label }), { label })
64
+ : state === "same"
65
+ ? withInterp(t("{{label}}: no changes", { label }), { label })
66
+ : withInterp(t("{{label}}: {{added}} added, {{removed}} removed", { label, ...counts }), {
67
+ label,
68
+ ...counts,
69
+ });
70
+ const words = { added: t("added"), removed: t("removed") };
71
+
72
+ const mono = {
73
+ ...knobProps.body,
74
+ fontFamily: "$mono",
75
+ letterSpacing: 0,
76
+ color: "$color12",
77
+ } as const;
78
+
79
+ const row = (line: DiffLine, index: number) => {
80
+ const marked = line.kind !== "same";
81
+ return (
82
+ <XStack
83
+ key={index}
84
+ backgroundColor={washes[line.kind]}
85
+ data-diff-line={line.kind}
86
+ {...(!isWeb && marked
87
+ ? { accessible: true, accessibilityLabel: `${words[line.kind]}: ${line.text}` }
88
+ : null)}
89
+ >
90
+ <XStack
91
+ aria-hidden
92
+ userSelect="none"
93
+ flexShrink={0}
94
+ gap="$2"
95
+ paddingHorizontal="$2"
96
+ data-diff-gutter=""
97
+ >
98
+ {lineNumbers ? (
99
+ <>
100
+ <Text {...mono} color="$color11" minWidth="$2" textAlign="right">
101
+ {line.before ?? ""}
102
+ </Text>
103
+ <Text {...mono} color="$color11" minWidth="$2" textAlign="right">
104
+ {line.after ?? ""}
105
+ </Text>
106
+ </>
107
+ ) : null}
108
+ <Text {...mono}>{glyphs[line.kind]}</Text>
109
+ </XStack>
110
+ <Text
111
+ {...mono}
112
+ flex={1}
113
+ render={isWeb ? elements[line.kind] : undefined}
114
+ textDecorationLine="none"
115
+ {...(isWeb ? { whiteSpace: "pre-wrap" } : null)}
116
+ >
117
+ {marked && isWeb ? <Text style={hiddenWord}>{`${words[line.kind]}: `}</Text> : null}
118
+ {line.text}
119
+ </Text>
120
+ </XStack>
121
+ );
122
+ };
123
+
124
+ return (
125
+ <YStack
126
+ role="region"
127
+ aria-label={summary}
128
+ accessibilityLabel={summary}
129
+ overflow="hidden"
130
+ {...knobProps.borderRadius}
131
+ data-diff-state={state}
132
+ {...frameProps}
133
+ >
134
+ {state === "changed" ? (
135
+ lines.map(row)
136
+ ) : (
137
+ <XStack paddingHorizontal="$2" data-diff-empty={state}>
138
+ <Text {...mono} color="$color11">
139
+ {state === "unknown" ? unknownMark : t("No changes")}
140
+ </Text>
141
+ </XStack>
142
+ )}
143
+ </YStack>
144
+ );
145
+ }
@@ -0,0 +1,66 @@
1
+ /**
2
+ * LC-185 ELAPSED-NOT-SPINNER: under a fake clock, a short wait is a bare
3
+ * spinner; past the threshold the elapsed time joins it and keeps counting;
4
+ * determinate work draws the bar.
5
+ */
6
+ import { renderWithProviders } from "@multiplatform.one/test-utils";
7
+ import { act, cleanup } from "@testing-library/react";
8
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
9
+ import { Default } from "./ElapsedProgress.stories";
10
+ import { ElapsedProgress, formatElapsed } from "./index";
11
+
12
+ beforeEach(() => {
13
+ vi.useFakeTimers();
14
+ vi.setSystemTime(new Date("2026-10-29T12:00:00Z"));
15
+ });
16
+
17
+ afterEach(() => {
18
+ cleanup();
19
+ vi.useRealTimers();
20
+ });
21
+
22
+ function elapsedOf(container: HTMLElement) {
23
+ return container.querySelector("[data-elapsed]")?.textContent ?? null;
24
+ }
25
+
26
+ describe("ElapsedProgress (LC-185)", () => {
27
+ it("formats the length as m:ss, then h:mm:ss", () => {
28
+ expect(formatElapsed(4_000)).toBe("0:04");
29
+ expect(formatElapsed(65_000)).toBe("1:05");
30
+ expect(formatElapsed(2 * 3_600_000 + 4 * 60_000 + 9_000)).toBe("2:04:09");
31
+ });
32
+
33
+ it("a short wait is a bare spinner; past the threshold the time joins and counts", () => {
34
+ const { container } = renderWithProviders(
35
+ <ElapsedProgress startedAt={Date.now()} label="Sync" />,
36
+ );
37
+ expect(container.querySelector("[role='status']")).toBeTruthy();
38
+ expect(elapsedOf(container)).toBeNull();
39
+
40
+ act(() => {
41
+ vi.advanceTimersByTime(4_000);
42
+ });
43
+ expect(elapsedOf(container)).toBe("0:04");
44
+ act(() => {
45
+ vi.advanceTimersByTime(61_000);
46
+ });
47
+ expect(elapsedOf(container)).toBe("1:05");
48
+ expect(container.querySelector("[aria-label='Sync, running for 1:05']")).toBeTruthy();
49
+ });
50
+
51
+ it("the Main story, a minute in, shows the length beside the spinner", () => {
52
+ const { container } = renderWithProviders(<>{Default.render?.({} as never, {} as never)}</>);
53
+ expect(elapsedOf(container)).toBe("1:05");
54
+ expect(container.querySelector("[role='status']")).toBeTruthy();
55
+ });
56
+
57
+ it("determinate work draws the bar and the length, no spinner", () => {
58
+ const { container } = renderWithProviders(
59
+ <ElapsedProgress startedAt={Date.now() - 95_000} progress={0.42} label="Upload" />,
60
+ );
61
+ expect(container.querySelector("[data-elapsed-state='determinate']")).toBeTruthy();
62
+ expect(container.querySelector("[role='progressbar']")).toBeTruthy();
63
+ expect(container.querySelector(".mp1-spinner")).toBeNull();
64
+ expect(elapsedOf(container)).toBe("1:35");
65
+ });
66
+ });
@@ -0,0 +1,43 @@
1
+ import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
2
+ import { useState } from "react";
3
+ import { YStack } from "tamagui";
4
+ import { ElapsedProgress } from "./index";
5
+
6
+ const meta: Meta<typeof ElapsedProgress> = {
7
+ title: "Components/ElapsedProgress",
8
+ component: ElapsedProgress,
9
+ parameters: {
10
+ status: { type: "beta" },
11
+ docs: {
12
+ description: {
13
+ component:
14
+ "Long work shows how long (LC-185). Determinate progress draws the bar beside the elapsed time; otherwise the spinner stands alone for the first few seconds and then the elapsed time joins it. Reduced motion stops the spinner, never the count.",
15
+ },
16
+ },
17
+ },
18
+ };
19
+ export default meta;
20
+
21
+ type Story = StoryObj<typeof ElapsedProgress>;
22
+
23
+ function Started({ agoMs, progress, label }: { agoMs: number; progress?: number; label?: string }) {
24
+ const [startedAt] = useState(() => Date.now() - agoMs);
25
+ return <ElapsedProgress startedAt={startedAt} progress={progress} label={label} />;
26
+ }
27
+
28
+ /** A sync that has run a minute and five seconds: spinner plus its length. */
29
+ export const Default: Story = {
30
+ name: "Main",
31
+ render: () => <Started agoMs={65_000} label="Sync" />,
32
+ };
33
+
34
+ export const States: Story = {
35
+ render: () => (
36
+ <YStack gap="$4" maxWidth={360}>
37
+ <Started agoMs={0} label="Short wait" />
38
+ <Started agoMs={65_000} label="Sync" />
39
+ <Started agoMs={2 * 3_600_000 + 4 * 60_000} label="Build" />
40
+ <Started agoMs={95_000} progress={0.42} label="Upload" />
41
+ </YStack>
42
+ ),
43
+ };