@workbench-kit/react 0.0.2-prototype.0.1.2 → 0.0.2-prototype.0.2.2

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 (534) hide show
  1. package/package.json +31 -23
  2. package/src/brand/TilepaperAppIcon.tsx +181 -0
  3. package/src/brand/index.ts +2 -0
  4. package/src/brand/tilepaper-app-icon-geometry.ts +201 -0
  5. package/src/icons/WorkbenchIcon.tsx +57 -0
  6. package/src/icons/WorkbenchIconContext.tsx +25 -0
  7. package/src/icons/file-icon.ts +154 -0
  8. package/src/icons/index.ts +17 -0
  9. package/src/icons/resolveWorkbenchIcon.ts +48 -0
  10. package/src/icons/types.ts +28 -0
  11. package/src/index.ts +261 -71
  12. package/src/jdw/JdwPreview.tsx +165 -8
  13. package/src/jdw/JdwPreviewViewport.tsx +190 -0
  14. package/src/jdw/JsonCodeEditorPane.tsx +165 -15
  15. package/src/jdw/builtins/renderBuiltinWidgetLeaf.tsx +101 -0
  16. package/src/jdw/createBuiltinJdwRegistry.ts +330 -5
  17. package/src/jdw/cssRenderBackend.tsx +96 -7
  18. package/src/jdw/document.ts +0 -3
  19. package/src/jdw/fixtures/jdw-sample-screens.ts +10 -8
  20. package/src/jdw/index.ts +9 -4
  21. package/src/jdw/jdw-preview-viewport.css +41 -0
  22. package/src/jdw/renderJdw.tsx +49 -8
  23. package/src/json-config/JsonConfigWorkbench.tsx +11 -14
  24. package/src/layout/ViewEmptyState.tsx +14 -0
  25. package/src/layout/WorkbenchCanvas.tsx +113 -6
  26. package/src/layout/WorkbenchLayout.tsx +3 -0
  27. package/src/layout/WorkbenchLayoutBase.tsx +43 -2
  28. package/src/layout/WorkbenchMediaPreviewViewport.tsx +122 -0
  29. package/src/layout/WorkbenchPropertyOverrideLabel.tsx +90 -0
  30. package/src/layout/WorkbenchPropertyPanel.tsx +153 -17
  31. package/src/layout/WorkbenchPropertySearch.tsx +51 -0
  32. package/src/layout/WorkbenchTree.tsx +9 -10
  33. package/src/layout/canvas/canvas-drag-ghost.css +21 -0
  34. package/src/layout/canvas/canvas-drag-preview-frame.css +15 -0
  35. package/src/layout/canvas/canvas-drop-indicator.css +16 -0
  36. package/src/layout/canvas/canvas-frame-handle.css +37 -0
  37. package/src/layout/canvas/canvas-frame-surface.css +24 -0
  38. package/src/layout/canvas/canvas-guide-block.css +17 -0
  39. package/src/layout/canvas/canvas-guide-layer.css +6 -0
  40. package/src/layout/canvas/canvas-guide-line.css +22 -0
  41. package/src/layout/canvas/canvas-item-badge.css +23 -0
  42. package/src/layout/canvas/canvas-item-frame.css +54 -0
  43. package/src/layout/canvas/canvas-pane-surface.css +9 -0
  44. package/src/layout/canvas/canvas-placeholder.css +21 -0
  45. package/src/layout/canvas/canvas-resize-frame.css +9 -0
  46. package/src/layout/canvas/canvas-resize-handle.css +74 -0
  47. package/src/layout/canvas/canvas-resize-preview.css +11 -0
  48. package/src/layout/canvas/canvas-selection-marquee.css +14 -0
  49. package/src/layout/canvas/canvas-viewport.css +18 -0
  50. package/src/layout/canvas/index.css +19 -0
  51. package/src/layout/canvas/preview-canvas.css +144 -0
  52. package/src/layout/editor/editor-body.css +9 -0
  53. package/src/layout/editor/editor-bottom-panel.css +44 -0
  54. package/src/layout/editor/editor-frame.css +14 -0
  55. package/src/layout/editor/editor-viewport.css +7 -0
  56. package/src/layout/editor/floating-menu.css +91 -0
  57. package/src/layout/editor/index.css +10 -0
  58. package/src/layout/editor/parse-error.css +9 -0
  59. package/src/layout/editor/problem-item.css +52 -0
  60. package/src/layout/editor/problem-list.css +7 -0
  61. package/src/layout/editor/render-surface.css +13 -0
  62. package/src/layout/fillScrollContract.ts +49 -0
  63. package/src/layout/fullscreen/fullscreen-backdrop.css +31 -0
  64. package/src/layout/fullscreen/fullscreen-button.css +44 -0
  65. package/src/layout/fullscreen/fullscreen-carousel.css +20 -0
  66. package/src/layout/fullscreen/fullscreen-content.css +8 -0
  67. package/src/layout/fullscreen/fullscreen-empty.css +16 -0
  68. package/src/layout/fullscreen/fullscreen-header.css +77 -0
  69. package/src/layout/fullscreen/fullscreen-hero.css +41 -0
  70. package/src/layout/fullscreen/fullscreen-nav-button.css +29 -0
  71. package/src/layout/fullscreen/fullscreen-option.css +83 -0
  72. package/src/layout/fullscreen/fullscreen-pill-row.css +6 -0
  73. package/src/layout/fullscreen/fullscreen-pill.css +10 -0
  74. package/src/layout/fullscreen/fullscreen-root.css +11 -0
  75. package/src/layout/fullscreen/index.css +13 -0
  76. package/src/layout/index.ts +156 -0
  77. package/src/layout/layout-base/banner.css +32 -0
  78. package/src/layout/layout-base/center.css +7 -0
  79. package/src/layout/layout-base/column.css +7 -0
  80. package/src/layout/layout-base/divider.css +5 -0
  81. package/src/layout/layout-base/empty.css +12 -0
  82. package/src/layout/layout-base/fill-scroll.css +36 -0
  83. package/src/layout/layout-base/fill.css +18 -0
  84. package/src/layout/layout-base/index.css +13 -0
  85. package/src/layout/layout-base/pane.css +6 -0
  86. package/src/layout/layout-base/panel-scroll.css +5 -0
  87. package/src/layout/layout-base/panel-surface.css +14 -0
  88. package/src/layout/layout-base/root.css +9 -0
  89. package/src/layout/layout-base/section-title.css +8 -0
  90. package/src/layout/layout.css +10 -0
  91. package/src/layout/layoutHelpers.ts +4 -2
  92. package/src/layout/media/index.css +2 -0
  93. package/src/layout/media/media-preview-viewport.css +69 -0
  94. package/src/layout/{Panel.tsx → panel/Panel.tsx} +29 -40
  95. package/src/layout/panel/TemplateGallery.tsx +90 -0
  96. package/src/layout/panel/WorkbenchAuthoringShell.tsx +57 -0
  97. package/src/layout/panel/WorkbenchLabeledPane.tsx +81 -0
  98. package/src/layout/panel/WorkbenchSidebarStack.tsx +15 -0
  99. package/src/layout/panel/filter-bar.css +59 -0
  100. package/src/layout/panel/index.css +7 -0
  101. package/src/layout/panel/index.ts +70 -0
  102. package/src/layout/panel/preview-pane.css +63 -0
  103. package/src/layout/panel/template-gallery.css +131 -0
  104. package/src/layout/panel/workbench-authoring-shell.css +48 -0
  105. package/src/layout/panel/workbench-labeled-pane.css +69 -0
  106. package/src/layout/panel/workbench-sidebar-stack.css +18 -0
  107. package/src/layout/property/color-input.css +8 -0
  108. package/src/layout/property/color-row.css +6 -0
  109. package/src/layout/property/index.css +15 -0
  110. package/src/layout/property/property-card.css +8 -0
  111. package/src/layout/property/property-grid.css +24 -0
  112. package/src/layout/property/property-hint.css +4 -0
  113. package/src/layout/property/property-inline.css +10 -0
  114. package/src/layout/property/property-key-value.css +29 -0
  115. package/src/layout/property/property-override-label.css +34 -0
  116. package/src/layout/property/property-panel.css +20 -0
  117. package/src/layout/property/property-row.css +17 -0
  118. package/src/layout/property/property-search.css +43 -0
  119. package/src/layout/property/property-section.css +97 -0
  120. package/src/layout/property/property-stack.css +11 -0
  121. package/src/layout/property/property-toggle.css +14 -0
  122. package/src/layout/propertyFieldFilter.ts +84 -0
  123. package/src/layout/sidebar/SideBarViewFrame.tsx +235 -0
  124. package/src/layout/sidebar/SideBarViewTabStrip.tsx +60 -0
  125. package/src/layout/sidebar/SideBarViewTitleMenu.tsx +75 -0
  126. package/src/layout/sidebar/SidebarActionIconBar.tsx +242 -0
  127. package/src/layout/sidebar/SidebarSectionNestingContext.tsx +21 -0
  128. package/src/layout/sidebar/SidebarSlotChrome.tsx +32 -0
  129. package/src/layout/sidebar/SidebarToolbar.tsx +10 -0
  130. package/src/layout/sidebar/WorkbenchActionSidebar.tsx +73 -0
  131. package/src/layout/{WorkbenchSidebarActions.tsx → sidebar/WorkbenchSidebarActions.tsx} +105 -51
  132. package/src/layout/sidebar/WorkbenchSidebarSectionStack.tsx +165 -0
  133. package/src/layout/sidebar/index.css +5 -0
  134. package/src/layout/sidebar/index.ts +55 -0
  135. package/src/layout/sidebar/sidebar-chrome.css +95 -0
  136. package/src/layout/sidebar/sidebar-section-stack.css +25 -0
  137. package/src/layout/sidebar/sidebar-section.css +124 -0
  138. package/src/layout/sidebar/sidebar-view.css +290 -0
  139. package/src/layout/tree/drag-preview.css +25 -0
  140. package/src/layout/tree/index.css +10 -0
  141. package/src/layout/tree/template-glyph.css +96 -0
  142. package/src/layout/tree/tree-action.css +20 -0
  143. package/src/layout/tree/tree-drag-overlay.css +13 -0
  144. package/src/layout/tree/tree-drop-line.css +17 -0
  145. package/src/layout/tree/tree-drop-zone.css +13 -0
  146. package/src/layout/tree/tree-expander.css +23 -0
  147. package/src/layout/tree/tree-item.css +93 -0
  148. package/src/layout/tree/tree.css +49 -0
  149. package/src/layout/usePreviewViewport.ts +428 -0
  150. package/src/modal/ConfirmDialog.tsx +1 -1
  151. package/src/modal/Modal.tsx +148 -305
  152. package/src/modal/ModalResizeHandles.tsx +40 -0
  153. package/src/modal/ModalTitlebar.tsx +86 -0
  154. package/src/modal/modal.css +291 -0
  155. package/src/modal/modalContainer.ts +36 -0
  156. package/src/modal/modalPosition.ts +36 -0
  157. package/src/modal/modalSize.ts +84 -0
  158. package/src/modal/modalTypes.ts +13 -0
  159. package/src/modal/useModalContainerViewport.ts +41 -0
  160. package/src/modal/useModalDrag.ts +118 -0
  161. package/src/modal/useModalResize.ts +122 -0
  162. package/src/modal/useModalWindowFrame.ts +122 -0
  163. package/src/overlay/ContextMenu.tsx +28 -50
  164. package/src/overlay/clampFixedOverlayPosition.ts +22 -0
  165. package/src/overlay/context-menu.css +127 -0
  166. package/src/overlay/index.ts +31 -0
  167. package/src/overlay/measureAnchoredOverlayPanel.ts +107 -0
  168. package/src/overlay/overlay.css +2 -0
  169. package/src/overlay/pointerPassthroughRegion.ts +83 -0
  170. package/src/overlay/useAnchoredOverlayPanel.ts +222 -0
  171. package/src/overlay/useClampedFixedOverlayPosition.ts +27 -0
  172. package/src/overlay/useContextMenuState.ts +59 -0
  173. package/src/overlay/useFixedOverlayDismiss.ts +49 -0
  174. package/src/overlay/usePointerPassthroughRegion.ts +85 -0
  175. package/src/primitives/{AbsoluteBox.tsx → absolute-box/AbsoluteBox.tsx} +1 -1
  176. package/src/primitives/absolute-box/index.ts +1 -0
  177. package/src/primitives/{Badge.tsx → badge/Badge.tsx} +4 -2
  178. package/src/primitives/badge/badge.css +20 -0
  179. package/src/primitives/badge/index.ts +1 -0
  180. package/src/primitives/{Button.tsx → button/Button.tsx} +3 -2
  181. package/src/primitives/button/button.css +76 -0
  182. package/src/primitives/button/index.ts +1 -0
  183. package/src/primitives/catalog-browse-card/CatalogBrowseCard.tsx +121 -0
  184. package/src/primitives/catalog-browse-card/catalog-browse-card.css +175 -0
  185. package/src/primitives/catalog-browse-card/index.ts +1 -0
  186. package/src/primitives/catalog-browse-pane/CatalogBrowseFacetChips.tsx +59 -0
  187. package/src/primitives/catalog-browse-pane/CatalogBrowsePane.tsx +360 -0
  188. package/src/primitives/catalog-browse-pane/catalog-browse-facet-chips.css +8 -0
  189. package/src/primitives/catalog-browse-pane/catalog-browse-pane.css +84 -0
  190. package/src/primitives/catalog-browse-pane/filterCatalogBrowseItems.ts +27 -0
  191. package/src/primitives/catalog-browse-pane/index.ts +3 -0
  192. package/src/primitives/catalog-filter-overlay/CatalogFilterOverlay.tsx +73 -0
  193. package/src/primitives/catalog-filter-overlay/catalog-filter-overlay.css +65 -0
  194. package/src/primitives/catalog-filter-overlay/index.ts +1 -0
  195. package/src/primitives/checkbox/Checkbox.tsx +40 -0
  196. package/src/primitives/checkbox/checkbox.css +81 -0
  197. package/src/primitives/checkbox/index.ts +1 -0
  198. package/src/primitives/chip/Chip.tsx +43 -0
  199. package/src/primitives/chip/chip.css +110 -0
  200. package/src/primitives/chip/index.ts +2 -0
  201. package/src/primitives/clearable-text-input/ClearableTextInput.tsx +78 -0
  202. package/src/primitives/clearable-text-input/clearable-text-input.css +15 -0
  203. package/src/primitives/clearable-text-input/index.ts +1 -0
  204. package/src/primitives/codicon/Codicon.tsx +20 -0
  205. package/src/primitives/codicon/index.ts +1 -0
  206. package/src/primitives/{EmptyState.tsx → empty-state/EmptyState.tsx} +9 -3
  207. package/src/primitives/empty-state/empty-state.css +20 -0
  208. package/src/primitives/empty-state/index.ts +1 -0
  209. package/src/primitives/external-link-button/ExternalLinkButton.tsx +56 -0
  210. package/src/primitives/external-link-button/index.ts +1 -0
  211. package/src/primitives/{Field.tsx → field/Field.tsx} +2 -1
  212. package/src/primitives/field/field.css +51 -0
  213. package/src/primitives/field/index.ts +1 -0
  214. package/src/primitives/file-icon/FileIcon.tsx +21 -0
  215. package/src/primitives/file-icon/index.ts +1 -0
  216. package/src/primitives/{IconButton.tsx → icon-button/IconButton.tsx} +6 -4
  217. package/src/primitives/icon-button/icon-button.css +46 -0
  218. package/src/primitives/icon-button/index.ts +1 -0
  219. package/src/primitives/index.ts +210 -50
  220. package/src/primitives/library-detail-layout/LibraryDetailLayout.tsx +135 -0
  221. package/src/primitives/library-detail-layout/index.ts +1 -0
  222. package/src/primitives/library-detail-layout/library-detail-layout.css +169 -0
  223. package/src/primitives/library-facet-filter-panel/LibraryFacetFilterPanel.tsx +454 -0
  224. package/src/primitives/library-facet-filter-panel/index.ts +1 -0
  225. package/src/primitives/library-facet-filter-panel/library-facet-filter-panel.css +205 -0
  226. package/src/primitives/library-facet-filter-strip/LibraryFacetFilterStrip.tsx +527 -0
  227. package/src/primitives/library-facet-filter-strip/index.ts +1 -0
  228. package/src/primitives/library-facet-filter-strip/library-facet-filter-strip.css +31 -0
  229. package/src/primitives/{List.tsx → list/List.tsx} +15 -6
  230. package/src/primitives/list/index.ts +1 -0
  231. package/src/primitives/list/list-empty-state.css +10 -0
  232. package/src/primitives/list/list-item.css +93 -0
  233. package/src/primitives/list/list.css +6 -0
  234. package/src/primitives/number-input/NumberInput.tsx +235 -0
  235. package/src/primitives/number-input/index.ts +1 -0
  236. package/src/primitives/number-input/number-input.css +105 -0
  237. package/src/primitives/panel-loading/PanelLoading.tsx +29 -0
  238. package/src/primitives/panel-loading/index.ts +1 -0
  239. package/src/primitives/panel-loading/panel-loading.css +16 -0
  240. package/src/primitives/panel-surface/panel-surface.css +77 -0
  241. package/src/primitives/primitives.css +36 -0
  242. package/src/primitives/record-media-hero/RecordMediaHero.tsx +81 -0
  243. package/src/primitives/record-media-hero/index.ts +1 -0
  244. package/src/primitives/record-media-hero/record-media-hero.css +84 -0
  245. package/src/primitives/scroll-area/ScrollArea.tsx +200 -0
  246. package/src/primitives/scroll-area/index.ts +1 -0
  247. package/src/primitives/scroll-area/scroll-area-overlay.css +69 -0
  248. package/src/primitives/scroll-area-infinite-load/ScrollAreaInfiniteSentinel.tsx +22 -0
  249. package/src/primitives/scroll-area-infinite-load/index.ts +2 -0
  250. package/src/primitives/scroll-area-infinite-load/scroll-area-infinite-sentinel.css +6 -0
  251. package/src/primitives/scroll-area-infinite-load/useScrollAreaInfiniteLoad.ts +84 -0
  252. package/src/primitives/searchable-multi-select/SearchableMultiSelect.tsx +378 -0
  253. package/src/primitives/searchable-multi-select/index.ts +9 -0
  254. package/src/primitives/searchable-multi-select/overlay.ts +125 -0
  255. package/src/primitives/searchable-multi-select/searchable-multi-select.css +129 -0
  256. package/src/primitives/select/Select.tsx +21 -3
  257. package/src/primitives/select/overlay.ts +23 -4
  258. package/src/primitives/select/select.app.css +5 -2
  259. package/src/primitives/select/select.css +49 -12
  260. package/src/primitives/styles.css +3 -952
  261. package/src/primitives/tabbed-panels/TabbedPanels.tsx +68 -0
  262. package/src/primitives/tabbed-panels/index.ts +2 -0
  263. package/src/primitives/tabbed-panels/tabbed-panels.css +58 -0
  264. package/src/primitives/{TextArea.tsx → text-area/TextArea.tsx} +2 -1
  265. package/src/primitives/text-area/index.ts +1 -0
  266. package/src/primitives/{TextInput.tsx → text-input/TextInput.tsx} +2 -1
  267. package/src/primitives/text-input/index.ts +1 -0
  268. package/src/primitives/text-input/input.css +54 -0
  269. package/src/primitives/{Toolbar.tsx → toolbar/Toolbar.tsx} +1 -1
  270. package/src/primitives/toolbar/index.ts +1 -0
  271. package/src/primitives/visually-hidden/visually-hidden.css +11 -0
  272. package/src/primitives/{WorkbenchEditor.tsx → workbench-editor/WorkbenchEditor.tsx} +81 -43
  273. package/src/primitives/workbench-editor/button-group.css +10 -0
  274. package/src/primitives/workbench-editor/editor-tabs.css +201 -0
  275. package/src/primitives/workbench-editor/index.ts +1 -0
  276. package/src/primitives/workbench-editor/resizable-panels.css +53 -0
  277. package/src/primitives/workbench-editor/segmented-control.css +98 -0
  278. package/src/primitives/workbench-media-slot/WorkbenchMediaPlaceholder.tsx +25 -0
  279. package/src/primitives/workbench-media-slot/WorkbenchMediaSlot.tsx +60 -0
  280. package/src/primitives/workbench-media-slot/index.ts +2 -0
  281. package/src/primitives/workbench-media-slot/media-slot.css +72 -0
  282. package/src/primitives/workbench-thumbnail/WorkbenchThumbnail.tsx +38 -0
  283. package/src/primitives/workbench-thumbnail/index.ts +1 -0
  284. package/src/primitives/workbench-thumbnail/thumbnail.css +69 -0
  285. package/src/scrollbars.css +77 -2
  286. package/src/styles.css +14 -7735
  287. package/src/test-utils/workbenchMonacoMock.tsx +37 -0
  288. package/src/utils/dragMime.ts +89 -0
  289. package/src/utils/useWorkbenchMediaImage.ts +37 -0
  290. package/src/widget-asset/WidgetAssetEditor.tsx +9 -7
  291. package/src/widget-asset/WidgetAssetModeControls.tsx +1 -1
  292. package/src/widget-asset/WidgetAssetWorkbench.tsx +5 -6
  293. package/src/widget-studio/create-widget-studio-workspace-editor.tsx +1 -2
  294. package/src/widget-studio/index.ts +4 -1
  295. package/src/widget-studio/resolve-widget-studio-asset-catalog.ts +27 -10
  296. package/src/widget-tree/WidgetAssetPalette.tsx +35 -7
  297. package/src/widget-tree/WidgetInspectorPanel.tsx +53 -3
  298. package/src/widget-tree/WidgetSourceEditor.tsx +90 -3
  299. package/src/widget-tree/WidgetTreeCanvasPreview.tsx +875 -0
  300. package/src/widget-tree/WidgetTreeLab.tsx +411 -83
  301. package/src/widget-tree/WidgetTreeModeControls.tsx +30 -1
  302. package/src/widget-tree/WidgetTreeSidePanel.tsx +24 -34
  303. package/src/widget-tree/WidgetTreeView.tsx +711 -11
  304. package/src/widget-tree/WidgetTreeWorkbench.tsx +59 -15
  305. package/src/widget-tree/WidgetTreeWorkspaceShell.tsx +26 -8
  306. package/src/widget-tree/index.ts +22 -4
  307. package/src/widget-tree/widget-placement-asset-dnd.ts +35 -0
  308. package/src/widget-tree/widget-tree-document.ts +3 -9
  309. package/src/widget-tree/widget-tree-editor-state.ts +40 -0
  310. package/src/widget-tree/widget-tree-layout.ts +48 -3
  311. package/src/widget-tree/widget-tree-play-helpers.ts +69 -58
  312. package/src/workbench/ActivityBar.tsx +128 -21
  313. package/src/workbench/ArtifactShell.tsx +8 -8
  314. package/src/workbench/CommandGroupShell.tsx +131 -0
  315. package/src/workbench/CommandList.tsx +167 -0
  316. package/src/workbench/CommandPalette.tsx +194 -596
  317. package/src/workbench/ConfirmationFlow.tsx +3 -5
  318. package/src/workbench/MarkdownPreview.tsx +8 -12
  319. package/src/workbench/ShortcutCommandBridge.tsx +1 -4
  320. package/src/workbench/SplitView.tsx +385 -36
  321. package/src/workbench/StatusBar.tsx +4 -2
  322. package/src/workbench/StructuredArtifactEditor.tsx +3 -3
  323. package/src/workbench/Timeline.tsx +2 -7
  324. package/src/workbench/WorkbenchCanvasShell.defaults.ts +106 -0
  325. package/src/workbench/WorkbenchCanvasShell.model.ts +46 -0
  326. package/src/workbench/WorkbenchCanvasShell.tsx +32 -146
  327. package/src/workbench/WorkbenchDesktopTitleBar.tsx +126 -0
  328. package/src/workbench/WorkbenchEditorTabs.tsx +52 -0
  329. package/src/workbench/WorkbenchModalPortal.tsx +52 -0
  330. package/src/workbench/WorkbenchPlatformContext.tsx +31 -0
  331. package/src/workbench/WorkbenchShell.tsx +144 -26
  332. package/src/workbench/WorkbenchShellTitleBarLayoutControls.tsx +80 -0
  333. package/src/workbench/WorkbenchStandaloneShell.tsx +327 -41
  334. package/src/workbench/WorkbenchThemeProvider.tsx +142 -0
  335. package/src/workbench/WorkbenchViewEditor.tsx +75 -0
  336. package/src/workbench/WorkbenchViewSidebar.tsx +85 -0
  337. package/src/workbench/WorkbenchWindowChromeControls.tsx +290 -0
  338. package/src/workbench/activityBarOrder.ts +98 -0
  339. package/src/workbench/appearanceLabels.ts +28 -0
  340. package/src/workbench/auth/WorkbenchLoginView.tsx +4 -6
  341. package/src/workbench/auth/auth-flows.css +440 -0
  342. package/src/workbench/auth/auth.css +3 -0
  343. package/src/workbench/auth/profile-modals.css +115 -0
  344. package/src/workbench/bootstrap/WorkbenchBootstrapGate.tsx +45 -0
  345. package/src/workbench/bootstrap/WorkbenchBootstrapView.tsx +100 -0
  346. package/src/workbench/bootstrap/index.ts +12 -0
  347. package/src/workbench/bootstrap/useWorkbenchBootstrap.ts +130 -0
  348. package/src/workbench/chat/ChatCommandProposalCard.tsx +115 -0
  349. package/src/workbench/chat/ChatComposer.tsx +32 -34
  350. package/src/workbench/chat/ChatConversationBar.tsx +134 -0
  351. package/src/workbench/chat/ChatHistoryMenu.tsx +171 -0
  352. package/src/workbench/chat/ChatHistoryMenuRow.tsx +74 -0
  353. package/src/workbench/chat/ChatMessageCollapsible.tsx +115 -0
  354. package/src/workbench/chat/ChatMessageItem.tsx +293 -19
  355. package/src/workbench/chat/ChatMessageList.tsx +109 -24
  356. package/src/workbench/chat/ChatPanel.tsx +132 -19
  357. package/src/workbench/chat/ChatPhasedRunProgress.tsx +202 -0
  358. package/src/workbench/chat/ChatRenameDialog.tsx +77 -0
  359. package/src/workbench/chat/chat-conversation.css +273 -0
  360. package/src/workbench/chat/chat-ui.css +1124 -0
  361. package/src/workbench/chat/chat.css +3 -0
  362. package/src/workbench/chat/chatConversation.ts +46 -0
  363. package/src/workbench/chat/chatHistoryRowMenuItems.ts +29 -0
  364. package/src/workbench/chat/chatMessageMeta.tsx +252 -0
  365. package/src/workbench/chat/chatScroll.ts +22 -0
  366. package/src/workbench/chat/index.ts +47 -1
  367. package/src/workbench/chat/slashCommand.ts +5 -7
  368. package/src/workbench/chat/types.ts +35 -0
  369. package/src/workbench/chat/useCancelRuntimeOnUnmount.ts +60 -0
  370. package/src/workbench/chat/useChatPrependPagination.ts +233 -0
  371. package/src/workbench/chat/useChatRuntimeState.ts +3 -15
  372. package/src/workbench/chat/useSlashCommandSuggest.ts +76 -23
  373. package/src/workbench/chrome/index.css +6 -0
  374. package/src/workbench/chrome/workbench-desktop-titlebar.css +60 -0
  375. package/src/workbench/chrome/workbench-host.css +85 -0
  376. package/src/workbench/chrome/workbench-layout-regions.css +42 -0
  377. package/src/workbench/chrome/workbench-platform-chrome.css +142 -0
  378. package/src/workbench/chrome/workbench-shell-titlebar.css +124 -0
  379. package/src/workbench/command-execution-policy.ts +61 -0
  380. package/src/workbench/command-model.ts +275 -0
  381. package/src/workbench/command-palette/command-palette.css +156 -0
  382. package/src/workbench/commands.ts +62 -6
  383. package/src/workbench/editor-tabs/index.ts +22 -0
  384. package/src/workbench/editor-tabs-dnd.ts +162 -0
  385. package/src/workbench/editorTabContextMenu.ts +111 -0
  386. package/src/workbench/hardReset.ts +64 -0
  387. package/src/workbench/index.ts +234 -2
  388. package/src/workbench/jdw/jdw-editors.css +4 -0
  389. package/src/workbench/jdw/jdw.css +2 -0
  390. package/src/workbench/management/AccountManagementPanel.tsx +82 -0
  391. package/src/workbench/management/CommandInspectorPanel.tsx +127 -0
  392. package/src/workbench/management/CommandManagementPanel.tsx +129 -0
  393. package/src/workbench/management/CommandManagementSidebar.tsx +318 -0
  394. package/src/workbench/management/ExtensionManagementPanel.tsx +498 -0
  395. package/src/workbench/management/ExtensionManagementSidebar.tsx +492 -0
  396. package/src/workbench/management/IntegrationCommandActions.tsx +78 -0
  397. package/src/workbench/management/IntegrationSettingsSurface.tsx +290 -0
  398. package/src/workbench/management/IntegrationsShell.tsx +53 -0
  399. package/src/workbench/management/KeybindingCaptureField.tsx +142 -0
  400. package/src/workbench/management/KeybindingManagementPanel.tsx +120 -0
  401. package/src/workbench/management/LibraryCatalogPickerDialog.tsx +208 -0
  402. package/src/workbench/management/LibraryFacetFilterDialog.tsx +62 -0
  403. package/src/workbench/management/ManagementCard.tsx +89 -0
  404. package/src/workbench/management/ManagementFilterChips.tsx +41 -0
  405. package/src/workbench/management/ManagementGroup.tsx +56 -0
  406. package/src/workbench/management/ManagementPanelControls.tsx +43 -0
  407. package/src/workbench/management/ManagementPanelFrame.tsx +109 -0
  408. package/src/workbench/management/WorkbenchDialogFrame.tsx +148 -0
  409. package/src/workbench/management/WorkbenchNotice.tsx +211 -0
  410. package/src/workbench/management/build-command-management-groups.ts +157 -0
  411. package/src/workbench/management/command-inspector-uri.ts +26 -0
  412. package/src/workbench/management/extension-category-display.ts +42 -0
  413. package/src/workbench/management/format-command-run-state.ts +19 -0
  414. package/src/workbench/management/index.ts +130 -0
  415. package/src/workbench/management/integration-command-action.ts +25 -0
  416. package/src/workbench/management/library-catalog-picker-dialog.css +56 -0
  417. package/src/workbench/management/library-facet-filter-dialog.css +8 -0
  418. package/src/workbench/management/management-panel.css +444 -0
  419. package/src/workbench/management/management.css +4 -0
  420. package/src/workbench/management/types.ts +126 -0
  421. package/src/workbench/markdownRemarkPlugins.ts +4 -0
  422. package/src/workbench/schema/index.ts +0 -1
  423. package/src/workbench/settings/NavigationPanel.tsx +41 -2
  424. package/src/workbench/settings/SchemaForm.tsx +20 -7
  425. package/src/workbench/settings/SectionTabPanel.tsx +172 -0
  426. package/src/workbench/settings/SectionedPanel.tsx +40 -286
  427. package/src/workbench/settings/StructuredDataForm.tsx +106 -26
  428. package/src/workbench/settings/StructuredDataSchemaPanel.tsx +345 -93
  429. package/src/workbench/settings/StructuredDataTableView.tsx +2 -2
  430. package/src/workbench/settings/WorkbenchPanelRegion.tsx +1 -1
  431. package/src/workbench/settings/WorkbenchSettingsModal.tsx +116 -62
  432. package/src/workbench/settings/WorkbenchSettingsNav.tsx +3 -3
  433. package/src/workbench/settings/extensionSettingsForm.ts +34 -0
  434. package/src/workbench/settings/index.ts +36 -1
  435. package/src/workbench/settings/navigation-panel.css +59 -0
  436. package/src/workbench/settings/panel-region.css +3 -2
  437. package/src/workbench/settings/schema-form.css +36 -0
  438. package/src/workbench/settings/schemaFormSettingSpec.ts +177 -0
  439. package/src/workbench/settings/schemaFormSettingsCategory.tsx +21 -0
  440. package/src/workbench/settings/section-tab-panel.css +157 -0
  441. package/src/workbench/settings/sectionScrollSpyDom.ts +139 -0
  442. package/src/workbench/settings/sectioned-panel.css +162 -0
  443. package/src/workbench/settings/sectionedPanelScrollSpy.ts +158 -28
  444. package/src/workbench/settings/settings-responsive.css +58 -0
  445. package/src/workbench/settings/settings.css +11 -0
  446. package/src/workbench/settings/settingsCommit.tsx +55 -0
  447. package/src/workbench/settings/structured-data-form.css +114 -0
  448. package/src/workbench/settings/structured-data-schema-panel.css +33 -19
  449. package/src/workbench/settings/structuredDataFormModel.ts +140 -0
  450. package/src/workbench/settings/structuredDataSchema.ts +111 -658
  451. package/src/workbench/settings/structuredDataSchemaDate.ts +197 -0
  452. package/src/workbench/settings/structuredDataSchemaField.ts +105 -0
  453. package/src/workbench/settings/structuredDataSchemaSection.ts +74 -0
  454. package/src/workbench/settings/structuredDataSchemaTable.ts +120 -0
  455. package/src/workbench/settings/structuredDataSchemaTypes.ts +308 -0
  456. package/src/workbench/settings/structuredDataSchemaValidation.ts +166 -0
  457. package/src/workbench/settings/useSectionScrollSpy.ts +420 -0
  458. package/src/workbench/settings/workbench-settings-modal.css +273 -0
  459. package/src/workbench/shell/activity-bar.css +245 -0
  460. package/src/workbench/shell/confirmation-flow.css +87 -0
  461. package/src/workbench/shell/index.css +5 -0
  462. package/src/workbench/shell/split-view.css +188 -0
  463. package/src/workbench/shell/status-bar.css +141 -0
  464. package/src/workbench/shell.ts +133 -2
  465. package/src/workbench/shellPresets.ts +36 -0
  466. package/src/workbench/shellState.ts +16 -23
  467. package/src/workbench/shellViewModel.ts +160 -0
  468. package/src/workbench/sidebarViewPlacementDnd.ts +61 -0
  469. package/src/workbench/standalone.ts +9 -9
  470. package/src/workbench/status.ts +10 -6
  471. package/src/workbench/theme.ts +8 -2
  472. package/src/workbench/themePresets.ts +191 -0
  473. package/src/workbench/useDeferredWorkbenchMount.ts +71 -0
  474. package/src/workbench/useEditorTabsStripDnd.ts +262 -0
  475. package/src/workbench/useWorkbenchAppearanceDocumentSync.tsx +17 -0
  476. package/src/workbench/useWorkbenchEditorTabContextMenu.tsx +66 -0
  477. package/src/workbench/useWorkbenchSidebarActionBarDnd.ts +227 -0
  478. package/src/workbench/useWorkbenchSidebarLayout.tsx +232 -0
  479. package/src/workbench/useWorkbenchSidebarViewPlacementDropZone.ts +194 -0
  480. package/src/workbench/useWorkbenchStandaloneShellStateSync.tsx +112 -0
  481. package/src/workbench/views/action-list.css +144 -0
  482. package/src/workbench/views/artifact-preview.css +184 -0
  483. package/src/workbench/views/command-inspector.css +98 -0
  484. package/src/workbench/views/command-list.css +356 -0
  485. package/src/workbench/views/commands-sidebar.css +51 -0
  486. package/src/workbench/views/extensions-sidebar.css +175 -0
  487. package/src/workbench/views/multi-provider-explorer.css +182 -0
  488. package/src/workbench/views/search.css +10 -0
  489. package/src/workbench/views/timeline.css +239 -0
  490. package/src/workbench/views/view-hosts.css +37 -0
  491. package/src/workbench/views/view-sidebar.css +21 -0
  492. package/src/workbench/views/views.css +12 -0
  493. package/src/workbench/widgets/widget-tree.css +598 -0
  494. package/src/workbench/widgets/widgets.css +2 -0
  495. package/src/workbench/workbench-chrome.css +4 -0
  496. package/src/workbench/workbenchContextMenu.ts +18 -0
  497. package/src/workbench/workbenchModalViewState.ts +52 -0
  498. package/src/workbench/workbenchOverlaysContext.tsx +21 -0
  499. package/src/workbench/workbenchPlatformChrome.ts +40 -0
  500. package/src/workbench/workbenchSidebarLayoutContext.ts +46 -0
  501. package/src/workbench/workbenchStandaloneShellReactContext.tsx +80 -0
  502. package/src/workbench/workbenchViewRouteState.ts +151 -0
  503. package/src/workbench/workspace/WorkspaceDraftsContext.tsx +59 -71
  504. package/src/workbench/workspace/WorkspaceEditor.tsx +27 -123
  505. package/src/workbench/workspace/WorkspaceEditorPanel.tsx +67 -8
  506. package/src/workbench/workspace/WorkspaceExplorer.tsx +149 -51
  507. package/src/workbench/workspace/WorkspaceExplorerPanel.tsx +73 -0
  508. package/src/workbench/workspace/WorkspaceFileIcon.tsx +4 -160
  509. package/src/workbench/workspace/WorkspacePathLabel.tsx +42 -0
  510. package/src/workbench/workspace/WorkspaceSearchPanel.tsx +18 -15
  511. package/src/workbench/workspace/WorkspaceSearchResults.tsx +6 -2
  512. package/src/workbench/workspace/build-workspace-explorer-nodes.ts +44 -0
  513. package/src/workbench/workspace/createVirtualWorkspaceExplorerPort.ts +141 -0
  514. package/src/workbench/workspace/explorer-tree-style.ts +18 -0
  515. package/src/workbench/workspace/index.ts +45 -32
  516. package/src/workbench/workspace/json-config-workbench.css +57 -0
  517. package/src/workbench/workspace/monaco-panel.css +71 -0
  518. package/src/workbench/workspace/path.ts +2 -0
  519. package/src/workbench/workspace/useWorkspaceExplorerController.ts +490 -0
  520. package/src/workbench/workspace/workspace-editor.css +235 -0
  521. package/src/workbench/workspace/workspace-explorer-panel.css +33 -0
  522. package/src/workbench/workspace/workspace.css +5 -0
  523. package/src/workbench/workspace/workspaceExplorerController.ts +193 -0
  524. package/src/workbench/workspace/workspaceJsonDiagnostics.ts +2 -2
  525. package/src/workbench-menu-surfaces.css +57 -0
  526. package/src/jdw/builtins/renderBuiltinWidgetNode.tsx +0 -126
  527. package/src/layout/SideBarViewFrame.tsx +0 -367
  528. package/src/primitives/Checkbox.tsx +0 -21
  529. package/src/primitives/NumberInput.tsx +0 -38
  530. package/src/primitives/ScrollArea.tsx +0 -42
  531. package/src/primitives/Select.tsx +0 -1
  532. package/src/primitives/StatusBar.tsx +0 -46
  533. package/src/primitives/WorkbenchChrome.tsx +0 -424
  534. package/src/workbench/workspace/MultiProviderExplorer.tsx +0 -625
