@workbench-kit/react 0.0.2-prototype.0.2.6 → 0.0.2-prototype.0.2.8

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 (568) hide show
  1. package/README.md +87 -0
  2. package/package.json +20 -18
  3. package/src/brand/TilepaperAppIcon.tsx +181 -181
  4. package/src/brand/index.ts +2 -2
  5. package/src/brand/tilepaper-app-icon-geometry.ts +201 -201
  6. package/src/icons/WorkbenchIcon.tsx +57 -57
  7. package/src/icons/WorkbenchIconContext.tsx +25 -25
  8. package/src/icons/file-icon.ts +154 -154
  9. package/src/icons/index.ts +17 -17
  10. package/src/icons/resolveWorkbenchIcon.ts +48 -48
  11. package/src/icons/types.ts +28 -28
  12. package/src/index.ts +735 -735
  13. package/src/jdw/JdwPreview.tsx +195 -195
  14. package/src/jdw/JdwPreviewViewport.tsx +190 -190
  15. package/src/jdw/JsonCodeEditorPane.tsx +425 -424
  16. package/src/jdw/builtins/renderBuiltinWidgetLeaf.tsx +130 -130
  17. package/src/jdw/createBuiltinJdwRegistry.ts +436 -436
  18. package/src/jdw/cssRenderBackend.tsx +223 -223
  19. package/src/jdw/document.ts +35 -35
  20. package/src/jdw/fixtures/jdw-fixtures.ts +52 -52
  21. package/src/jdw/fixtures/jdw-sample-screens.ts +524 -524
  22. package/src/jdw/index.ts +50 -50
  23. package/src/jdw/jdw-preview-viewport.css +41 -41
  24. package/src/jdw/parse.ts +1 -1
  25. package/src/jdw/renderJdw.tsx +73 -73
  26. package/src/json-config/JsonConfigWorkbench.tsx +313 -313
  27. package/src/json-config/index.ts +6 -6
  28. package/src/json-config/json-config-editor-state.ts +42 -42
  29. package/src/layout/ViewEmptyState.tsx +14 -14
  30. package/src/layout/WorkbenchCanvas.tsx +956 -956
  31. package/src/layout/WorkbenchFullscreen.tsx +368 -368
  32. package/src/layout/WorkbenchLayout.tsx +8 -8
  33. package/src/layout/WorkbenchLayoutBase.tsx +335 -335
  34. package/src/layout/WorkbenchMediaPreviewViewport.tsx +122 -122
  35. package/src/layout/WorkbenchPropertyOverrideLabel.tsx +90 -90
  36. package/src/layout/WorkbenchPropertyPanel.tsx +633 -633
  37. package/src/layout/WorkbenchPropertySearch.tsx +51 -51
  38. package/src/layout/WorkbenchTree.tsx +350 -350
  39. package/src/layout/canvas/canvas-drag-ghost.css +21 -21
  40. package/src/layout/canvas/canvas-drag-preview-frame.css +15 -15
  41. package/src/layout/canvas/canvas-drop-indicator.css +16 -16
  42. package/src/layout/canvas/canvas-frame-handle.css +37 -37
  43. package/src/layout/canvas/canvas-frame-surface.css +24 -24
  44. package/src/layout/canvas/canvas-guide-block.css +17 -17
  45. package/src/layout/canvas/canvas-guide-layer.css +6 -6
  46. package/src/layout/canvas/canvas-guide-line.css +22 -22
  47. package/src/layout/canvas/canvas-item-badge.css +23 -23
  48. package/src/layout/canvas/canvas-item-frame.css +54 -54
  49. package/src/layout/canvas/canvas-pane-surface.css +9 -9
  50. package/src/layout/canvas/canvas-placeholder.css +21 -21
  51. package/src/layout/canvas/canvas-resize-frame.css +9 -9
  52. package/src/layout/canvas/canvas-resize-handle.css +74 -74
  53. package/src/layout/canvas/canvas-resize-preview.css +11 -11
  54. package/src/layout/canvas/canvas-selection-marquee.css +14 -14
  55. package/src/layout/canvas/canvas-viewport.css +18 -18
  56. package/src/layout/canvas/index.css +19 -19
  57. package/src/layout/canvas/preview-canvas.css +144 -144
  58. package/src/layout/editor/editor-body.css +9 -9
  59. package/src/layout/editor/editor-bottom-panel.css +44 -44
  60. package/src/layout/editor/editor-frame.css +14 -14
  61. package/src/layout/editor/editor-viewport.css +7 -7
  62. package/src/layout/editor/floating-menu.css +91 -91
  63. package/src/layout/editor/index.css +10 -10
  64. package/src/layout/editor/parse-error.css +9 -9
  65. package/src/layout/editor/problem-item.css +52 -52
  66. package/src/layout/editor/problem-list.css +7 -7
  67. package/src/layout/editor/render-surface.css +13 -13
  68. package/src/layout/fillScrollContract.ts +49 -49
  69. package/src/layout/fullscreen/fullscreen-backdrop.css +31 -31
  70. package/src/layout/fullscreen/fullscreen-button.css +44 -44
  71. package/src/layout/fullscreen/fullscreen-carousel.css +20 -20
  72. package/src/layout/fullscreen/fullscreen-content.css +8 -8
  73. package/src/layout/fullscreen/fullscreen-empty.css +16 -16
  74. package/src/layout/fullscreen/fullscreen-header.css +77 -77
  75. package/src/layout/fullscreen/fullscreen-hero.css +41 -41
  76. package/src/layout/fullscreen/fullscreen-nav-button.css +29 -29
  77. package/src/layout/fullscreen/fullscreen-option.css +83 -83
  78. package/src/layout/fullscreen/fullscreen-pill-row.css +6 -6
  79. package/src/layout/fullscreen/fullscreen-pill.css +10 -10
  80. package/src/layout/fullscreen/fullscreen-root.css +11 -11
  81. package/src/layout/fullscreen/index.css +13 -13
  82. package/src/layout/index.ts +156 -156
  83. package/src/layout/layout-base/banner.css +32 -32
  84. package/src/layout/layout-base/center.css +7 -7
  85. package/src/layout/layout-base/column.css +7 -7
  86. package/src/layout/layout-base/divider.css +5 -5
  87. package/src/layout/layout-base/empty.css +12 -12
  88. package/src/layout/layout-base/fill-scroll.css +36 -36
  89. package/src/layout/layout-base/fill.css +18 -18
  90. package/src/layout/layout-base/index.css +13 -13
  91. package/src/layout/layout-base/pane.css +6 -6
  92. package/src/layout/layout-base/panel-scroll.css +5 -5
  93. package/src/layout/layout-base/panel-surface.css +14 -14
  94. package/src/layout/layout-base/root.css +9 -9
  95. package/src/layout/layout-base/section-title.css +8 -8
  96. package/src/layout/layout.css +10 -10
  97. package/src/layout/layoutHelpers.ts +27 -27
  98. package/src/layout/media/index.css +2 -2
  99. package/src/layout/media/media-preview-viewport.css +69 -69
  100. package/src/layout/panel/Panel.tsx +161 -161
  101. package/src/layout/panel/TemplateGallery.tsx +90 -90
  102. package/src/layout/panel/WorkbenchAuthoringShell.tsx +57 -57
  103. package/src/layout/panel/WorkbenchLabeledPane.tsx +81 -81
  104. package/src/layout/panel/WorkbenchSidebarStack.tsx +15 -15
  105. package/src/layout/panel/filter-bar.css +59 -59
  106. package/src/layout/panel/index.css +7 -7
  107. package/src/layout/panel/index.ts +70 -70
  108. package/src/layout/panel/preview-pane.css +63 -63
  109. package/src/layout/panel/template-gallery.css +131 -131
  110. package/src/layout/panel/workbench-authoring-shell.css +48 -48
  111. package/src/layout/panel/workbench-labeled-pane.css +69 -69
  112. package/src/layout/panel/workbench-sidebar-stack.css +18 -18
  113. package/src/layout/property/color-input.css +8 -8
  114. package/src/layout/property/color-row.css +6 -6
  115. package/src/layout/property/index.css +15 -15
  116. package/src/layout/property/property-card.css +8 -8
  117. package/src/layout/property/property-grid.css +24 -24
  118. package/src/layout/property/property-hint.css +4 -4
  119. package/src/layout/property/property-inline.css +10 -10
  120. package/src/layout/property/property-key-value.css +29 -29
  121. package/src/layout/property/property-override-label.css +34 -34
  122. package/src/layout/property/property-panel.css +20 -20
  123. package/src/layout/property/property-row.css +17 -17
  124. package/src/layout/property/property-search.css +43 -43
  125. package/src/layout/property/property-section.css +97 -97
  126. package/src/layout/property/property-stack.css +11 -11
  127. package/src/layout/property/property-toggle.css +14 -14
  128. package/src/layout/propertyFieldFilter.ts +84 -84
  129. package/src/layout/sidebar/SideBarViewFrame.tsx +235 -235
  130. package/src/layout/sidebar/SideBarViewTabStrip.tsx +60 -60
  131. package/src/layout/sidebar/SideBarViewTitleMenu.tsx +75 -75
  132. package/src/layout/sidebar/SidebarActionIconBar.tsx +242 -242
  133. package/src/layout/sidebar/SidebarSectionNestingContext.tsx +21 -21
  134. package/src/layout/sidebar/SidebarSlotChrome.tsx +32 -32
  135. package/src/layout/sidebar/SidebarToolbar.tsx +10 -10
  136. package/src/layout/sidebar/WorkbenchActionSidebar.tsx +73 -73
  137. package/src/layout/sidebar/WorkbenchSidebarActions.tsx +328 -328
  138. package/src/layout/sidebar/WorkbenchSidebarSectionStack.tsx +165 -165
  139. package/src/layout/sidebar/index.css +5 -5
  140. package/src/layout/sidebar/index.ts +55 -55
  141. package/src/layout/sidebar/sidebar-chrome.css +95 -95
  142. package/src/layout/sidebar/sidebar-section-stack.css +25 -25
  143. package/src/layout/sidebar/sidebar-section.css +124 -124
  144. package/src/layout/sidebar/sidebar-view.css +290 -290
  145. package/src/layout/tree/drag-preview.css +25 -25
  146. package/src/layout/tree/index.css +10 -10
  147. package/src/layout/tree/template-glyph.css +96 -96
  148. package/src/layout/tree/tree-action.css +20 -20
  149. package/src/layout/tree/tree-drag-overlay.css +13 -13
  150. package/src/layout/tree/tree-drop-line.css +17 -17
  151. package/src/layout/tree/tree-drop-zone.css +13 -13
  152. package/src/layout/tree/tree-expander.css +23 -23
  153. package/src/layout/tree/tree-item.css +93 -93
  154. package/src/layout/tree/tree.css +49 -49
  155. package/src/layout/usePreviewViewport.ts +428 -428
  156. package/src/modal/ConfirmDialog.tsx +61 -61
  157. package/src/modal/Modal.tsx +243 -213
  158. package/src/modal/ModalResizeHandles.tsx +40 -40
  159. package/src/modal/ModalTitlebar.tsx +86 -86
  160. package/src/modal/modal.css +291 -291
  161. package/src/modal/modalContainer.ts +36 -36
  162. package/src/modal/modalPosition.ts +36 -36
  163. package/src/modal/modalSize.ts +84 -84
  164. package/src/modal/modalTypes.ts +13 -13
  165. package/src/modal/useModalContainerViewport.ts +41 -41
  166. package/src/modal/useModalDrag.ts +118 -118
  167. package/src/modal/useModalFocusTrap.ts +142 -0
  168. package/src/modal/useModalResize.ts +122 -122
  169. package/src/modal/useModalWindowFrame.ts +122 -122
  170. package/src/overlay/ContextMenu.tsx +124 -124
  171. package/src/overlay/clampFixedOverlayPosition.ts +22 -22
  172. package/src/overlay/context-menu.css +127 -127
  173. package/src/overlay/index.ts +31 -31
  174. package/src/overlay/measureAnchoredOverlayPanel.ts +107 -107
  175. package/src/overlay/overlay.css +2 -2
  176. package/src/overlay/pointerPassthroughRegion.ts +83 -83
  177. package/src/overlay/useAnchoredOverlayPanel.ts +222 -222
  178. package/src/overlay/useClampedFixedOverlayPosition.ts +27 -27
  179. package/src/overlay/useContextMenuState.ts +59 -59
  180. package/src/overlay/useFixedOverlayDismiss.ts +49 -49
  181. package/src/overlay/usePointerPassthroughRegion.ts +87 -87
  182. package/src/primitives/absolute-box/AbsoluteBox.tsx +46 -46
  183. package/src/primitives/absolute-box/index.ts +1 -1
  184. package/src/primitives/badge/Badge.tsx +14 -14
  185. package/src/primitives/badge/badge.css +20 -20
  186. package/src/primitives/badge/index.ts +1 -1
  187. package/src/primitives/button/Button.tsx +45 -45
  188. package/src/primitives/button/button.css +76 -76
  189. package/src/primitives/button/index.ts +1 -1
  190. package/src/primitives/catalog-browse-card/CatalogBrowseCard.tsx +121 -121
  191. package/src/primitives/catalog-browse-card/catalog-browse-card.css +175 -175
  192. package/src/primitives/catalog-browse-card/index.ts +1 -1
  193. package/src/primitives/catalog-browse-pane/CatalogBrowseFacetChips.tsx +59 -59
  194. package/src/primitives/catalog-browse-pane/CatalogBrowsePane.tsx +360 -360
  195. package/src/primitives/catalog-browse-pane/catalog-browse-facet-chips.css +8 -8
  196. package/src/primitives/catalog-browse-pane/catalog-browse-pane.css +84 -84
  197. package/src/primitives/catalog-browse-pane/filterCatalogBrowseItems.ts +27 -27
  198. package/src/primitives/catalog-browse-pane/index.ts +3 -3
  199. package/src/primitives/catalog-filter-overlay/CatalogFilterOverlay.tsx +73 -73
  200. package/src/primitives/catalog-filter-overlay/catalog-filter-overlay.css +65 -65
  201. package/src/primitives/catalog-filter-overlay/index.ts +1 -1
  202. package/src/primitives/checkbox/Checkbox.tsx +40 -40
  203. package/src/primitives/checkbox/checkbox.css +81 -81
  204. package/src/primitives/checkbox/index.ts +1 -1
  205. package/src/primitives/chip/Chip.tsx +43 -43
  206. package/src/primitives/chip/chip.css +110 -110
  207. package/src/primitives/chip/index.ts +2 -2
  208. package/src/primitives/clearable-text-input/ClearableTextInput.tsx +78 -78
  209. package/src/primitives/clearable-text-input/clearable-text-input.css +15 -15
  210. package/src/primitives/clearable-text-input/index.ts +1 -1
  211. package/src/primitives/codicon/Codicon.tsx +20 -20
  212. package/src/primitives/codicon/index.ts +1 -1
  213. package/src/primitives/empty-state/EmptyState.tsx +33 -33
  214. package/src/primitives/empty-state/empty-state.css +20 -20
  215. package/src/primitives/empty-state/index.ts +1 -1
  216. package/src/primitives/external-link-button/ExternalLinkButton.tsx +56 -56
  217. package/src/primitives/external-link-button/index.ts +1 -1
  218. package/src/primitives/field/Field.tsx +39 -39
  219. package/src/primitives/field/field.css +51 -51
  220. package/src/primitives/field/index.ts +1 -1
  221. package/src/primitives/file-icon/FileIcon.tsx +21 -21
  222. package/src/primitives/file-icon/index.ts +1 -1
  223. package/src/primitives/icon-button/IconButton.tsx +37 -37
  224. package/src/primitives/icon-button/icon-button.css +46 -46
  225. package/src/primitives/icon-button/index.ts +1 -1
  226. package/src/primitives/index.ts +265 -265
  227. package/src/primitives/library-detail-layout/LibraryDetailLayout.tsx +135 -135
  228. package/src/primitives/library-detail-layout/index.ts +1 -1
  229. package/src/primitives/library-detail-layout/library-detail-layout.css +169 -169
  230. package/src/primitives/library-facet-filter-panel/LibraryFacetFilterPanel.tsx +454 -454
  231. package/src/primitives/library-facet-filter-panel/index.ts +1 -1
  232. package/src/primitives/library-facet-filter-panel/library-facet-filter-panel.css +205 -205
  233. package/src/primitives/library-facet-filter-strip/LibraryFacetFilterStrip.tsx +527 -527
  234. package/src/primitives/library-facet-filter-strip/index.ts +1 -1
  235. package/src/primitives/library-facet-filter-strip/library-facet-filter-strip.css +31 -31
  236. package/src/primitives/list/List.tsx +120 -120
  237. package/src/primitives/list/index.ts +1 -1
  238. package/src/primitives/list/list-empty-state.css +10 -10
  239. package/src/primitives/list/list-item.css +93 -93
  240. package/src/primitives/list/list.css +6 -6
  241. package/src/primitives/number-input/NumberInput.tsx +235 -235
  242. package/src/primitives/number-input/index.ts +1 -1
  243. package/src/primitives/number-input/number-input.css +105 -105
  244. package/src/primitives/panel-loading/PanelLoading.tsx +29 -29
  245. package/src/primitives/panel-loading/index.ts +1 -1
  246. package/src/primitives/panel-loading/panel-loading.css +16 -16
  247. package/src/primitives/panel-surface/panel-surface.css +77 -77
  248. package/src/primitives/primitives.css +36 -36
  249. package/src/primitives/record-media-hero/RecordMediaHero.tsx +81 -81
  250. package/src/primitives/record-media-hero/index.ts +1 -1
  251. package/src/primitives/record-media-hero/record-media-hero.css +84 -84
  252. package/src/primitives/scroll-area/ScrollArea.tsx +200 -200
  253. package/src/primitives/scroll-area/index.ts +1 -1
  254. package/src/primitives/scroll-area/scroll-area-overlay.css +69 -69
  255. package/src/primitives/scroll-area-infinite-load/ScrollAreaInfiniteSentinel.tsx +22 -22
  256. package/src/primitives/scroll-area-infinite-load/index.ts +2 -2
  257. package/src/primitives/scroll-area-infinite-load/scroll-area-infinite-sentinel.css +6 -6
  258. package/src/primitives/scroll-area-infinite-load/useScrollAreaInfiniteLoad.ts +84 -84
  259. package/src/primitives/searchable-multi-select/SearchableMultiSelect.tsx +378 -378
  260. package/src/primitives/searchable-multi-select/index.ts +9 -9
  261. package/src/primitives/searchable-multi-select/overlay.ts +125 -125
  262. package/src/primitives/searchable-multi-select/searchable-multi-select.css +129 -129
  263. package/src/primitives/select/Select.tsx +284 -284
  264. package/src/primitives/select/index.ts +2 -2
  265. package/src/primitives/select/options.ts +38 -38
  266. package/src/primitives/select/overlay.ts +82 -82
  267. package/src/primitives/select/select.app.css +12 -12
  268. package/src/primitives/select/select.css +177 -177
  269. package/src/primitives/select/types.ts +18 -18
  270. package/src/primitives/styles.css +6 -6
  271. package/src/primitives/tabbed-panels/TabbedPanels.tsx +68 -68
  272. package/src/primitives/tabbed-panels/index.ts +2 -2
  273. package/src/primitives/tabbed-panels/tabbed-panels.css +58 -58
  274. package/src/primitives/text-area/TextArea.tsx +37 -37
  275. package/src/primitives/text-area/index.ts +1 -1
  276. package/src/primitives/text-input/TextInput.tsx +34 -34
  277. package/src/primitives/text-input/index.ts +1 -1
  278. package/src/primitives/text-input/input.css +54 -54
  279. package/src/primitives/toolbar/Toolbar.tsx +8 -8
  280. package/src/primitives/toolbar/index.ts +1 -1
  281. package/src/primitives/visually-hidden/visually-hidden.css +11 -11
  282. package/src/primitives/workbench-editor/WorkbenchEditor.tsx +432 -432
  283. package/src/primitives/workbench-editor/button-group.css +10 -10
  284. package/src/primitives/workbench-editor/editor-tabs.css +201 -201
  285. package/src/primitives/workbench-editor/index.ts +1 -1
  286. package/src/primitives/workbench-editor/resizable-panels.css +53 -53
  287. package/src/primitives/workbench-editor/segmented-control.css +98 -98
  288. package/src/primitives/workbench-media-slot/WorkbenchMediaPlaceholder.tsx +25 -25
  289. package/src/primitives/workbench-media-slot/WorkbenchMediaSlot.tsx +60 -60
  290. package/src/primitives/workbench-media-slot/index.ts +2 -2
  291. package/src/primitives/workbench-media-slot/media-slot.css +72 -72
  292. package/src/primitives/workbench-thumbnail/WorkbenchThumbnail.tsx +38 -38
  293. package/src/primitives/workbench-thumbnail/index.ts +1 -1
  294. package/src/primitives/workbench-thumbnail/thumbnail.css +69 -69
  295. package/src/scrollbars.css +144 -144
  296. package/src/styles.css +16 -17
  297. package/src/test-utils/workbenchMonacoMock.tsx +37 -37
  298. package/src/utils/codicon.ts +17 -17
  299. package/src/utils/dragMime.ts +89 -89
  300. package/src/utils/useWorkbenchMediaImage.ts +37 -37
  301. package/src/widget-asset/WidgetAssetEditor.tsx +142 -142
  302. package/src/widget-asset/WidgetAssetMetadataForm.tsx +82 -82
  303. package/src/widget-asset/WidgetAssetModeControls.tsx +42 -42
  304. package/src/widget-asset/WidgetAssetSourceEditor.tsx +50 -50
  305. package/src/widget-asset/WidgetAssetWorkbench.tsx +111 -111
  306. package/src/widget-asset/index.ts +17 -17
  307. package/src/widget-asset/widget-asset-document.ts +37 -37
  308. package/src/widget-asset/widget-asset-mode.ts +3 -3
  309. package/src/widget-studio/builtin-widget-asset-catalog.ts +12 -12
  310. package/src/widget-studio/create-widget-studio-workspace-editor.tsx +78 -78
  311. package/src/widget-studio/index.ts +10 -10
  312. package/src/widget-studio/resolve-widget-studio-asset-catalog.ts +43 -43
  313. package/src/widget-tree/WidgetAssetPalette.tsx +105 -105
  314. package/src/widget-tree/WidgetInspectorPanel.tsx +316 -316
  315. package/src/widget-tree/WidgetSourceEditor.tsx +143 -143
  316. package/src/widget-tree/WidgetTreeCanvasPreview.tsx +875 -875
  317. package/src/widget-tree/WidgetTreeLab.tsx +600 -600
  318. package/src/widget-tree/WidgetTreeModeControls.tsx +73 -73
  319. package/src/widget-tree/WidgetTreeSidePanel.tsx +39 -39
  320. package/src/widget-tree/WidgetTreeView.tsx +797 -797
  321. package/src/widget-tree/WidgetTreeWorkbench.tsx +155 -155
  322. package/src/widget-tree/WidgetTreeWorkspaceShell.tsx +172 -172
  323. package/src/widget-tree/demo-registry.ts +32 -32
  324. package/src/widget-tree/demo-widget-assets.ts +4 -4
  325. package/src/widget-tree/index.ts +45 -45
  326. package/src/widget-tree/widget-placement-asset-dnd.ts +35 -35
  327. package/src/widget-tree/widget-tree-document.ts +14 -14
  328. package/src/widget-tree/widget-tree-editor-state.ts +40 -40
  329. package/src/widget-tree/widget-tree-layout.ts +76 -76
  330. package/src/widget-tree/widget-tree-mode.ts +7 -7
  331. package/src/widget-tree/widget-tree-play-helpers.ts +85 -85
  332. package/src/workbench/auth/WorkbenchAuthGate.tsx +61 -61
  333. package/src/workbench/auth/WorkbenchLoginView.tsx +633 -633
  334. package/src/workbench/auth/auth-flows.css +440 -440
  335. package/src/workbench/auth/auth.css +3 -3
  336. package/src/workbench/auth/index.ts +19 -19
  337. package/src/workbench/auth/profile-modals.css +115 -115
  338. package/src/workbench/bootstrap/WorkbenchBootstrapGate.tsx +45 -45
  339. package/src/workbench/bootstrap/WorkbenchBootstrapView.tsx +100 -100
  340. package/src/workbench/bootstrap/index.ts +12 -12
  341. package/src/workbench/bootstrap/useWorkbenchBootstrap.ts +130 -130
  342. package/src/workbench/chat/ChatCommandProposalCard.tsx +115 -115
  343. package/src/workbench/chat/ChatComposer.tsx +163 -163
  344. package/src/workbench/chat/ChatConversationBar.tsx +134 -134
  345. package/src/workbench/chat/ChatHistoryMenu.tsx +171 -171
  346. package/src/workbench/chat/ChatHistoryMenuRow.tsx +74 -74
  347. package/src/workbench/chat/ChatMessageCollapsible.tsx +119 -115
  348. package/src/workbench/chat/ChatMessageItem.tsx +376 -318
  349. package/src/workbench/chat/ChatMessageList.tsx +134 -134
  350. package/src/workbench/chat/ChatPanel.tsx +177 -168
  351. package/src/workbench/chat/ChatPhasedRunProgress.tsx +275 -202
  352. package/src/workbench/chat/ChatRenameDialog.tsx +77 -77
  353. package/src/workbench/chat/chat-conversation.css +273 -273
  354. package/src/workbench/chat/chat-ui.css +1132 -1124
  355. package/src/workbench/chat/chat.css +3 -3
  356. package/src/workbench/chat/chatConversation.ts +46 -46
  357. package/src/workbench/chat/chatHistoryRowMenuItems.ts +29 -29
  358. package/src/workbench/chat/chatMessageMeta.tsx +252 -252
  359. package/src/workbench/chat/chatScroll.ts +22 -22
  360. package/src/workbench/chat/index.ts +65 -64
  361. package/src/workbench/chat/slashCommand.ts +26 -26
  362. package/src/workbench/chat/types.ts +45 -45
  363. package/src/workbench/chat/useCancelRuntimeOnUnmount.ts +60 -60
  364. package/src/workbench/chat/useChatPrependPagination.ts +233 -233
  365. package/src/workbench/chat/useChatRuntimeState.ts +64 -64
  366. package/src/workbench/chat/useSlashCommandSuggest.ts +154 -154
  367. package/src/workbench/{WorkbenchModalPortal.tsx → chrome/WorkbenchModalPortal.tsx} +52 -52
  368. package/src/workbench/{WorkbenchPlatformContext.tsx → chrome/WorkbenchPlatformContext.tsx} +31 -31
  369. package/src/workbench/chrome/index.css +6 -6
  370. package/src/workbench/chrome/workbench-chrome.css +4 -0
  371. package/src/workbench/chrome/workbench-desktop-titlebar.css +60 -60
  372. package/src/workbench/chrome/workbench-host.css +85 -85
  373. package/src/workbench/chrome/workbench-layout-regions.css +42 -42
  374. package/src/workbench/chrome/workbench-platform-chrome.css +142 -142
  375. package/src/workbench/chrome/workbench-shell-titlebar.css +124 -124
  376. package/src/workbench/{workbenchModalViewState.ts → chrome/workbenchModalViewState.ts} +52 -52
  377. package/src/workbench/{workbenchOverlaysContext.tsx → chrome/workbenchOverlaysContext.tsx} +21 -21
  378. package/src/workbench/{workbenchPlatformChrome.ts → chrome/workbenchPlatformChrome.ts} +40 -40
  379. package/src/workbench/command-palette/command-palette.css +156 -156
  380. package/src/workbench/{CommandGroupShell.tsx → commands/CommandGroupShell.tsx} +131 -131
  381. package/src/workbench/{CommandList.tsx → commands/CommandList.tsx} +167 -167
  382. package/src/workbench/{CommandPalette.tsx → commands/CommandPalette.tsx} +391 -417
  383. package/src/workbench/{ConfirmationFlow.tsx → commands/ConfirmationFlow.tsx} +243 -243
  384. package/src/workbench/{ShortcutCommandBridge.tsx → commands/ShortcutCommandBridge.tsx} +365 -365
  385. package/src/workbench/{command-execution-policy.ts → commands/command-execution-policy.ts} +61 -61
  386. package/src/workbench/{command-model.ts → commands/command-model.ts} +279 -275
  387. package/src/workbench/{commands.ts → commands/commands.ts} +576 -576
  388. package/src/workbench/{keyboard.ts → commands/keyboard.ts} +53 -53
  389. package/src/workbench/{workbenchContextMenu.ts → commands/workbenchContextMenu.ts} +18 -18
  390. package/src/workbench/{WorkbenchEditorTabs.tsx → editor/WorkbenchEditorTabs.tsx} +52 -52
  391. package/src/workbench/{editor-tabs-dnd.ts → editor/editor-tabs-dnd.ts} +162 -162
  392. package/src/workbench/{editorTabContextMenu.ts → editor/editorTabContextMenu.ts} +111 -111
  393. package/src/workbench/{useEditorTabsStripDnd.ts → editor/useEditorTabsStripDnd.ts} +262 -262
  394. package/src/workbench/{useWorkbenchEditorTabContextMenu.tsx → editor/useWorkbenchEditorTabContextMenu.tsx} +66 -66
  395. package/src/workbench/editor-tabs/index.ts +22 -22
  396. package/src/workbench/index.ts +694 -675
  397. package/src/workbench/management/AccountManagementPanel.tsx +82 -82
  398. package/src/workbench/management/CommandInspectorPanel.tsx +127 -127
  399. package/src/workbench/management/CommandManagementPanel.tsx +129 -129
  400. package/src/workbench/management/CommandManagementSidebar.tsx +318 -318
  401. package/src/workbench/management/ExtensionManagementPanel.tsx +527 -498
  402. package/src/workbench/management/ExtensionManagementSidebar.tsx +509 -492
  403. package/src/workbench/management/IntegrationCommandActions.tsx +78 -78
  404. package/src/workbench/management/IntegrationSettingsSurface.tsx +290 -290
  405. package/src/workbench/management/IntegrationsShell.tsx +53 -53
  406. package/src/workbench/management/KeybindingCaptureField.tsx +142 -142
  407. package/src/workbench/management/KeybindingManagementPanel.tsx +120 -120
  408. package/src/workbench/management/LibraryCatalogPickerDialog.tsx +208 -208
  409. package/src/workbench/management/LibraryFacetFilterDialog.tsx +62 -62
  410. package/src/workbench/management/ManagementCard.tsx +89 -89
  411. package/src/workbench/management/ManagementFilterChips.tsx +41 -41
  412. package/src/workbench/management/ManagementGroup.tsx +56 -56
  413. package/src/workbench/management/ManagementPanelControls.tsx +43 -43
  414. package/src/workbench/management/ManagementPanelFrame.tsx +109 -109
  415. package/src/workbench/management/WorkbenchDialogFrame.tsx +148 -148
  416. package/src/workbench/management/WorkbenchNotice.tsx +211 -211
  417. package/src/workbench/management/build-command-management-groups.ts +157 -157
  418. package/src/workbench/management/command-inspector-uri.ts +26 -26
  419. package/src/workbench/management/extension-category-display.ts +42 -42
  420. package/src/workbench/management/extension-install-approval.ts +72 -0
  421. package/src/workbench/management/format-command-run-state.ts +19 -19
  422. package/src/workbench/management/index.ts +137 -130
  423. package/src/workbench/management/integration-command-action.ts +25 -25
  424. package/src/workbench/management/library-catalog-picker-dialog.css +56 -56
  425. package/src/workbench/management/library-facet-filter-dialog.css +8 -8
  426. package/src/workbench/management/management-panel.css +444 -444
  427. package/src/workbench/management/management.css +4 -4
  428. package/src/workbench/management/types.ts +139 -126
  429. package/src/workbench/{MarkdownPreview.tsx → markdown/MarkdownPreview.tsx} +162 -147
  430. package/src/workbench/markdown/markdownRemarkPlugins.ts +12 -0
  431. package/src/workbench/markdown/sanitizeMarkdownHref.ts +29 -0
  432. package/src/workbench/schema/index.ts +47 -47
  433. package/src/workbench/schema/workbenchDocument.ts +31 -31
  434. package/src/workbench/schema/workbenchDocumentActions.ts +6 -6
  435. package/src/workbench/schema/workbenchDocumentAdapter.ts +9 -9
  436. package/src/workbench/schema/workbenchDocumentPatch.ts +13 -13
  437. package/src/workbench/schema/workbenchDocumentRenderer.tsx +702 -702
  438. package/src/workbench/settings/NavigationPanel.tsx +86 -86
  439. package/src/workbench/settings/SchemaForm.tsx +433 -433
  440. package/src/workbench/settings/SectionTabPanel.tsx +172 -172
  441. package/src/workbench/settings/SectionedPanel.tsx +169 -169
  442. package/src/workbench/settings/StructuredDataForm.tsx +619 -619
  443. package/src/workbench/settings/StructuredDataSchemaPanel.tsx +811 -811
  444. package/src/workbench/settings/StructuredDataSchemaPanelEmbed.tsx +21 -21
  445. package/src/workbench/settings/StructuredDataSchemaPanelFrame.tsx +76 -76
  446. package/src/workbench/settings/StructuredDataTableView.tsx +127 -127
  447. package/src/workbench/settings/WorkbenchPanelRegion.tsx +46 -46
  448. package/src/workbench/settings/WorkbenchSettingsModal.tsx +251 -251
  449. package/src/workbench/settings/WorkbenchSettingsNav.tsx +57 -57
  450. package/src/workbench/settings/WorkbenchSettingsSection.tsx +30 -30
  451. package/src/workbench/settings/extensionSettingsForm.ts +34 -34
  452. package/src/workbench/settings/index.ts +177 -177
  453. package/src/workbench/settings/navigation-panel.css +59 -59
  454. package/src/workbench/settings/panel-region.css +22 -22
  455. package/src/workbench/settings/schema-form.css +36 -36
  456. package/src/workbench/settings/schemaFormSettingSpec.ts +177 -177
  457. package/src/workbench/settings/schemaFormSettingsCategory.tsx +21 -21
  458. package/src/workbench/settings/section-tab-panel.css +157 -157
  459. package/src/workbench/settings/sectionScrollSpyDom.ts +139 -139
  460. package/src/workbench/settings/sectioned-panel.css +162 -162
  461. package/src/workbench/settings/sectionedPanelScrollSpy.ts +273 -273
  462. package/src/workbench/settings/settings-responsive.css +58 -58
  463. package/src/workbench/settings/settings.css +11 -11
  464. package/src/workbench/settings/settingsCommit.tsx +55 -55
  465. package/src/workbench/settings/structured-data-form.css +114 -114
  466. package/src/workbench/settings/structured-data-schema-panel.css +344 -344
  467. package/src/workbench/settings/structured-data-table-view.css +85 -85
  468. package/src/workbench/settings/structuredDataFormModel.ts +140 -140
  469. package/src/workbench/settings/structuredDataSchema.ts +339 -339
  470. package/src/workbench/settings/structuredDataSchemaDate.ts +197 -197
  471. package/src/workbench/settings/structuredDataSchemaField.ts +105 -105
  472. package/src/workbench/settings/structuredDataSchemaSection.ts +74 -74
  473. package/src/workbench/settings/structuredDataSchemaTable.ts +120 -120
  474. package/src/workbench/settings/structuredDataSchemaTypes.ts +308 -308
  475. package/src/workbench/settings/structuredDataSchemaValidation.ts +166 -166
  476. package/src/workbench/settings/types.ts +16 -16
  477. package/src/workbench/settings/useSectionScrollSpy.ts +420 -420
  478. package/src/workbench/settings/workbench-settings-modal.css +273 -273
  479. package/src/workbench/{ActivityBar.tsx → shell/ActivityBar.tsx} +159 -159
  480. package/src/workbench/{ArtifactShell.tsx → shell/ArtifactShell.tsx} +397 -397
  481. package/src/workbench/{SplitView.tsx → shell/SplitView.tsx} +485 -485
  482. package/src/workbench/{StatusBar.tsx → shell/StatusBar.tsx} +180 -180
  483. package/src/workbench/{StructuredArtifactEditor.tsx → shell/StructuredArtifactEditor.tsx} +205 -205
  484. package/src/workbench/{Timeline.tsx → shell/Timeline.tsx} +297 -297
  485. package/src/workbench/{WorkbenchCanvasShell.defaults.ts → shell/WorkbenchCanvasShell.defaults.ts} +106 -106
  486. package/src/workbench/{WorkbenchCanvasShell.model.ts → shell/WorkbenchCanvasShell.model.ts} +46 -46
  487. package/src/workbench/{WorkbenchCanvasShell.tsx → shell/WorkbenchCanvasShell.tsx} +827 -827
  488. package/src/workbench/{WorkbenchDesktopTitleBar.tsx → shell/WorkbenchDesktopTitleBar.tsx} +126 -126
  489. package/src/workbench/{WorkbenchShell.tsx → shell/WorkbenchShell.tsx} +192 -192
  490. package/src/workbench/{WorkbenchShellTitleBarLayoutControls.tsx → shell/WorkbenchShellTitleBarLayoutControls.tsx} +80 -80
  491. package/src/workbench/{WorkbenchStandaloneShell.tsx → shell/WorkbenchStandaloneShell.tsx} +604 -604
  492. package/src/workbench/{WorkbenchViewEditor.tsx → shell/WorkbenchViewEditor.tsx} +75 -75
  493. package/src/workbench/{WorkbenchViewSidebar.tsx → shell/WorkbenchViewSidebar.tsx} +85 -85
  494. package/src/workbench/{WorkbenchWindowChromeControls.tsx → shell/WorkbenchWindowChromeControls.tsx} +293 -290
  495. package/src/workbench/shell/activity-bar.css +245 -245
  496. package/src/workbench/{activityBarOrder.ts → shell/activityBarOrder.ts} +98 -98
  497. package/src/workbench/{appearanceLabels.ts → shell/appearanceLabels.ts} +28 -28
  498. package/src/workbench/shell/confirmation-flow.css +87 -87
  499. package/src/workbench/{hardReset.ts → shell/hardReset.ts} +64 -64
  500. package/src/workbench/shell/index.css +5 -5
  501. package/src/workbench/{shell.ts → shell/shell.ts} +152 -146
  502. package/src/workbench/{shellPresets.ts → shell/shellPresets.ts} +36 -36
  503. package/src/workbench/{shellState.ts → shell/shellState.ts} +196 -196
  504. package/src/workbench/{shellViewModel.ts → shell/shellViewModel.ts} +160 -160
  505. package/src/workbench/{sidebarViewPlacementDnd.ts → shell/sidebarViewPlacementDnd.ts} +61 -61
  506. package/src/workbench/shell/split-view.css +188 -188
  507. package/src/workbench/{standalone.ts → shell/standalone.ts} +101 -101
  508. package/src/workbench/shell/status-bar.css +141 -141
  509. package/src/workbench/{status.ts → shell/status.ts} +133 -133
  510. package/src/workbench/{useDeferredWorkbenchMount.ts → shell/useDeferredWorkbenchMount.ts} +71 -71
  511. package/src/workbench/{useWorkbenchAppearanceDocumentSync.tsx → shell/useWorkbenchAppearanceDocumentSync.tsx} +17 -17
  512. package/src/workbench/{useWorkbenchSidebarActionBarDnd.ts → shell/useWorkbenchSidebarActionBarDnd.ts} +227 -227
  513. package/src/workbench/{useWorkbenchSidebarLayout.tsx → shell/useWorkbenchSidebarLayout.tsx} +232 -232
  514. package/src/workbench/{useWorkbenchSidebarViewPlacementDropZone.ts → shell/useWorkbenchSidebarViewPlacementDropZone.ts} +194 -194
  515. package/src/workbench/{useWorkbenchStandaloneShellStateSync.tsx → shell/useWorkbenchStandaloneShellStateSync.tsx} +112 -112
  516. package/src/workbench/{workbenchSidebarLayoutContext.ts → shell/workbenchSidebarLayoutContext.ts} +46 -46
  517. package/src/workbench/{workbenchStandaloneShellReactContext.tsx → shell/workbenchStandaloneShellReactContext.tsx} +80 -80
  518. package/src/workbench/{workbenchViewRouteState.ts → shell/workbenchViewRouteState.ts} +151 -151
  519. package/src/workbench/{WorkbenchThemeProvider.tsx → theme/WorkbenchThemeProvider.tsx} +142 -142
  520. package/src/workbench/{theme.ts → theme/theme.ts} +50 -50
  521. package/src/workbench/{themePresets.ts → theme/themePresets.ts} +191 -191
  522. package/src/workbench/views/action-list.css +144 -144
  523. package/src/workbench/views/artifact-preview.css +184 -184
  524. package/src/workbench/views/command-inspector.css +98 -98
  525. package/src/workbench/views/command-list.css +356 -356
  526. package/src/workbench/views/commands-sidebar.css +51 -51
  527. package/src/workbench/views/extensions-sidebar.css +175 -175
  528. package/src/workbench/views/multi-provider-explorer.css +182 -182
  529. package/src/workbench/views/search.css +10 -10
  530. package/src/workbench/views/timeline.css +239 -239
  531. package/src/workbench/views/view-hosts.css +37 -37
  532. package/src/workbench/views/view-sidebar.css +21 -21
  533. package/src/workbench/views/views.css +12 -12
  534. package/src/workbench/widgets/widget-tree.css +598 -598
  535. package/src/workbench/widgets/widgets.css +2 -2
  536. package/src/workbench/workspace/WorkspaceDraftsContext.tsx +99 -99
  537. package/src/workbench/workspace/WorkspaceEditor.tsx +165 -165
  538. package/src/workbench/workspace/WorkspaceEditorPanel.tsx +393 -393
  539. package/src/workbench/workspace/WorkspaceExplorer.tsx +630 -630
  540. package/src/workbench/workspace/WorkspaceExplorerPanel.tsx +73 -73
  541. package/src/workbench/workspace/WorkspaceFileIcon.tsx +23 -23
  542. package/src/workbench/workspace/WorkspaceHighlightedText.tsx +22 -22
  543. package/src/workbench/workspace/WorkspacePathLabel.tsx +42 -42
  544. package/src/workbench/workspace/WorkspaceSearchPanel.tsx +116 -116
  545. package/src/workbench/workspace/WorkspaceSearchResults.tsx +51 -51
  546. package/src/workbench/workspace/build-workspace-explorer-nodes.ts +44 -44
  547. package/src/workbench/workspace/createVirtualWorkspaceExplorerPort.ts +141 -141
  548. package/src/workbench/workspace/explorer-tree-style.ts +18 -18
  549. package/src/workbench/workspace/index.ts +169 -169
  550. package/src/workbench/workspace/json-config-workbench.css +57 -57
  551. package/src/workbench/workspace/mimeType.ts +45 -45
  552. package/src/workbench/workspace/monaco-panel.css +71 -71
  553. package/src/workbench/workspace/path.ts +12 -12
  554. package/src/workbench/workspace/search.ts +6 -6
  555. package/src/workbench/workspace/tree.ts +1 -1
  556. package/src/workbench/workspace/types.ts +10 -10
  557. package/src/workbench/workspace/useVirtualWorkspace.ts +111 -111
  558. package/src/workbench/workspace/useWorkspaceExplorerController.ts +490 -490
  559. package/src/workbench/workspace/workspace-editor.css +235 -235
  560. package/src/workbench/workspace/workspace-explorer-panel.css +33 -33
  561. package/src/workbench/workspace/workspace.css +5 -5
  562. package/src/workbench/workspace/workspaceExplorerController.ts +193 -193
  563. package/src/workbench/workspace/workspaceJsonDiagnostics.ts +84 -83
  564. package/src/workbench-menu-surfaces.css +57 -57
  565. package/src/workbench/jdw/jdw-editors.css +0 -4
  566. package/src/workbench/jdw/jdw.css +0 -2
  567. package/src/workbench/markdownRemarkPlugins.ts +0 -4
  568. package/src/workbench/workbench-chrome.css +0 -4
