cursedbelt 5.40.0 → 5.45.1

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 (589) hide show
  1. package/dist/react/Toast.d.ts +12 -2
  2. package/dist/react/Toast.d.ts.map +1 -1
  3. package/dist/react/Toast.js +32 -3
  4. package/dist/react/Toast.js.map +1 -1
  5. package/dist/react/analytics/MetricDrilldown.js +1 -1
  6. package/dist/react/canvas-hud/CanvasMinimap.d.ts +32 -0
  7. package/dist/react/canvas-hud/CanvasMinimap.d.ts.map +1 -0
  8. package/dist/react/canvas-hud/CanvasMinimap.js +32 -0
  9. package/dist/react/canvas-hud/CanvasMinimap.js.map +1 -0
  10. package/dist/react/canvas-hud/CanvasNodeMenu.d.ts +34 -0
  11. package/dist/react/canvas-hud/CanvasNodeMenu.d.ts.map +1 -0
  12. package/dist/react/canvas-hud/CanvasNodeMenu.js +21 -0
  13. package/dist/react/canvas-hud/CanvasNodeMenu.js.map +1 -0
  14. package/dist/react/canvas-hud/CanvasSearchField.d.ts +27 -0
  15. package/dist/react/canvas-hud/CanvasSearchField.d.ts.map +1 -0
  16. package/dist/react/canvas-hud/CanvasSearchField.js +35 -0
  17. package/dist/react/canvas-hud/CanvasSearchField.js.map +1 -0
  18. package/dist/react/canvas-hud/HudControls.d.ts +43 -0
  19. package/dist/react/canvas-hud/HudControls.d.ts.map +1 -0
  20. package/dist/react/canvas-hud/HudControls.js +22 -0
  21. package/dist/react/canvas-hud/HudControls.js.map +1 -0
  22. package/dist/react/canvas-hud/index.d.ts +13 -0
  23. package/dist/react/canvas-hud/index.d.ts.map +1 -0
  24. package/dist/react/canvas-hud/index.js +7 -0
  25. package/dist/react/canvas-hud/index.js.map +1 -0
  26. package/dist/react/canvas-hud/useCanvasWheel.d.ts +41 -0
  27. package/dist/react/canvas-hud/useCanvasWheel.d.ts.map +1 -0
  28. package/dist/react/canvas-hud/useCanvasWheel.js +65 -0
  29. package/dist/react/canvas-hud/useCanvasWheel.js.map +1 -0
  30. package/dist/react/canvas-hud/viewport.d.ts +68 -0
  31. package/dist/react/canvas-hud/viewport.d.ts.map +1 -0
  32. package/dist/react/canvas-hud/viewport.js +77 -0
  33. package/dist/react/canvas-hud/viewport.js.map +1 -0
  34. package/dist/react/charts/AreaChart.d.ts.map +1 -1
  35. package/dist/react/charts/AreaChart.js +5 -5
  36. package/dist/react/charts/AreaChart.js.map +1 -1
  37. package/dist/react/charts/BarChart.d.ts.map +1 -1
  38. package/dist/react/charts/BarChart.js +3 -3
  39. package/dist/react/charts/BarChart.js.map +1 -1
  40. package/dist/react/charts/ChartCard.d.ts +53 -0
  41. package/dist/react/charts/ChartCard.d.ts.map +1 -0
  42. package/dist/react/charts/ChartCard.js +46 -0
  43. package/dist/react/charts/ChartCard.js.map +1 -0
  44. package/dist/react/charts/ChartFrame.d.ts +12 -5
  45. package/dist/react/charts/ChartFrame.d.ts.map +1 -1
  46. package/dist/react/charts/ChartFrame.js +12 -5
  47. package/dist/react/charts/ChartFrame.js.map +1 -1
  48. package/dist/react/charts/ChartLegend.js +1 -1
  49. package/dist/react/charts/ChartLegend.js.map +1 -1
  50. package/dist/react/charts/HeatmapChart.js +3 -3
  51. package/dist/react/charts/HeatmapChart.js.map +1 -1
  52. package/dist/react/charts/IntervalTimeline.js +1 -1
  53. package/dist/react/charts/IntervalTimeline.js.map +1 -1
  54. package/dist/react/charts/LineChart.d.ts.map +1 -1
  55. package/dist/react/charts/LineChart.js +3 -3
  56. package/dist/react/charts/LineChart.js.map +1 -1
  57. package/dist/react/charts/TimeSeriesChart.d.ts.map +1 -1
  58. package/dist/react/charts/TimeSeriesChart.js +6 -6
  59. package/dist/react/charts/TimeSeriesChart.js.map +1 -1
  60. package/dist/react/charts/chartBox.d.ts +46 -0
  61. package/dist/react/charts/chartBox.d.ts.map +1 -0
  62. package/dist/react/charts/chartBox.js +45 -0
  63. package/dist/react/charts/chartBox.js.map +1 -0
  64. package/dist/react/charts/index.d.ts +2 -0
  65. package/dist/react/charts/index.d.ts.map +1 -1
  66. package/dist/react/charts/index.js +2 -0
  67. package/dist/react/charts/index.js.map +1 -1
  68. package/dist/react/charts/shared.d.ts +13 -2
  69. package/dist/react/charts/shared.d.ts.map +1 -1
  70. package/dist/react/charts/shared.js +14 -3
  71. package/dist/react/charts/shared.js.map +1 -1
  72. package/dist/react/chat/Bubble.js +4 -4
  73. package/dist/react/chat/Bubble.js.map +1 -1
  74. package/dist/react/chat/MessageScroller.js +1 -1
  75. package/dist/react/chat/MessageScroller.js.map +1 -1
  76. package/dist/react/components/ActionBar.d.ts.map +1 -1
  77. package/dist/react/components/ActionBar.js +63 -1
  78. package/dist/react/components/ActionBar.js.map +1 -1
  79. package/dist/react/components/AddItemsMenu.js +1 -1
  80. package/dist/react/components/AddItemsMenu.js.map +1 -1
  81. package/dist/react/components/Alert.d.ts +16 -2
  82. package/dist/react/components/Alert.d.ts.map +1 -1
  83. package/dist/react/components/Alert.js +35 -2
  84. package/dist/react/components/Alert.js.map +1 -1
  85. package/dist/react/components/AppShell.d.ts +55 -33
  86. package/dist/react/components/AppShell.d.ts.map +1 -1
  87. package/dist/react/components/AppShell.js +141 -31
  88. package/dist/react/components/AppShell.js.map +1 -1
  89. package/dist/react/components/AsyncPanel.d.ts +21 -3
  90. package/dist/react/components/AsyncPanel.d.ts.map +1 -1
  91. package/dist/react/components/AsyncPanel.js +50 -6
  92. package/dist/react/components/AsyncPanel.js.map +1 -1
  93. package/dist/react/components/BannerLane.d.ts +32 -0
  94. package/dist/react/components/BannerLane.d.ts.map +1 -0
  95. package/dist/react/components/BannerLane.js +41 -0
  96. package/dist/react/components/BannerLane.js.map +1 -0
  97. package/dist/react/components/Button.d.ts.map +1 -1
  98. package/dist/react/components/Button.js +2 -1
  99. package/dist/react/components/Button.js.map +1 -1
  100. package/dist/react/components/Checkbox.d.ts.map +1 -1
  101. package/dist/react/components/Checkbox.js +7 -2
  102. package/dist/react/components/Checkbox.js.map +1 -1
  103. package/dist/react/components/ChipFilterStrip.js +1 -1
  104. package/dist/react/components/ChipFilterStrip.js.map +1 -1
  105. package/dist/react/components/ComboboxField.d.ts.map +1 -1
  106. package/dist/react/components/ComboboxField.js +14 -4
  107. package/dist/react/components/ComboboxField.js.map +1 -1
  108. package/dist/react/components/CommentThread.js +2 -2
  109. package/dist/react/components/CommentThread.js.map +1 -1
  110. package/dist/react/components/ConfirmDialog.js +1 -1
  111. package/dist/react/components/ConfirmDialog.js.map +1 -1
  112. package/dist/react/components/DataTable/DataTable.d.ts +18 -2
  113. package/dist/react/components/DataTable/DataTable.d.ts.map +1 -1
  114. package/dist/react/components/DataTable/DataTable.js +51 -12
  115. package/dist/react/components/DataTable/DataTable.js.map +1 -1
  116. package/dist/react/components/DataTable/Pagination.js +1 -1
  117. package/dist/react/components/DataTable/Pagination.js.map +1 -1
  118. package/dist/react/components/DataTable/RowActions.d.ts +7 -1
  119. package/dist/react/components/DataTable/RowActions.d.ts.map +1 -1
  120. package/dist/react/components/DataTable/RowActions.js +10 -3
  121. package/dist/react/components/DataTable/RowActions.js.map +1 -1
  122. package/dist/react/components/DataTable/TableFilterBuilder.js +1 -1
  123. package/dist/react/components/DataTable/TableFilterBuilder.js.map +1 -1
  124. package/dist/react/components/DataTable/cells/CodeCell.js +1 -1
  125. package/dist/react/components/DataTable/cells/CodeCell.js.map +1 -1
  126. package/dist/react/components/DataTable/cells/LinkCell.js +1 -1
  127. package/dist/react/components/DataTable/cells/LinkCell.js.map +1 -1
  128. package/dist/react/components/DataTable/index.d.ts +1 -1
  129. package/dist/react/components/DataTable/index.d.ts.map +1 -1
  130. package/dist/react/components/DataTable/index.js.map +1 -1
  131. package/dist/react/components/DataTable/types.d.ts +20 -0
  132. package/dist/react/components/DataTable/types.d.ts.map +1 -1
  133. package/dist/react/components/DataTable/types.js +22 -0
  134. package/dist/react/components/DataTable/types.js.map +1 -1
  135. package/dist/react/components/DateTimeField.d.ts.map +1 -1
  136. package/dist/react/components/DateTimeField.js +4 -1
  137. package/dist/react/components/DateTimeField.js.map +1 -1
  138. package/dist/react/components/DeleteButton.js +2 -0
  139. package/dist/react/components/DeleteButton.js.map +1 -1
  140. package/dist/react/components/Drawer.js +3 -3
  141. package/dist/react/components/Drawer.js.map +1 -1
  142. package/dist/react/components/DropdownMenu.d.ts +16 -0
  143. package/dist/react/components/DropdownMenu.d.ts.map +1 -1
  144. package/dist/react/components/DropdownMenu.js +22 -6
  145. package/dist/react/components/DropdownMenu.js.map +1 -1
  146. package/dist/react/components/EmptyState.d.ts +10 -2
  147. package/dist/react/components/EmptyState.d.ts.map +1 -1
  148. package/dist/react/components/EmptyState.js +10 -5
  149. package/dist/react/components/EmptyState.js.map +1 -1
  150. package/dist/react/components/EventTimeline.js +1 -1
  151. package/dist/react/components/EventTimeline.js.map +1 -1
  152. package/dist/react/components/Field.d.ts.map +1 -1
  153. package/dist/react/components/Field.js +4 -1
  154. package/dist/react/components/Field.js.map +1 -1
  155. package/dist/react/components/FileDropZone.js +1 -1
  156. package/dist/react/components/FileDropZone.js.map +1 -1
  157. package/dist/react/components/Grid.d.ts +9 -1
  158. package/dist/react/components/Grid.d.ts.map +1 -1
  159. package/dist/react/components/Grid.js +20 -2
  160. package/dist/react/components/Grid.js.map +1 -1
  161. package/dist/react/components/Guide.d.ts +31 -0
  162. package/dist/react/components/Guide.d.ts.map +1 -0
  163. package/dist/react/components/Guide.js +18 -0
  164. package/dist/react/components/Guide.js.map +1 -0
  165. package/dist/react/components/InfoHintImpl.d.ts +0 -13
  166. package/dist/react/components/InfoHintImpl.d.ts.map +1 -1
  167. package/dist/react/components/InfoHintImpl.js +17 -1
  168. package/dist/react/components/InfoHintImpl.js.map +1 -1
  169. package/dist/react/components/InlineEditableText.js +1 -1
  170. package/dist/react/components/InlineEditableText.js.map +1 -1
  171. package/dist/react/components/IsolatedFrame.js +1 -1
  172. package/dist/react/components/IsolatedFrame.js.map +1 -1
  173. package/dist/react/components/ListToolbar.d.ts.map +1 -1
  174. package/dist/react/components/ListToolbar.js +2 -2
  175. package/dist/react/components/ListToolbar.js.map +1 -1
  176. package/dist/react/components/LogViewer.d.ts +26 -2
  177. package/dist/react/components/LogViewer.d.ts.map +1 -1
  178. package/dist/react/components/LogViewer.js +41 -26
  179. package/dist/react/components/LogViewer.js.map +1 -1
  180. package/dist/react/components/Modal.d.ts +5 -1
  181. package/dist/react/components/Modal.d.ts.map +1 -1
  182. package/dist/react/components/Modal.js +18 -8
  183. package/dist/react/components/Modal.js.map +1 -1
  184. package/dist/react/components/Page.d.ts +51 -7
  185. package/dist/react/components/Page.d.ts.map +1 -1
  186. package/dist/react/components/Page.js +53 -8
  187. package/dist/react/components/Page.js.map +1 -1
  188. package/dist/react/components/PageGuideButton.d.ts +11 -0
  189. package/dist/react/components/PageGuideButton.d.ts.map +1 -0
  190. package/dist/react/components/PageGuideButton.js +52 -0
  191. package/dist/react/components/PageGuideButton.js.map +1 -0
  192. package/dist/react/components/PageGuidePopover.d.ts +14 -0
  193. package/dist/react/components/PageGuidePopover.d.ts.map +1 -0
  194. package/dist/react/components/PageGuidePopover.js +25 -0
  195. package/dist/react/components/PageGuidePopover.js.map +1 -0
  196. package/dist/react/components/PanelSeparator.js +1 -1
  197. package/dist/react/components/PanelSeparator.js.map +1 -1
  198. package/dist/react/components/Popover.d.ts.map +1 -1
  199. package/dist/react/components/Popover.js +2 -1
  200. package/dist/react/components/Popover.js.map +1 -1
  201. package/dist/react/components/PromptDialog.js +1 -1
  202. package/dist/react/components/PromptDialog.js.map +1 -1
  203. package/dist/react/components/ScrollArea.d.ts +9 -1
  204. package/dist/react/components/ScrollArea.d.ts.map +1 -1
  205. package/dist/react/components/ScrollArea.js +9 -3
  206. package/dist/react/components/ScrollArea.js.map +1 -1
  207. package/dist/react/components/Section.d.ts +5 -2
  208. package/dist/react/components/Section.d.ts.map +1 -1
  209. package/dist/react/components/Section.js +5 -2
  210. package/dist/react/components/Section.js.map +1 -1
  211. package/dist/react/components/Skeleton.d.ts +19 -1
  212. package/dist/react/components/Skeleton.d.ts.map +1 -1
  213. package/dist/react/components/Skeleton.js +24 -2
  214. package/dist/react/components/Skeleton.js.map +1 -1
  215. package/dist/react/components/StatStrip.js +1 -1
  216. package/dist/react/components/StatStrip.js.map +1 -1
  217. package/dist/react/components/StatTile.d.ts +30 -3
  218. package/dist/react/components/StatTile.d.ts.map +1 -1
  219. package/dist/react/components/StatTile.js +35 -9
  220. package/dist/react/components/StatTile.js.map +1 -1
  221. package/dist/react/components/StatTileGrid.d.ts +10 -1
  222. package/dist/react/components/StatTileGrid.d.ts.map +1 -1
  223. package/dist/react/components/StatTileGrid.js +50 -33
  224. package/dist/react/components/StatTileGrid.js.map +1 -1
  225. package/dist/react/components/StatusPill.d.ts.map +1 -1
  226. package/dist/react/components/StatusPill.js +26 -1
  227. package/dist/react/components/StatusPill.js.map +1 -1
  228. package/dist/react/components/Surface.d.ts +1 -1
  229. package/dist/react/components/Surface.d.ts.map +1 -1
  230. package/dist/react/components/Surface.js +20 -11
  231. package/dist/react/components/Surface.js.map +1 -1
  232. package/dist/react/components/SwatchPicker.d.ts.map +1 -1
  233. package/dist/react/components/SwatchPicker.js +5 -1
  234. package/dist/react/components/SwatchPicker.js.map +1 -1
  235. package/dist/react/components/Switch.js +1 -1
  236. package/dist/react/components/Switch.js.map +1 -1
  237. package/dist/react/components/TagsInput.d.ts.map +1 -1
  238. package/dist/react/components/TagsInput.js +3 -1
  239. package/dist/react/components/TagsInput.js.map +1 -1
  240. package/dist/react/components/WidgetHeader.js +1 -1
  241. package/dist/react/components/WidgetHeader.js.map +1 -1
  242. package/dist/react/components/calendar/CalendarLegend.js +1 -1
  243. package/dist/react/components/calendar/CalendarLegend.js.map +1 -1
  244. package/dist/react/components/calendar/DayAgenda.js +1 -1
  245. package/dist/react/components/calendar/DayAgenda.js.map +1 -1
  246. package/dist/react/components/calendar/EventChip.js +1 -1
  247. package/dist/react/components/calendar/EventChip.js.map +1 -1
  248. package/dist/react/components/calendar/MonthGrid.js +1 -1
  249. package/dist/react/components/calendar/MonthGrid.js.map +1 -1
  250. package/dist/react/components/calendar/WeekView.js +2 -2
  251. package/dist/react/components/calendar/WeekView.js.map +1 -1
  252. package/dist/react/components/cardFrame.d.ts +16 -0
  253. package/dist/react/components/cardFrame.d.ts.map +1 -0
  254. package/dist/react/components/cardFrame.js +24 -0
  255. package/dist/react/components/cardFrame.js.map +1 -0
  256. package/dist/react/components/dialog.d.ts.map +1 -1
  257. package/dist/react/components/dialog.js +2 -1
  258. package/dist/react/components/dialog.js.map +1 -1
  259. package/dist/react/dashboard-grid/WidgetFrame.js +2 -2
  260. package/dist/react/dashboard-grid/WidgetFrame.js.map +1 -1
  261. package/dist/react/emoji/EmojiPicker.js +1 -1
  262. package/dist/react/emoji/EmojiPicker.js.map +1 -1
  263. package/dist/react/file-tree/FileTree.d.ts +8 -1
  264. package/dist/react/file-tree/FileTree.d.ts.map +1 -1
  265. package/dist/react/file-tree/FileTree.js +29 -4
  266. package/dist/react/file-tree/FileTree.js.map +1 -1
  267. package/dist/react/filter-rail/FilterRail.js +1 -1
  268. package/dist/react/filter-rail/FilterRail.js.map +1 -1
  269. package/dist/react/folder-tree/FolderPicker.d.ts.map +1 -1
  270. package/dist/react/folder-tree/FolderPicker.js +5 -1
  271. package/dist/react/folder-tree/FolderPicker.js.map +1 -1
  272. package/dist/react/icons.d.ts +28 -0
  273. package/dist/react/icons.d.ts.map +1 -1
  274. package/dist/react/icons.js +29 -1
  275. package/dist/react/icons.js.map +1 -1
  276. package/dist/react/index.d.ts +9 -6
  277. package/dist/react/index.d.ts.map +1 -1
  278. package/dist/react/index.js +6 -3
  279. package/dist/react/index.js.map +1 -1
  280. package/dist/react/lib/menuSections.d.ts +8 -0
  281. package/dist/react/lib/menuSections.d.ts.map +1 -0
  282. package/dist/react/lib/menuSections.js +37 -0
  283. package/dist/react/lib/menuSections.js.map +1 -0
  284. package/dist/react/lib/whenIdle.d.ts +7 -0
  285. package/dist/react/lib/whenIdle.d.ts.map +1 -0
  286. package/dist/react/lib/whenIdle.js +14 -0
  287. package/dist/react/lib/whenIdle.js.map +1 -0
  288. package/dist/react/markdown/Markdown.js +2 -2
  289. package/dist/react/markdown/Markdown.js.map +1 -1
  290. package/dist/react/media/DenseGalleryShell.d.ts +7 -1
  291. package/dist/react/media/DenseGalleryShell.d.ts.map +1 -1
  292. package/dist/react/media/DenseGalleryShell.js +3 -3
  293. package/dist/react/media/DenseGalleryShell.js.map +1 -1
  294. package/dist/react/media/HoverScrubVideoThumb.js +1 -1
  295. package/dist/react/media/HoverScrubVideoThumb.js.map +1 -1
  296. package/dist/react/media/MaskPainter.js +1 -1
  297. package/dist/react/media/MediaUploadControl.js +1 -1
  298. package/dist/react/media/MediaUploadControl.js.map +1 -1
  299. package/dist/react/media/VideoTrimmer.js +1 -1
  300. package/dist/react/media/VideoTrimmer.js.map +1 -1
  301. package/dist/react/media/denseGallery.css +96 -1
  302. package/dist/react/media-gallery/MediaGallery.d.ts +5 -2
  303. package/dist/react/media-gallery/MediaGallery.d.ts.map +1 -1
  304. package/dist/react/media-gallery/MediaGallery.js +1 -1
  305. package/dist/react/media-gallery/MediaGallery.js.map +1 -1
  306. package/dist/react/namespace/NamespaceTargetCapsule.js +1 -1
  307. package/dist/react/namespace/NamespaceTargetCapsule.js.map +1 -1
  308. package/dist/react/nav/BreadcrumbTrail.js +1 -1
  309. package/dist/react/nav/BreadcrumbTrail.js.map +1 -1
  310. package/dist/react/nav/CommandBar.d.ts +7 -1
  311. package/dist/react/nav/CommandBar.d.ts.map +1 -1
  312. package/dist/react/nav/CommandBar.js +5 -3
  313. package/dist/react/nav/CommandBar.js.map +1 -1
  314. package/dist/react/nav/PlaceBar.d.ts.map +1 -1
  315. package/dist/react/nav/PlaceBar.js +7 -9
  316. package/dist/react/nav/PlaceBar.js.map +1 -1
  317. package/dist/react/nav/SideNav.d.ts +12 -2
  318. package/dist/react/nav/SideNav.d.ts.map +1 -1
  319. package/dist/react/nav/SideNav.js +42 -22
  320. package/dist/react/nav/SideNav.js.map +1 -1
  321. package/dist/react/nav/TopBar.d.ts +65 -31
  322. package/dist/react/nav/TopBar.d.ts.map +1 -1
  323. package/dist/react/nav/TopBar.js +59 -24
  324. package/dist/react/nav/TopBar.js.map +1 -1
  325. package/dist/react/nav/index.d.ts +1 -1
  326. package/dist/react/nav/index.d.ts.map +1 -1
  327. package/dist/react/nav/index.js +1 -1
  328. package/dist/react/nav/index.js.map +1 -1
  329. package/dist/react/nav/navShared.d.ts +10 -1
  330. package/dist/react/nav/navShared.d.ts.map +1 -1
  331. package/dist/react/nav/navShared.js +23 -0
  332. package/dist/react/nav/navShared.js.map +1 -1
  333. package/dist/react/notifications/NotificationFeed.js +2 -2
  334. package/dist/react/notifications/NotificationFeed.js.map +1 -1
  335. package/dist/react/palette/Command.d.ts.map +1 -1
  336. package/dist/react/palette/Command.js +1 -1
  337. package/dist/react/palette/Command.js.map +1 -1
  338. package/dist/react/palette/CommandPalette.d.ts +13 -1
  339. package/dist/react/palette/CommandPalette.d.ts.map +1 -1
  340. package/dist/react/palette/CommandPalette.js +44 -8
  341. package/dist/react/palette/CommandPalette.js.map +1 -1
  342. package/dist/react/palette/commandSources.d.ts +57 -0
  343. package/dist/react/palette/commandSources.d.ts.map +1 -0
  344. package/dist/react/palette/commandSources.js +129 -0
  345. package/dist/react/palette/commandSources.js.map +1 -0
  346. package/dist/react/palette/index.d.ts +1 -0
  347. package/dist/react/palette/index.d.ts.map +1 -1
  348. package/dist/react/palette/index.js +1 -0
  349. package/dist/react/palette/index.js.map +1 -1
  350. package/dist/react/rich-text/RichTextEditor.js +1 -1
  351. package/dist/react/rich-text/RichTextEditor.js.map +1 -1
  352. package/dist/react/rich-text/RichTextToolbar.js +1 -1
  353. package/dist/react/rich-text/RichTextToolbar.js.map +1 -1
  354. package/dist/scripts/guardrailsEnforce.d.ts.map +1 -1
  355. package/dist/styles-areas/analytics.css +16 -16
  356. package/dist/styles-areas/auth.css +2 -2
  357. package/dist/styles-areas/calendar.css +5 -6
  358. package/dist/styles-areas/canvas-hud.css +30 -0
  359. package/dist/styles-areas/chart-table.css +1 -1
  360. package/dist/styles-areas/charts.css +3 -3
  361. package/dist/styles-areas/chat.css +7 -6
  362. package/dist/styles-areas/companion-link.css +2 -2
  363. package/dist/styles-areas/core.css +99 -90
  364. package/dist/styles-areas/dashboard-grid.css +4 -4
  365. package/dist/styles-areas/data-table.css +16 -16
  366. package/dist/styles-areas/disk-usage.css +5 -5
  367. package/dist/styles-areas/emoji.css +2 -2
  368. package/dist/styles-areas/fields.css +13 -14
  369. package/dist/styles-areas/filter-rail.css +4 -4
  370. package/dist/styles-areas/folder-tree.css +6 -6
  371. package/dist/styles-areas/layout-engine.css +4 -4
  372. package/dist/styles-areas/markdown.css +2 -1
  373. package/dist/styles-areas/master-detail.css +3 -3
  374. package/dist/styles-areas/media-gallery.css +7 -6
  375. package/dist/styles-areas/media.css +12 -13
  376. package/dist/styles-areas/nav.css +28 -14
  377. package/dist/styles-areas/notifications.css +4 -4
  378. package/dist/styles-areas/overlays.css +4 -4
  379. package/dist/styles-areas/palette.css +5 -4
  380. package/dist/styles-areas/rich-text.css +3 -3
  381. package/dist/styles-areas/sharing.css +4 -3
  382. package/dist/styles-areas/stats.css +9 -8
  383. package/dist/styles-areas/test-report.css +4 -4
  384. package/dist/styles-areas/wizard.css +6 -5
  385. package/dist/styles-areas/workbench.css +10 -9
  386. package/dist/styles-areas/workbook-viewer.css +2 -2
  387. package/dist/styles-utilities.css +296 -190
  388. package/dist/testing/designAudit.d.ts.map +1 -1
  389. package/dist/testing/designAudit.js +4 -0
  390. package/dist/testing/designAudit.js.map +1 -1
  391. package/dist/testing/designBaseline.d.ts.map +1 -1
  392. package/dist/testing/designBaseline.js +4 -0
  393. package/dist/testing/designBaseline.js.map +1 -1
  394. package/dist/theme.css +103 -2
  395. package/package.json +10 -2
  396. package/scripts/generateAreaStyles.ts +3 -1
  397. package/scripts/guardrails-baseline.json +2 -1
  398. package/scripts/guardrailsEnforce.spec.ts +64 -0
  399. package/scripts/guardrailsEnforce.ts +65 -8
  400. package/scripts/styleAreas.ts +89 -6
  401. package/src/bundlerOnlyEntries.spec.ts +25 -8
  402. package/src/nodeTypesDeclared.spec.ts +47 -0
  403. package/src/react/Toast.spec.tsx +43 -0
  404. package/src/react/Toast.tsx +45 -2
  405. package/src/react/analytics/MetricDrilldown.tsx +1 -1
  406. package/src/react/canvas-hud/CanvasMinimap.tsx +88 -0
  407. package/src/react/canvas-hud/CanvasNodeMenu.tsx +91 -0
  408. package/src/react/canvas-hud/CanvasSearchField.tsx +91 -0
  409. package/src/react/canvas-hud/HudControls.spec.tsx +160 -0
  410. package/src/react/canvas-hud/HudControls.tsx +128 -0
  411. package/src/react/canvas-hud/index.ts +33 -0
  412. package/src/react/canvas-hud/useCanvasWheel.ts +99 -0
  413. package/src/react/canvas-hud/viewport.spec.ts +105 -0
  414. package/src/react/canvas-hud/viewport.ts +124 -0
  415. package/src/react/charts/AreaChart.tsx +9 -8
  416. package/src/react/charts/BarChart.tsx +11 -10
  417. package/src/react/charts/ChartCard.tsx +146 -0
  418. package/src/react/charts/ChartFrame.tsx +28 -10
  419. package/src/react/charts/ChartLegend.tsx +1 -1
  420. package/src/react/charts/HeatmapChart.tsx +5 -5
  421. package/src/react/charts/IntervalTimeline.tsx +2 -2
  422. package/src/react/charts/LineChart.tsx +9 -8
  423. package/src/react/charts/TimeSeriesChart.tsx +11 -10
  424. package/src/react/charts/chartBox.spec.ts +40 -0
  425. package/src/react/charts/chartBox.ts +75 -0
  426. package/src/react/charts/index.ts +2 -0
  427. package/src/react/charts/shared.ts +16 -3
  428. package/src/react/chat/Bubble.tsx +5 -5
  429. package/src/react/chat/MessageScroller.tsx +1 -1
  430. package/src/react/components/ActionBar.spec.tsx +90 -0
  431. package/src/react/components/ActionBar.tsx +82 -2
  432. package/src/react/components/AddItemsMenu.tsx +1 -1
  433. package/src/react/components/Alert.spec.tsx +32 -2
  434. package/src/react/components/Alert.tsx +47 -3
  435. package/src/react/components/AppShell.spec.tsx +199 -13
  436. package/src/react/components/AppShell.tsx +254 -92
  437. package/src/react/components/AsyncPanel.spec.tsx +17 -1
  438. package/src/react/components/AsyncPanel.tsx +88 -6
  439. package/src/react/components/BannerLane.tsx +128 -0
  440. package/src/react/components/Button.tsx +2 -0
  441. package/src/react/components/Checkbox.spec.tsx +18 -0
  442. package/src/react/components/Checkbox.tsx +8 -5
  443. package/src/react/components/ChipFilterStrip.tsx +1 -1
  444. package/src/react/components/ComboboxField.tsx +20 -3
  445. package/src/react/components/CommentThread.tsx +2 -2
  446. package/src/react/components/ConfirmDialog.tsx +1 -1
  447. package/src/react/components/DataTable/DataTable.tsx +80 -8
  448. package/src/react/components/DataTable/Pagination.tsx +1 -1
  449. package/src/react/components/DataTable/RowActions.tsx +55 -2
  450. package/src/react/components/DataTable/TableFilterBuilder.tsx +1 -1
  451. package/src/react/components/DataTable/cells/CodeCell.tsx +1 -1
  452. package/src/react/components/DataTable/cells/LinkCell.tsx +1 -1
  453. package/src/react/components/DataTable/index.ts +1 -0
  454. package/src/react/components/DataTable/numericColumn.spec.ts +19 -0
  455. package/src/react/components/DataTable/types.ts +36 -0
  456. package/src/react/components/DateTimeField.tsx +3 -1
  457. package/src/react/components/DeleteButton.tsx +3 -0
  458. package/src/react/components/Drawer.tsx +3 -3
  459. package/src/react/components/DropdownMenu.spec.tsx +55 -0
  460. package/src/react/components/DropdownMenu.tsx +73 -20
  461. package/src/react/components/EmptyState.tsx +26 -7
  462. package/src/react/components/EventTimeline.tsx +1 -1
  463. package/src/react/components/Field.spec.tsx +3 -2
  464. package/src/react/components/Field.tsx +7 -4
  465. package/src/react/components/Field.width.spec.tsx +14 -3
  466. package/src/react/components/FileDropZone.tsx +1 -1
  467. package/src/react/components/Grid.spec.tsx +44 -0
  468. package/src/react/components/Grid.tsx +41 -11
  469. package/src/react/components/Guide.tsx +77 -0
  470. package/src/react/components/InfoHint.spec.tsx +21 -0
  471. package/src/react/components/InfoHintImpl.tsx +22 -1
  472. package/src/react/components/InlineEditableText.tsx +1 -1
  473. package/src/react/components/IsolatedFrame.tsx +1 -1
  474. package/src/react/components/ListToolbar.spec.tsx +12 -0
  475. package/src/react/components/ListToolbar.tsx +8 -5
  476. package/src/react/components/LogViewer.tsx +118 -18
  477. package/src/react/components/Modal.spec.tsx +17 -2
  478. package/src/react/components/Modal.tsx +25 -10
  479. package/src/react/components/MultiSelectField.spec.tsx +6 -0
  480. package/src/react/components/Page.spec.tsx +89 -5
  481. package/src/react/components/Page.tsx +100 -16
  482. package/src/react/components/PageGuideButton.spec.tsx +39 -0
  483. package/src/react/components/PageGuideButton.tsx +110 -0
  484. package/src/react/components/PageGuidePopover.tsx +52 -0
  485. package/src/react/components/PanelSeparator.tsx +1 -1
  486. package/src/react/components/Popover.tsx +3 -1
  487. package/src/react/components/PromptDialog.tsx +1 -1
  488. package/src/react/components/ScrollArea.spec.tsx +20 -0
  489. package/src/react/components/ScrollArea.tsx +19 -0
  490. package/src/react/components/Section.spec.tsx +82 -1
  491. package/src/react/components/Section.tsx +10 -4
  492. package/src/react/components/Skeleton.tsx +50 -2
  493. package/src/react/components/StatStrip.tsx +1 -1
  494. package/src/react/components/StatTile.tsx +84 -11
  495. package/src/react/components/StatTileGrid.spec.tsx +6 -1
  496. package/src/react/components/StatTileGrid.tsx +25 -0
  497. package/src/react/components/StatusPill.tsx +26 -1
  498. package/src/react/components/Surface.tsx +22 -14
  499. package/src/react/components/SwatchPicker.tsx +4 -0
  500. package/src/react/components/Switch.tsx +1 -1
  501. package/src/react/components/TagsInput.spec.tsx +8 -0
  502. package/src/react/components/TagsInput.tsx +3 -1
  503. package/src/react/components/WidgetHeader.tsx +1 -1
  504. package/src/react/components/calendar/CalendarLegend.tsx +1 -1
  505. package/src/react/components/calendar/DayAgenda.tsx +1 -1
  506. package/src/react/components/calendar/EventChip.tsx +1 -1
  507. package/src/react/components/calendar/MonthGrid.tsx +1 -1
  508. package/src/react/components/calendar/WeekView.tsx +2 -2
  509. package/src/react/components/cardFrame.ts +28 -0
  510. package/src/react/components/dataDisplay.spec.tsx +176 -0
  511. package/src/react/components/dialog.tsx +4 -1
  512. package/src/react/components/entryChunks.graph.spec.ts +89 -0
  513. package/src/react/dashboard-grid/WidgetFrame.tsx +2 -2
  514. package/src/react/emoji/EmojiPicker.tsx +1 -1
  515. package/src/react/file-tree/FileTree.spec.tsx +49 -0
  516. package/src/react/file-tree/FileTree.tsx +37 -4
  517. package/src/react/filter-rail/FilterRail.tsx +1 -1
  518. package/src/react/folder-tree/FolderPicker.spec.tsx +8 -0
  519. package/src/react/folder-tree/FolderPicker.tsx +4 -1
  520. package/src/react/icons.spec.ts +21 -1
  521. package/src/react/icons.tsx +136 -2
  522. package/src/react/index.ts +38 -3
  523. package/src/react/lib/menuSections.ts +33 -0
  524. package/src/react/lib/whenIdle.ts +13 -0
  525. package/src/react/markdown/Markdown.tsx +2 -2
  526. package/src/react/media/DenseGalleryShell.tsx +20 -4
  527. package/src/react/media/HoverScrubVideoThumb.tsx +2 -2
  528. package/src/react/media/MaskPainter.tsx +1 -1
  529. package/src/react/media/MediaUploadControl.tsx +1 -1
  530. package/src/react/media/VideoTrimmer.tsx +1 -1
  531. package/src/react/media/denseGallery.css +96 -1
  532. package/src/react/media-gallery/MediaGallery.spec.tsx +26 -0
  533. package/src/react/media-gallery/MediaGallery.tsx +10 -3
  534. package/src/react/namespace/NamespaceTargetCapsule.tsx +1 -1
  535. package/src/react/nav/BreadcrumbTrail.tsx +2 -2
  536. package/src/react/nav/CommandBar.tsx +14 -3
  537. package/src/react/nav/PlaceBar.tsx +18 -8
  538. package/src/react/nav/SideNav.tsx +99 -17
  539. package/src/react/nav/TopBar.spec.tsx +78 -21
  540. package/src/react/nav/TopBar.tsx +270 -98
  541. package/src/react/nav/index.ts +8 -1
  542. package/src/react/nav/nav.spec.tsx +46 -2
  543. package/src/react/nav/navShared.tsx +23 -2
  544. package/src/react/notifications/NotificationFeed.tsx +2 -2
  545. package/src/react/palette/Command.tsx +1 -1
  546. package/src/react/palette/CommandPalette.spec.tsx +31 -0
  547. package/src/react/palette/CommandPalette.tsx +108 -11
  548. package/src/react/palette/commandSources.tsx +186 -0
  549. package/src/react/palette/index.ts +7 -0
  550. package/src/react/rich-text/RichTextEditor.tsx +1 -1
  551. package/src/react/rich-text/RichTextToolbar.tsx +1 -1
  552. package/src/styles-areas/analytics.css +16 -16
  553. package/src/styles-areas/auth.css +2 -2
  554. package/src/styles-areas/calendar.css +5 -6
  555. package/src/styles-areas/canvas-hud.css +30 -0
  556. package/src/styles-areas/chart-table.css +1 -1
  557. package/src/styles-areas/charts.css +3 -3
  558. package/src/styles-areas/chat.css +7 -6
  559. package/src/styles-areas/companion-link.css +2 -2
  560. package/src/styles-areas/core.css +99 -90
  561. package/src/styles-areas/dashboard-grid.css +4 -4
  562. package/src/styles-areas/data-table.css +16 -16
  563. package/src/styles-areas/disk-usage.css +5 -5
  564. package/src/styles-areas/emoji.css +2 -2
  565. package/src/styles-areas/fields.css +13 -14
  566. package/src/styles-areas/filter-rail.css +4 -4
  567. package/src/styles-areas/folder-tree.css +6 -6
  568. package/src/styles-areas/layout-engine.css +4 -4
  569. package/src/styles-areas/markdown.css +2 -1
  570. package/src/styles-areas/master-detail.css +3 -3
  571. package/src/styles-areas/media-gallery.css +7 -6
  572. package/src/styles-areas/media.css +12 -13
  573. package/src/styles-areas/nav.css +28 -14
  574. package/src/styles-areas/notifications.css +4 -4
  575. package/src/styles-areas/overlays.css +4 -4
  576. package/src/styles-areas/palette.css +5 -4
  577. package/src/styles-areas/rich-text.css +3 -3
  578. package/src/styles-areas/sharing.css +4 -3
  579. package/src/styles-areas/stats.css +9 -8
  580. package/src/styles-areas/test-report.css +4 -4
  581. package/src/styles-areas/wizard.css +6 -5
  582. package/src/styles-areas/workbench.css +10 -9
  583. package/src/styles-areas/workbook-viewer.css +2 -2
  584. package/src/styles-utilities.css +296 -190
  585. package/src/stylesAreas.spec.ts +17 -0
  586. package/src/testing/designAudit.ts +3 -0
  587. package/src/testing/designBaseline.ts +4 -0
  588. package/src/theme.css +103 -2
  589. package/src/themeDarkScopeAliases.spec.ts +65 -0