@@ -1,16 +1,22 @@
1
1
  import { useMemo, type ReactNode } from 'react';
2
2
  import {
3
3
  parseJsonWidgetData,
4
- validateJsonWidgetData,
4
+ resolveJsonWidgetValues,
5
+ validateJsonWidgetNode,
6
+ type JsonWidgetValueMap,
5
7
  type JsonWidgetNode,
8
+ type ValidationIssue,
6
9
  } from '@workbench-kit/jdw';
7
10
 
8
11
  import { renderJdwWithLayout, type CssRenderBackendOptions } from './cssRenderBackend.js';
9
12
 
10
- export type RenderJdwOptions = CssRenderBackendOptions;
13
+ export interface RenderJdwOptions extends CssRenderBackendOptions {
14
+ readonly strictKnownTypes?: boolean | undefined;
15
+ readonly values?: JsonWidgetValueMap | undefined;
16
+ }
11
17
 
12
18
  export function renderJdwNode(node: JsonWidgetNode, options: RenderJdwOptions = {}): ReactNode {
13
- return renderJdwWithLayout(node, options);
19
+ return renderJdwWithLayout(resolveJsonWidgetValues(node, options.values), options);
14
20
  }
15
21
 
16
22
  export function renderJdw(source: string, options: RenderJdwOptions = {}): ReactNode {
@@ -19,14 +25,49 @@ export function renderJdw(source: string, options: RenderJdwOptions = {}): React
19
25
  return null;
20
26
  }