@@ -1,956 +1,956 @@
1
- import { forwardRef, useRef } from 'react';
2
- import type {
3
- ComponentPropsWithRef,
4
- CSSProperties,
5
- PointerEvent as ReactPointerEvent,
6
- ReactNode,
7
- } from 'react';
8
- import { Button } from '../primitives/button';
9
- import { cx } from '../utils/cx';
10
- import { toAngleValue, toLineLengthValue, toLengthValue } from './layoutHelpers';
11
-
12
- export interface WorkbenchCanvasItemFrameProps extends ComponentPropsWithRef<'div'> {
13
- cursor?: CSSProperties['cursor'] | undefined;
14
- focused?: boolean | undefined;
15
- height: number | string;
16
- hovered?: boolean | undefined;
17
- interactive?: boolean | undefined;
18
- opacity?: number | string | undefined;
19
- overflow?: CSSProperties['overflow'] | undefined;
20
- rotation?: number | string | undefined;
21
- selected?: boolean | undefined;
22
- touchAction?: CSSProperties['touchAction'] | undefined;
23
- transform?: string | undefined;
24
- transient?: boolean | undefined;
25
- width: number | string;
26
- x: number | string;
27
- y: number | string;
28
- zIndex?: number | string | undefined;
29
- }
30
-
31
- export const WorkbenchCanvasItemFrame = forwardRef<HTMLDivElement, WorkbenchCanvasItemFrameProps>(
32
- function WorkbenchCanvasItemFrame(
33
- {
34
- className,
35
- cursor,
36
- focused = false,
37
- height,
38
- hovered = false,
39
- interactive = false,
40
- opacity,
41
- overflow,
42
- rotation,
43
- selected = false,
44
- style,
45
- touchAction,
46
- transform,
47
- transient = false,
48
- width,
49
- x,
50
- y,
51
- zIndex,
52
- ...props
53
- },
54
- ref,
55
- ) {
56
- const frameStyle = {
57
- '--ui-workbench-canvas-item-x': toLengthValue(x),
58
- '--ui-workbench-canvas-item-y': toLengthValue(y),
59
- '--ui-workbench-canvas-item-width': toLengthValue(width),
60
- '--ui-workbench-canvas-item-height': toLengthValue(height),
61
- ...(cursor !== undefined ? { '--ui-workbench-canvas-item-cursor': cursor } : {}),
62
- ...(opacity !== undefined ? { '--ui-workbench-canvas-item-opacity': String(opacity) } : {}),
63
- ...(overflow !== undefined ? { '--ui-workbench-canvas-item-overflow': overflow } : {}),
64
- ...(rotation !== undefined
65
- ? { '--ui-workbench-canvas-item-transform': `rotate(${toAngleValue(rotation)})` }
66
- : {}),
67
- ...(touchAction !== undefined
68
- ? { '--ui-workbench-canvas-item-touch-action': touchAction }
69
- : {}),
70
- ...(transform !== undefined ? { '--ui-workbench-canvas-item-transform': transform } : {}),
71
- ...(zIndex !== undefined ? { '--ui-workbench-canvas-item-z-index': String(zIndex) } : {}),
72
- ...style,
73
- } as CSSProperties;
74
-
75
- return (
76
- <div
77
- ref={ref}
78
- aria-selected={selected}
79
- className={cx('ui-workbench-canvas-item-frame', className)}
80
- data-focused={focused ? 'true' : 'false'}
81
- data-hovered={hovered ? 'true' : 'false'}
82
- data-interactive={interactive ? 'true' : 'false'}
83
- data-selected={selected ? 'true' : 'false'}
84
- data-transient={transient ? 'true' : 'false'}
85
- style={frameStyle}
86
- {...props}
87
- />
88
- );
89
- },
90
- );
91
-
92
- export interface WorkbenchCanvasPaneSurfaceProps extends ComponentPropsWithRef<'div'> {
93
- children?: ReactNode;
94
- }
95
-
96
- export const WorkbenchCanvasPaneSurface = forwardRef<
97
- HTMLDivElement,
98
- WorkbenchCanvasPaneSurfaceProps
99
- >(function WorkbenchCanvasPaneSurface({ className, ...props }, ref) {
100
- return <div ref={ref} className={cx('ui-workbench-canvas-pane-surface', className)} {...props} />;
101
- });
102
-
103
- export interface WorkbenchCanvasFrameSurfaceProps extends ComponentPropsWithRef<'div'> {
104
- bottom?: number | string | undefined;
105
- height?: number | string | undefined;
106
- left?: number | string | undefined;
107
- opacity?: number | string | undefined;
108
- right?: number | string | undefined;
109
- selected?: boolean | undefined;
110
- top?: number | string | undefined;
111
- transform?: string | undefined;
112
- transient?: boolean | undefined;
113
- width?: number | string | undefined;
114
- }
115
-
116
- export function WorkbenchCanvasFrameSurface({
117
- bottom,
118
- className,
119
- height,
120
- left,
121
- opacity,
122
- right,
123
- selected = false,
124
- style,
125
- top,
126
- transform,
127
- transient = false,
128
- width,
129
- ...props
130
- }: WorkbenchCanvasFrameSurfaceProps) {
131
- const surfaceStyle = {
132
- ...(bottom !== undefined
133
- ? { '--ui-workbench-canvas-frame-bottom': toLengthValue(bottom) }
134
- : {}),
135
- ...(height !== undefined
136
- ? { '--ui-workbench-canvas-frame-height': toLengthValue(height) }
137
- : {}),
138
- ...(left !== undefined ? { '--ui-workbench-canvas-frame-left': toLengthValue(left) } : {}),
139
- ...(opacity !== undefined ? { '--ui-workbench-canvas-frame-opacity': String(opacity) } : {}),
140
- ...(right !== undefined ? { '--ui-workbench-canvas-frame-right': toLengthValue(right) } : {}),
141
- ...(top !== undefined ? { '--ui-workbench-canvas-frame-top': toLengthValue(top) } : {}),
142
- ...(transform !== undefined ? { '--ui-workbench-canvas-frame-transform': transform } : {}),
143
- ...(width !== undefined ? { '--ui-workbench-canvas-frame-width': toLengthValue(width) } : {}),
144
- ...style,
145
- } as CSSProperties;
146
-
147
- return (
148
- <div
149
- className={cx('ui-workbench-canvas-frame-surface', className)}
150
- data-selected={selected ? 'true' : 'false'}
151
- data-transient={transient ? 'true' : 'false'}
152
- style={surfaceStyle}
153
- {...props}
154
- />
155
- );
156
- }
157
-
158
- export interface WorkbenchCanvasViewportProps extends ComponentPropsWithRef<'div'> {
159
- children?: ReactNode;
160
- grid?: boolean | undefined;
161
- gridSize?: number | string | undefined;
162
- height: number | string;
163
- width: number | string;
164
- }
165
-
166
- export const WorkbenchCanvasViewport = forwardRef<HTMLDivElement, WorkbenchCanvasViewportProps>(
167
- function WorkbenchCanvasViewport(
168
- { className, grid = true, gridSize = 20, height, style, width, ...props },
169
- ref,
170
- ) {
171
- const viewportStyle = {
172
- '--ui-workbench-canvas-viewport-width': toLengthValue(width),
173
- '--ui-workbench-canvas-viewport-height': toLengthValue(height),
174
- '--ui-workbench-canvas-viewport-grid-size': toLengthValue(gridSize),
175
- ...style,
176
- } as CSSProperties;
177
-
178
- return (
179
- <div
180
- ref={ref}
181
- className={cx('ui-workbench-canvas-viewport', className)}
182
- data-grid={grid ? 'true' : 'false'}
183
- style={viewportStyle}
184
- {...props}
185
- />
186
- );
187
- },
188
- );
189
-
190
- export interface WorkbenchCanvasSelectionMarqueeProps extends ComponentPropsWithRef<'div'> {
191
- height: number | string;
192
- width: number | string;
193
- x: number | string;
194
- y: number | string;
195
- }
196
-
197
- export function WorkbenchCanvasSelectionMarquee({
198
- className,
199
- height,
200
- style,
201
- width,
202
- x,
203
- y,
204
- ...props
205
- }: WorkbenchCanvasSelectionMarqueeProps) {
206
- const marqueeStyle = {
207
- '--ui-workbench-canvas-selection-marquee-x': toLengthValue(x),
208
- '--ui-workbench-canvas-selection-marquee-y': toLengthValue(y),
209
- '--ui-workbench-canvas-selection-marquee-width': toLengthValue(width),
210
- '--ui-workbench-canvas-selection-marquee-height': toLengthValue(height),
211
- ...style,
212
- } as CSSProperties;
213
-
214
- return (
215
- <div
216
- className={cx('ui-workbench-canvas-selection-marquee', className)}
217
- style={marqueeStyle}
218
- {...props}
219
- />
220
- );
221
- }
222
-
223
- export type WorkbenchCanvasGuideBlockTone = 'gap' | 'padding';
224
-
225
- export interface WorkbenchCanvasGuideBlockProps extends ComponentPropsWithRef<'div'> {
226
- height: number | string;
227
- tone?: WorkbenchCanvasGuideBlockTone | undefined;
228
- width: number | string;
229
- x: number | string;
230
- y: number | string;
231
- zIndex?: number | string | undefined;
232
- }
233
-
234
- export function WorkbenchCanvasGuideBlock({
235
- className,
236
- height,
237
- style,
238
- tone = 'gap',
239
- width,
240
- x,
241
- y,
242
- zIndex,
243
- ...props
244
- }: WorkbenchCanvasGuideBlockProps) {
245
- const blockStyle = {
246
- '--ui-workbench-canvas-guide-block-x': toLengthValue(x),
247
- '--ui-workbench-canvas-guide-block-y': toLengthValue(y),
248
- '--ui-workbench-canvas-guide-block-width': toLengthValue(width),
249
- '--ui-workbench-canvas-guide-block-height': toLengthValue(height),
250
- ...(zIndex !== undefined
251
- ? { '--ui-workbench-canvas-guide-block-z-index': String(zIndex) }
252
- : {}),
253
- ...style,
254
- } as CSSProperties;
255
-
256
- return (
257
- <div
258
- className={cx('ui-workbench-canvas-guide-block', className)}
259
- data-tone={tone}
260
- style={blockStyle}
261
- {...props}
262
- />
263
- );
264
- }
265
-
266
- export interface WorkbenchCanvasPlaceholderProps extends ComponentPropsWithRef<'div'> {
267
- height?: number | string | undefined;
268
- width?: number | string | undefined;
269
- x?: number | string | undefined;
270
- y?: number | string | undefined;
271
- }
272
-
273
- export function WorkbenchCanvasPlaceholder({
274
- className,
275
- height,
276
- style,
277
- width,
278
- x,
279
- y,
280
- ...props
281
- }: WorkbenchCanvasPlaceholderProps) {
282
- const positioned =
283
- x !== undefined || y !== undefined || width !== undefined || height !== undefined;
284
- const placeholderStyle = {
285
- ...(x !== undefined ? { '--ui-workbench-canvas-placeholder-x': toLengthValue(x) } : {}),
286
- ...(y !== undefined ? { '--ui-workbench-canvas-placeholder-y': toLengthValue(y) } : {}),
287
- ...(width !== undefined
288
- ? { '--ui-workbench-canvas-placeholder-width': toLengthValue(width) }
289
- : {}),
290
- ...(height !== undefined
291
- ? { '--ui-workbench-canvas-placeholder-height': toLengthValue(height) }
292
- : {}),
293
- ...style,
294
- } as CSSProperties;
295
-
296
- return (
297
- <div
298
- className={cx('ui-workbench-canvas-placeholder', className)}
299
- data-positioned={positioned ? 'true' : 'false'}
300
- style={placeholderStyle}
301
- {...props}
302
- />
303
- );
304
- }
305
-
306
- export interface WorkbenchCanvasDropIndicatorProps extends ComponentPropsWithRef<'div'> {
307
- height: number | string;
308
- width: number | string;
309
- x: number | string;
310
- y: number | string;
311
- zIndex?: number | string | undefined;
312
- }
313
-
314
- export function WorkbenchCanvasDropIndicator({
315
- className,
316
- height,
317
- style,
318
- width,
319
- x,
320
- y,
321
- zIndex,
322
- ...props
323
- }: WorkbenchCanvasDropIndicatorProps) {
324
- const indicatorStyle = {
325
- '--ui-workbench-canvas-drop-indicator-x': toLengthValue(x),
326
- '--ui-workbench-canvas-drop-indicator-y': toLengthValue(y),
327
- '--ui-workbench-canvas-drop-indicator-width': toLengthValue(width),
328
- '--ui-workbench-canvas-drop-indicator-height': toLengthValue(height),
329
- ...(zIndex !== undefined
330
- ? { '--ui-workbench-canvas-drop-indicator-z-index': String(zIndex) }
331
- : {}),
332
- ...style,
333
- } as CSSProperties;
334
-
335
- return (
336
- <div
337
- className={cx('ui-workbench-canvas-drop-indicator', className)}
338
- style={indicatorStyle}
339
- {...props}
340
- />
341
- );
342
- }
343
-
344
- export interface WorkbenchCanvasDragPreviewFrameProps extends ComponentPropsWithRef<'div'> {
345
- height: number | string;
346
- opacity?: number | string | undefined;
347
- rotation?: number | string | undefined;
348
- width: number | string;
349
- x: number | string;
350
- y: number | string;
351
- zIndex?: number | string | undefined;
352
- }
353
-
354
- export function WorkbenchCanvasDragPreviewFrame({
355
- className,
356
- height,
357
- opacity,
358
- rotation,
359
- style,
360
- width,
361
- x,
362
- y,
363
- zIndex,
364
- ...props
365
- }: WorkbenchCanvasDragPreviewFrameProps) {
366
- const frameStyle = {
367
- '--ui-workbench-canvas-drag-preview-frame-x': toLengthValue(x),
368
- '--ui-workbench-canvas-drag-preview-frame-y': toLengthValue(y),
369
- '--ui-workbench-canvas-drag-preview-frame-width': toLengthValue(width),
370
- '--ui-workbench-canvas-drag-preview-frame-height': toLengthValue(height),
371
- ...(opacity !== undefined
372
- ? { '--ui-workbench-canvas-drag-preview-frame-opacity': String(opacity) }
373
- : {}),
374
- ...(rotation !== undefined
375
- ? {
376
- '--ui-workbench-canvas-drag-preview-frame-transform': `rotate(${toAngleValue(rotation)})`,
377
- }
378
- : {}),
379
- ...(zIndex !== undefined
380
- ? { '--ui-workbench-canvas-drag-preview-frame-z-index': String(zIndex) }
381
- : {}),
382
- ...style,
383
- } as CSSProperties;
384
-
385
- return (
386
- <div
387
- className={cx('ui-workbench-canvas-drag-preview-frame', className)}
388
- style={frameStyle}
389
- {...props}
390
- />
391
- );
392
- }
393
-
394
- export type WorkbenchCanvasGuideLineAxis = 'x' | 'y';
395
- export type WorkbenchCanvasGuideLineSource = 'grid' | 'object';
396
-
397
- export type WorkbenchCanvasGuideLayerProps = ComponentPropsWithRef<'div'>;
398
-
399
- export function WorkbenchCanvasGuideLayer({ className, ...props }: WorkbenchCanvasGuideLayerProps) {
400
- return <div className={cx('ui-workbench-canvas-guide-layer', className)} {...props} />;
401
- }
402
-
403
- export interface WorkbenchCanvasGuideLineProps extends ComponentPropsWithRef<'div'> {
404
- axis: WorkbenchCanvasGuideLineAxis;
405
- end: number | string;
406
- position: number | string;
407
- source?: WorkbenchCanvasGuideLineSource | undefined;
408
- start: number | string;
409
- }
410
-
411
- export function WorkbenchCanvasGuideLine({
412
- axis,
413
- className,
414
- end,
415
- position,
416
- source = 'object',
417
- start,
418
- style,
419
- ...props
420
- }: WorkbenchCanvasGuideLineProps) {
421
- const lineStyle = {
422
- '--ui-workbench-canvas-guide-line-position': toLengthValue(position),
423
- '--ui-workbench-canvas-guide-line-start': toLengthValue(start),
424
- '--ui-workbench-canvas-guide-line-length': toLineLengthValue(start, end),
425
- ...style,
426
- } as CSSProperties;
427
-
428
- return (
429
- <div
430
- className={cx('ui-workbench-canvas-guide-line', className)}
431
- data-axis={axis}
432
- data-source={source}
433
- style={lineStyle}
434
- {...props}
435
- />
436
- );
437
- }
438
-
439
- export interface WorkbenchCanvasDragGhostProps extends ComponentPropsWithRef<'div'> {
440
- height: number | string;
441
- width: number | string;
442
- x: number | string;
443
- y: number | string;
444
- zIndex?: number | string | undefined;
445
- }
446
-
447
- export function WorkbenchCanvasDragGhost({
448
- className,
449
- height,
450
- style,
451
- width,
452
- x,
453
- y,
454
- zIndex,
455
- ...props
456
- }: WorkbenchCanvasDragGhostProps) {
457
- const ghostStyle = {
458
- '--ui-workbench-canvas-drag-ghost-x': toLengthValue(x),
459
- '--ui-workbench-canvas-drag-ghost-y': toLengthValue(y),
460
- '--ui-workbench-canvas-drag-ghost-width': toLengthValue(width),
461
- '--ui-workbench-canvas-drag-ghost-height': toLengthValue(height),
462
- ...(zIndex !== undefined ? { '--ui-workbench-canvas-drag-ghost-z-index': String(zIndex) } : {}),
463
- ...style,
464
- } as CSSProperties;
465
-
466
- return (
467
- <div
468
- className={cx('ui-workbench-canvas-drag-ghost', className)}
469
- style={ghostStyle}
470
- {...props}
471
- />
472
- );
473
- }
474
-
475
- export interface WorkbenchCanvasDragGhostContentProps extends ComponentPropsWithRef<'div'> {
476
- height: number | string;
477
- width: number | string;
478
- }
479
-
480
- export function WorkbenchCanvasDragGhostContent({
481
- className,
482
- height,
483
- style,
484
- width,
485
- ...props
486
- }: WorkbenchCanvasDragGhostContentProps) {
487
- const contentStyle = {
488
- '--ui-workbench-canvas-drag-ghost-content-width': toLengthValue(width),
489
- '--ui-workbench-canvas-drag-ghost-content-height': toLengthValue(height),
490
- ...style,
491
- } as CSSProperties;
492
-
493
- return (
494
- <div
495
- className={cx('ui-workbench-canvas-drag-ghost-content', className)}
496
- style={contentStyle}
497
- {...props}
498
- />
499
- );
500
- }
501
-
502
- interface WorkbenchCanvasFrameHandleDrag {
503
- pointerId: number;
504
- startX: number;
505
- startY: number;
506
- }
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
-
531
- export interface WorkbenchCanvasFrameHandleProps extends Omit<
532
- ComponentPropsWithRef<'div'>,
533
- | 'children'
534
- | 'onDragEnd'
535
- | 'onDragStart'
536
- | 'onPointerCancel'
537
- | 'onPointerDown'
538
- | 'onPointerMove'
539
- | 'onPointerUp'
540
- > {
541
- children?: ReactNode;
542
- label?: ReactNode;
543
- onDragCancel?: (event: ReactPointerEvent<HTMLDivElement>) => void;
544
- onDragEnd?: (dx: number, dy: number, event: ReactPointerEvent<HTMLDivElement>) => void;
545
- onDragMove?: (dx: number, dy: number, event: ReactPointerEvent<HTMLDivElement>) => void;
546
- onDragStart?: (event: ReactPointerEvent<HTMLDivElement>) => void;
547
- onPointerCancel?: (event: ReactPointerEvent<HTMLDivElement>) => void;
548
- onPointerDown?: (event: ReactPointerEvent<HTMLDivElement>) => void;
549
- onPointerMove?: (event: ReactPointerEvent<HTMLDivElement>) => void;
550
- onPointerUp?: (event: ReactPointerEvent<HTMLDivElement>) => void;
551
- stopPropagation?: boolean;
552
- }
553
-
554
- export function WorkbenchCanvasFrameHandle({
555
- children,
556
- className,
557
- label,
558
- onDragCancel,
559
- onDragEnd,
560
- onDragMove,
561
- onDragStart,
562
- onPointerCancel,
563
- onPointerDown,
564
- onPointerMove,
565
- onPointerUp,
566
- stopPropagation = true,
567
- ...props
568
- }: WorkbenchCanvasFrameHandleProps) {
569
- const handleRef = useRef<HTMLDivElement>(null);
570
- const dragRef = useRef<WorkbenchCanvasFrameHandleDrag | null>(null);
571
- const content = children ?? label;
572
-
573
- const handlePointerDown = (event: ReactPointerEvent<HTMLDivElement>) => {
574
- onPointerDown?.(event);
575
- if (event.defaultPrevented || event.button !== 0) return;
576
-
577
- const element = handleRef.current;
578
- if (!element) return;
579
-
580
- if (stopPropagation) event.stopPropagation();
581
- dragRef.current = {
582
- pointerId: event.pointerId,
583
- startX: event.clientX,
584
- startY: event.clientY,
585
- };
586
- trySetPointerCapture(element, event.pointerId);
587
- onDragStart?.(event);
588
- };
589
-
590
- const handlePointerMove = (event: ReactPointerEvent<HTMLDivElement>) => {
591
- onPointerMove?.(event);
592
- const drag = dragRef.current;
593
- if (!drag || drag.pointerId !== event.pointerId) return;
594
- onDragMove?.(event.clientX - drag.startX, event.clientY - drag.startY, event);
595
- };
596
-
597
- const handlePointerUp = (event: ReactPointerEvent<HTMLDivElement>) => {
598
- onPointerUp?.(event);
599
- const drag = dragRef.current;
600
- if (!drag || drag.pointerId !== event.pointerId) return;
601
-
602
- tryReleasePointerCapture(handleRef.current, event.pointerId);
603
- dragRef.current = null;
604
- const dx = event.clientX - drag.startX;
605
- const dy = event.clientY - drag.startY;
606
- if (dx !== 0 || dy !== 0) {
607
- onDragEnd?.(dx, dy, event);
608
- } else {
609
- onDragCancel?.(event);
610
- }
611
- };
612
-
613
- const handlePointerCancel = (event: ReactPointerEvent<HTMLDivElement>) => {
614
- onPointerCancel?.(event);
615
- const drag = dragRef.current;
616
- if (!drag || drag.pointerId !== event.pointerId) return;
617
-
618
- tryReleasePointerCapture(handleRef.current, event.pointerId);
619
- dragRef.current = null;
620
- onDragCancel?.(event);
621
- };
622
-
623
- return (
624
- <div
625
- ref={handleRef}
626
- className={cx('ui-workbench-canvas-frame-handle', className)}
627
- onPointerCancel={handlePointerCancel}
628
- onPointerDown={handlePointerDown}
629
- onPointerMove={handlePointerMove}
630
- onPointerUp={handlePointerUp}
631
- {...props}
632
- >
633
- <span className="ui-workbench-canvas-frame-handle__label">{content}</span>
634
- </div>
635
- );
636
- }
637
-
638
- export interface WorkbenchCanvasItemBadgeProps extends ComponentPropsWithRef<'span'> {
639
- selected?: boolean | undefined;
640
- }
641
-
642
- export function WorkbenchCanvasItemBadge({
643
- className,
644
- selected = false,
645
- ...props
646
- }: WorkbenchCanvasItemBadgeProps) {
647
- return (
648
- <span
649
- className={cx('ui-workbench-canvas-item-badge', className)}
650
- data-selected={selected ? 'true' : 'false'}
651
- {...props}
652
- />
653
- );
654
- }
655
-
656
- export interface WorkbenchCanvasResizeHandleProps extends Omit<
657
- ComponentPropsWithRef<'button'>,
658
- 'children'
659
- > {
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;
665
- position?: WorkbenchCanvasResizeHandlePosition | undefined;
666
- stopPropagation?: boolean;
667
- }
668
-
669
- export type WorkbenchCanvasResizeHandlePosition = 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' | 'nw';
670
-
671
- export function WorkbenchCanvasResizeHandle({
672
- className,
673
- label = 'Resize',
674
- onPointerCancel,
675
- onPointerDown,
676
- onPointerMove,
677
- onPointerUp,
678
- onResizeCancel,
679
- onResizeEnd,
680
- onResizeMove,
681
- onResizeStart,
682
- position = 'se',
683
- stopPropagation = true,
684
- type = 'button',
685
- ...props
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
-
740
- return (
741
- <button
742
- ref={handleRef}
743
- aria-label={label}
744
- className={cx('ui-workbench-canvas-resize-handle', className)}
745
- data-position={position}
746
- onPointerCancel={handlePointerCancel}
747
- onPointerDown={handlePointerDown}
748
- onPointerMove={handlePointerMove}
749
- onPointerUp={handlePointerUp}
750
- title={label}
751
- type={type}
752
- {...props}
753
- />
754
- );
755
- }
756
-
757
- export interface WorkbenchCanvasResizeFrameProps extends ComponentPropsWithRef<'div'> {
758
- height: number | string;
759
- width: number | string;
760
- x: number | string;
761
- y: number | string;
762
- zIndex?: number | string;
763
- }
764
-
765
- export const WorkbenchCanvasResizeFrame = forwardRef<
766
- HTMLDivElement,
767
- WorkbenchCanvasResizeFrameProps
768
- >(function WorkbenchCanvasResizeFrame(
769
- { className, height, style, width, x, y, zIndex, ...props },
770
- ref,
771
- ) {
772
- const frameStyle = {
773
- '--ui-workbench-canvas-resize-frame-x': toLengthValue(x),
774
- '--ui-workbench-canvas-resize-frame-y': toLengthValue(y),
775
- '--ui-workbench-canvas-resize-frame-width': toLengthValue(width),
776
- '--ui-workbench-canvas-resize-frame-height': toLengthValue(height),
777
- ...(zIndex !== undefined
778
- ? { '--ui-workbench-canvas-resize-frame-z-index': String(zIndex) }
779
- : {}),
780
- ...style,
781
- } as CSSProperties;
782
-
783
- return (
784
- <div
785
- ref={ref}
786
- className={cx('ui-workbench-canvas-resize-frame', className)}
787
- style={frameStyle}
788
- {...props}
789
- />
790
- );
791
- });
792
-
793
- export interface WorkbenchCanvasResizePreviewProps extends ComponentPropsWithRef<'div'> {
794
- height: number | string;
795
- width: number | string;
796
- x: number | string;
797
- y: number | string;
798
- zIndex?: number | string;
799
- }
800
-
801
- export function WorkbenchCanvasResizePreview({
802
- className,
803
- height,
804
- style,
805
- width,
806
- x,
807
- y,
808
- zIndex,
809
- ...props
810
- }: WorkbenchCanvasResizePreviewProps) {
811
- const previewStyle = {
812
- '--ui-workbench-canvas-resize-preview-x': toLengthValue(x),
813
- '--ui-workbench-canvas-resize-preview-y': toLengthValue(y),
814
- '--ui-workbench-canvas-resize-preview-width': toLengthValue(width),
815
- '--ui-workbench-canvas-resize-preview-height': toLengthValue(height),
816
- ...(zIndex !== undefined
817
- ? { '--ui-workbench-canvas-resize-preview-z-index': String(zIndex) }
818
- : {}),
819
- ...style,
820
- } as CSSProperties;
821
-
822
- return (
823
- <div
824
- className={cx('ui-workbench-canvas-resize-preview', className)}
825
- style={previewStyle}
826
- {...props}
827
- />
828
- );
829
- }
830
-
831
- export interface WorkbenchRenderSurfaceProps extends ComponentPropsWithRef<'div'> {
832
- transparent?: boolean | undefined;
833
- }
834
-
835
- export function WorkbenchRenderSurface({
836
- className,
837
- transparent = false,
838
- ...props
839
- }: WorkbenchRenderSurfaceProps) {
840
- return (
841
- <div
842
- className={cx('ui-workbench-render-surface', className)}
843
- data-transparent={transparent ? 'true' : 'false'}
844
- {...props}
845
- />
846
- );
847
- }
848
-
849
- export interface WorkbenchPreviewCanvasProps extends Omit<
850
- ComponentPropsWithRef<'div'>,
851
- 'children'
852
- > {
853
- children: ReactNode;
854
- frameHeight: number;
855
- frameTitle?: ReactNode;
856
- frameWidth: number;
857
- help?: ReactNode;
858
- isPanning?: boolean;
859
- onResetView?: () => void;
860
- resetLabel?: ReactNode;
861
- resetTitle?: string;
862
- showViewportGrid?: boolean;
863
- showWindowFrame?: boolean;
864
- stageStyle?: CSSProperties;
865
- viewportGridSize?: number;
866
- viewportProps?: ComponentPropsWithRef<'div'>;
867
- }
868
-
869
- export function WorkbenchPreviewCanvas({
870
- children,
871
- className,
872
- frameHeight,
873
- frameTitle = 'Preview',
874
- frameWidth,
875
- help,
876
- isPanning = false,
877
- onResetView,
878
- resetLabel = 'Reset',
879
- resetTitle = 'Reset View',
880
- showViewportGrid = false,
881
- showWindowFrame = true,
882
- stageStyle,
883
- viewportGridSize = 8,
884
- viewportProps,
885
- ...props
886
- }: WorkbenchPreviewCanvasProps) {
887
- const {
888
- className: viewportClassName,
889
- ref: interactionRef,
890
- style: viewportStyle,
891
- ...restViewportProps
892
- } = viewportProps ?? {};
893
-
894
- return (
895
- <div
896
- className={cx('ui-workbench-preview-canvas', className)}
897
- data-panning={isPanning ? 'true' : 'false'}
898
- {...props}
899
- ref={interactionRef}
900
- >
901
- {onResetView ? (
902
- <Button
903
- compact
904
- className="ui-workbench-preview-canvas__reset"
905
- type="button"
906
- onClick={onResetView}
907
- title={resetTitle}
908
- >
909
- {resetLabel}
910
- </Button>
911
- ) : null}
912
-
913
- <div
914
- className="ui-workbench-preview-canvas__stage"
915
- data-panning={isPanning ? 'true' : 'false'}
916
- style={stageStyle}
917
- >
918
- <div
919
- className="ui-workbench-preview-canvas__frame"
920
- style={{
921
- width: frameWidth,
922
- height: frameHeight,
923
- }}
924
- >
925
- {showWindowFrame ? (
926
- <div className="ui-workbench-preview-canvas__titlebar">
927
- <div className="ui-workbench-preview-canvas__window-controls">
928
- <div className="ui-workbench-preview-canvas__dot" data-tone="close" />
929
- <div className="ui-workbench-preview-canvas__dot" data-tone="minimize" />
930
- <div className="ui-workbench-preview-canvas__dot" data-tone="maximize" />
931
- </div>
932
- <span className="ui-workbench-preview-canvas__title">{frameTitle}</span>
933
- </div>
934
- ) : null}
935
- <div
936
- className={cx('ui-workbench-preview-canvas__viewport', viewportClassName)}
937
- data-grid={showViewportGrid ? 'true' : 'false'}
938
- style={
939
- showViewportGrid
940
- ? ({
941
- '--ui-workbench-preview-viewport-grid-size': `${viewportGridSize}px`,
942
- ...viewportStyle,
943
- } as CSSProperties)
944
- : viewportStyle
945
- }
946
- {...restViewportProps}
947
- >
948
- {children}
949
- </div>
950
- </div>
951
- </div>
952
-
953
- {help ? <div className="ui-workbench-preview-canvas__help">{help}</div> : null}
954
- </div>
955
- );
956
- }
1
+ import { forwardRef, useRef } from 'react';
2
+ import type {
3
+ ComponentPropsWithRef,
4
+ CSSProperties,
5
+ PointerEvent as ReactPointerEvent,
6
+ ReactNode,
7
+ } from 'react';
8
+ import { Button } from '../primitives/button';
9
+ import { cx } from '../utils/cx';
10
+ import { toAngleValue, toLineLengthValue, toLengthValue } from './layoutHelpers';
11
+
12
+ export interface WorkbenchCanvasItemFrameProps extends ComponentPropsWithRef<'div'> {
13
+ cursor?: CSSProperties['cursor'] | undefined;
14
+ focused?: boolean | undefined;
15
+ height: number | string;
16
+ hovered?: boolean | undefined;
17
+ interactive?: boolean | undefined;
18
+ opacity?: number | string | undefined;
19
+ overflow?: CSSProperties['overflow'] | undefined;
20
+ rotation?: number | string | undefined;
21
+ selected?: boolean | undefined;
22
+ touchAction?: CSSProperties['touchAction'] | undefined;
23
+ transform?: string | undefined;
24
+ transient?: boolean | undefined;
25
+ width: number | string;
26
+ x: number | string;
27
+ y: number | string;
28
+ zIndex?: number | string | undefined;
29
+ }
30
+
31
+ export const WorkbenchCanvasItemFrame = forwardRef<HTMLDivElement, WorkbenchCanvasItemFrameProps>(
32
+ function WorkbenchCanvasItemFrame(
33
+ {
34
+ className,
35
+ cursor,
36
+ focused = false,
37
+ height,
38
+ hovered = false,
39
+ interactive = false,
40
+ opacity,
41
+ overflow,
42
+ rotation,
43
+ selected = false,
44
+ style,
45
+ touchAction,
46
+ transform,
47
+ transient = false,
48
+ width,
49
+ x,
50
+ y,
51
+ zIndex,
52
+ ...props
53
+ },
54
+ ref,
55
+ ) {
56
+ const frameStyle = {
57
+ '--ui-workbench-canvas-item-x': toLengthValue(x),
58
+ '--ui-workbench-canvas-item-y': toLengthValue(y),
59
+ '--ui-workbench-canvas-item-width': toLengthValue(width),
60
+ '--ui-workbench-canvas-item-height': toLengthValue(height),
61
+ ...(cursor !== undefined ? { '--ui-workbench-canvas-item-cursor': cursor } : {}),
62
+ ...(opacity !== undefined ? { '--ui-workbench-canvas-item-opacity': String(opacity) } : {}),
63
+ ...(overflow !== undefined ? { '--ui-workbench-canvas-item-overflow': overflow } : {}),
64
+ ...(rotation !== undefined
65
+ ? { '--ui-workbench-canvas-item-transform': `rotate(${toAngleValue(rotation)})` }
66
+ : {}),
67
+ ...(touchAction !== undefined
68
+ ? { '--ui-workbench-canvas-item-touch-action': touchAction }
69
+ : {}),
70
+ ...(transform !== undefined ? { '--ui-workbench-canvas-item-transform': transform } : {}),
71
+ ...(zIndex !== undefined ? { '--ui-workbench-canvas-item-z-index': String(zIndex) } : {}),
72
+ ...style,
73
+ } as CSSProperties;
74
+
75
+ return (
76
+ <div
77
+ ref={ref}
78
+ aria-selected={selected}
79
+ className={cx('ui-workbench-canvas-item-frame', className)}
80
+ data-focused={focused ? 'true' : 'false'}
81
+ data-hovered={hovered ? 'true' : 'false'}
82
+ data-interactive={interactive ? 'true' : 'false'}
83
+ data-selected={selected ? 'true' : 'false'}
84
+ data-transient={transient ? 'true' : 'false'}
85
+ style={frameStyle}
86
+ {...props}
87
+ />
88
+ );
89
+ },
90
+ );
91
+
92
+ export interface WorkbenchCanvasPaneSurfaceProps extends ComponentPropsWithRef<'div'> {
93
+ children?: ReactNode;
94
+ }
95
+
96
+ export const WorkbenchCanvasPaneSurface = forwardRef<
97
+ HTMLDivElement,
98
+ WorkbenchCanvasPaneSurfaceProps
99
+ >(function WorkbenchCanvasPaneSurface({ className, ...props }, ref) {
100
+ return <div ref={ref} className={cx('ui-workbench-canvas-pane-surface', className)} {...props} />;
101
+ });
102
+
103
+ export interface WorkbenchCanvasFrameSurfaceProps extends ComponentPropsWithRef<'div'> {
104
+ bottom?: number | string | undefined;
105
+ height?: number | string | undefined;
106
+ left?: number | string | undefined;
107
+ opacity?: number | string | undefined;
108
+ right?: number | string | undefined;
109
+ selected?: boolean | undefined;
110
+ top?: number | string | undefined;
111
+ transform?: string | undefined;
112
+ transient?: boolean | undefined;
113
+ width?: number | string | undefined;
114
+ }
115
+
116
+ export function WorkbenchCanvasFrameSurface({
117
+ bottom,
118
+ className,
119
+ height,
120
+ left,
121
+ opacity,
122
+ right,
123
+ selected = false,
124
+ style,
125
+ top,
126
+ transform,
127
+ transient = false,
128
+ width,
129
+ ...props
130
+ }: WorkbenchCanvasFrameSurfaceProps) {
131
+ const surfaceStyle = {
132
+ ...(bottom !== undefined
133
+ ? { '--ui-workbench-canvas-frame-bottom': toLengthValue(bottom) }
134
+ : {}),
135
+ ...(height !== undefined
136
+ ? { '--ui-workbench-canvas-frame-height': toLengthValue(height) }
137
+ : {}),
138
+ ...(left !== undefined ? { '--ui-workbench-canvas-frame-left': toLengthValue(left) } : {}),
139
+ ...(opacity !== undefined ? { '--ui-workbench-canvas-frame-opacity': String(opacity) } : {}),
140
+ ...(right !== undefined ? { '--ui-workbench-canvas-frame-right': toLengthValue(right) } : {}),
141
+ ...(top !== undefined ? { '--ui-workbench-canvas-frame-top': toLengthValue(top) } : {}),
142
+ ...(transform !== undefined ? { '--ui-workbench-canvas-frame-transform': transform } : {}),
143
+ ...(width !== undefined ? { '--ui-workbench-canvas-frame-width': toLengthValue(width) } : {}),
144
+ ...style,
145
+ } as CSSProperties;
146
+
147
+ return (
148
+ <div
149
+ className={cx('ui-workbench-canvas-frame-surface', className)}
150
+ data-selected={selected ? 'true' : 'false'}
151
+ data-transient={transient ? 'true' : 'false'}
152
+ style={surfaceStyle}
153
+ {...props}
154
+ />
155
+ );
156
+ }
157
+
158
+ export interface WorkbenchCanvasViewportProps extends ComponentPropsWithRef<'div'> {
159
+ children?: ReactNode;
160
+ grid?: boolean | undefined;
161
+ gridSize?: number | string | undefined;
162
+ height: number | string;
163
+ width: number | string;
164
+ }
165
+
166
+ export const WorkbenchCanvasViewport = forwardRef<HTMLDivElement, WorkbenchCanvasViewportProps>(
167
+ function WorkbenchCanvasViewport(
168
+ { className, grid = true, gridSize = 20, height, style, width, ...props },
169
+ ref,
170
+ ) {
171
+ const viewportStyle = {
172
+ '--ui-workbench-canvas-viewport-width': toLengthValue(width),
173
+ '--ui-workbench-canvas-viewport-height': toLengthValue(height),
174
+ '--ui-workbench-canvas-viewport-grid-size': toLengthValue(gridSize),
175
+ ...style,
176
+ } as CSSProperties;
177
+
178
+ return (
179
+ <div
180
+ ref={ref}
181
+ className={cx('ui-workbench-canvas-viewport', className)}
182
+ data-grid={grid ? 'true' : 'false'}
183
+ style={viewportStyle}
184
+ {...props}
185
+ />
186
+ );
187
+ },
188
+ );
189
+
190
+ export interface WorkbenchCanvasSelectionMarqueeProps extends ComponentPropsWithRef<'div'> {
191
+ height: number | string;
192
+ width: number | string;
193
+ x: number | string;
194
+ y: number | string;
195
+ }
196
+
197
+ export function WorkbenchCanvasSelectionMarquee({
198
+ className,
199
+ height,
200
+ style,
201
+ width,
202
+ x,
203
+ y,
204
+ ...props
205
+ }: WorkbenchCanvasSelectionMarqueeProps) {
206
+ const marqueeStyle = {
207
+ '--ui-workbench-canvas-selection-marquee-x': toLengthValue(x),
208
+ '--ui-workbench-canvas-selection-marquee-y': toLengthValue(y),
209
+ '--ui-workbench-canvas-selection-marquee-width': toLengthValue(width),
210
+ '--ui-workbench-canvas-selection-marquee-height': toLengthValue(height),
211
+ ...style,
212
+ } as CSSProperties;
213
+
214
+ return (
215
+ <div
216
+ className={cx('ui-workbench-canvas-selection-marquee', className)}
217
+ style={marqueeStyle}
218
+ {...props}
219
+ />
220
+ );
221
+ }
222
+
223
+ export type WorkbenchCanvasGuideBlockTone = 'gap' | 'padding';
224
+
225
+ export interface WorkbenchCanvasGuideBlockProps extends ComponentPropsWithRef<'div'> {
226
+ height: number | string;
227
+ tone?: WorkbenchCanvasGuideBlockTone | undefined;
228
+ width: number | string;
229
+ x: number | string;
230
+ y: number | string;
231
+ zIndex?: number | string | undefined;
232
+ }
233
+
234
+ export function WorkbenchCanvasGuideBlock({
235
+ className,
236
+ height,
237
+ style,
238
+ tone = 'gap',
239
+ width,
240
+ x,
241
+ y,
242
+ zIndex,
243
+ ...props
244
+ }: WorkbenchCanvasGuideBlockProps) {
245
+ const blockStyle = {
246
+ '--ui-workbench-canvas-guide-block-x': toLengthValue(x),
247
+ '--ui-workbench-canvas-guide-block-y': toLengthValue(y),
248
+ '--ui-workbench-canvas-guide-block-width': toLengthValue(width),
249
+ '--ui-workbench-canvas-guide-block-height': toLengthValue(height),
250
+ ...(zIndex !== undefined
251
+ ? { '--ui-workbench-canvas-guide-block-z-index': String(zIndex) }
252
+ : {}),
253
+ ...style,
254
+ } as CSSProperties;
255
+
256
+ return (
257
+ <div
258
+ className={cx('ui-workbench-canvas-guide-block', className)}
259
+ data-tone={tone}
260
+ style={blockStyle}
261
+ {...props}
262
+ />
263
+ );
264
+ }
265
+
266
+ export interface WorkbenchCanvasPlaceholderProps extends ComponentPropsWithRef<'div'> {
267
+ height?: number | string | undefined;
268
+ width?: number | string | undefined;
269
+ x?: number | string | undefined;
270
+ y?: number | string | undefined;
271
+ }
272
+
273
+ export function WorkbenchCanvasPlaceholder({
274
+ className,
275
+ height,
276
+ style,
277
+ width,
278
+ x,
279
+ y,
280
+ ...props
281
+ }: WorkbenchCanvasPlaceholderProps) {
282
+ const positioned =
283
+ x !== undefined || y !== undefined || width !== undefined || height !== undefined;
284
+ const placeholderStyle = {
285
+ ...(x !== undefined ? { '--ui-workbench-canvas-placeholder-x': toLengthValue(x) } : {}),
286
+ ...(y !== undefined ? { '--ui-workbench-canvas-placeholder-y': toLengthValue(y) } : {}),
287
+ ...(width !== undefined
288
+ ? { '--ui-workbench-canvas-placeholder-width': toLengthValue(width) }
289
+ : {}),
290
+ ...(height !== undefined
291
+ ? { '--ui-workbench-canvas-placeholder-height': toLengthValue(height) }
292
+ : {}),
293
+ ...style,
294
+ } as CSSProperties;
295
+
296
+ return (
297
+ <div
298
+ className={cx('ui-workbench-canvas-placeholder', className)}
299
+ data-positioned={positioned ? 'true' : 'false'}
300
+ style={placeholderStyle}
301
+ {...props}
302
+ />
303
+ );
304
+ }
305
+
306
+ export interface WorkbenchCanvasDropIndicatorProps extends ComponentPropsWithRef<'div'> {
307
+ height: number | string;
308
+ width: number | string;
309
+ x: number | string;
310
+ y: number | string;
311
+ zIndex?: number | string | undefined;
312
+ }
313
+
314
+ export function WorkbenchCanvasDropIndicator({
315
+ className,
316
+ height,
317
+ style,
318
+ width,
319
+ x,
320
+ y,
321
+ zIndex,
322
+ ...props
323
+ }: WorkbenchCanvasDropIndicatorProps) {
324
+ const indicatorStyle = {
325
+ '--ui-workbench-canvas-drop-indicator-x': toLengthValue(x),
326
+ '--ui-workbench-canvas-drop-indicator-y': toLengthValue(y),
327
+ '--ui-workbench-canvas-drop-indicator-width': toLengthValue(width),
328
+ '--ui-workbench-canvas-drop-indicator-height': toLengthValue(height),
329
+ ...(zIndex !== undefined
330
+ ? { '--ui-workbench-canvas-drop-indicator-z-index': String(zIndex) }
331
+ : {}),
332
+ ...style,
333
+ } as CSSProperties;
334
+
335
+ return (
336
+ <div
337
+ className={cx('ui-workbench-canvas-drop-indicator', className)}
338
+ style={indicatorStyle}
339
+ {...props}
340
+ />
341
+ );
342
+ }
343
+
344
+ export interface WorkbenchCanvasDragPreviewFrameProps extends ComponentPropsWithRef<'div'> {
345
+ height: number | string;
346
+ opacity?: number | string | undefined;
347
+ rotation?: number | string | undefined;
348
+ width: number | string;
349
+ x: number | string;
350
+ y: number | string;
351
+ zIndex?: number | string | undefined;
352
+ }
353
+
354
+ export function WorkbenchCanvasDragPreviewFrame({
355
+ className,
356
+ height,
357
+ opacity,
358
+ rotation,
359
+ style,
360
+ width,
361
+ x,
362
+ y,
363
+ zIndex,
364
+ ...props
365
+ }: WorkbenchCanvasDragPreviewFrameProps) {
366
+ const frameStyle = {
367
+ '--ui-workbench-canvas-drag-preview-frame-x': toLengthValue(x),
368
+ '--ui-workbench-canvas-drag-preview-frame-y': toLengthValue(y),
369
+ '--ui-workbench-canvas-drag-preview-frame-width': toLengthValue(width),
370
+ '--ui-workbench-canvas-drag-preview-frame-height': toLengthValue(height),
371
+ ...(opacity !== undefined
372
+ ? { '--ui-workbench-canvas-drag-preview-frame-opacity': String(opacity) }
373
+ : {}),
374
+ ...(rotation !== undefined
375
+ ? {
376
+ '--ui-workbench-canvas-drag-preview-frame-transform': `rotate(${toAngleValue(rotation)})`,
377
+ }
378
+ : {}),
379
+ ...(zIndex !== undefined
380
+ ? { '--ui-workbench-canvas-drag-preview-frame-z-index': String(zIndex) }
381
+ : {}),
382
+ ...style,
383
+ } as CSSProperties;
384
+
385
+ return (
386
+ <div
387
+ className={cx('ui-workbench-canvas-drag-preview-frame', className)}
388
+ style={frameStyle}
389
+ {...props}
390
+ />
391
+ );
392
+ }
393
+
394
+ export type WorkbenchCanvasGuideLineAxis = 'x' | 'y';
395
+ export type WorkbenchCanvasGuideLineSource = 'grid' | 'object';
396
+
397
+ export type WorkbenchCanvasGuideLayerProps = ComponentPropsWithRef<'div'>;
398
+
399
+ export function WorkbenchCanvasGuideLayer({ className, ...props }: WorkbenchCanvasGuideLayerProps) {
400
+ return <div className={cx('ui-workbench-canvas-guide-layer', className)} {...props} />;
401
+ }
402
+
403
+ export interface WorkbenchCanvasGuideLineProps extends ComponentPropsWithRef<'div'> {
404
+ axis: WorkbenchCanvasGuideLineAxis;
405
+ end: number | string;
406
+ position: number | string;
407
+ source?: WorkbenchCanvasGuideLineSource | undefined;
408
+ start: number | string;
409
+ }
410
+
411
+ export function WorkbenchCanvasGuideLine({
412
+ axis,
413
+ className,
414
+ end,
415
+ position,
416
+ source = 'object',
417
+ start,
418
+ style,
419
+ ...props
420
+ }: WorkbenchCanvasGuideLineProps) {
421
+ const lineStyle = {
422
+ '--ui-workbench-canvas-guide-line-position': toLengthValue(position),
423
+ '--ui-workbench-canvas-guide-line-start': toLengthValue(start),
424
+ '--ui-workbench-canvas-guide-line-length': toLineLengthValue(start, end),
425
+ ...style,
426
+ } as CSSProperties;
427
+
428
+ return (
429
+ <div
430
+ className={cx('ui-workbench-canvas-guide-line', className)}
431
+ data-axis={axis}
432
+ data-source={source}
433
+ style={lineStyle}
434
+ {...props}
435
+ />
436
+ );
437
+ }
438
+
439
+ export interface WorkbenchCanvasDragGhostProps extends ComponentPropsWithRef<'div'> {
440
+ height: number | string;
441
+ width: number | string;
442
+ x: number | string;
443
+ y: number | string;
444
+ zIndex?: number | string | undefined;
445
+ }
446
+
447
+ export function WorkbenchCanvasDragGhost({
448
+ className,
449
+ height,
450
+ style,
451
+ width,
452
+ x,
453
+ y,
454
+ zIndex,
455
+ ...props
456
+ }: WorkbenchCanvasDragGhostProps) {
457
+ const ghostStyle = {
458
+ '--ui-workbench-canvas-drag-ghost-x': toLengthValue(x),
459
+ '--ui-workbench-canvas-drag-ghost-y': toLengthValue(y),
460
+ '--ui-workbench-canvas-drag-ghost-width': toLengthValue(width),
461
+ '--ui-workbench-canvas-drag-ghost-height': toLengthValue(height),
462
+ ...(zIndex !== undefined ? { '--ui-workbench-canvas-drag-ghost-z-index': String(zIndex) } : {}),
463
+ ...style,
464
+ } as CSSProperties;
465
+
466
+ return (
467
+ <div
468
+ className={cx('ui-workbench-canvas-drag-ghost', className)}
469
+ style={ghostStyle}
470
+ {...props}
471
+ />
472
+ );
473
+ }
474
+
475
+ export interface WorkbenchCanvasDragGhostContentProps extends ComponentPropsWithRef<'div'> {
476
+ height: number | string;
477
+ width: number | string;
478
+ }
479
+
480
+ export function WorkbenchCanvasDragGhostContent({
481
+ className,
482
+ height,
483
+ style,
484
+ width,
485
+ ...props
486
+ }: WorkbenchCanvasDragGhostContentProps) {
487
+ const contentStyle = {
488
+ '--ui-workbench-canvas-drag-ghost-content-width': toLengthValue(width),
489
+ '--ui-workbench-canvas-drag-ghost-content-height': toLengthValue(height),
490
+ ...style,
491
+ } as CSSProperties;
492
+
493
+ return (
494
+ <div
495
+ className={cx('ui-workbench-canvas-drag-ghost-content', className)}
496
+ style={contentStyle}
497
+ {...props}
498
+ />
499
+ );
500
+ }
501
+
502
+ interface WorkbenchCanvasFrameHandleDrag {
503
+ pointerId: number;
504
+ startX: number;
505
+ startY: number;
506
+ }
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
+
531
+ export interface WorkbenchCanvasFrameHandleProps extends Omit<
532
+ ComponentPropsWithRef<'div'>,
533
+ | 'children'
534
+ | 'onDragEnd'
535
+ | 'onDragStart'
536
+ | 'onPointerCancel'
537
+ | 'onPointerDown'
538
+ | 'onPointerMove'
539
+ | 'onPointerUp'
540
+ > {
541
+ children?: ReactNode;
542
+ label?: ReactNode;
543
+ onDragCancel?: (event: ReactPointerEvent<HTMLDivElement>) => void;
544
+ onDragEnd?: (dx: number, dy: number, event: ReactPointerEvent<HTMLDivElement>) => void;
545
+ onDragMove?: (dx: number, dy: number, event: ReactPointerEvent<HTMLDivElement>) => void;
546
+ onDragStart?: (event: ReactPointerEvent<HTMLDivElement>) => void;
547
+ onPointerCancel?: (event: ReactPointerEvent<HTMLDivElement>) => void;
548
+ onPointerDown?: (event: ReactPointerEvent<HTMLDivElement>) => void;
549
+ onPointerMove?: (event: ReactPointerEvent<HTMLDivElement>) => void;
550
+ onPointerUp?: (event: ReactPointerEvent<HTMLDivElement>) => void;
551
+ stopPropagation?: boolean;
552
+ }
553
+
554
+ export function WorkbenchCanvasFrameHandle({
555
+ children,
556
+ className,
557
+ label,
558
+ onDragCancel,
559
+ onDragEnd,
560
+ onDragMove,
561
+ onDragStart,
562
+ onPointerCancel,
563
+ onPointerDown,
564
+ onPointerMove,
565
+ onPointerUp,
566
+ stopPropagation = true,
567
+ ...props
568
+ }: WorkbenchCanvasFrameHandleProps) {
569
+ const handleRef = useRef<HTMLDivElement>(null);
570
+ const dragRef = useRef<WorkbenchCanvasFrameHandleDrag | null>(null);
571
+ const content = children ?? label;
572
+
573
+ const handlePointerDown = (event: ReactPointerEvent<HTMLDivElement>) => {
574
+ onPointerDown?.(event);
575
+ if (event.defaultPrevented || event.button !== 0) return;
576
+
577
+ const element = handleRef.current;
578
+ if (!element) return;
579
+
580
+ if (stopPropagation) event.stopPropagation();
581
+ dragRef.current = {
582
+ pointerId: event.pointerId,
583
+ startX: event.clientX,
584
+ startY: event.clientY,
585
+ };
586
+ trySetPointerCapture(element, event.pointerId);
587
+ onDragStart?.(event);
588
+ };
589
+
590
+ const handlePointerMove = (event: ReactPointerEvent<HTMLDivElement>) => {
591
+ onPointerMove?.(event);
592
+ const drag = dragRef.current;
593
+ if (!drag || drag.pointerId !== event.pointerId) return;
594
+ onDragMove?.(event.clientX - drag.startX, event.clientY - drag.startY, event);
595
+ };
596
+
597
+ const handlePointerUp = (event: ReactPointerEvent<HTMLDivElement>) => {
598
+ onPointerUp?.(event);
599
+ const drag = dragRef.current;
600
+ if (!drag || drag.pointerId !== event.pointerId) return;
601
+
602
+ tryReleasePointerCapture(handleRef.current, event.pointerId);
603
+ dragRef.current = null;
604
+ const dx = event.clientX - drag.startX;
605
+ const dy = event.clientY - drag.startY;
606
+ if (dx !== 0 || dy !== 0) {
607
+ onDragEnd?.(dx, dy, event);
608
+ } else {
609
+ onDragCancel?.(event);
610
+ }
611
+ };
612
+
613
+ const handlePointerCancel = (event: ReactPointerEvent<HTMLDivElement>) => {
614
+ onPointerCancel?.(event);
615
+ const drag = dragRef.current;
616
+ if (!drag || drag.pointerId !== event.pointerId) return;
617
+
618
+ tryReleasePointerCapture(handleRef.current, event.pointerId);
619
+ dragRef.current = null;
620
+ onDragCancel?.(event);
621
+ };
622
+
623
+ return (
624
+ <div
625
+ ref={handleRef}
626
+ className={cx('ui-workbench-canvas-frame-handle', className)}
627
+ onPointerCancel={handlePointerCancel}
628
+ onPointerDown={handlePointerDown}
629
+ onPointerMove={handlePointerMove}
630
+ onPointerUp={handlePointerUp}
631
+ {...props}
632
+ >
633
+ <span className="ui-workbench-canvas-frame-handle__label">{content}</span>
634
+ </div>
635
+ );
636
+ }
637
+
638
+ export interface WorkbenchCanvasItemBadgeProps extends ComponentPropsWithRef<'span'> {
639
+ selected?: boolean | undefined;
640
+ }
641
+
642
+ export function WorkbenchCanvasItemBadge({
643
+ className,
644
+ selected = false,
645
+ ...props
646
+ }: WorkbenchCanvasItemBadgeProps) {
647
+ return (
648
+ <span
649
+ className={cx('ui-workbench-canvas-item-badge', className)}
650
+ data-selected={selected ? 'true' : 'false'}
651
+ {...props}
652
+ />
653
+ );
654
+ }
655
+
656
+ export interface WorkbenchCanvasResizeHandleProps extends Omit<
657
+ ComponentPropsWithRef<'button'>,
658
+ 'children'
659
+ > {
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;
665
+ position?: WorkbenchCanvasResizeHandlePosition | undefined;
666
+ stopPropagation?: boolean;
667
+ }
668
+
669
+ export type WorkbenchCanvasResizeHandlePosition = 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' | 'nw';
670
+
671
+ export function WorkbenchCanvasResizeHandle({
672
+ className,
673
+ label = 'Resize',
674
+ onPointerCancel,
675
+ onPointerDown,
676
+ onPointerMove,
677
+ onPointerUp,
678
+ onResizeCancel,
679
+ onResizeEnd,
680
+ onResizeMove,
681
+ onResizeStart,
682
+ position = 'se',
683
+ stopPropagation = true,
684
+ type = 'button',
685
+ ...props
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
+
740
+ return (
741
+ <button
742
+ ref={handleRef}
743
+ aria-label={label}
744
+ className={cx('ui-workbench-canvas-resize-handle', className)}
745
+ data-position={position}
746
+ onPointerCancel={handlePointerCancel}
747
+ onPointerDown={handlePointerDown}
748
+ onPointerMove={handlePointerMove}
749
+ onPointerUp={handlePointerUp}
750
+ title={label}
751
+ type={type}
752
+ {...props}
753
+ />
754
+ );
755
+ }
756
+
757
+ export interface WorkbenchCanvasResizeFrameProps extends ComponentPropsWithRef<'div'> {
758
+ height: number | string;
759
+ width: number | string;
760
+ x: number | string;
761
+ y: number | string;
762
+ zIndex?: number | string;
763
+ }
764
+
765
+ export const WorkbenchCanvasResizeFrame = forwardRef<
766
+ HTMLDivElement,
767
+ WorkbenchCanvasResizeFrameProps
768
+ >(function WorkbenchCanvasResizeFrame(
769
+ { className, height, style, width, x, y, zIndex, ...props },
770
+ ref,
771
+ ) {
772
+ const frameStyle = {
773
+ '--ui-workbench-canvas-resize-frame-x': toLengthValue(x),
774
+ '--ui-workbench-canvas-resize-frame-y': toLengthValue(y),
775
+ '--ui-workbench-canvas-resize-frame-width': toLengthValue(width),
776
+ '--ui-workbench-canvas-resize-frame-height': toLengthValue(height),
777
+ ...(zIndex !== undefined
778
+ ? { '--ui-workbench-canvas-resize-frame-z-index': String(zIndex) }
779
+ : {}),
780
+ ...style,
781
+ } as CSSProperties;
782
+
783
+ return (
784
+ <div
785
+ ref={ref}
786
+ className={cx('ui-workbench-canvas-resize-frame', className)}
787
+ style={frameStyle}
788
+ {...props}
789
+ />
790
+ );
791
+ });
792
+
793
+ export interface WorkbenchCanvasResizePreviewProps extends ComponentPropsWithRef<'div'> {
794
+ height: number | string;
795
+ width: number | string;
796
+ x: number | string;
797
+ y: number | string;
798
+ zIndex?: number | string;
799
+ }
800
+
801
+ export function WorkbenchCanvasResizePreview({
802
+ className,
803
+ height,
804
+ style,
805
+ width,
806
+ x,
807
+ y,
808
+ zIndex,
809
+ ...props
810
+ }: WorkbenchCanvasResizePreviewProps) {
811
+ const previewStyle = {
812
+ '--ui-workbench-canvas-resize-preview-x': toLengthValue(x),
813
+ '--ui-workbench-canvas-resize-preview-y': toLengthValue(y),
814
+ '--ui-workbench-canvas-resize-preview-width': toLengthValue(width),
815
+ '--ui-workbench-canvas-resize-preview-height': toLengthValue(height),
816
+ ...(zIndex !== undefined
817
+ ? { '--ui-workbench-canvas-resize-preview-z-index': String(zIndex) }
818
+ : {}),
819
+ ...style,
820
+ } as CSSProperties;
821
+
822
+ return (
823
+ <div
824
+ className={cx('ui-workbench-canvas-resize-preview', className)}
825
+ style={previewStyle}
826
+ {...props}
827
+ />
828
+ );
829
+ }
830
+
831
+ export interface WorkbenchRenderSurfaceProps extends ComponentPropsWithRef<'div'> {
832
+ transparent?: boolean | undefined;
833
+ }
834
+
835
+ export function WorkbenchRenderSurface({
836
+ className,
837
+ transparent = false,
838
+ ...props
839
+ }: WorkbenchRenderSurfaceProps) {
840
+ return (
841
+ <div
842
+ className={cx('ui-workbench-render-surface', className)}
843
+ data-transparent={transparent ? 'true' : 'false'}
844
+ {...props}
845
+ />
846
+ );
847
+ }
848
+
849
+ export interface WorkbenchPreviewCanvasProps extends Omit<
850
+ ComponentPropsWithRef<'div'>,
851
+ 'children'
852
+ > {
853
+ children: ReactNode;
854
+ frameHeight: number;
855
+ frameTitle?: ReactNode;
856
+ frameWidth: number;
857
+ help?: ReactNode;
858
+ isPanning?: boolean;
859
+ onResetView?: () => void;
860
+ resetLabel?: ReactNode;
861
+ resetTitle?: string;
862
+ showViewportGrid?: boolean;
863
+ showWindowFrame?: boolean;
864
+ stageStyle?: CSSProperties;
865
+ viewportGridSize?: number;
866
+ viewportProps?: ComponentPropsWithRef<'div'>;
867
+ }
868
+
869
+ export function WorkbenchPreviewCanvas({
870
+ children,
871
+ className,
872
+ frameHeight,
873
+ frameTitle = 'Preview',
874
+ frameWidth,
875
+ help,
876
+ isPanning = false,
877
+ onResetView,
878
+ resetLabel = 'Reset',
879
+ resetTitle = 'Reset View',
880
+ showViewportGrid = false,
881
+ showWindowFrame = true,
882
+ stageStyle,
883
+ viewportGridSize = 8,
884
+ viewportProps,
885
+ ...props
886
+ }: WorkbenchPreviewCanvasProps) {
887
+ const {
888
+ className: viewportClassName,
889
+ ref: interactionRef,
890
+ style: viewportStyle,
891
+ ...restViewportProps
892
+ } = viewportProps ?? {};
893
+
894
+ return (
895
+ <div
896
+ className={cx('ui-workbench-preview-canvas', className)}
897
+ data-panning={isPanning ? 'true' : 'false'}
898
+ {...props}
899
+ ref={interactionRef}
900
+ >
901
+ {onResetView ? (
902
+ <Button
903
+ compact
904
+ className="ui-workbench-preview-canvas__reset"
905
+ type="button"
906
+ onClick={onResetView}
907
+ title={resetTitle}
908
+ >
909
+ {resetLabel}
910
+ </Button>
911
+ ) : null}
912
+
913
+ <div
914
+ className="ui-workbench-preview-canvas__stage"
915
+ data-panning={isPanning ? 'true' : 'false'}
916
+ style={stageStyle}
917
+ >
918
+ <div
919
+ className="ui-workbench-preview-canvas__frame"
920
+ style={{
921
+ width: frameWidth,
922
+ height: frameHeight,
923
+ }}
924
+ >
925
+ {showWindowFrame ? (
926
+ <div className="ui-workbench-preview-canvas__titlebar">
927
+ <div className="ui-workbench-preview-canvas__window-controls">
928
+ <div className="ui-workbench-preview-canvas__dot" data-tone="close" />
929
+ <div className="ui-workbench-preview-canvas__dot" data-tone="minimize" />
930
+ <div className="ui-workbench-preview-canvas__dot" data-tone="maximize" />
931
+ </div>
932
+ <span className="ui-workbench-preview-canvas__title">{frameTitle}</span>
933
+ </div>
934
+ ) : null}
935
+ <div
936
+ className={cx('ui-workbench-preview-canvas__viewport', viewportClassName)}
937
+ data-grid={showViewportGrid ? 'true' : 'false'}
938
+ style={
939
+ showViewportGrid
940
+ ? ({
941
+ '--ui-workbench-preview-viewport-grid-size': `${viewportGridSize}px`,
942
+ ...viewportStyle,
943
+ } as CSSProperties)
944
+ : viewportStyle
945
+ }
946
+ {...restViewportProps}
947
+ >
948
+ {children}
949
+ </div>
950
+ </div>
951
+ </div>
952
+
953
+ {help ? <div className="ui-workbench-preview-canvas__help">{help}</div> : null}
954
+ </div>
955
+ );
956
+ }