@multiplatform.one/components 7.77.2 → 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 (535) 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.cjs +2 -6
  38. package/dist/cjs/Lightbox/MediaControl.native.js +2 -8
  39. package/dist/cjs/Lightbox/MediaControl.native.js.map +1 -1
  40. package/dist/cjs/Lightbox/index.gnome.native.js.map +1 -1
  41. package/dist/cjs/Lightbox/index.native.js +1 -1
  42. package/dist/cjs/Lightbox/shared.native.js.map +1 -1
  43. package/dist/cjs/Lightbox/useLightbox.native.js.map +1 -1
  44. package/dist/cjs/MachineLiteral/index.cjs +98 -0
  45. package/dist/cjs/MachineLiteral/index.native.js +102 -0
  46. package/dist/cjs/MachineLiteral/index.native.js.map +1 -0
  47. package/dist/cjs/Material/blur.cjs +34 -0
  48. package/dist/cjs/Material/blur.native.js +100 -0
  49. package/dist/cjs/Material/blur.native.js.map +1 -0
  50. package/dist/cjs/Material/index.cjs +9 -3
  51. package/dist/cjs/Material/index.native.js +9 -3
  52. package/dist/cjs/Material/index.native.js.map +1 -1
  53. package/dist/cjs/Meter/index.cjs +3 -1
  54. package/dist/cjs/Meter/index.native.js +4 -2
  55. package/dist/cjs/Meter/index.native.js.map +1 -1
  56. package/dist/cjs/Meter/meter.native.js.map +1 -1
  57. package/dist/cjs/OverflowRow/index.native.js +1 -1
  58. package/dist/cjs/OverflowRow/index.native.js.map +1 -1
  59. package/dist/cjs/Pagination.native.js +1 -1
  60. package/dist/cjs/Pagination.native.js.map +1 -1
  61. package/dist/cjs/Popover.native.js +1 -1
  62. package/dist/cjs/Popover.native.js.map +1 -1
  63. package/dist/cjs/ProgressSteps/index.native.js.map +1 -1
  64. package/dist/cjs/Quote/index.native.js.map +1 -1
  65. package/dist/cjs/SchemeToggle/index.native.js +1 -1
  66. package/dist/cjs/SchemeToggle/index.native.js.map +1 -1
  67. package/dist/cjs/ScrollView/revealFocusedField.native.js.map +1 -1
  68. package/dist/cjs/Separator/index.native.js.map +1 -1
  69. package/dist/cjs/Sheet.native.js.map +1 -1
  70. package/dist/cjs/SheetModal/SheetHeader.native.js.map +1 -1
  71. package/dist/cjs/SheetModal/SheetNavigation.native.js.map +1 -1
  72. package/dist/cjs/SheetModal/detents.native.js.map +1 -1
  73. package/dist/cjs/SheetModal/useSheetFrameFocus.native.js.map +1 -1
  74. package/dist/cjs/Skeleton/index.native.js.map +1 -1
  75. package/dist/cjs/SkipLink/index.native.js.map +1 -1
  76. package/dist/cjs/SortableList/SortableHandle.native.js.map +1 -1
  77. package/dist/cjs/SortableList/index.cjs +4 -1
  78. package/dist/cjs/SortableList/index.native.js +4 -1
  79. package/dist/cjs/SortableList/index.native.js.map +1 -1
  80. package/dist/cjs/SortableList/useSortableRows.native.js.map +1 -1
  81. package/dist/cjs/SortableList/useUserOrder.cjs +84 -0
  82. package/dist/cjs/SortableList/useUserOrder.native.js +107 -0
  83. package/dist/cjs/SortableList/useUserOrder.native.js.map +1 -0
  84. package/dist/cjs/Tabs/index.native.js +1 -1
  85. package/dist/cjs/Tabs/index.native.js.map +1 -1
  86. package/dist/cjs/Text.native.js.map +1 -1
  87. package/dist/cjs/ThemePresetPicker/index.native.js +2 -2
  88. package/dist/cjs/ThemePresetPicker/index.native.js.map +1 -1
  89. package/dist/cjs/Toast/index.native.js.map +1 -1
  90. package/dist/cjs/Toast/store.native.js.map +1 -1
  91. package/dist/cjs/Tooltip/nativePress.native.js.map +1 -1
  92. package/dist/cjs/Tooltip/tooltipShared.native.js.map +1 -1
  93. package/dist/cjs/TreeSelect/index.cjs +7 -1
  94. package/dist/cjs/TreeSelect/index.native.js +8 -2
  95. package/dist/cjs/TreeSelect/index.native.js.map +1 -1
  96. package/dist/cjs/TreeSelect/treeSelectModel.native.js.map +1 -1
  97. package/dist/cjs/Video/PlayerChrome.native.js.map +1 -1
  98. package/dist/cjs/Video/VideoFrame.native.js.map +1 -1
  99. package/dist/cjs/Video/types.native.js.map +1 -1
  100. package/dist/cjs/Wheel/index.native.js.map +1 -1
  101. package/dist/cjs/Wizard/index.native.js +2 -2
  102. package/dist/cjs/Wizard/index.native.js.map +1 -1
  103. package/dist/cjs/actions/ActionBar.native.js.map +1 -1
  104. package/dist/cjs/actions/DangerSection.native.js.map +1 -1
  105. package/dist/cjs/actions/DestructiveAction.native.js.map +1 -1
  106. package/dist/cjs/actions/HeaderActions.native.js +2 -2
  107. package/dist/cjs/actions/HeaderActions.native.js.map +1 -1
  108. package/dist/cjs/actions/StandardAction.native.js +1 -1
  109. package/dist/cjs/actions/StandardAction.native.js.map +1 -1
  110. package/dist/cjs/actions/devWarn.native.js.map +1 -1
  111. package/dist/cjs/actions/index.native.js.map +1 -1
  112. package/dist/cjs/actions/severity.native.js.map +1 -1
  113. package/dist/cjs/appShell/Dock.native.js.map +1 -1
  114. package/dist/cjs/appShell/MpoTabHost.native.js.map +1 -1
  115. package/dist/cjs/appShell/ScopeMenu.native.js.map +1 -1
  116. package/dist/cjs/appShell/SettingsSplit.native.js +1 -1
  117. package/dist/cjs/appShell/SettingsSplit.native.js.map +1 -1
  118. package/dist/cjs/appShell/Springboard.native.js +1 -1
  119. package/dist/cjs/appShell/Springboard.native.js.map +1 -1
  120. package/dist/cjs/appShell/SystemBar.native.js.map +1 -1
  121. package/dist/cjs/appShell/TabBar.cjs +10 -5
  122. package/dist/cjs/appShell/TabBar.native.js +11 -6
  123. package/dist/cjs/appShell/TabBar.native.js.map +1 -1
  124. package/dist/cjs/appShell/TabHost.native.js +1 -0
  125. package/dist/cjs/appShell/TabHost.native.js.map +1 -1
  126. package/dist/cjs/appShell/appTile.native.js +1 -1
  127. package/dist/cjs/appShell/appTile.native.js.map +1 -1
  128. package/dist/cjs/appShell/bottomChrome.native.js.map +1 -1
  129. package/dist/cjs/appShell/index.native.js.map +1 -1
  130. package/dist/cjs/charts/Axis.native.js.map +1 -1
  131. package/dist/cjs/charts/BarChart.native.js.map +1 -1
  132. package/dist/cjs/charts/ChartDataView.native.js +1 -1
  133. package/dist/cjs/charts/ChartDataView.native.js.map +1 -1
  134. package/dist/cjs/charts/ChartSurface.native.js.map +1 -1
  135. package/dist/cjs/charts/LineChart.native.js.map +1 -1
  136. package/dist/cjs/charts/PieChart.native.js.map +1 -1
  137. package/dist/cjs/charts/Sparkline.cjs +1 -1
  138. package/dist/cjs/charts/Sparkline.native.js +1 -1
  139. package/dist/cjs/charts/Sparkline.native.js.map +1 -1
  140. package/dist/cjs/charts/accessibility.native.js.map +1 -1
  141. package/dist/cjs/charts/chartHeight.native.js.map +1 -1
  142. package/dist/cjs/charts/composeChart.native.js.map +1 -1
  143. package/dist/cjs/charts/index.native.js.map +1 -1
  144. package/dist/cjs/charts/math.native.js.map +1 -1
  145. package/dist/cjs/charts/series.native.js.map +1 -1
  146. package/dist/cjs/charts/svg.native.js.map +1 -1
  147. package/dist/cjs/charts/types.native.js.map +1 -1
  148. package/dist/cjs/charts/useChartTheme.native.js.map +1 -1
  149. package/dist/cjs/code/Code/index.native.js.map +1 -1
  150. package/dist/cjs/code/CodeBlock/index.native.js +7 -7
  151. package/dist/cjs/code/CodeBlock/index.native.js.map +1 -1
  152. package/dist/cjs/code/HighlightedCode/index.native.js.map +1 -1
  153. package/dist/cjs/code/Highlighter/houseSyntaxTheme.native.js.map +1 -1
  154. package/dist/cjs/code/Highlighter/index.native.js.map +1 -1
  155. package/dist/cjs/code/Highlighter/namedGroupMatchAll.native.js.map +1 -1
  156. package/dist/cjs/code/Pre/index.native.js.map +1 -1
  157. package/dist/cjs/code/index.native.js +5 -5
  158. package/dist/cjs/code/index.native.js.map +1 -1
  159. package/dist/cjs/componentColors.cjs +1 -1
  160. package/dist/cjs/componentColors.native.js +1 -1
  161. package/dist/cjs/componentColors.native.js.map +1 -1
  162. package/dist/cjs/feedback/ConfirmDialog.native.js.map +1 -1
  163. package/dist/cjs/feedback/NotifyHost.native.js +2 -2
  164. package/dist/cjs/feedback/NotifyHost.native.js.map +1 -1
  165. package/dist/cjs/feedback/copy.native.js.map +1 -1
  166. package/dist/cjs/feedback/index.native.js.map +1 -1
  167. package/dist/cjs/feedback/notify.native.js.map +1 -1
  168. package/dist/cjs/feedback/route.native.js.map +1 -1
  169. package/dist/cjs/feedback/store.native.js.map +1 -1
  170. package/dist/cjs/formLayouts/FormLayouts.native.js +1 -1
  171. package/dist/cjs/formLayouts/FormLayouts.native.js.map +1 -1
  172. package/dist/cjs/formLayouts/PreferencePanel.native.js +2 -2
  173. package/dist/cjs/formLayouts/PreferencePanel.native.js.map +1 -1
  174. package/dist/cjs/formLayouts/index.native.js.map +1 -1
  175. package/dist/cjs/hooks/index.native.js +1 -1
  176. package/dist/cjs/hooks/index.native.js.map +1 -1
  177. package/dist/cjs/hooks/useClipboard.native.js.map +1 -1
  178. package/dist/cjs/hooks/useDocumentTitle.native.js.map +1 -1
  179. package/dist/cjs/hooks/useHoldCue.native.js.map +1 -1
  180. package/dist/cjs/icons/CheckRegular.native.js.map +1 -1
  181. package/dist/cjs/icons/MinusRegular.native.js.map +1 -1
  182. package/dist/cjs/icons/index.native.js.map +1 -1
  183. package/dist/cjs/icons/lucide.native.js.map +1 -1
  184. package/dist/cjs/icons/themed.native.js.map +1 -1
  185. package/dist/cjs/images/Image/ImageFrame.native.js +1 -1
  186. package/dist/cjs/images/Image/ImageFrame.native.js.map +1 -1
  187. package/dist/cjs/images/Image/framing.native.js.map +1 -1
  188. package/dist/cjs/images/Image/index.native.js +1 -1
  189. package/dist/cjs/images/Image/mediaRadius.native.js.map +1 -1
  190. package/dist/cjs/images/Image/shared.native.js +1 -1
  191. package/dist/cjs/images/Image/shared.native.js.map +1 -1
  192. package/dist/cjs/images/Image/types.native.js.map +1 -1
  193. package/dist/cjs/images/index.native.js.map +1 -1
  194. package/dist/cjs/index.cjs +6 -1
  195. package/dist/cjs/index.native.js +42 -37
  196. package/dist/cjs/index.native.js.map +1 -1
  197. package/dist/cjs/knobImmuneExports.native.js.map +1 -1
  198. package/dist/cjs/layouts/AsyncBoundary.native.js +2 -2
  199. package/dist/cjs/layouts/AsyncBoundary.native.js.map +1 -1
  200. package/dist/cjs/layouts/Debug/index.native.js.map +1 -1
  201. package/dist/cjs/layouts/EmptyState.native.js.map +1 -1
  202. package/dist/cjs/layouts/IdentityPlate.native.js.map +1 -1
  203. package/dist/cjs/layouts/KeyboardAvoidingWrapper/behavior.native.js.map +1 -1
  204. package/dist/cjs/layouts/PageTemplates.native.js.map +1 -1
  205. package/dist/cjs/layouts/PaneScaffold.native.js.map +1 -1
  206. package/dist/cjs/layouts/SafeAreaWrapper/insets.native.js.map +1 -1
  207. package/dist/cjs/layouts/StatusDot.native.js.map +1 -1
  208. package/dist/cjs/layouts/StatusGlyphStrip.native.js +1 -1
  209. package/dist/cjs/layouts/StatusGlyphStrip.native.js.map +1 -1
  210. package/dist/cjs/layouts/ViewSwitcher.native.js.map +1 -1
  211. package/dist/cjs/layouts/attachments.native.js +1 -1
  212. package/dist/cjs/layouts/attachments.native.js.map +1 -1
  213. package/dist/cjs/layouts/bottomAccessory.native.js.map +1 -1
  214. package/dist/cjs/layouts/breadcrumbs.native.js.map +1 -1
  215. package/dist/cjs/layouts/index.native.js +3 -3
  216. package/dist/cjs/layouts/index.native.js.map +1 -1
  217. package/dist/cjs/layouts/page.cjs +0 -4
  218. package/dist/cjs/layouts/page.native.js +2 -6
  219. package/dist/cjs/layouts/page.native.js.map +1 -1
  220. package/dist/cjs/layouts/pageHeadingScope.native.js.map +1 -1
  221. package/dist/cjs/layouts/screenScroll.native.js.map +1 -1
  222. package/dist/cjs/layouts/shellSidebarSlot.native.js.map +1 -1
  223. package/dist/cjs/layouts/sidebar.native.js +1 -1
  224. package/dist/cjs/layouts/sidebar.native.js.map +1 -1
  225. package/dist/cjs/layouts/tags.native.js +2 -2
  226. package/dist/cjs/layouts/tags.native.js.map +1 -1
  227. package/dist/cjs/layouts/timeline.native.js +2 -2
  228. package/dist/cjs/layouts/timeline.native.js.map +1 -1
  229. package/dist/cjs/layouts/toolbar.native.js +1 -1
  230. package/dist/cjs/layouts/toolbar.native.js.map +1 -1
  231. package/dist/cjs/shared/actionScan.native.js.map +1 -1
  232. package/dist/cjs/shared/i18n.native.js.map +1 -1
  233. package/dist/cjs/shared/restoreRetries.native.js.map +1 -1
  234. package/dist/cjs/shared/t.native.js.map +1 -1
  235. package/dist/cjs/shared/textRidesText.native.js.map +1 -1
  236. package/dist/cjs/shared/useReturnFocusOnClose.native.js.map +1 -1
  237. package/dist/cjs/surfaces.native.js +1 -1
  238. package/dist/cjs/surfaces.native.js.map +1 -1
  239. package/dist/cjs/tamagui.native.js +1 -1
  240. package/dist/cjs/tamagui.native.js.map +1 -1
  241. package/dist/cjs/testSetup.native.js.map +1 -1
  242. package/dist/cjs/utils/setTinted.native.js.map +1 -1
  243. package/dist/cjs/utils/unwrapText.native.js.map +1 -1
  244. package/dist/cjs/views/Calendar.native.js +1 -1
  245. package/dist/cjs/views/Calendar.native.js.map +1 -1
  246. package/dist/cjs/views/Dashboard.native.js +2 -2
  247. package/dist/cjs/views/Dashboard.native.js.map +1 -1
  248. package/dist/cjs/views/Gantt.native.js +2 -2
  249. package/dist/cjs/views/Gantt.native.js.map +1 -1
  250. package/dist/cjs/views/GanttDateGrip.native.js.map +1 -1
  251. package/dist/cjs/views/ImageGrid.cjs +9 -12
  252. package/dist/cjs/views/ImageGrid.native.js +11 -18
  253. package/dist/cjs/views/ImageGrid.native.js.map +1 -1
  254. package/dist/cjs/views/Kanban.native.js +1 -1
  255. package/dist/cjs/views/List.native.js.map +1 -1
  256. package/dist/cjs/views/ListGroup.native.js.map +1 -1
  257. package/dist/cjs/views/ListRow.native.js.map +1 -1
  258. package/dist/cjs/views/Matrix.native.js +2 -2
  259. package/dist/cjs/views/Matrix.native.js.map +1 -1
  260. package/dist/cjs/views/ReportBuilder.cjs +3 -3
  261. package/dist/cjs/views/ReportBuilder.native.js +5 -5
  262. package/dist/cjs/views/ReportBuilder.native.js.map +1 -1
  263. package/dist/cjs/views/ShortcutCard.native.js.map +1 -1
  264. package/dist/cjs/views/TreeView.native.js.map +1 -1
  265. package/dist/cjs/views/calendarMath.native.js.map +1 -1
  266. package/dist/cjs/views/ganttIntervals.native.js.map +1 -1
  267. package/dist/cjs/views/ganttMath.native.js.map +1 -1
  268. package/dist/cjs/views/index.cjs +3 -1
  269. package/dist/cjs/views/index.native.js +3 -1
  270. package/dist/cjs/views/index.native.js.map +1 -1
  271. package/dist/cjs/views/kanbanDnd.native.js.map +1 -1
  272. package/dist/cjs/views/matrixMath.native.js.map +1 -1
  273. package/dist/cjs/views/sameNameScope.cjs +39 -0
  274. package/dist/cjs/views/sameNameScope.native.js +63 -0
  275. package/dist/cjs/views/sameNameScope.native.js.map +1 -0
  276. package/dist/cjs/views/treeViewDnd.native.js.map +1 -1
  277. package/dist/cjs/views/treeViewLayout.native.js.map +1 -1
  278. package/dist/cjs/views/treeViewMotion.native.js.map +1 -1
  279. package/dist/cjs/views/treeViewReveal.native.js.map +1 -1
  280. package/dist/cjs/views/usePageFlowLoadMore.cjs +83 -0
  281. package/dist/cjs/views/usePageFlowLoadMore.native.js +93 -0
  282. package/dist/cjs/views/usePageFlowLoadMore.native.js.map +1 -0
  283. package/dist/cjs/views/widgetChrome.native.js.map +1 -1
  284. package/dist/esm/Diff/diff.mjs +58 -0
  285. package/dist/esm/Diff/diff.mjs.map +1 -0
  286. package/dist/esm/Diff/diff.native.js +79 -0
  287. package/dist/esm/Diff/diff.native.js.map +1 -0
  288. package/dist/esm/Diff/index.mjs +147 -0
  289. package/dist/esm/Diff/index.mjs.map +1 -0
  290. package/dist/esm/Diff/index.native.js +151 -0
  291. package/dist/esm/Diff/index.native.js.map +1 -0
  292. package/dist/esm/ElapsedProgress/index.mjs +76 -0
  293. package/dist/esm/ElapsedProgress/index.mjs.map +1 -0
  294. package/dist/esm/ElapsedProgress/index.native.js +83 -0
  295. package/dist/esm/ElapsedProgress/index.native.js.map +1 -0
  296. package/dist/esm/Lightbox/MediaControl.mjs +3 -7
  297. package/dist/esm/Lightbox/MediaControl.mjs.map +1 -1
  298. package/dist/esm/Lightbox/MediaControl.native.js +3 -9
  299. package/dist/esm/Lightbox/MediaControl.native.js.map +1 -1
  300. package/dist/esm/MachineLiteral/index.mjs +73 -0
  301. package/dist/esm/MachineLiteral/index.mjs.map +1 -0
  302. package/dist/esm/MachineLiteral/index.native.js +74 -0
  303. package/dist/esm/MachineLiteral/index.native.js.map +1 -0
  304. package/dist/esm/Material/blur.mjs +8 -0
  305. package/dist/esm/Material/blur.mjs.map +1 -0
  306. package/dist/esm/Material/blur.native.js +67 -0
  307. package/dist/esm/Material/blur.native.js.map +1 -0
  308. package/dist/esm/Material/index.mjs +10 -4
  309. package/dist/esm/Material/index.mjs.map +1 -1
  310. package/dist/esm/Material/index.native.js +10 -4
  311. package/dist/esm/Material/index.native.js.map +1 -1
  312. package/dist/esm/Meter/index.mjs +4 -3
  313. package/dist/esm/Meter/index.mjs.map +1 -1
  314. package/dist/esm/Meter/index.native.js +4 -3
  315. package/dist/esm/Meter/index.native.js.map +1 -1
  316. package/dist/esm/SortableList/index.mjs +2 -1
  317. package/dist/esm/SortableList/index.mjs.map +1 -1
  318. package/dist/esm/SortableList/index.native.js +2 -1
  319. package/dist/esm/SortableList/index.native.js.map +1 -1
  320. package/dist/esm/SortableList/useUserOrder.mjs +58 -0
  321. package/dist/esm/SortableList/useUserOrder.mjs.map +1 -0
  322. package/dist/esm/SortableList/useUserOrder.native.js +78 -0
  323. package/dist/esm/SortableList/useUserOrder.native.js.map +1 -0
  324. package/dist/esm/TreeSelect/index.mjs +8 -2
  325. package/dist/esm/TreeSelect/index.mjs.map +1 -1
  326. package/dist/esm/TreeSelect/index.native.js +8 -2
  327. package/dist/esm/TreeSelect/index.native.js.map +1 -1
  328. package/dist/esm/appShell/TabBar.mjs +10 -5
  329. package/dist/esm/appShell/TabBar.mjs.map +1 -1
  330. package/dist/esm/appShell/TabBar.native.js +10 -5
  331. package/dist/esm/appShell/TabBar.native.js.map +1 -1
  332. package/dist/esm/appShell/TabHost.native.js +1 -0
  333. package/dist/esm/appShell/TabHost.native.js.map +1 -1
  334. package/dist/esm/charts/Sparkline.mjs +1 -1
  335. package/dist/esm/charts/Sparkline.mjs.map +1 -1
  336. package/dist/esm/charts/Sparkline.native.js +1 -1
  337. package/dist/esm/charts/Sparkline.native.js.map +1 -1
  338. package/dist/esm/componentColors.mjs +1 -1
  339. package/dist/esm/componentColors.native.js +1 -1
  340. package/dist/esm/index.mjs +5 -2
  341. package/dist/esm/index.mjs.map +1 -1
  342. package/dist/esm/index.native.js +5 -2
  343. package/dist/esm/index.native.js.map +1 -1
  344. package/dist/esm/layouts/page.mjs +0 -4
  345. package/dist/esm/layouts/page.mjs.map +1 -1
  346. package/dist/esm/layouts/page.native.js +0 -4
  347. package/dist/esm/layouts/page.native.js.map +1 -1
  348. package/dist/esm/views/ImageGrid.mjs +10 -13
  349. package/dist/esm/views/ImageGrid.mjs.map +1 -1
  350. package/dist/esm/views/ImageGrid.native.js +10 -17
  351. package/dist/esm/views/ImageGrid.native.js.map +1 -1
  352. package/dist/esm/views/ReportBuilder.mjs +4 -4
  353. package/dist/esm/views/ReportBuilder.mjs.map +1 -1
  354. package/dist/esm/views/ReportBuilder.native.js +4 -4
  355. package/dist/esm/views/ReportBuilder.native.js.map +1 -1
  356. package/dist/esm/views/index.mjs +2 -1
  357. package/dist/esm/views/index.mjs.map +1 -1
  358. package/dist/esm/views/index.native.js +2 -1
  359. package/dist/esm/views/index.native.js.map +1 -1
  360. package/dist/esm/views/sameNameScope.mjs +14 -0
  361. package/dist/esm/views/sameNameScope.mjs.map +1 -0
  362. package/dist/esm/views/sameNameScope.native.js +35 -0
  363. package/dist/esm/views/sameNameScope.native.js.map +1 -0
  364. package/dist/esm/views/usePageFlowLoadMore.mjs +57 -0
  365. package/dist/esm/views/usePageFlowLoadMore.mjs.map +1 -0
  366. package/dist/esm/views/usePageFlowLoadMore.native.js +64 -0
  367. package/dist/esm/views/usePageFlowLoadMore.native.js.map +1 -0
  368. package/dist/jsx/Diff/diff.mjs +58 -0
  369. package/dist/jsx/Diff/diff.mjs.map +1 -0
  370. package/dist/jsx/Diff/diff.native.js +108 -0
  371. package/dist/jsx/Diff/diff.native.js.map +1 -0
  372. package/dist/jsx/Diff/index.mjs +147 -0
  373. package/dist/jsx/Diff/index.mjs.map +1 -0
  374. package/dist/jsx/Diff/index.native.js +181 -0
  375. package/dist/jsx/Diff/index.native.js.map +1 -0
  376. package/dist/jsx/ElapsedProgress/index.mjs +76 -0
  377. package/dist/jsx/ElapsedProgress/index.mjs.map +1 -0
  378. package/dist/jsx/ElapsedProgress/index.native.js +112 -0
  379. package/dist/jsx/ElapsedProgress/index.native.js.map +1 -0
  380. package/dist/jsx/Lightbox/MediaControl.mjs +3 -7
  381. package/dist/jsx/Lightbox/MediaControl.mjs.map +1 -1
  382. package/dist/jsx/Lightbox/MediaControl.native.js +2 -8
  383. package/dist/jsx/Lightbox/MediaControl.native.js.map +1 -1
  384. package/dist/jsx/MachineLiteral/index.mjs +73 -0
  385. package/dist/jsx/MachineLiteral/index.mjs.map +1 -0
  386. package/dist/jsx/MachineLiteral/index.native.js +102 -0
  387. package/dist/jsx/MachineLiteral/index.native.js.map +1 -0
  388. package/dist/jsx/Material/blur.mjs +8 -0
  389. package/dist/jsx/Material/blur.mjs.map +1 -0
  390. package/dist/jsx/Material/blur.native.js +100 -0
  391. package/dist/jsx/Material/blur.native.js.map +1 -0
  392. package/dist/jsx/Material/index.mjs +10 -4
  393. package/dist/jsx/Material/index.mjs.map +1 -1
  394. package/dist/jsx/Material/index.native.js +9 -3
  395. package/dist/jsx/Material/index.native.js.map +1 -1
  396. package/dist/jsx/Meter/index.mjs +4 -3
  397. package/dist/jsx/Meter/index.mjs.map +1 -1
  398. package/dist/jsx/Meter/index.native.js +3 -1
  399. package/dist/jsx/Meter/index.native.js.map +1 -1
  400. package/dist/jsx/SortableList/index.mjs +2 -1
  401. package/dist/jsx/SortableList/index.mjs.map +1 -1
  402. package/dist/jsx/SortableList/index.native.js +4 -1
  403. package/dist/jsx/SortableList/index.native.js.map +1 -1
  404. package/dist/jsx/SortableList/useUserOrder.mjs +58 -0
  405. package/dist/jsx/SortableList/useUserOrder.mjs.map +1 -0
  406. package/dist/jsx/SortableList/useUserOrder.native.js +107 -0
  407. package/dist/jsx/SortableList/useUserOrder.native.js.map +1 -0
  408. package/dist/jsx/TreeSelect/index.mjs +8 -2
  409. package/dist/jsx/TreeSelect/index.mjs.map +1 -1
  410. package/dist/jsx/TreeSelect/index.native.js +7 -1
  411. package/dist/jsx/TreeSelect/index.native.js.map +1 -1
  412. package/dist/jsx/appShell/TabBar.mjs +10 -5
  413. package/dist/jsx/appShell/TabBar.mjs.map +1 -1
  414. package/dist/jsx/appShell/TabBar.native.js +10 -5
  415. package/dist/jsx/appShell/TabBar.native.js.map +1 -1
  416. package/dist/jsx/appShell/TabHost.native.js +1 -0
  417. package/dist/jsx/appShell/TabHost.native.js.map +1 -1
  418. package/dist/jsx/charts/Sparkline.mjs +1 -1
  419. package/dist/jsx/charts/Sparkline.mjs.map +1 -1
  420. package/dist/jsx/charts/Sparkline.native.js +1 -1
  421. package/dist/jsx/charts/Sparkline.native.js.map +1 -1
  422. package/dist/jsx/componentColors.mjs +1 -1
  423. package/dist/jsx/componentColors.native.js +1 -1
  424. package/dist/jsx/feedback/NotifyHost.native.js +1 -1
  425. package/dist/jsx/formLayouts/PreferencePanel.native.js +1 -1
  426. package/dist/jsx/index.js +5 -2
  427. package/dist/jsx/index.js.map +1 -1
  428. package/dist/jsx/index.mjs +5 -2
  429. package/dist/jsx/index.mjs.map +1 -1
  430. package/dist/jsx/index.native.js +7 -2
  431. package/dist/jsx/index.native.js.map +1 -1
  432. package/dist/jsx/layouts/AsyncBoundary.native.js +1 -1
  433. package/dist/jsx/layouts/AsyncBoundary.native.js.map +1 -1
  434. package/dist/jsx/layouts/page.mjs +0 -4
  435. package/dist/jsx/layouts/page.mjs.map +1 -1
  436. package/dist/jsx/layouts/page.native.js +0 -4
  437. package/dist/jsx/layouts/page.native.js.map +1 -1
  438. package/dist/jsx/views/ImageGrid.mjs +10 -13
  439. package/dist/jsx/views/ImageGrid.mjs.map +1 -1
  440. package/dist/jsx/views/ImageGrid.native.js +9 -16
  441. package/dist/jsx/views/ImageGrid.native.js.map +1 -1
  442. package/dist/jsx/views/ReportBuilder.mjs +4 -4
  443. package/dist/jsx/views/ReportBuilder.mjs.map +1 -1
  444. package/dist/jsx/views/ReportBuilder.native.js +3 -3
  445. package/dist/jsx/views/ReportBuilder.native.js.map +1 -1
  446. package/dist/jsx/views/index.mjs +2 -1
  447. package/dist/jsx/views/index.mjs.map +1 -1
  448. package/dist/jsx/views/index.native.js +2 -0
  449. package/dist/jsx/views/index.native.js.map +1 -1
  450. package/dist/jsx/views/sameNameScope.mjs +14 -0
  451. package/dist/jsx/views/sameNameScope.mjs.map +1 -0
  452. package/dist/jsx/views/sameNameScope.native.js +63 -0
  453. package/dist/jsx/views/sameNameScope.native.js.map +1 -0
  454. package/dist/jsx/views/usePageFlowLoadMore.mjs +57 -0
  455. package/dist/jsx/views/usePageFlowLoadMore.mjs.map +1 -0
  456. package/dist/jsx/views/usePageFlowLoadMore.native.js +93 -0
  457. package/dist/jsx/views/usePageFlowLoadMore.native.js.map +1 -0
  458. package/package.json +18 -9
  459. package/src/Diff/Diff.spec.tsx +105 -0
  460. package/src/Diff/Diff.stories.tsx +44 -0
  461. package/src/Diff/diff.ts +61 -0
  462. package/src/Diff/index.tsx +145 -0
  463. package/src/ElapsedProgress/ElapsedProgress.spec.tsx +66 -0
  464. package/src/ElapsedProgress/ElapsedProgress.stories.tsx +43 -0
  465. package/src/ElapsedProgress/index.tsx +89 -0
  466. package/src/Lightbox/Lightbox.spec.tsx +1 -1
  467. package/src/Lightbox/MediaControl.tsx +6 -14
  468. package/src/MachineLiteral/MachineLiteral.spec.tsx +86 -0
  469. package/src/MachineLiteral/MachineLiteral.stories.tsx +44 -0
  470. package/src/MachineLiteral/index.tsx +75 -0
  471. package/src/Material/blur.native.spec.tsx +135 -0
  472. package/src/Material/blur.native.tsx +93 -0
  473. package/src/Material/blur.ts +11 -0
  474. package/src/Material/index.tsx +18 -6
  475. package/src/Meter/index.tsx +4 -2
  476. package/src/SortableList/index.tsx +2 -0
  477. package/src/SortableList/useUserOrder.spec.tsx +110 -0
  478. package/src/SortableList/useUserOrder.ts +96 -0
  479. package/src/TreeSelect/TreeSelect.rows.spec.tsx +44 -0
  480. package/src/TreeSelect/index.tsx +12 -1
  481. package/src/appShell/TabBar.tsx +3 -0
  482. package/src/appShell/TabHost.native.spec.tsx +21 -1
  483. package/src/appShell/TabHost.native.tsx +8 -0
  484. package/src/charts/Sparkline.tsx +3 -3
  485. package/src/componentColors.ts +1 -1
  486. package/src/index.ts +7 -0
  487. package/src/layouts/page.tsx +1 -8
  488. package/src/layouts/pageChrome.phone.spec.tsx +14 -0
  489. package/src/presentationEmpty.spec.tsx +71 -0
  490. package/src/views/ImageGrid.native-press.spec.tsx +172 -0
  491. package/src/views/ImageGrid.tsx +11 -17
  492. package/src/views/ReportBuilder.tsx +4 -3
  493. package/src/views/index.ts +1 -0
  494. package/src/views/sameNameScope.spec.tsx +55 -0
  495. package/src/views/sameNameScope.ts +22 -0
  496. package/src/views/usePageFlowLoadMore.ts +79 -0
  497. package/types/Diff/diff.d.ts +17 -0
  498. package/types/Diff/diff.d.ts.map +1 -0
  499. package/types/Diff/index.d.ts +15 -0
  500. package/types/Diff/index.d.ts.map +1 -0
  501. package/types/ElapsedProgress/index.d.ts +15 -0
  502. package/types/ElapsedProgress/index.d.ts.map +1 -0
  503. package/types/Lightbox/MediaControl.d.ts +2 -4
  504. package/types/Lightbox/MediaControl.d.ts.map +1 -1
  505. package/types/MachineLiteral/index.d.ts +13 -0
  506. package/types/MachineLiteral/index.d.ts.map +1 -0
  507. package/types/Material/blur.d.ts +9 -0
  508. package/types/Material/blur.d.ts.map +1 -0
  509. package/types/Material/blur.native.d.ts +38 -0
  510. package/types/Material/blur.native.d.ts.map +1 -0
  511. package/types/Material/index.d.ts.map +1 -1
  512. package/types/Meter/index.d.ts +2 -0
  513. package/types/Meter/index.d.ts.map +1 -1
  514. package/types/SortableList/index.d.ts +2 -0
  515. package/types/SortableList/index.d.ts.map +1 -1
  516. package/types/SortableList/useUserOrder.d.ts +28 -0
  517. package/types/SortableList/useUserOrder.d.ts.map +1 -0
  518. package/types/TreeSelect/index.d.ts.map +1 -1
  519. package/types/appShell/TabBar.d.ts.map +1 -1
  520. package/types/appShell/TabHost.native.d.ts +1 -0
  521. package/types/appShell/TabHost.native.d.ts.map +1 -1
  522. package/types/charts/Sparkline.d.ts +2 -2
  523. package/types/charts/Sparkline.d.ts.map +1 -1
  524. package/types/componentColors.d.ts +1 -1
  525. package/types/index.d.ts +5 -2
  526. package/types/index.d.ts.map +1 -1
  527. package/types/layouts/page.d.ts.map +1 -1
  528. package/types/views/ImageGrid.d.ts.map +1 -1
  529. package/types/views/ReportBuilder.d.ts.map +1 -1
  530. package/types/views/index.d.ts +1 -0
  531. package/types/views/index.d.ts.map +1 -1
  532. package/types/views/sameNameScope.d.ts +8 -0
  533. package/types/views/sameNameScope.d.ts.map +1 -0
  534. package/types/views/usePageFlowLoadMore.d.ts +26 -0
  535. package/types/views/usePageFlowLoadMore.d.ts.map +1 -0