21
27
 
22
- validateJsonWidgetData(source);
23
- return renderJdwWithLayout(parsed.value, options);
28
+ const node = resolveJsonWidgetValues(parsed.value, options.values);
29
+ const issues: ValidationIssue[] = [];
30
+ validateJsonWidgetNode(node, 'root', issues, {
31
+ registeredTypes: options.registry?.types(),
32
+ strictKnownTypes: options.strictKnownTypes,
33
+ });
34
+ if (issues.length > 0) {
35
+ return null;
36
+ }
37
+
38
+ return renderJdwWithLayout(node, options);
24
39
  }
25
40
 
26
41
  export function useRenderJdw(source: string, options: RenderJdwOptions = {}): ReactNode {
27
- const { registry, emptyLabel, layoutConstraints } = options;
42
+ const {
43
+ registry,
44
+ emptyLabel,
45
+ layoutConstraints,
46
+ selectedPath,
47
+ strictKnownTypes,
48
+ onSelectPath,
49
+ values,
50
+ } = options;
28
51
  return useMemo(
29
- () => renderJdw(source, { registry, emptyLabel, layoutConstraints }),
30
- [emptyLabel, layoutConstraints, registry, source],
52
+ () =>
53
+ renderJdw(source, {
54
+ registry,
55
+ emptyLabel,
56
+ layoutConstraints,
57
+ selectedPath,
58
+ strictKnownTypes,
59
+ onSelectPath,
60
+ values,
61
+ }),
62
+ [
63
+ emptyLabel,
64
+ layoutConstraints,
65
+ onSelectPath,
66
+ registry,
67
+ selectedPath,
68
+ source,
69
+ strictKnownTypes,
70
+ values,
71
+ ],
31
72
  );
32
73
  }