@@ -0,0 +1,176 @@
1
+ import { afterEach, beforeAll, describe, expect, spyOn, test } from 'bun:test';
2
+ import { act, cleanup, fireEvent, render, waitFor } from '@testing-library/react';
3
+ import { AsyncPanel } from './AsyncPanel.js';
4
+ import { DataTable, preloadDataTableParts } from './DataTable/DataTable.js';
5
+ import type { ColDef } from './DataTable/types.js';
6
+ import { EmptyState } from './EmptyState.js';
7
+ import { LogViewer } from './LogViewer.js';
8
+ import { STATUS_ATTENTION_TONE } from './StatusPill.js';
9
+ import { StatTile } from './StatTile.js';
10
+ import { StatTileGrid } from './StatTileGrid.js';
11
+
12
+ // Task 2464's unit half — what happy-dom can decide, through the components alone (the pure
13
+ // helpers are specced beside them: `DataTable/numericColumn.spec.ts`, `charts/chartBox.spec.ts`,
14
+ // `StatTileGrid.spec.tsx`, `AsyncPanel.spec.tsx`). Layout (fit at 2560, chart resize, the log's
15
+ // follow pause) is measured in `e2e/data-display.spec.ts`.
16
+
17
+ beforeAll(preloadDataTableParts);
18
+ afterEach(cleanup);
19
+
20
+ interface Row extends Record<string, unknown> {
21
+ step: string;
22
+ runs: number;
23
+ code: string;
24
+ }
25
+ const ROWS: Row[] = [
26
+ { step: 'gate', runs: 2472, code: '41' },
27
+ { step: 'prove-red', runs: 531, code: '7' },
28
+ ];
29
+ const COLUMNS: ColDef<Row>[] = [
30
+ { key: 'step', label: 'Step', type: 'text' },
31
+ { key: 'runs', label: 'Runs', type: 'number' },
32
+ ];
33
+
34
+ describe('DAT-1 · numeric columns', () => {
35
+ test('numeric header and cells stack digits; the warning fires once in dev', () => {
36
+ const warn = spyOn(console, 'warn').mockImplementation(() => undefined);
37
+ const { container } = render(
38
+ <DataTable<Row> columns={[...COLUMNS, { key: 'code', label: 'Code', type: 'text' }]} data={ROWS} hidePagination />,
39
+ );
40
+ const th = [...container.querySelectorAll('thead th')].find((n) => n.textContent?.includes('Runs'));
41
+ expect(th?.className).toContain('tabular-nums');
42
+ const cells = container.querySelectorAll('tbody tr:first-child td');
43
+ expect(cells[1]?.className).toContain('tabular-nums');
44
+ expect(cells[0]?.className).not.toContain('tabular-nums');
45
+ expect(warn.mock.calls.some(([m]) => String(m).includes('"code"'))).toBe(true);
46
+ warn.mockRestore();
47
+ });
48
+ });
49
+
50
+ describe('DAT-3 / DAT-5 · fit and the row action', () => {
51
+ test('`fit` marks the table and drops the full-width rule', () => {
52
+ const { container } = render(<DataTable<Row> columns={COLUMNS} data={ROWS} fit hidePagination />);
53
+ const table = container.querySelector('table');
54
+ expect(table?.getAttribute('data-cb-table-fit')).toBe('true');
55
+ expect(table?.className.split(' ')).not.toContain('w-full');
56
+ expect(table?.className).toContain('w-auto');
57
+ });
58
+
59
+ test('one inline action where the row returns one, none where it returns null', () => {
60
+ const { container } = render(
61
+ <DataTable<Row>
62
+ columns={COLUMNS}
63
+ data={ROWS}
64
+ hidePagination
65
+ rowAction={(r) => (r.runs > 1000 ? { label: 'Retry', onClick: () => undefined } : null)}
66
+ />,
67
+ );
68
+ const rows = container.querySelectorAll('tbody tr');
69
+ expect(rows[0]?.textContent).toContain('Retry');
70
+ expect(rows[1]?.textContent).not.toContain('Retry');
71
+ });
72
+
73
+ test('a right-click opens the row menu only where the row has one', () => {
74
+ const { container } = render(
75
+ <DataTable<Row> columns={COLUMNS} data={ROWS} hidePagination rowMenu={() => [{ key: 'o', label: 'Open', onClick: () => undefined }]} />,
76
+ );
77
+ const row = container.querySelector('tbody tr') as HTMLElement;
78
+ const event = new MouseEvent('contextmenu', { bubbles: true, cancelable: true });
79
+ act(() => {
80
+ row.dispatchEvent(event);
81
+ });
82
+ expect(event.defaultPrevented).toBe(true);
83
+ });
84
+ });
85
+
86
+ describe('STA-3 · filtered to nothing', () => {
87
+ test('EmptyState `onClearFilters` is the filtered variant with its own verb', () => {
88
+ let cleared = 0;
89
+ const { getByText, container } = render(<EmptyState onClearFilters={() => cleared++} />);
90
+ expect(getByText('No matches')).toBeDefined();
91
+ expect(container.querySelector('[data-cb-empty-state]')?.getAttribute('data-cb-empty-state')).toBe('filtered');
92
+ fireEvent.click(getByText('Clear filters'));
93
+ expect(cleared).toBe(1);
94
+ });
95
+
96
+ test('a DataTable searched to nothing offers Clear filters, which brings the rows back', async () => {
97
+ const { container, getByText } = render(<DataTable<Row> columns={COLUMNS} data={ROWS} hidePagination />);
98
+ const input = container.querySelector('input') as HTMLInputElement;
99
+ fireEvent.change(input, { target: { value: 'zzz-nothing' } });
100
+ await waitFor(() => expect(getByText('Clear filters')).toBeDefined());
101
+ fireEvent.click(getByText('Clear filters'));
102
+ await waitFor(() => expect(container.querySelectorAll('tbody tr').length).toBe(2));
103
+ });
104
+
105
+ test('an empty dataset is NOT the filtered variant', () => {
106
+ const { container } = render(<DataTable<Row> columns={COLUMNS} data={[]} hidePagination />);
107
+ expect(container.textContent).toContain('No results');
108
+ expect(container.textContent).not.toContain('Clear filters');
109
+ });
110
+ });
111
+
112
+ describe('DAT-8 / DAT-9 · StatTile', () => {
113
+ test('one value size per grid — the longest value sets it for every tile', () => {
114
+ const { container } = render(
115
+ <StatTileGrid>
116
+ <StatTile label='a' value='21' />
117
+ <StatTile label='b' value='61h 20m' />
118
+ <StatTile label='c' value='Executing now' />
119
+ </StatTileGrid>,
120
+ );
121
+ const sizes = [...container.querySelectorAll('[data-cb-stat-size]')].map((n) => n.getAttribute('data-cb-stat-size'));
122
+ expect(sizes).toEqual(['sm', 'sm', 'sm']);
123
+ });
124
+
125
+ test('a budget past its max reads as the real percentage, in the critical tone', () => {
126
+ const { container, getByText } = render(
127
+ <StatTile label='DO' value='1.11M' budget={{ used: 1.11, max: 1, verb: 'of the allowance', window: 'Oct' }} />,
128
+ );
129
+ expect(getByText('111% of the allowance')).toBeDefined();
130
+ expect(container.querySelector('[data-cb-stat-budget]')?.getAttribute('data-cb-stat-budget')).toBe('critical');
131
+ });
132
+ });
133
+
134
+ describe('STA-1 / STA-2 · AsyncPanel', () => {
135
+ test('first load is a skeleton of the content\'s shape', () => {
136
+ const { container } = render(
137
+ <AsyncPanel loading skeleton='tiles'>
138
+ <p>never</p>
139
+ </AsyncPanel>,
140
+ );
141
+ expect(container.querySelector('[data-cb-skeleton="tiles"]')).not.toBeNull();
142
+ });
143
+
144
+ test('a refetch keeps the data on screen and says it is updating', () => {
145
+ const { getByText, rerender, container } = render(
146
+ <AsyncPanel updatedAt={Date.now() - 12_000}>
147
+ <p>the goods</p>
148
+ </AsyncPanel>,
149
+ );
150
+ expect(container.querySelector('[data-cb-freshness]')?.getAttribute('data-cb-freshness')).toBe('fresh');
151
+ rerender(
152
+ <AsyncPanel loading updatedAt={Date.now() - 12_000}>
153
+ <p>the goods</p>
154
+ </AsyncPanel>,
155
+ );
156
+ expect(getByText('the goods')).toBeDefined();
157
+ expect(getByText('Updating…')).toBeDefined();
158
+ });
159
+ });
160
+
161
+ describe('DAT-4 / DAT-13 · status and the log', () => {
162
+ test('the operator vocabulary of station and roms is rationed, not neutral', () => {
163
+ expect(STATUS_ATTENTION_TONE.interrupted).toBe('error');
164
+ expect(STATUS_ATTENTION_TONE['not-answering']).toBe('error');
165
+ expect(STATUS_ATTENTION_TONE.stale).toBe('warning');
166
+ expect(STATUS_ATTENTION_TONE.transcoding).toBe('success');
167
+ });
168
+
169
+ test('a log with a stream draws the header strip and no empty toolbar row', () => {
170
+ const { container, getByText } = render(
171
+ <LogViewer text={'a\nb'} stream='Batch B1' age='3m' openFullLog={{ href: '#x' }} filterable={false} />,
172
+ );
173
+ expect(container.querySelector('[data-cb-log-header]')?.textContent).toContain('Batch B1');
174
+ expect(getByText(/Open full log/)).toBeDefined();
175
+ });
176
+ });
@@ -1,6 +1,7 @@
1
1
  import * as DialogPrimitive from '@radix-ui/react-dialog';