@@ -23,6 +23,8 @@ import { Text } from "../Text";
23
23
  export { SortableHandle, SortableHandleWell } from "./SortableHandle";
24
24
  export { SortableSessionProvider, useSortableRows } from "./useSortableRows";
25
25
  export type { SortableSession, UseSortableRowsOptions } from "./useSortableRows";
26
+ export { applyUserOrder, useUserOrder } from "./useUserOrder";
27
+ export type { UseUserOrderOptions, UserOrderStorage } from "./useUserOrder";
26
28
 
27
29
  export type SortableDisabledStyle = "keepLabel" | "dimWhole";
28
30
 
@@ -0,0 +1,110 @@
1
+ /**
2
+ * LC-209 USER-ORDER: a hand-arranged collection keeps the user's order. A new
3
+ * item lands last with every other index unchanged, a data refresh that
4
+ * returns the source's own order changes nothing, and a reload reads the same
5
+ * arrangement back.
6
+ */
7
+ import { renderWithProviders } from "@multiplatform.one/test-utils";
8
+ import { act, cleanup, fireEvent } from "@testing-library/react";
9
+ import { useState } from "react";
10
+ import { afterEach, describe, expect, it } from "vitest";
11
+ import { SortableList } from "./index";
12
+ import { applyUserOrder, useUserOrder, type UserOrderStorage } from "./useUserOrder";
13
+
14
+ afterEach(cleanup);
15
+
16
+ interface Pin {
17
+ id: string;
18
+ label: string;
19
+ }
20
+
21
+ const source: Pin[] = [
22
+ { id: "mail", label: "Mail" },
23
+ { id: "files", label: "Files" },
24
+ { id: "chat", label: "Chat" },
25
+ ];
26
+ const idOf = (pin: Pin) => pin.id;
27
+
28
+ function memoryStorage(): UserOrderStorage & { data: Map<string, string> } {
29
+ const data = new Map<string, string>();
30
+ return {
31
+ data,
32
+ getItem: (key) => data.get(key) ?? null,
33
+ setItem: (key, value) => {
34
+ data.set(key, value);
35
+ },
36
+ };
37
+ }
38
+
39
+ let refresh: (pins: Pin[]) => void = () => {};
40
+
41
+ function Dock({ storage }: { storage: UserOrderStorage }) {
42
+ const [pins, setPins] = useState(source);
43
+ refresh = setPins;
44
+ const ordered = useUserOrder("dock", pins, idOf, { storage });
45
+ return (
46
+ <SortableList
47
+ items={ordered.items}
48
+ getId={idOf}
49
+ getLabel={(pin) => pin.label}
50
+ onChange={ordered.onChange}
51
+ />
52
+ );
53
+ }
54
+
55
+ function shown(container: HTMLElement) {
56
+ return [...container.querySelectorAll("[data-sortable-row]")].map((row) =>
57
+ row.getAttribute("data-sortable-row"),
58
+ );
59
+ }
60
+
61
+ function moveDown(container: HTMLElement, id: string) {
62
+ const row = container.querySelector(`[data-sortable-row="${id}"]`) as HTMLElement;
63
+ row.focus();
64
+ fireEvent.keyDown(row, { key: " " });
65
+ fireEvent.keyDown(row, { key: "ArrowDown" });
66
+ fireEvent.keyDown(row, { key: " " });
67
+ }
68
+
69
+ describe("applyUserOrder (LC-209)", () => {
70
+ it("keeps saved places and appends new ids at the end", () => {
71
+ const result = applyUserOrder(
72
+ [...source, { id: "maps", label: "Maps" }],
73
+ ["chat", "mail", "files"],
74
+ idOf,
75
+ );
76
+ expect(result.items.map(idOf)).toEqual(["chat", "mail", "files", "maps"]);
77
+ expect(result.order).toEqual(["chat", "mail", "files", "maps"]);
78
+ });
79
+
80
+ it("an id missing from a partial read keeps its slot", () => {
81
+ const result = applyUserOrder([source[0]!, source[2]!], ["files", "chat", "mail"], idOf);
82
+ expect(result.items.map(idOf)).toEqual(["chat", "mail"]);
83
+ expect(result.order).toEqual(["files", "chat", "mail"]);
84
+ });
85
+ });
86
+
87
+ describe("a reorderable dock keeps the user's order (LC-209)", () => {
88
+ it("a new item lands last and the others keep their index", () => {
89
+ const storage = memoryStorage();
90
+ const { container } = renderWithProviders(<Dock storage={storage} />);
91
+ moveDown(container, "mail");
92
+ expect(shown(container)).toEqual(["files", "mail", "chat"]);
93
+
94
+ act(() => refresh([...source, { id: "maps", label: "Maps" }]));
95
+ expect(shown(container)).toEqual(["files", "mail", "chat", "maps"]);
96
+ });
97
+
98
+ it("a refresh in the source's order and a reload both keep the arrangement", () => {
99
+ const storage = memoryStorage();
100
+ const first = renderWithProviders(<Dock storage={storage} />);
101
+ moveDown(first.container, "mail");
102
+ act(() => refresh([...source]));
103
+ expect(shown(first.container)).toEqual(["files", "mail", "chat"]);
104
+ first.unmount();
105
+
106
+ const reloaded = renderWithProviders(<Dock storage={storage} />);
107
+ expect(shown(reloaded.container)).toEqual(["files", "mail", "chat"]);
108
+ expect(JSON.parse(storage.data.get("dock") ?? "[]")).toEqual(["files", "mail", "chat"]);
109
+ });
110
+ });
@@ -0,0 +1,96 @@
1
+ import { useCallback, useEffect, useMemo, useState } from "react";
2
+
3
+ /** Where a user's arrangement lives; defaults to the browser's localStorage. */
4
+ export interface UserOrderStorage {
5
+ getItem: (key: string) => string | null;
6
+ setItem: (key: string, value: string) => void;
7
+ }
8
+
9
+ const memory = new Map<string, string>();
10
+ const memoryStorage: UserOrderStorage = {
11
+ getItem: (key) => memory.get(key) ?? null,
12
+ setItem: (key, value) => {
13
+ memory.set(key, value);
14
+ },
15
+ };
16
+
17
+ function defaultStorage(): UserOrderStorage {
18
+ try {
19
+ const local = (globalThis as { localStorage?: UserOrderStorage }).localStorage;
20
+ if (local && typeof local.getItem === "function") return local;
21
+ } catch {
22
+ // storage blocked
23
+ }
24
+ return memoryStorage;
25
+ }
26
+
27
+ function readOrder(storage: UserOrderStorage, key: string): string[] {
28
+ try {
29
+ const parsed = JSON.parse(storage.getItem(key) ?? "[]") as unknown;
30
+ return Array.isArray(parsed) ? parsed.filter((id): id is string => typeof id === "string") : [];
31
+ } catch {
32
+ return [];
33
+ }
34
+ }
35
+
36
+ /**
37
+ * The items in the user's order (LC-209): known ids keep their saved place,
38
+ * new ids land at the end in the order the source gave them. Ids missing
39
+ * from this read keep their slot in `order`, so a partial refresh never
40
+ * reshuffles them.
41
+ */
42
+ export function applyUserOrder<T>(
43
+ items: readonly T[],
44
+ order: readonly string[],
45
+ getId: (item: T) => string,
46
+ ): { items: T[]; order: string[] } {
47
+ const byId = new Map(items.map((item) => [getId(item), item] as const));
48
+ const known = new Set(order);
49
+ const placed = order.flatMap((id) => {
50
+ const item = byId.get(id);
51
+ return item === undefined ? [] : [item];
52
+ });
53
+ const added = items.filter((item) => !known.has(getId(item)));
54
+ return {
55
+ items: [...placed, ...added],
56
+ order: [...order, ...added.map(getId)],
57
+ };
58
+ }
59
+
60
+ export interface UseUserOrderOptions {
61
+ storage?: UserOrderStorage;
62
+ }
63
+
64
+ /**
65
+ * Keeps a hand-arranged collection in the user's order across data refreshes
66
+ * and reloads. Feed `items` from any source order; render the returned
67
+ * `items`; pass `onChange` to SortableList.
68
+ */
69
+ export function useUserOrder<T>(
70
+ key: string,
71
+ items: readonly T[],
72
+ getId: (item: T) => string,
73
+ options: UseUserOrderOptions = {},
74
+ ) {
75
+ const storage = useMemo(() => options.storage ?? defaultStorage(), [options.storage]);
76
+ const [order, setOrder] = useState(() => readOrder(storage, key));
77
+ const arranged = useMemo(() => applyUserOrder(items, order, getId), [items, order, getId]);
78
+
79
+ useEffect(() => {
80
+ if (arranged.order.length === order.length) return;
81
+ storage.setItem(key, JSON.stringify(arranged.order));
82
+ setOrder(arranged.order);
83
+ }, [arranged.order, order.length, storage, key]);
84
+
85
+ const onChange = useCallback(
86
+ (next: T[]) => {
87
+ const shown = new Set(next.map(getId));
88
+ const ids = [...next.map(getId), ...order.filter((id) => !shown.has(id))];
89
+ storage.setItem(key, JSON.stringify(ids));
90
+ setOrder(ids);
91
+ },
92
+ [getId, order, storage, key],
93
+ );
94
+
95
+ return { items: arranged.items, onChange };
96
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * LC-222 LIST-HEIGHT-IN-ROWS: the desktop tree panel caps its scroller at a
3
+ * visible-row count times its row pitch, not a pixel literal.
4
+ */
5
+ import { listHeightForRows } from "@multiplatform.one/theme";
6
+ import { renderWithProviders } from "@multiplatform.one/test-utils";
7
+ import { cleanup, waitFor } from "@testing-library/react";
8
+ import { afterEach, describe, expect, it } from "vitest";
9
+ import type { TreeNode } from "../views/TreeView";
10
+ import { TreeSelect } from "./index";
11
+
12
+ afterEach(cleanup);
13
+
14
+ const nodes: TreeNode[] = Array.from({ length: 12 }, (_, index) => ({
15
+ id: `n${index}`,
16
+ label: `Account ${index + 1}`,
17
+ }));
18
+
19
+ describe("TreeSelect panel height (LC-222)", () => {
20
+ it("states its cap as eight rows at the row pitch", async () => {
21
+ Object.defineProperty(window, "innerWidth", {
22
+ configurable: true,
23
+ writable: true,
24
+ value: 1200,
25
+ });
26
+ window.dispatchEvent(new Event("resize"));
27
+ const { baseElement } = renderWithProviders(<TreeSelect label="Account" nodes={nodes} open />);
28
+ const scroller = await waitFor(() => {
29
+ const found = baseElement.querySelector("[data-visible-rows]") as HTMLElement | null;
30
+ expect(found).toBeTruthy();
31
+ return found as HTMLElement;
32
+ });
33
+ const rows = Number(scroller.getAttribute("data-visible-rows"));
34
+ const pitch = Number(scroller.getAttribute("data-row-pitch"));
35
+ expect(rows).toBe(8);
36
+ expect(pitch).toBeGreaterThan(0);
37
+ const rowHeights = [...baseElement.querySelectorAll("[data-row-height]")].map((row) =>
38
+ Number(row.getAttribute("data-row-height")),
39
+ );
40
+ expect(new Set(rowHeights)).toEqual(new Set([pitch]));
41
+ const style = `${scroller.getAttribute("style") ?? ""} ${scroller.className}`;
42
+ expect(style).toContain(String(listHeightForRows(rows, pitch)));
43
+ });
44
+ });
@@ -26,6 +26,7 @@ import {
26
26
  ensureFocusVisibleRing,
27
27
  ensureKeyboardModalityTracking,
28
28
  keyboardFocusRingProps,
29
+ listHeightForRows,
29
30
  useMenuRowCheckInk,
30
31
  menuRowChecked,
31
32
  useResolvedKnobs,
@@ -617,6 +618,9 @@ function handleTreeKeys(args: {
617
618
  }
618
619
  }
619
620
 
621
+ /** Rows the desktop tree panel shows before it scrolls (LC-222). */
622
+ const TREE_SELECT_VISIBLE_ROWS = 8;
623
+
620
624
  function FloatingTreeSelect({
621
625
  nodes,
622
626
  value,
@@ -653,6 +657,7 @@ function FloatingTreeSelect({
653
657
  accessibilityLabel?: string;
654
658
  }) {
655
659
  const overlayZIndex = useOverlayZIndex("dropdown");
660
+ const { knobProps } = useResolvedKnobs();
656
661
  const treeId = useId();
657
662
  const searchRef = useRef<HTMLInputElement | null>(null);
658
663
  const state = useTreeSelectState({ nodes, value, open, defaultExpandedIds });
@@ -790,7 +795,13 @@ function FloatingTreeSelect({
790
795
  activeDescendant={activeDescendant}
791
796
  sizeToken={sizeToken}
792
797
  />
793
- <YStack overflow="scroll" maxHeight={320} id={treeId}>
798
+ <YStack
799
+ overflow="scroll"
800
+ maxHeight={listHeightForRows(TREE_SELECT_VISIBLE_ROWS, knobProps.nestedControl.px)}
801
+ data-visible-rows={TREE_SELECT_VISIBLE_ROWS}
802
+ data-row-pitch={knobProps.nestedControl.px}
803
+ id={treeId}
804
+ >
794
805
  <TreeSelectPanelBody
795
806
  rows={state.rows}
796
807
  selectedId={value}
@@ -23,6 +23,7 @@ import { isWeb } from "@multiplatform.one/platform";
23
23
  import { type ComponentType, type ReactNode, useEffect, useState } from "react";
24
24
  import { XStack, YStack } from "tamagui";
25
25
  import { materials, useMaterial } from "../Material";
26
+ import { MaterialBlurFill } from "../Material/blur";
26
27
  import { Text } from "../Text";
27
28
  import { setBottomChromeInset, setFloatingBarMounted, useBottomAccessory } from "./bottomChrome";
28
29
  import { useBottomInset } from "./bottomInset";
@@ -248,6 +249,7 @@ export function TabBar({
248
249
  onLayout={(event) => setAccessoryHeight(Math.round(event.nativeEvent.layout.height))}
249
250
  data-testid={`${testID}-accessory`}
250
251
  >
252
+ <MaterialBlurFill radius={1000} />
251
253
  {accessory}
252
254
  </XStack>
253
255
  ) : null}
@@ -261,6 +263,7 @@ export function TabBar({
261
263
  {...material}
262
264
  data-testid={`${testID}-capsule`}
263
265
  >
266
+ <MaterialBlurFill radius={1000} />
264
267
  {items.map((item) => (
265
268
  <TabBarButton
266
269
  key={item.key}
@@ -46,10 +46,18 @@ const fakeTabs: NativeTabs = {
46
46
  />
47
47
  </div>
48
48
  ),
49
- Screen: ({ children, tabKey, isFocused, icon, title }) => (
49
+ Screen: ({
50
+ children,
51
+ tabKey,
52
+ isFocused,
53
+ icon,
54
+ title,
55
+ overrideScrollViewContentInsetAdjustmentBehavior,
56
+ }) => (
50
57
  <section
51
58
  data-testid={`native-screen-${tabKey}`}
52
59
  data-focused={String(Boolean(isFocused))}
60
+ data-inset-adjust={String(overrideScrollViewContentInsetAdjustmentBehavior)}
53
61
  data-symbol={icon?.ios.name}
54
62
  aria-label={title}
55
63
  >
@@ -164,6 +172,18 @@ describe("NativeTabHost", () => {
164
172
  );
165
173
  expect(screen.getByTestId("inset").textContent).toBe("0");
166
174
  });
175
+
176
+ it("clears the bar once: the published inset, never the native scroll-inset adjustment too (FZ-8640)", () => {
177
+ renderNative("/pokemon");
178
+ expect(Number(screen.getByTestId("inset").textContent)).toBeGreaterThanOrEqual(
179
+ nativeTabBarHeight,
180
+ );
181
+ for (const item of items) {
182
+ expect(
183
+ screen.getByTestId(`native-screen-${item.key}`).getAttribute("data-inset-adjust"),
184
+ ).toBe("false");
185
+ }
186
+ });
167
187
  });
168
188
 
169
189
  describe("TabHost fallback", () => {
@@ -13,6 +13,12 @@
13
13
  * without RNSTabsHost, a platform other than iOS, or an item without an SF
14
14
  * Symbol keeps the MPO TabBar. Android stays on the MPO TabBar until the
15
15
  * items carry image icons the Material bar can draw.
16
+ *
17
+ * The bar's clearance is the inset this host publishes, as with the MPO
18
+ * TabBar, so a Screen pads by it whether or not it scrolls. Each tab screen
19
+ * leaves its scroll view's inset adjustment off: react-native-screens would
20
+ * otherwise flip the first scroll view to `automatic`, and UIKit would add
21
+ * the bar's height a second time (FZ-8640).
16
22
  */
17
23
  import { useGlyphColor, useIdentityInkOnSurface } from "@multiplatform.one/theme";
18
24
  import { type ComponentType, type ReactNode, useEffect, useRef, useState } from "react";
@@ -53,6 +59,7 @@ export interface NativeTabs {
53
59
  selectedIcon?: IconProp["ios"];
54
60
  tabBarItemAccessibilityLabel?: string;
55
61
  tabBarItemTestID?: string;
62
+ overrideScrollViewContentInsetAdjustmentBehavior?: boolean;
56
63
  }>;
57
64
  }
58
65
 
@@ -139,6 +146,7 @@ export function NativeTabHost({
139
146
  }
140
147
  tabBarItemAccessibilityLabel={item.label}
141
148
  tabBarItemTestID={`tab-bar-item-${item.key.replace(/^\/+/, "") || "root"}`}
149
+ overrideScrollViewContentInsetAdjustmentBehavior={false}
142
150
  >
143
151
  {item.key === focusedKey ? children : null}
144
152
  </Screen>
@@ -9,8 +9,8 @@ import type { ChartCurve, ChartDatum } from "./types";
9
9
  import { useChartTheme } from "./useChartTheme";
10
10
 
11
11
  export interface SparklineProps extends Omit<YStackProps, "children" | "width" | "height"> {
12
- /** Series values — bare numbers or full data points. */
13
- data: Array<number | ChartDatum>;
12
+ /** Series values — bare numbers or full data points. Null is no reading (LC-220). */
13
+ data: Array<number | ChartDatum> | null | undefined;
14
14
  /** Drawing height as a theme size token or pixels (default 36). */
15
15
  height?: ChartHeight;
16
16
  /** Fixed width; omit to track the parent responsively. */
@@ -50,7 +50,7 @@ export function Sparkline({
50
50
  const { t } = useTranslation();
51
51
  const { palette } = useChartTheme();
52
52
  const stroke = color ?? palette.single;
53
- const normalized: ChartDatum[] = data.map((entry, index) =>
53
+ const normalized: ChartDatum[] = (data ?? []).map((entry, index) =>
54
54
  typeof entry === "number" ? { label: String(index + 1), value: entry } : entry,
55
55
  );
56
56
  const ariaLabel =
@@ -131,7 +131,7 @@ export const componentColors = {
131
131
  debug: "$color9",
132
132
 
133
133
  /**
134
- * The round material plate under an icon control floating over a photo
134
+ * The flat round plate under an icon control floating over a photo
135
135
  * (LC-176). The fill sits steps above the viewer's dark ground so the
136
136
  * plate reads on black as well as on a bright frame (FZ-8009 r2).
137
137
  */
package/src/index.ts CHANGED
@@ -5,22 +5,29 @@ export {
5
5
  SortableHandle,
6
6
  SortableHandleWell,
7
7
  SortableSessionProvider,
8
+ applyUserOrder,
8
9
  useSortableRows,
10
+ useUserOrder,
9
11
  } from "./SortableList";
10
12
  export type {
11
13
  SortableListProps,
12
14
  SortableDisabledStyle,
13
15
  SortableSession,
14
16
  UseSortableRowsOptions,
17
+ UseUserOrderOptions,
18
+ UserOrderStorage,
15
19
  } from "./SortableList";
16
20
  export * from "./Badge";
17
21
  export * from "./Carousel";
18
22
  export * from "./Chip";
19
23
  export * from "./Kbd";
20
24
  export * from "./CopyField";
25
+ export * from "./Diff";
26
+ export * from "./ElapsedProgress";
21
27
  export * from "./DotIndicator";
22
28
  export * from "./DropdownMenu";
23
29
  export * from "./ContextMenu";
30
+ export * from "./MachineLiteral";
24
31
  export * from "./Material";
25
32
  export * from "./Meter";
26
33
  export { Lightbox, useLightbox } from "./Lightbox";
@@ -517,14 +517,7 @@ export function PageHeader({
517
517
  >
518
518
  {/* LC-153: page-head actions are a bar; neutral buttons go plain. */}
519
519
  <Surface bar>
520
- <IconButtonGroup
521
- {...knobProps.gap}
522
- justifyContent="flex-end"
523
- flexWrap="wrap"
524
- flexGrow={1}
525
- flexShrink={1}
526
- minWidth={0}
527
- >
520
+ <IconButtonGroup {...knobProps.gap} justifyContent="flex-end">
528
521
  {actions}
529
522
  </IconButtonGroup>
530
523
  </Surface>
@@ -61,4 +61,18 @@ describe("PageHeader actions (LC-142)", () => {
61
61
  expect(atoms(row, "_jc-")).toEqual(["_jc-flex-end"]);
62
62
  expect(atoms(row?.parentElement ?? null, "_fw-")).toEqual([]);
63
63
  });
64
+
65
+ it("hug their buttons: the group never wraps or grows (FZ-8521)", () => {
66
+ const { container } = renderWithProviders(
67
+ <PageHeader
68
+ title="Pokemon"
69
+ subtitle="21 Pokemon in the Pokédex"
70
+ actions={<button type="button">Add</button>}
71
+ />,
72
+ );
73
+ const group = container.querySelector("[data-page-header-actions] [data-mp-icon-button-group]");
74
+ expect(group).toBeTruthy();
75
+ expect(atoms(group, "_fw-")).toEqual([]);
76
+ expect(atoms(group, "_fg-")).toEqual([]);
77
+ });
64
78
  });
@@ -0,0 +1,71 @@
1
+ /**
2
+ * LC-220 EMPTY-IS-DRAWN: a presentation component given no reading draws its
3
+ * own empty form at the populated box (the bare track, the em dash, the empty
4
+ * surface), shows no "0", and its accessible name says there is no reading.
5
+ */
6
+ import { renderWithProviders } from "@multiplatform.one/test-utils";
7
+ import { cleanup, screen } from "@testing-library/react";
8
+ import { afterEach, describe, expect, it } from "vitest";
9
+ import { Sparkline } from "./charts/Sparkline";
10
+ import { Default as DiffMain, NoReading } from "./Diff/Diff.stories";
11
+ import { Diff, type DiffProps } from "./Diff";
12
+ import { Meter, type MeterProps } from "./Meter";
13
+ import { Default as MeterMain, Unknown } from "./Meter/Meter.stories";
14
+
15
+ afterEach(cleanup);
16
+
17
+ const noZero = /(^|[^\d.])0([^\d.]|$)/;
18
+
19
+ describe("presentation components draw their empty form (LC-220)", () => {
20
+ it("Meter: the bare track at the populated height, an em dash, no fill, no reading spoken", () => {
21
+ const full = renderWithProviders(<Meter {...(MeterMain.args as MeterProps)} />);
22
+ const fullRail = full.container.querySelector("[role='meter']") as HTMLElement;
23
+ const height = fullRail.getAttribute("data-meter-track-height");
24
+ full.unmount();
25
+
26
+ const { container } = renderWithProviders(
27
+ <Meter {...(Unknown.args as MeterProps)} value={null} />,
28
+ );
29
+ const rail = container.querySelector("[role='meter']") as HTMLElement;
30
+ expect(rail).toBeTruthy();
31
+ expect(rail.getAttribute("data-meter-track-height")).toBe(height);
32
+ expect(rail.getAttribute("data-meter-fill")).toBeNull();
33
+ expect(rail.getAttribute("aria-valuenow")).toBeNull();
34
+ expect(rail.getAttribute("aria-valuetext")).toBe("No reading");
35
+ expect(container.textContent).toContain("—");
36
+ expect(container.textContent).not.toMatch(noZero);
37
+ });
38
+
39
+ it("Diff: the same frame with an em dash and a no-reading name, never 0 added", () => {
40
+ const full = renderWithProviders(<Diff {...(DiffMain.args as DiffProps)} />);
41
+ const fullFrame = full.container.querySelector("[role='region']") as HTMLElement;
42
+ const fullClass = fullFrame.className;
43
+ full.unmount();
44
+
45
+ const { container } = renderWithProviders(<Diff {...(NoReading.args as DiffProps)} />);
46
+ const frame = container.querySelector("[role='region']") as HTMLElement;
47
+ expect(frame.className).toBe(fullClass);
48
+ expect(frame.getAttribute("aria-label")).toMatch(/no reading$/);
49
+ expect(container.textContent).toBe("—");
50
+ expect(container.textContent).not.toMatch(noZero);
51
+ });
52
+
53
+ it("Sparkline: the surface keeps its box and says no data, with no point drawn", () => {
54
+ const full = renderWithProviders(
55
+ <Sparkline width={160} data={[3, 5, 4, 8]} title="Sessions" />,
56
+ );
57
+ const fullSvg = full.container.querySelector("svg") as SVGElement;
58
+ const height = fullSvg.getAttribute("height");
59
+ full.unmount();
60
+
61
+ const { container } = renderWithProviders(
62
+ <Sparkline width={160} data={null} title="Sessions" />,
63
+ );
64
+ const svg = container.querySelector("svg") as SVGElement;
65
+ expect(svg.getAttribute("height")).toBe(height);
66
+ expect(svg.getAttribute("width")).toBe("160");
67
+ expect(screen.getByRole("img").getAttribute("aria-label")).toMatch(/no data$/);
68
+ expect(container.querySelectorAll("path")).toHaveLength(0);
69
+ expect(container.textContent).not.toMatch(noZero);
70
+ });
71
+ });