@@ -2,11 +2,11 @@ import { useMemo, useState, type ReactNode } from 'react';
2
2
  import type { WidgetRegistryContract } from '@workbench-kit/contracts';
3
3
  import { parseJsonWidgetData } from '@workbench-kit/jdw';
4
4
 
5
- import { Panel, PanelBody, PanelHeader } from '../layout/Panel';
6
- import { EmptyState } from '../primitives/EmptyState';
7
- import { Button } from '../primitives/Button';
8
- import { IconButton } from '../primitives/IconButton';
9
- import { Toolbar } from '../primitives/Toolbar';
5
+ import { Panel, PanelBody, PanelHeader } from '../layout/panel';
6
+ import { EmptyState } from '../primitives/empty-state';
7
+ import { Button } from '../primitives/button';
8
+ import { IconButton } from '../primitives/icon-button';
9
+ import { Toolbar } from '../primitives/toolbar';
10
10
  import { JsonCodeEditorPane, JsonConfigValidationBanner } from '../jdw/JsonCodeEditorPane.js';
11
11
  import { JdwPreview } from '../jdw/JdwPreview.js';
12
12
  import { SplitView } from '../workbench/SplitView';
@@ -18,15 +18,14 @@ import { createJsonConfigEditorState } from './json-config-editor-state.js';
18
18
 