2
2
  import { type ComponentPropsWithoutRef, forwardRef, useEffect } from 'react';
3
3
  import { cn } from '../lib/cn.js';
4
+ import { CardFrameContext } from './cardFrame.js';
4
5
  import { useFloatingContainer } from '../lib/floatingContainer.js';
5
6
  import { noteDialogOpen } from '../lib/openDialogs.js';
6
7
 
@@ -115,7 +116,9 @@ export const DialogContent = forwardRef<HTMLDivElement, DialogContentProps>(
115
116
  {...props}
116
117
  >
117
118
  <CountsAsOpen />
118
- {children}
119
+ {/* A dialog floats: what it holds starts a fresh stack of container levels, even
120
+ when it was opened from inside a card (React context crosses the portal). */}
121
+ <CardFrameContext.Provider value={false}>{children}</CardFrameContext.Provider>
119
122
  </DialogPrimitive.Content>
120
123
  </DialogPortal>
121
124
  );
@@ -0,0 +1,89 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+ import { existsSync, readFileSync } from 'node:fs';
3
+ import { dirname, join, relative } from 'node:path';
4
+
5
+ /**
6
+ * What an app's entry chunk must NOT carry. Forge task 2533: AppShell keeps its ⌘K palette off
7
+ * it; task 2535: `Page`'s header keeps its ⓘ guide popover off it. Whatever a module reaches
8
+ * through STATIC imports lands in the chunk that imports it, so this walks AppShell's static
9
+ * graph (Bun's own scanner — type-only imports and `import()` excluded) and refuses the palette
10
+ * body and the packages only it needs. A dynamic `import()` is the split, and is not followed.
11
+ */
12
+ const SRC = join(import.meta.dir, '..', '..');
13
+ // One per loader: a `.ts` file's `<const T>` generic is not JSX, and a TSX parse refuses it.
14
+ const transpilers = { ts: new Bun.Transpiler({ loader: 'ts' }), tsx: new Bun.Transpiler({ loader: 'tsx' }) };
15
+
16
+ function resolveLocal(from: string, spec: string): string | null {
17
+ const base = join(dirname(from), spec.replace(/\.js$/, ''));
18
+ for (const candidate of [`${base}.ts`, `${base}.tsx`, join(base, 'index.ts'), join(base, 'index.tsx')]) {
19
+ if (existsSync(candidate)) return candidate;
20
+ }
21
+ return null;
22
+ }
23
+
24
+ function staticGraph(entry: string): { files: Set<string>; packages: Set<string> } {
25
+ const files = new Set<string>();
26
+ const packages = new Set<string>();
27
+ const queue = [entry];
28
+ while (queue.length > 0) {
29
+ const file = queue.pop() as string;
30
+ if (files.has(file)) continue;
31
+ files.add(file);
32
+ for (const { path, kind } of transpilers[file.endsWith('.tsx') ? 'tsx' : 'ts'].scanImports(readFileSync(file, 'utf8'))) {
33
+ if (kind !== 'import-statement') continue;
34
+ if (!path.startsWith('.')) {
35
+ packages.add(path);
36
+ continue;
37
+ }
38
+ const next = resolveLocal(file, path);
39
+ if (next) queue.push(next);
40
+ }
41
+ }
42
+ return { files, packages };
43
+ }
44
+
45
+ describe('AppShell static graph', () => {
46
+ const { files, packages } = staticGraph(join(SRC, 'react', 'components', 'AppShell.tsx'));
47
+ const local = [...files].map((f) => relative(SRC, f));
48
+
49
+ test('the walker sees the shell itself and what it draws on every page', () => {
50
+ expect(local).toContain('react/components/AppShell.tsx');
51
+ expect(local).toContain('react/palette/useCommandPalette.ts');
52
+ expect(local).toContain('react/nav/SideNav.tsx');
53
+ });
54
+
55
+ test('🔴 the command palette body is not in it — it is fetched on idle or first open', () => {
56
+ expect(local).not.toContain('react/palette/CommandPalette.tsx');
57
+ expect(local).not.toContain('react/palette/Command.tsx');
58
+ });
59
+
60
+ test('🔴 neither are the packages only the palette needs', () => {
61
+ // `cursedbelt-core/palette/hotkeys` stays: it is the ⌘K binding `useCommandPalette` registers.
62
+ const palettePackages = [...packages].filter(
63
+ (p) => p === 'cmdk' || p.startsWith('@leeoniya/ufuzzy') || p === 'cursedbelt-core/palette/fuzzy-rank',
64
+ );
65
+ expect(palettePackages).toEqual([]);
66
+ });
67
+ });
68
+
69
+ describe('Page static graph', () => {
70
+ const { files, packages } = staticGraph(join(SRC, 'react', 'components', 'Page.tsx'));
71
+ const local = [...files].map((f) => relative(SRC, f));
72
+
73
+ test('the walker sees the page and its guide trigger', () => {
74
+ expect(local).toContain('react/components/Page.tsx');
75
+ expect(local).toContain('react/components/PageGuideButton.tsx');
76
+ });
77
+
78
+ test('🔴 the guide popover is not in it — it is fetched on idle or on the first hover, focus or press', () => {
79
+ expect(local).not.toContain('react/components/PageGuidePopover.tsx');
80
+ expect(local).not.toContain('react/components/Popover.tsx');
81
+ });
82
+
83
+ test('🔴 neither is the positioning engine a closed popover does not need', () => {
84
+ const floating = [...packages].filter(
85
+ (p) => p.startsWith('@radix-ui/react-popover') || p.startsWith('@radix-ui/react-popper') || p.startsWith('@floating-ui/'),
86
+ );
87
+ expect(floating).toEqual([]);
88
+ });
89
+ });
@@ -84,9 +84,9 @@ export function WidgetFrame({
84
84
  </>
85
85
  }
86
86
  className={cn(
87
- 'dashboard-drag-handle h-auto min-h-[2.75rem] cursor-grab select-none active:cursor-grabbing',
87
+ 'dashboard-drag-handle h-auto min-h-11 cursor-grab select-none active:cursor-grabbing',
88
88
  onKeyDown !== undefined &&
89
- 'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-ring',
89
+ 'focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-ring',
90
90
  )}
91
91
  {...(onKeyDown !== undefined && {
92
92
  tabIndex: 0,
@@ -57,7 +57,7 @@ function EmojiMartPanel(props: Record<string, unknown>) {
57
57
  if (failed) throw failed;
58
58
  return (
59
59
  <>
60
- {!ready && <Skeleton className='h-[420px] w-[352px]' />}
60
+ {!ready && <Skeleton className='h-105 w-88' />}
61
61
  <div ref={host} />
62
62
  </>
63
63
  );
@@ -673,6 +673,55 @@ describe('where you are', () => {
673
673
  view.rerender(<FileTree nodes={TREE} selectedId='dinos' onSelect={() => undefined} />);
674
674
  expect(scrolled).toEqual([]);
675
675
  });
676
+
677
+ test('a changed revealKey reveals the SAME selection again; an unchanged one does not', () => {
678
+ const scrolled: string[] = [];
679
+ const props = { nodes: TREE, onSelect: () => undefined, selectedId: 'dinos' };
680
+ const view = render(<FileTree {...props} revealKey={0} />);
681
+ for (const row of screen.getAllByRole('treeitem') as HTMLElement[]) {
682
+ row.scrollIntoView = () => scrolled.push((row.textContent ?? '').trim());
683
+ row.getBoundingClientRect = () => ({ top: 900, bottom: 920 }) as DOMRect;
684
+ }
685
+ (view.container.querySelector('.cbft-scroll') as HTMLElement).getBoundingClientRect = () =>
686
+ ({ top: 0, bottom: 400 }) as DOMRect;
687
+ view.rerender(<FileTree {...props} revealKey={0} />);
688
+ expect(scrolled).toEqual([]);
689
+ view.rerender(<FileTree {...props} revealKey={1} />);
690
+ expect(scrolled).toEqual(['Dinos']);
691
+ });
692
+
693
+ test('🔴 under scroll="host" the HOST scroller is the frame, not the tree drawn at full height', () => {
694
+ // music's rail: the tree is laid out at its natural height inside the rail's scroller, so
695
+ // its own frame holds every row and measuring against it never scrolled a revealed row
696
+ // into view (owner, 2026-10-01: "the file tree does not open to it").
697
+ const scrolled: string[] = [];
698
+ const host = document.createElement('div');
699
+ host.style.overflowY = 'auto';
700
+ document.body.append(host);
701
+ host.getBoundingClientRect = () => ({ top: 0, bottom: 400 }) as DOMRect;
702
+ const props = { nodes: TREE, onSelect: () => undefined, scroll: 'host' as const };
703
+ const view = render(<FileTree {...props} selectedId={null} />, { container: host });
704
+ try {
705
+ // The tree's own box spans every row — exactly what made the old check a no-op.
706
+ (host.querySelector('.cbft-scroll') as HTMLElement).getBoundingClientRect = () =>
707
+ ({ top: 0, bottom: 2000 }) as DOMRect;
708
+ for (const row of screen.getAllByRole('treeitem') as HTMLElement[]) {
709
+ row.scrollIntoView = () => scrolled.push((row.textContent ?? '').trim());
710
+ row.getBoundingClientRect = () => ({ top: 900, bottom: 920 }) as DOMRect;
711
+ }
712
+ view.rerender(<FileTree {...props} selectedId='dinos' />);
713
+ expect(scrolled).toEqual(['Dinos']);
714
+
715
+ // …and a row the host already shows still does not jump.
716
+ for (const row of screen.getAllByRole('treeitem') as HTMLElement[])
717
+ row.getBoundingClientRect = () => ({ top: 10, bottom: 32 }) as DOMRect;
718
+ view.rerender(<FileTree {...props} selectedId='simpsons' />);
719
+ expect(scrolled).toEqual(['Dinos']);
720
+ } finally {
721
+ view.unmount();
722
+ host.remove();
723
+ }
724
+ });
676
725
  });
677
726
 
678
727
  /**
@@ -365,6 +365,13 @@ export interface FileTreeProps {
365
365
  * Wire it to whatever decides the fetch plan, never to the stored collapse.
366
366
  */
367
367
  onRevealExpand?: (ids: readonly string[]) => void;
368
+ /**
369
+ * Change it to reveal the selection AGAIN — VS Code's *Reveal in Explorer* on the file that
370
+ * is already selected. The reveal otherwise fires once per {@link selectedId}, so a "show me
371
+ * where it is" button pressed after the reader scrolled away or shut its folder did nothing.
372
+ * Any value; only a change counts. Omit it and nothing differs.
373
+ */
374
+ revealKey?: unknown;
368
375
 
369
376
  /**
370
377
  * The rows kept in a section of their own ABOVE the folders — *"pin open files where they
@@ -809,6 +816,7 @@ export function FileTree({
809
816
  onCollapsedChange,
810
817
  expandOnReveal = false,
811
818
  onRevealExpand,
819
+ revealKey,
812
820
  pinnedIds,
813
821
  onPinnedChange,
814
822
  pinnedLabel = 'Pinned',
@@ -1327,7 +1335,9 @@ export function FileTree({
1327
1335
  announceReveal.current = onRevealExpand;
1328
1336
  }, [revealShut, onRevealExpand]);
1329
1337
  /** The selection an expanding reveal has already fired for — see limit 1 below. */
1330
- const revealedFor = useRef<string | null>(null);
1338
+ const revealedFor = useRef<string | null | undefined>(null);
1339
+ /** The {@link FileTreeProps.revealKey} last honoured — a change re-arms `revealedFor`. */
1340
+ const revealedKey = useRef(revealKey);
1331
1341
 
1332
1342
  /**
1333
1343
  * Bring the selected row into view — the explorer's *reveal*.
@@ -1384,10 +1394,14 @@ export function FileTree({
1384
1394
  * expansion returns without scrolling and the re-render it causes is what lands the scroll.
1385
1395
  * What it must NOT be is the trigger for expanding again — that is `revealedFor`, below.
1386
1396
  */
1387
- // biome-ignore lint/correctness/useExhaustiveDependencies: `selectedId` is the trigger and not a read; `drag` is a guard and not a trigger; `revealOpened` is the second pass — see just above.
1397
+ // biome-ignore lint/correctness/useExhaustiveDependencies: `selectedId` and `revealKey` are the triggers; `drag` is a guard and not a trigger; `revealOpened` is the second pass — see just above.
1388
1398
  useEffect(() => {
1389
1399
  const scroller = scrollRef.current;
1390
1400
  if (!scroller || drag?.active) return;
1401
+ if (revealedKey.current !== revealKey) {
1402
+ revealedKey.current = revealKey;
1403
+ revealedFor.current = undefined;
1404
+ }
1391
1405
  /*
1392
1406
  * Once per selection, whatever it finds — the ref moves even when there is nothing shut to
1393
1407
  * open, so a later hand-shut of one of these folders cannot be undone by this effect.
@@ -1408,12 +1422,19 @@ export function FileTree({
1408
1422
  scroller.querySelector<HTMLElement>('.cbft-row[data-holds-open]');
1409
1423
  if (!row?.scrollIntoView) return;
1410
1424
  const box = row.getBoundingClientRect();
1411
- const frame = scroller.getBoundingClientRect();
1425
+ /*
1426
+ * 🔴 Under `scroll='host'` the tree's own frame is NOT what clips it: it is drawn at full
1427
+ * height, so every row is always "inside" it and this check returned before scrolling —
1428
+ * a reveal in music's rail opened the folders and lit the row eight hundred pixels below
1429
+ * the fold (owner, 2026-10-01: *"the file tree does not open to it"*). The frame that
1430
+ * decides "already visible" is the host's scroller.
1431
+ */
1432
+ const frame = (scroll === 'host' ? hostScroller(scroller) : scroller).getBoundingClientRect();
1412
1433
  if (box.top >= frame.top && box.bottom <= frame.bottom) return;
1413
1434
  // `nearest` on both axes: the least movement that makes the row visible, and no sideways
1414
1435
  // travel in a list that does not scroll sideways.
1415
1436
  row.scrollIntoView({ block: 'nearest', inline: 'nearest' });
1416
- }, [selectedId, revealOpened]);
1437
+ }, [selectedId, revealOpened, revealKey]);
1417
1438
 
1418
1439
  // ── The drag ──────────────────────────────────────────────────────────────────────────
1419
1440
 
@@ -3249,3 +3270,15 @@ function nameOf(nodes: readonly FileTreeNode[], id: string): string {
3249
3270
  }
3250
3271
  return '';
3251
3272
  }