19
19
  export type JsonConfigPreviewKind = 'auto' | 'none' | 'schema' | 'widget';
20
20
  export type JsonConfigWorkbenchMode = 'code' | 'form' | 'preview';
21
- type JsonConfigWorkbenchModeInput = JsonConfigWorkbenchMode | 'split';
22
21
 
23
22
  export interface JsonConfigWorkbenchProps {
24
23
  activePattern?: string | undefined;
25
24
  baselineValue?: string | undefined;
26
- defaultMode?: JsonConfigWorkbenchModeInput | undefined;
25
+ defaultMode?: JsonConfigWorkbenchMode | undefined;
27
26
  emptyPreviewLabel?: ReactNode | undefined;
28
27
  headerActions?: ReactNode | undefined;
29
- mode?: JsonConfigWorkbenchModeInput | undefined;
28
+ mode?: JsonConfigWorkbenchMode | undefined;
30
29
  onChange: (value: string) => void;
31
30
  onApply?: (() => void) | undefined;
32
31
  onDiscard?: (() => void) | undefined;
@@ -94,8 +93,7 @@ export function JsonConfigWorkbench({
94
93
  widgetRegistry,
95
94
  }: JsonConfigWorkbenchProps) {
96
95
  const formAvailable = schema !== null && schema !== undefined;
97
- const [uncontrolledMode, setUncontrolledMode] =
98
- useState<JsonConfigWorkbenchModeInput>(defaultMode);
96
+ const [uncontrolledMode, setUncontrolledMode] = useState<JsonConfigWorkbenchMode>(defaultMode);
99
97
  const resolvedMode = normalizeJsonConfigWorkbenchMode(mode ?? uncontrolledMode, formAvailable);
100
98
 
101
99
  const setMode = (nextMode: JsonConfigWorkbenchMode) => {
@@ -266,15 +264,14 @@ export function JsonConfigWorkbench({
266
264
  }
267
265
 
268
266
  function normalizeJsonConfigWorkbenchMode(
269
- mode: JsonConfigWorkbenchModeInput,
267
+ mode: JsonConfigWorkbenchMode,
270
268
  formAvailable: boolean,
271
269
  ): JsonConfigWorkbenchMode {
272
- const normalized = mode === 'split' ? 'code' : mode;
273
- if (normalized === 'form' && !formAvailable) {
270
+ if (mode === 'form' && !formAvailable) {
274
271
  return 'code';
275
272
  }
276
273
 
277
- return normalized;
274
+ return mode;
278
275
  }
279
276
 
280
277
  function JsonConfigModeControls({
@@ -0,0 +1,14 @@
1
+ import type { ComponentPropsWithRef, ReactNode } from 'react';
2
+ import { cx } from '../utils/cx';
3
+
4
+ export interface ViewEmptyStateProps extends ComponentPropsWithRef<'p'> {
5
+ children: ReactNode;
6
+ }
7
+
8
+ export function ViewEmptyState({ children, className, ...props }: ViewEmptyStateProps) {
9
+ return (
10
+ <p className={cx('ui-view-empty-state', 'ui-panel-centered-state', className)} {...props}>
11
+ {children}
12
+ </p>
13
+ );
14
+ }
@@ -5,12 +5,13 @@ import type {
5
5
  PointerEvent as ReactPointerEvent,
6
6
  ReactNode,
7
7
  } from 'react';
8
- import { Button } from '../primitives/Button';
8
+ import { Button } from '../primitives/button';
9
9
  import { cx } from '../utils/cx';
10
10
  import { toAngleValue, toLineLengthValue, toLengthValue } from './layoutHelpers';
11
11
 
12
12
  export interface WorkbenchCanvasItemFrameProps extends ComponentPropsWithRef<'div'> {
13
13
  cursor?: CSSProperties['cursor'] | undefined;
14
+ focused?: boolean | undefined;
14
15
  height: number | string;
15
16
  hovered?: boolean | undefined;
16
17
  interactive?: boolean | undefined;
@@ -32,6 +33,7 @@ export const WorkbenchCanvasItemFrame = forwardRef<HTMLDivElement, WorkbenchCanv
32
33
  {
33
34
  className,
34
35
  cursor,
36
+ focused = false,
35
37
  height,
36
38
  hovered = false,
37
39
  interactive = false,
@@ -75,6 +77,7 @@ export const WorkbenchCanvasItemFrame = forwardRef<HTMLDivElement, WorkbenchCanv
75
77
  ref={ref}
76
78
  aria-selected={selected}
77
79
  className={cx('ui-workbench-canvas-item-frame', className)}
80
+ data-focused={focused ? 'true' : 'false'}
78
81
  data-hovered={hovered ? 'true' : 'false'}
79
82
  data-interactive={interactive ? 'true' : 'false'}
80
83
  data-selected={selected ? 'true' : 'false'}
@@ -86,7 +89,9 @@ export const WorkbenchCanvasItemFrame = forwardRef<HTMLDivElement, WorkbenchCanv
86
89
  },
87
90
  );
88
91
 
89
- export type WorkbenchCanvasPaneSurfaceProps = ComponentPropsWithRef<'div'>;
92
+ export interface WorkbenchCanvasPaneSurfaceProps extends ComponentPropsWithRef<'div'> {
93
+ children?: ReactNode;
94
+ }
90
95
 
91
96
  export const WorkbenchCanvasPaneSurface = forwardRef<
92
97
  HTMLDivElement,
@@ -151,6 +156,7 @@ export function WorkbenchCanvasFrameSurface({
151
156
  }
152
157
 
153
158
  export interface WorkbenchCanvasViewportProps extends ComponentPropsWithRef<'div'> {
159
+ children?: ReactNode;
154
160
  grid?: boolean | undefined;
155
161
  gridSize?: number | string | undefined;
156
162
  height: number | string;
@@ -499,6 +505,29 @@ interface WorkbenchCanvasFrameHandleDrag {
499
505
  startY: number;
500
506
  }
501
507
 
508
+ function trySetPointerCapture(element: HTMLElement, pointerId: number): void {
509
+ if (typeof element.setPointerCapture !== 'function') return;
510
+
511
+ try {
512
+ element.setPointerCapture(pointerId);
513
+ } catch {
514
+ // Synthetic pointer events in Storybook/jsdom may not register an active pointer.
515
+ }
516
+ }
517
+
518
+ function tryReleasePointerCapture(element: HTMLElement | null, pointerId: number): void {
519
+ if (!element || typeof element.releasePointerCapture !== 'function') return;
520
+
521
+ try {
522
+ if (typeof element.hasPointerCapture === 'function' && !element.hasPointerCapture(pointerId)) {
523
+ return;
524
+ }
525
+ element.releasePointerCapture(pointerId);
526
+ } catch {
527
+ // Ignore stale synthetic pointer captures.
528
+ }
529
+ }
530
+
502
531
  export interface WorkbenchCanvasFrameHandleProps extends Omit<
503
532
  ComponentPropsWithRef<'div'>,
504
533
  | 'children'
@@ -549,12 +578,12 @@ export function WorkbenchCanvasFrameHandle({
549
578
  if (!element) return;
550
579
 
551
580
  if (stopPropagation) event.stopPropagation();
552
- element.setPointerCapture(event.pointerId);
553
581
  dragRef.current = {
554
582
  pointerId: event.pointerId,
555
583
  startX: event.clientX,
556
584
  startY: event.clientY,
557
585
  };
586
+ trySetPointerCapture(element, event.pointerId);
558
587
  onDragStart?.(event);
559
588
  };
560
589
 
@@ -570,7 +599,7 @@ export function WorkbenchCanvasFrameHandle({
570
599
  const drag = dragRef.current;
571
600
  if (!drag || drag.pointerId !== event.pointerId) return;
572
601
 
573
- handleRef.current?.releasePointerCapture(event.pointerId);
602
+ tryReleasePointerCapture(handleRef.current, event.pointerId);
574
603
  dragRef.current = null;
575
604
  const dx = event.clientX - drag.startX;
576
605
  const dy = event.clientY - drag.startY;
@@ -586,7 +615,7 @@ export function WorkbenchCanvasFrameHandle({
586
615
  const drag = dragRef.current;
587
616
  if (!drag || drag.pointerId !== event.pointerId) return;
588
617
 
589
- handleRef.current?.releasePointerCapture(event.pointerId);
618
+ tryReleasePointerCapture(handleRef.current, event.pointerId);
590
619
  dragRef.current = null;
591
620
  onDragCancel?.(event);
592
621
  };
@@ -629,7 +658,12 @@ export interface WorkbenchCanvasResizeHandleProps extends Omit<
629
658
  'children'
630
659
  > {
631
660
  label?: string | undefined;
661
+ onResizeCancel?: (event: ReactPointerEvent<HTMLButtonElement>) => void;
662
+ onResizeEnd?: (dx: number, dy: number, event: ReactPointerEvent<HTMLButtonElement>) => void;
663
+ onResizeMove?: (dx: number, dy: number, event: ReactPointerEvent<HTMLButtonElement>) => void;
664
+ onResizeStart?: (event: ReactPointerEvent<HTMLButtonElement>) => void;
632
665
  position?: WorkbenchCanvasResizeHandlePosition | undefined;
666
+ stopPropagation?: boolean;
633
667
  }
634
668
 
635
669
  export type WorkbenchCanvasResizeHandlePosition = 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' | 'nw';
@@ -637,15 +671,82 @@ export type WorkbenchCanvasResizeHandlePosition = 'n' | 'ne' | 'e' | 'se' | 's'
637
671
  export function WorkbenchCanvasResizeHandle({
638
672
  className,
639
673
  label = 'Resize',
674
+ onPointerCancel,
675
+ onPointerDown,
676
+ onPointerMove,
677
+ onPointerUp,
678
+ onResizeCancel,
679
+ onResizeEnd,
680
+ onResizeMove,
681
+ onResizeStart,
640
682
  position = 'se',
683
+ stopPropagation = true,
641
684
  type = 'button',
642
685
  ...props
643
686
  }: WorkbenchCanvasResizeHandleProps) {
687
+ const handleRef = useRef<HTMLButtonElement>(null);
688
+ const dragRef = useRef<WorkbenchCanvasFrameHandleDrag | null>(null);
689
+
690
+ const handlePointerDown = (event: ReactPointerEvent<HTMLButtonElement>) => {
691
+ onPointerDown?.(event);
692
+ if (event.defaultPrevented || event.button !== 0) return;
693
+
694
+ const element = handleRef.current;
695
+ if (!element) return;
696
+
697
+ if (stopPropagation) event.stopPropagation();
698
+ dragRef.current = {
699
+ pointerId: event.pointerId,
700
+ startX: event.clientX,
701
+ startY: event.clientY,
702
+ };
703
+ trySetPointerCapture(element, event.pointerId);
704
+ onResizeStart?.(event);
705
+ };
706
+
707
+ const handlePointerMove = (event: ReactPointerEvent<HTMLButtonElement>) => {
708
+ onPointerMove?.(event);
709
+ const drag = dragRef.current;
710
+ if (!drag || drag.pointerId !== event.pointerId) return;
711
+ onResizeMove?.(event.clientX - drag.startX, event.clientY - drag.startY, event);
712
+ };
713
+
714
+ const handlePointerUp = (event: ReactPointerEvent<HTMLButtonElement>) => {
715
+ onPointerUp?.(event);
716
+ const drag = dragRef.current;
717
+ if (!drag || drag.pointerId !== event.pointerId) return;
718
+
719
+ tryReleasePointerCapture(handleRef.current, event.pointerId);
720
+ dragRef.current = null;
721
+ const dx = event.clientX - drag.startX;
722
+ const dy = event.clientY - drag.startY;
723
+ if (dx !== 0 || dy !== 0) {
724
+ onResizeEnd?.(dx, dy, event);
725
+ } else {
726
+ onResizeCancel?.(event);
727
+ }
728
+ };
729
+
730
+ const handlePointerCancel = (event: ReactPointerEvent<HTMLButtonElement>) => {
731
+ onPointerCancel?.(event);
732
+ const drag = dragRef.current;
733
+ if (!drag || drag.pointerId !== event.pointerId) return;
734
+
735
+ tryReleasePointerCapture(handleRef.current, event.pointerId);
736
+ dragRef.current = null;
737
+ onResizeCancel?.(event);
738
+ };
739
+
644
740
  return (
645
741
  <button
742
+ ref={handleRef}
646
743
  aria-label={label}
647
744
  className={cx('ui-workbench-canvas-resize-handle', className)}
648
745
  data-position={position}
746
+ onPointerCancel={handlePointerCancel}
747
+ onPointerDown={handlePointerDown}
748
+ onPointerMove={handlePointerMove}
749
+ onPointerUp={handlePointerUp}
649
750
  title={label}
650
751
  type={type}
651
752
  {...props}
@@ -785,12 +886,18 @@ export function WorkbenchPreviewCanvas({
785
886
  }: WorkbenchPreviewCanvasProps) {
786
887
  const {
787
888
  className: viewportClassName,
889
+ ref: interactionRef,
788
890
  style: viewportStyle,
789
891
  ...restViewportProps
790
892
  } = viewportProps ?? {};
791
893
 
792
894
  return (
793
- <div className={cx('ui-workbench-preview-canvas', className)} {...props}>
895
+ <div
896
+ className={cx('ui-workbench-preview-canvas', className)}
897
+ data-panning={isPanning ? 'true' : 'false'}
898
+ {...props}
899
+ ref={interactionRef}
900
+ >
794
901
  {onResetView ? (
795
902
  <Button
796
903
  compact
@@ -3,3 +3,6 @@ export * from './WorkbenchCanvas';
3
3
  export * from './WorkbenchFullscreen';
4
4
  export * from './WorkbenchTree';
5
5
  export * from './WorkbenchPropertyPanel';
6
+ export * from './WorkbenchPropertyOverrideLabel';
7
+ export * from './WorkbenchPropertySearch';
8
+ export * from './propertyFieldFilter';
@@ -1,7 +1,8 @@
1
1
  import type { ComponentPropsWithRef, CSSProperties, ReactNode } from 'react';
2
- import { ScrollArea } from '../primitives/ScrollArea';
2
+ import { ScrollArea } from '../primitives/scroll-area';
3
3
  import { cxCodicon } from '../utils/codicon';
4
4
  import { cx } from '../utils/cx';
5
+ import { workbenchFillScrollRoleProps } from './fillScrollContract';
5
6
  import { toLengthValue } from './layoutHelpers';
6
7
 
7
8
  export type WorkbenchRootProps = ComponentPropsWithRef<'div'>;
@@ -12,8 +13,48 @@ export function WorkbenchRoot({ className, ...props }: WorkbenchRootProps) {
12
13
 
13
14
  export type WorkbenchFillProps = ComponentPropsWithRef<'div'>;
14
15
 
16
+ /**
17
+ * Flex fill slot that clips overflow (`data-ui-fill-scroll-role="fill"`).
18
+ * Column by default; the last direct child stretches to fill remaining space.
19
+ */
15
20
  export function WorkbenchFill({ className, ...props }: WorkbenchFillProps) {
16
- return <div className={cx('ui-workbench-fill', className)} {...props} />;
21
+ return (
22
+ <div
23
+ className={cx('ui-workbench-fill', className)}
24
+ {...props}
25
+ {...workbenchFillScrollRoleProps('fill')}
26
+ />
27
+ );
28
+ }
29
+
30
+ export type WorkbenchFillChainProps = ComponentPropsWithRef<'div'>;
31
+
32
+ /**
33
+ * Root of an editor-in-pane fill chain. Descendant nodes that stamp
34
+ * `data-ui-fill-scroll-role` inherit clip/scroll overflow rules.
35
+ * Same last-child fill default as `WorkbenchFill` (toolbar + body stacks).
36
+ */
37
+ export function WorkbenchFillChain({ className, ...props }: WorkbenchFillChainProps) {
38
+ return (
39
+ <div
40
+ className={cx('ui-workbench-fill', 'ui-workbench-fill-chain', className)}
41
+ {...props}
42
+ {...workbenchFillScrollRoleProps('fill')}
43
+ />
44
+ );
45
+ }
46
+
47
+ export type WorkbenchScrollRegionProps = ComponentPropsWithRef<'div'>;
48
+
49
+ /** Named scroll owner inside a fill chain (`data-ui-fill-scroll-role="scroll"`). */
50
+ export function WorkbenchScrollRegion({ className, ...props }: WorkbenchScrollRegionProps) {
51
+ return (
52
+ <div
53
+ className={cx('ui-workbench-scroll-region', className)}
54
+ {...props}
55
+ {...workbenchFillScrollRoleProps('scroll')}
56
+ />
57
+ );
17
58
  }
18
59
 
19
60
  export type WorkbenchCenterProps = ComponentPropsWithRef<'main'>;
@@ -0,0 +1,122 @@
1
+ import {
2
+ useCallback,
3
+ useLayoutEffect,
4
+ useRef,
5
+ useState,
6
+ type ComponentPropsWithRef,
7
+ type ReactNode,
8
+ type SyntheticEvent,
9
+ } from 'react';
10
+
11
+ import { Button } from '../primitives/button';
12
+ import { cx } from '../utils/cx';
13
+ import { usePreviewViewport } from './usePreviewViewport';
14
+
15
+ export interface WorkbenchMediaPreviewViewportProps extends Omit<
16
+ ComponentPropsWithRef<'div'>,
17
+ 'children'
18
+ > {
19
+ readonly alt?: string | undefined;
20
+ readonly help?: ReactNode | undefined;
21
+ readonly imageUrl: string;
22
+ readonly maxZoom?: number | undefined;
23
+ readonly minZoom?: number | undefined;
24
+ readonly resetLabel?: ReactNode | undefined;
25
+ readonly resetTitle?: string | undefined;
26
+ readonly showReset?: boolean | undefined;
27
+ }
28
+
29
+ export function WorkbenchMediaPreviewViewport({
30
+ alt = '',
31
+ className,
32
+ help = 'Ctrl + Scroll to zoom | Drag to pan',
33
+ imageUrl,
34
+ maxZoom,
35
+ minZoom,
36
+ resetLabel,
37
+ resetTitle = 'Reset zoom and pan',
38
+ showReset = true,
39
+ ...props
40
+ }: WorkbenchMediaPreviewViewportProps) {
41
+ const [contentSize, setContentSize] = useState<{ height: number; width: number } | null>(null);
42
+ const imageRef = useRef<HTMLImageElement>(null);
43
+
44
+ const viewport = usePreviewViewport({
45
+ contentHeight: contentSize?.height,
46
+ contentWidth: contentSize?.width,
47
+ maxZoom,
48
+ minZoom,
49
+ });
50
+
51
+ const syncContentSize = useCallback((image: HTMLImageElement) => {
52
+ if (image.naturalWidth <= 0 || image.naturalHeight <= 0) {
53
+ return;
54
+ }
55
+
56
+ setContentSize({
57
+ height: image.naturalHeight,
58
+ width: image.naturalWidth,
59
+ });
60
+ }, []);
61
+
62
+ const handleImageLoad = useCallback(
63
+ (event: SyntheticEvent<HTMLImageElement>) => {
64
+ syncContentSize(event.currentTarget);
65
+ },
66
+ [syncContentSize],
67
+ );
68
+
69
+ useLayoutEffect(() => {
70
+ const image = imageRef.current;
71
+ if (!image) {
72
+ return;
73
+ }
74
+
75
+ if (image.complete) {
76
+ syncContentSize(image);
77
+ }
78
+ }, [imageUrl, syncContentSize]);
79
+
80
+ const resolvedResetLabel = resetLabel ?? `Reset (${Math.round(viewport.effectiveZoom * 100)}%)`;
81
+
82
+ return (
83
+ <div
84
+ className={cx('ui-workbench-media-preview-viewport', className)}
85
+ data-ui-workbench-media-preview-viewport="true"
86
+ {...props}
87
+ ref={viewport.setViewportElement}
88
+ >
89
+ {showReset ? (
90
+ <Button
91
+ compact
92
+ className="ui-workbench-media-preview-viewport__reset"
93
+ type="button"
94
+ onClick={viewport.resetView}
95
+ title={resetTitle}
96
+ >
97
+ {resolvedResetLabel}
98
+ </Button>
99
+ ) : null}
100
+
101
+ <div
102
+ className="ui-workbench-media-preview-viewport__stage"
103
+ data-panning={viewport.isPanning ? 'true' : 'false'}
104
+ style={viewport.stageStyle}
105
+ >
106
+ <img
107
+ alt={alt}
108
+ className="ui-workbench-media-preview-viewport__image"
109
+ draggable={false}
110
+ ref={imageRef}
111
+ src={imageUrl}
112
+ onDragStart={(event) => {
113
+ event.preventDefault();
114
+ }}
115
+ onLoad={handleImageLoad}
116
+ />
117
+ </div>
118
+
119
+ {help ? <div className="ui-workbench-media-preview-viewport__help">{help}</div> : null}
120
+ </div>
121
+ );
122
+ }
@@ -0,0 +1,90 @@
1
+ import type { JSX, ReactNode } from 'react';
2
+
3
+ import type { WorkbenchIconInput } from '../icons/types';
4
+ import { Badge } from '../primitives/badge';
5
+ import { Button } from '../primitives/button';
6
+ import { IconButton } from '../primitives/icon-button';
7
+ import { cx } from '../utils/cx';
8
+
9
+ export type WorkbenchPropertyOverrideResetAppearance = 'icon' | 'text';
10
+
11
+ export interface WorkbenchPropertyOverrideLabelProps {
12
+ readonly label: ReactNode;
13
+ readonly overridden: boolean;
14
+ readonly onReset?: () => void;
15
+ /** Storybook defaults OK; hosts should pass i18n strings. */
16
+ readonly customBadgeLabel?: string;
17
+ readonly defaultBadgeLabel?: string;
18
+ /**
19
+ * Accessible name for the Reset control. Used as `IconButton` label when
20
+ * `resetAppearance` is `"icon"`, or as visible button text when `"text"`.
21
+ */
22
+ readonly resetLabel?: string;
23
+ /** Dense inspectors default to icon; use `"text"` when the label must stay visible. */
24
+ readonly resetAppearance?: WorkbenchPropertyOverrideResetAppearance;
25
+ /** Codicon / host icon for icon Reset. Default `codicon-discard`. */
26
+ readonly resetIcon?: WorkbenchIconInput;
27
+ readonly className?: string;
28
+ }
29
+
30
+ /**
31
+ * Sparse-override inspector label chrome: Custom/Default badge + optional Reset.
32
+ * Compose into `Field label={...}` — hosts own override detection and reset writes.
33
+ */
34
+ export function WorkbenchPropertyOverrideLabel({
35
+ className,
36
+ customBadgeLabel = 'Custom',
37
+ defaultBadgeLabel = 'Default',
38
+ label,
39
+ onReset,
40
+ overridden,
41
+ resetAppearance = 'icon',
42
+ resetIcon = 'codicon-discard',
43
+ resetLabel = 'Reset',
44
+ }: WorkbenchPropertyOverrideLabelProps): JSX.Element {
45
+ const showReset = overridden && onReset != null;
46
+
47
+ return (
48
+ <span className={cx('ui-workbench-property-override-label', className)}>
49
+ <span className="ui-workbench-property-override-label__main">
50
+ <span className="ui-workbench-property-override-label__text">{label}</span>
51
+ <Badge
52
+ className="ui-workbench-property-override-label__badge"
53
+ data-ui-workbench-property-override-badge={overridden ? 'custom' : 'default'}
54
+ variant={overridden ? 'accent' : 'muted'}
55
+ >
56
+ {overridden ? customBadgeLabel : defaultBadgeLabel}
57
+ </Badge>
58
+ </span>
59
+ {showReset ? (
60
+ resetAppearance === 'text' ? (
61
+ <Button
62
+ className="ui-workbench-property-override-label__reset"
63
+ compact
64
+ data-ui-workbench-property-override-reset="true"
65
+ data-ui-workbench-property-override-reset-appearance="text"
66
+ type="button"
67
+ onClick={() => {
68
+ onReset();
69
+ }}
70
+ >
71
+ {resetLabel}
72
+ </Button>
73
+ ) : (
74
+ <IconButton
75
+ className="ui-workbench-property-override-label__reset"
76
+ compact
77
+ data-ui-workbench-property-override-reset="true"
78
+ data-ui-workbench-property-override-reset-appearance="icon"
79
+ icon={resetIcon}
80
+ label={resetLabel}
81
+ type="button"
82
+ onClick={() => {
83
+ onReset();
84
+ }}
85
+ />
86
+ )
87
+ ) : null}
88
+ </span>
89
+ );
90
+ }