3273
+
3274
+ /**
3275
+ * The element that actually clips a `scroll='host'` tree: its nearest ancestor that scrolls
3276
+ * vertically, or the document's scroller when nothing between here and the root does.
3277
+ */
3278
+ function hostScroller(from: HTMLElement): Element {
3279
+ for (let node = from.parentElement; node; node = node.parentElement) {
3280
+ const overflow = getComputedStyle(node).overflowY;
3281
+ if (overflow === 'auto' || overflow === 'scroll' || overflow === 'overlay') return node;
3282
+ }
3283
+ return document.scrollingElement ?? document.documentElement;
3284
+ }
@@ -443,7 +443,7 @@ function FilterRailRow({
443
443
  // Outlined rather than filled, so the row's own SELECTED paint stays readable
444
444
  // underneath it — a row can be both the current one and the drop target.
445
445
  item.dropActive &&
446
- 'outline outline-2 outline-dashed outline-offset-[-2px] outline-accent bg-accent/10',
446
+ 'outline outline-2 outline-dashed -outline-offset-2 outline-accent bg-accent/10',
447
447
  )}
448
448
  // A collapsed rail has no room to indent, and a 14rem-wide column has no room to
449
449
  // indent far — the step is deliberately small and it stops growing at depth 6, so a
@@ -18,6 +18,14 @@ function Harness({ initial = [] as string[] }: { initial?: string[] }) {
18
18
  }
19
19
 
20
20
  describe("FolderPicker", () => {
21
+ test("the trigger is a field at the locked control height, not a hand-padded box (FND-4)", () => {
22
+ const { container } = render(<Harness />);
23
+ const cls = (container.querySelector("button[aria-expanded]")?.getAttribute("class") ?? "").split(/\s+/);
24
+ expect(cls).toContain("h-[var(--control-h-md)]");
25
+ expect(cls).toContain("border-field-border");
26
+ expect(cls).not.toContain("py-1.5");
27
+ });
28
+
21
29
  test("every existing-folder option is labeled with its FULL breadcrumb path", () => {
22
30
  const { getByLabelText, queryByLabelText } = render(<Harness />);
23
31
  fireEvent.click(getByLabelText("Folder")); // open the panel
@@ -15,6 +15,7 @@
15
15
  import { useState } from "react";
16
16
  import { Button } from "../components/Button.js";
17
17
  import { Input } from "../components/Input.js";
18
+ import { fieldControlClass } from "../lib/field.js";
18
19
  import { FolderBreadcrumb } from "./FolderBreadcrumb.js";
19
20
  import { formatFolderPath, isValidFolderName, normalizeFolderName } from "cursedbelt-core/folder-tree/path";
20
21
  import { type FolderNode, flattenFolderTree } from "cursedbelt-core/folder-tree/tree";
@@ -102,7 +103,9 @@ export function FolderPicker({
102
103
  type="button"
103
104
  aria-label={ariaLabel}
104
105
  aria-expanded={open}
105
- className="flex items-center justify-between gap-2 rounded-md border border-[var(--border)] bg-[var(--background)] px-2.5 py-1.5 text-left text-sm"
106
+ // The shared field chrome at the locked control height, so the trigger lines up with
107
+ // an Input or TagsInput beside it (FND-4); it was hand-padded to 34px in its own colours.
108
+ className={`${fieldControlClass("md")} flex items-center justify-between gap-2 text-left`}
106
109
  onClick={() => (open ? close() : setOpen(true))}
107
110
  >
108
111
  <span className="min-w-0 truncate">{selectedLabel}</span>
@@ -3,10 +3,20 @@ import { render } from '@testing-library/react';
3
3
  import {
4
4
  createIconMapRegistry,
5
5
  DynamicIcon,
6
+ IconAdd,
7
+ IconArchive,
8
+ IconCopies,
9
+ IconFullscreen,
10
+ IconFullscreenExit,
11
+ IconGrid,
12
+ IconMore,
13
+ IconRefresh,
6
14
  IconRegistry,
15
+ IconScissors,
7
16
  IconSearch,
8
17
  IconSidebar,
9
18
  IconTable,
19
+ IconTrash,
10
20
  } from './icons.js';
11
21
 
12
22
  describe('createIconMapRegistry', () => {
@@ -72,11 +82,21 @@ describe('DynamicIcon with no iconMap', () => {
72
82
  describe('hand-drawn icons', () => {
73
83
  // Dependency-free SVG components (not routed through IconToken/lucide) shared by
74
84
  // hosts that don't carry lucide-react — collections and desk used to hand-roll
75
- // these three locally; see task 2382.
85
+ // these locally; see tasks 2382 and 2473.
76
86
  test.each([
77
87
  ['IconSidebar', IconSidebar],
78
88
  ['IconSearch', IconSearch],
79
89
  ['IconTable', IconTable],
90
+ ['IconAdd', IconAdd],
91
+ ['IconMore', IconMore],
92
+ ['IconFullscreen', IconFullscreen],
93
+ ['IconFullscreenExit', IconFullscreenExit],
94
+ ['IconRefresh', IconRefresh],
95
+ ['IconGrid', IconGrid],
96
+ ['IconTrash', IconTrash],
97
+ ['IconCopies', IconCopies],
98
+ ['IconArchive', IconArchive],
99
+ ['IconScissors', IconScissors],
80
100
  ] as const)('%s renders a sized svg with no lucide dependency', (_name, Icon) => {
81
101
  const { container } = render(Icon({ size: 24, className: 'test-class' }));
82
102
  const svg = container.querySelector('svg');