@workbench-kit/react 0.0.1-prototype.0 → 0.0.2-prototype.0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/package.json +33 -9
  2. package/src/index.ts +545 -43
  3. package/src/jdw/JdwPreview.tsx +38 -0
  4. package/src/jdw/JsonCodeEditorPane.tsx +274 -0
  5. package/src/jdw/builtins/renderBuiltinWidgetLeaf.tsx +29 -0
  6. package/src/jdw/builtins/renderBuiltinWidgetNode.tsx +126 -0
  7. package/src/jdw/createBuiltinJdwRegistry.ts +111 -0
  8. package/src/jdw/cssRenderBackend.tsx +134 -0
  9. package/src/jdw/document.ts +38 -0
  10. package/src/jdw/fixtures/jdw-fixtures.ts +52 -0
  11. package/src/jdw/fixtures/jdw-sample-screens.ts +522 -0
  12. package/src/jdw/index.ts +45 -0
  13. package/src/jdw/parse.ts +1 -0
  14. package/src/jdw/renderJdw.tsx +32 -0
  15. package/src/json-config/JsonConfigWorkbench.tsx +316 -0
  16. package/src/json-config/index.ts +6 -0
  17. package/src/json-config/json-config-editor-state.ts +42 -0
  18. package/src/layout/Panel.tsx +146 -1
  19. package/src/layout/SideBarViewFrame.tsx +367 -328
  20. package/src/layout/WorkbenchCanvas.tsx +849 -0
  21. package/src/layout/WorkbenchFullscreen.tsx +368 -0
  22. package/src/layout/WorkbenchLayout.tsx +5 -0
  23. package/src/layout/WorkbenchLayoutBase.tsx +294 -0
  24. package/src/layout/WorkbenchPropertyPanel.tsx +497 -0
  25. package/src/layout/WorkbenchSidebarActions.tsx +274 -0
  26. package/src/layout/WorkbenchTree.tsx +351 -0
  27. package/src/layout/layoutHelpers.ts +25 -0
  28. package/src/modal/ConfirmDialog.tsx +61 -53
  29. package/src/modal/Modal.tsx +295 -35
  30. package/src/overlay/ContextMenu.tsx +146 -145
  31. package/src/primitives/AbsoluteBox.tsx +46 -0
  32. package/src/primitives/Badge.tsx +12 -12
  33. package/src/primitives/Button.tsx +44 -14
  34. package/src/primitives/Checkbox.tsx +11 -5
  35. package/src/primitives/EmptyState.tsx +27 -26
  36. package/src/primitives/Field.tsx +38 -38
  37. package/src/primitives/IconButton.tsx +5 -2
  38. package/src/primitives/List.tsx +111 -0
  39. package/src/primitives/NumberInput.tsx +38 -0
  40. package/src/primitives/ScrollArea.tsx +42 -0
  41. package/src/primitives/Select.tsx +1 -12
  42. package/src/primitives/StatusBar.tsx +46 -0
  43. package/src/primitives/TextArea.tsx +36 -0
  44. package/src/primitives/TextInput.tsx +11 -2
  45. package/src/primitives/WorkbenchChrome.tsx +424 -0
  46. package/src/primitives/WorkbenchEditor.tsx +394 -0
  47. package/src/primitives/index.ts +105 -0
  48. package/src/primitives/select/Select.tsx +266 -0
  49. package/src/primitives/select/index.ts +2 -0
  50. package/src/primitives/select/options.ts +38 -0
  51. package/src/primitives/select/overlay.ts +63 -0
  52. package/src/primitives/select/select.app.css +9 -0
  53. package/src/primitives/select/select.css +140 -0
  54. package/src/primitives/select/types.ts +18 -0
  55. package/src/primitives/styles.css +955 -0
  56. package/src/scrollbars.css +69 -0
  57. package/src/styles.css +7738 -1762
  58. package/src/utils/codicon.ts +17 -0
  59. package/src/widget-asset/WidgetAssetEditor.tsx +140 -0
  60. package/src/widget-asset/WidgetAssetMetadataForm.tsx +82 -0
  61. package/src/widget-asset/WidgetAssetModeControls.tsx +42 -0
  62. package/src/widget-asset/WidgetAssetSourceEditor.tsx +50 -0
  63. package/src/widget-asset/WidgetAssetWorkbench.tsx +112 -0
  64. package/src/widget-asset/index.ts +17 -0
  65. package/src/widget-asset/widget-asset-document.ts +37 -0
  66. package/src/widget-asset/widget-asset-mode.ts +3 -0
  67. package/src/widget-studio/builtin-widget-asset-catalog.ts +12 -0
  68. package/src/widget-studio/create-widget-studio-workspace-editor.tsx +79 -0
  69. package/src/widget-studio/index.ts +7 -0
  70. package/src/widget-studio/resolve-widget-studio-asset-catalog.ts +26 -0
  71. package/src/widget-tree/WidgetAssetPalette.tsx +77 -0
  72. package/src/widget-tree/WidgetInspectorPanel.tsx +266 -0
  73. package/src/widget-tree/WidgetSourceEditor.tsx +56 -0
  74. package/src/widget-tree/WidgetTreeLab.tsx +272 -0
  75. package/src/widget-tree/WidgetTreeModeControls.tsx +44 -0
  76. package/src/widget-tree/WidgetTreeSidePanel.tsx +49 -0
  77. package/src/widget-tree/WidgetTreeView.tsx +97 -0
  78. package/src/widget-tree/WidgetTreeWorkbench.tsx +111 -0
  79. package/src/widget-tree/WidgetTreeWorkspaceShell.tsx +154 -0
  80. package/src/widget-tree/demo-registry.ts +32 -0
  81. package/src/widget-tree/demo-widget-assets.ts +4 -0
  82. package/src/widget-tree/index.ts +27 -0
  83. package/src/widget-tree/widget-tree-document.ts +20 -0
  84. package/src/widget-tree/widget-tree-layout.ts +31 -0
  85. package/src/widget-tree/widget-tree-mode.ts +7 -0
  86. package/src/widget-tree/widget-tree-play-helpers.ts +74 -0
  87. package/src/workbench/ActivityBar.tsx +52 -52
  88. package/src/workbench/ArtifactShell.tsx +397 -0
  89. package/src/workbench/CommandPalette.tsx +819 -0
  90. package/src/workbench/ConfirmationFlow.tsx +245 -0
  91. package/src/workbench/MarkdownPreview.tsx +151 -0
  92. package/src/workbench/ShortcutCommandBridge.tsx +368 -0
  93. package/src/workbench/SplitView.tsx +136 -136
  94. package/src/workbench/StatusBar.tsx +178 -123
  95. package/src/workbench/StructuredArtifactEditor.tsx +205 -0
  96. package/src/workbench/Timeline.tsx +302 -0
  97. package/src/workbench/WorkbenchCanvasShell.tsx +941 -0
  98. package/src/workbench/WorkbenchShell.tsx +74 -70
  99. package/src/workbench/WorkbenchStandaloneShell.tsx +318 -291
  100. package/src/workbench/auth/WorkbenchAuthGate.tsx +61 -0
  101. package/src/workbench/auth/WorkbenchLoginView.tsx +635 -0
  102. package/src/workbench/auth/index.ts +19 -0
  103. package/src/workbench/chat/ChatComposer.tsx +165 -148
  104. package/src/workbench/chat/ChatMessageItem.tsx +10 -1
  105. package/src/workbench/chat/index.ts +9 -0
  106. package/src/workbench/chat/slashCommand.ts +28 -0
  107. package/src/workbench/chat/useChatRuntimeState.ts +76 -0
  108. package/src/workbench/chat/useSlashCommandSuggest.ts +101 -0
  109. package/src/workbench/commands.ts +520 -490
  110. package/src/workbench/index.ts +443 -98
  111. package/src/workbench/keyboard.ts +53 -0
  112. package/src/workbench/schema/index.ts +48 -0
  113. package/src/workbench/schema/workbenchDocument.ts +31 -0
  114. package/src/workbench/schema/workbenchDocumentActions.ts +6 -0
  115. package/src/workbench/schema/workbenchDocumentAdapter.ts +9 -0
  116. package/src/workbench/schema/workbenchDocumentPatch.ts +13 -0
  117. package/src/workbench/schema/workbenchDocumentRenderer.tsx +702 -0
  118. package/src/workbench/settings/NavigationPanel.tsx +47 -0
  119. package/src/workbench/settings/SchemaForm.tsx +420 -0
  120. package/src/workbench/settings/SectionedPanel.tsx +415 -0
  121. package/src/workbench/settings/StructuredDataForm.tsx +539 -0
  122. package/src/workbench/settings/StructuredDataSchemaPanel.tsx +559 -0
  123. package/src/workbench/settings/StructuredDataSchemaPanelEmbed.tsx +21 -0
  124. package/src/workbench/settings/StructuredDataSchemaPanelFrame.tsx +76 -0
  125. package/src/workbench/settings/StructuredDataTableView.tsx +127 -0
  126. package/src/workbench/settings/WorkbenchPanelRegion.tsx +46 -0
  127. package/src/workbench/settings/WorkbenchSettingsModal.tsx +21 -12
  128. package/src/workbench/settings/WorkbenchSettingsNav.tsx +38 -22
  129. package/src/workbench/settings/index.ts +135 -0
  130. package/src/workbench/settings/panel-region.css +21 -0
  131. package/src/workbench/settings/sectionedPanelScrollSpy.ts +143 -0
  132. package/src/workbench/settings/structured-data-schema-panel.css +330 -0
  133. package/src/workbench/settings/structured-data-table-view.css +85 -0
  134. package/src/workbench/settings/structuredDataSchema.ts +886 -0
  135. package/src/workbench/shell.ts +15 -0
  136. package/src/workbench/shellState.ts +203 -203
  137. package/src/workbench/standalone.ts +101 -94
  138. package/src/workbench/status.ts +129 -0
  139. package/src/workbench/theme.ts +44 -0
  140. package/src/workbench/workspace/MultiProviderExplorer.tsx +625 -0
  141. package/src/workbench/workspace/WorkspaceDraftsContext.tsx +111 -0
  142. package/src/workbench/workspace/WorkspaceEditor.tsx +47 -12
  143. package/src/workbench/workspace/WorkspaceEditorPanel.tsx +334 -353
  144. package/src/workbench/workspace/WorkspaceExplorer.tsx +532 -524
  145. package/src/workbench/workspace/WorkspaceFileIcon.tsx +32 -2
  146. package/src/workbench/workspace/WorkspaceSearchPanel.tsx +113 -113
  147. package/src/workbench/workspace/WorkspaceSearchResults.tsx +47 -47
  148. package/src/workbench/workspace/index.ts +156 -98
  149. package/src/workbench/workspace/mimeType.ts +45 -0
  150. package/src/workbench/workspace/path.ts +10 -10
  151. package/src/workbench/workspace/search.ts +6 -6
  152. package/src/workbench/workspace/tree.ts +1 -1
  153. package/src/workbench/workspace/types.ts +10 -10
  154. package/src/workbench/workspace/useVirtualWorkspace.ts +111 -98
  155. package/src/workbench/workspace/workspaceJsonDiagnostics.ts +83 -0
@@ -0,0 +1,849 @@
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
+ height: number | string;
15
+ hovered?: boolean | undefined;
16
+ interactive?: boolean | undefined;
17
+ opacity?: number | string | undefined;
18
+ overflow?: CSSProperties['overflow'] | undefined;
19
+ rotation?: number | string | undefined;
20
+ selected?: boolean | undefined;
21
+ touchAction?: CSSProperties['touchAction'] | undefined;
22
+ transform?: string | undefined;
23
+ transient?: boolean | undefined;
24
+ width: number | string;
25
+ x: number | string;
26
+ y: number | string;
27
+ zIndex?: number | string | undefined;
28
+ }
29
+
30
+ export const WorkbenchCanvasItemFrame = forwardRef<HTMLDivElement, WorkbenchCanvasItemFrameProps>(
31
+ function WorkbenchCanvasItemFrame(
32
+ {
33
+ className,
34
+ cursor,
35
+ height,
36
+ hovered = false,
37
+ interactive = false,
38
+ opacity,
39
+ overflow,
40
+ rotation,
41
+ selected = false,
42
+ style,
43
+ touchAction,
44
+ transform,
45
+ transient = false,
46
+ width,
47
+ x,
48
+ y,
49
+ zIndex,
50
+ ...props
51
+ },
52
+ ref,
53
+ ) {
54
+ const frameStyle = {
55
+ '--ui-workbench-canvas-item-x': toLengthValue(x),
56
+ '--ui-workbench-canvas-item-y': toLengthValue(y),
57
+ '--ui-workbench-canvas-item-width': toLengthValue(width),
58
+ '--ui-workbench-canvas-item-height': toLengthValue(height),
59
+ ...(cursor !== undefined ? { '--ui-workbench-canvas-item-cursor': cursor } : {}),
60
+ ...(opacity !== undefined ? { '--ui-workbench-canvas-item-opacity': String(opacity) } : {}),
61
+ ...(overflow !== undefined ? { '--ui-workbench-canvas-item-overflow': overflow } : {}),
62
+ ...(rotation !== undefined
63
+ ? { '--ui-workbench-canvas-item-transform': `rotate(${toAngleValue(rotation)})` }
64
+ : {}),
65
+ ...(touchAction !== undefined
66
+ ? { '--ui-workbench-canvas-item-touch-action': touchAction }
67
+ : {}),
68
+ ...(transform !== undefined ? { '--ui-workbench-canvas-item-transform': transform } : {}),
69
+ ...(zIndex !== undefined ? { '--ui-workbench-canvas-item-z-index': String(zIndex) } : {}),
70
+ ...style,
71
+ } as CSSProperties;
72
+
73
+ return (
74
+ <div
75
+ ref={ref}
76
+ aria-selected={selected}
77
+ className={cx('ui-workbench-canvas-item-frame', className)}
78
+ data-hovered={hovered ? 'true' : 'false'}
79
+ data-interactive={interactive ? 'true' : 'false'}
80
+ data-selected={selected ? 'true' : 'false'}
81
+ data-transient={transient ? 'true' : 'false'}
82
+ style={frameStyle}
83
+ {...props}
84
+ />
85
+ );
86
+ },
87
+ );
88
+
89
+ export type WorkbenchCanvasPaneSurfaceProps = ComponentPropsWithRef<'div'>;
90
+
91
+ export const WorkbenchCanvasPaneSurface = forwardRef<
92
+ HTMLDivElement,
93
+ WorkbenchCanvasPaneSurfaceProps
94
+ >(function WorkbenchCanvasPaneSurface({ className, ...props }, ref) {
95
+ return <div ref={ref} className={cx('ui-workbench-canvas-pane-surface', className)} {...props} />;
96
+ });
97
+
98
+ export interface WorkbenchCanvasFrameSurfaceProps extends ComponentPropsWithRef<'div'> {
99
+ bottom?: number | string | undefined;
100
+ height?: number | string | undefined;
101
+ left?: number | string | undefined;
102
+ opacity?: number | string | undefined;
103
+ right?: number | string | undefined;
104
+ selected?: boolean | undefined;
105
+ top?: number | string | undefined;
106
+ transform?: string | undefined;
107
+ transient?: boolean | undefined;
108
+ width?: number | string | undefined;
109
+ }
110
+
111
+ export function WorkbenchCanvasFrameSurface({
112
+ bottom,
113
+ className,
114
+ height,
115
+ left,
116
+ opacity,
117
+ right,
118
+ selected = false,
119
+ style,
120
+ top,
121
+ transform,
122
+ transient = false,
123
+ width,
124
+ ...props
125
+ }: WorkbenchCanvasFrameSurfaceProps) {
126
+ const surfaceStyle = {
127
+ ...(bottom !== undefined
128
+ ? { '--ui-workbench-canvas-frame-bottom': toLengthValue(bottom) }
129
+ : {}),
130
+ ...(height !== undefined
131
+ ? { '--ui-workbench-canvas-frame-height': toLengthValue(height) }
132
+ : {}),
133
+ ...(left !== undefined ? { '--ui-workbench-canvas-frame-left': toLengthValue(left) } : {}),
134
+ ...(opacity !== undefined ? { '--ui-workbench-canvas-frame-opacity': String(opacity) } : {}),
135
+ ...(right !== undefined ? { '--ui-workbench-canvas-frame-right': toLengthValue(right) } : {}),
136
+ ...(top !== undefined ? { '--ui-workbench-canvas-frame-top': toLengthValue(top) } : {}),
137
+ ...(transform !== undefined ? { '--ui-workbench-canvas-frame-transform': transform } : {}),
138
+ ...(width !== undefined ? { '--ui-workbench-canvas-frame-width': toLengthValue(width) } : {}),
139
+ ...style,
140
+ } as CSSProperties;
141
+
142
+ return (
143
+ <div
144
+ className={cx('ui-workbench-canvas-frame-surface', className)}
145
+ data-selected={selected ? 'true' : 'false'}
146
+ data-transient={transient ? 'true' : 'false'}
147
+ style={surfaceStyle}
148
+ {...props}
149
+ />
150
+ );
151
+ }
152
+
153
+ export interface WorkbenchCanvasViewportProps extends ComponentPropsWithRef<'div'> {
154
+ grid?: boolean | undefined;
155
+ gridSize?: number | string | undefined;
156
+ height: number | string;
157
+ width: number | string;
158
+ }
159
+
160
+ export const WorkbenchCanvasViewport = forwardRef<HTMLDivElement, WorkbenchCanvasViewportProps>(
161
+ function WorkbenchCanvasViewport(
162
+ { className, grid = true, gridSize = 20, height, style, width, ...props },
163
+ ref,
164
+ ) {
165
+ const viewportStyle = {
166
+ '--ui-workbench-canvas-viewport-width': toLengthValue(width),
167
+ '--ui-workbench-canvas-viewport-height': toLengthValue(height),
168
+ '--ui-workbench-canvas-viewport-grid-size': toLengthValue(gridSize),
169
+ ...style,
170
+ } as CSSProperties;
171
+
172
+ return (
173
+ <div
174
+ ref={ref}
175
+ className={cx('ui-workbench-canvas-viewport', className)}
176
+ data-grid={grid ? 'true' : 'false'}
177
+ style={viewportStyle}
178
+ {...props}
179
+ />
180
+ );
181
+ },
182
+ );
183
+
184
+ export interface WorkbenchCanvasSelectionMarqueeProps extends ComponentPropsWithRef<'div'> {
185
+ height: number | string;
186
+ width: number | string;
187
+ x: number | string;
188
+ y: number | string;
189
+ }
190
+
191
+ export function WorkbenchCanvasSelectionMarquee({
192
+ className,
193
+ height,
194
+ style,
195
+ width,
196
+ x,
197
+ y,
198
+ ...props
199
+ }: WorkbenchCanvasSelectionMarqueeProps) {
200
+ const marqueeStyle = {
201
+ '--ui-workbench-canvas-selection-marquee-x': toLengthValue(x),
202
+ '--ui-workbench-canvas-selection-marquee-y': toLengthValue(y),
203
+ '--ui-workbench-canvas-selection-marquee-width': toLengthValue(width),
204
+ '--ui-workbench-canvas-selection-marquee-height': toLengthValue(height),
205
+ ...style,
206
+ } as CSSProperties;
207
+
208
+ return (
209
+ <div
210
+ className={cx('ui-workbench-canvas-selection-marquee', className)}
211
+ style={marqueeStyle}
212
+ {...props}
213
+ />
214
+ );
215
+ }
216
+
217
+ export type WorkbenchCanvasGuideBlockTone = 'gap' | 'padding';
218
+
219
+ export interface WorkbenchCanvasGuideBlockProps extends ComponentPropsWithRef<'div'> {
220
+ height: number | string;
221
+ tone?: WorkbenchCanvasGuideBlockTone | undefined;
222
+ width: number | string;
223
+ x: number | string;
224
+ y: number | string;
225
+ zIndex?: number | string | undefined;
226
+ }
227
+
228
+ export function WorkbenchCanvasGuideBlock({
229
+ className,
230
+ height,
231
+ style,
232
+ tone = 'gap',
233
+ width,
234
+ x,
235
+ y,
236
+ zIndex,
237
+ ...props
238
+ }: WorkbenchCanvasGuideBlockProps) {
239
+ const blockStyle = {
240
+ '--ui-workbench-canvas-guide-block-x': toLengthValue(x),
241
+ '--ui-workbench-canvas-guide-block-y': toLengthValue(y),
242
+ '--ui-workbench-canvas-guide-block-width': toLengthValue(width),
243
+ '--ui-workbench-canvas-guide-block-height': toLengthValue(height),
244
+ ...(zIndex !== undefined
245
+ ? { '--ui-workbench-canvas-guide-block-z-index': String(zIndex) }
246
+ : {}),
247
+ ...style,
248
+ } as CSSProperties;
249
+
250
+ return (
251
+ <div
252
+ className={cx('ui-workbench-canvas-guide-block', className)}
253
+ data-tone={tone}
254
+ style={blockStyle}
255
+ {...props}
256
+ />
257
+ );
258
+ }
259
+
260
+ export interface WorkbenchCanvasPlaceholderProps extends ComponentPropsWithRef<'div'> {
261
+ height?: number | string | undefined;
262
+ width?: number | string | undefined;
263
+ x?: number | string | undefined;
264
+ y?: number | string | undefined;
265
+ }
266
+
267
+ export function WorkbenchCanvasPlaceholder({
268
+ className,
269
+ height,
270
+ style,
271
+ width,
272
+ x,
273
+ y,
274
+ ...props
275
+ }: WorkbenchCanvasPlaceholderProps) {
276
+ const positioned =
277
+ x !== undefined || y !== undefined || width !== undefined || height !== undefined;
278
+ const placeholderStyle = {
279
+ ...(x !== undefined ? { '--ui-workbench-canvas-placeholder-x': toLengthValue(x) } : {}),
280
+ ...(y !== undefined ? { '--ui-workbench-canvas-placeholder-y': toLengthValue(y) } : {}),
281
+ ...(width !== undefined
282
+ ? { '--ui-workbench-canvas-placeholder-width': toLengthValue(width) }
283
+ : {}),
284
+ ...(height !== undefined
285
+ ? { '--ui-workbench-canvas-placeholder-height': toLengthValue(height) }
286
+ : {}),
287
+ ...style,
288
+ } as CSSProperties;
289
+
290
+ return (
291
+ <div
292
+ className={cx('ui-workbench-canvas-placeholder', className)}
293
+ data-positioned={positioned ? 'true' : 'false'}
294
+ style={placeholderStyle}
295
+ {...props}
296
+ />
297
+ );
298
+ }
299
+
300
+ export interface WorkbenchCanvasDropIndicatorProps extends ComponentPropsWithRef<'div'> {
301
+ height: number | string;
302
+ width: number | string;
303
+ x: number | string;
304
+ y: number | string;
305
+ zIndex?: number | string | undefined;
306
+ }
307
+
308
+ export function WorkbenchCanvasDropIndicator({
309
+ className,
310
+ height,
311
+ style,
312
+ width,
313
+ x,
314
+ y,
315
+ zIndex,
316
+ ...props
317
+ }: WorkbenchCanvasDropIndicatorProps) {
318
+ const indicatorStyle = {
319
+ '--ui-workbench-canvas-drop-indicator-x': toLengthValue(x),
320
+ '--ui-workbench-canvas-drop-indicator-y': toLengthValue(y),
321
+ '--ui-workbench-canvas-drop-indicator-width': toLengthValue(width),
322
+ '--ui-workbench-canvas-drop-indicator-height': toLengthValue(height),
323
+ ...(zIndex !== undefined
324
+ ? { '--ui-workbench-canvas-drop-indicator-z-index': String(zIndex) }
325
+ : {}),
326
+ ...style,
327
+ } as CSSProperties;
328
+
329
+ return (
330
+ <div
331
+ className={cx('ui-workbench-canvas-drop-indicator', className)}
332
+ style={indicatorStyle}
333
+ {...props}
334
+ />
335
+ );
336
+ }
337
+
338
+ export interface WorkbenchCanvasDragPreviewFrameProps extends ComponentPropsWithRef<'div'> {
339
+ height: number | string;
340
+ opacity?: number | string | undefined;
341
+ rotation?: number | string | undefined;
342
+ width: number | string;
343
+ x: number | string;
344
+ y: number | string;
345
+ zIndex?: number | string | undefined;
346
+ }
347
+
348
+ export function WorkbenchCanvasDragPreviewFrame({
349
+ className,
350
+ height,
351
+ opacity,
352
+ rotation,
353
+ style,
354
+ width,
355
+ x,
356
+ y,
357
+ zIndex,
358
+ ...props
359
+ }: WorkbenchCanvasDragPreviewFrameProps) {
360
+ const frameStyle = {
361
+ '--ui-workbench-canvas-drag-preview-frame-x': toLengthValue(x),
362
+ '--ui-workbench-canvas-drag-preview-frame-y': toLengthValue(y),
363
+ '--ui-workbench-canvas-drag-preview-frame-width': toLengthValue(width),
364
+ '--ui-workbench-canvas-drag-preview-frame-height': toLengthValue(height),
365
+ ...(opacity !== undefined
366
+ ? { '--ui-workbench-canvas-drag-preview-frame-opacity': String(opacity) }
367
+ : {}),
368
+ ...(rotation !== undefined
369
+ ? {
370
+ '--ui-workbench-canvas-drag-preview-frame-transform': `rotate(${toAngleValue(rotation)})`,
371
+ }
372
+ : {}),
373
+ ...(zIndex !== undefined
374
+ ? { '--ui-workbench-canvas-drag-preview-frame-z-index': String(zIndex) }
375
+ : {}),
376
+ ...style,
377
+ } as CSSProperties;
378
+
379
+ return (
380
+ <div
381
+ className={cx('ui-workbench-canvas-drag-preview-frame', className)}
382
+ style={frameStyle}
383
+ {...props}
384
+ />
385
+ );
386
+ }
387
+
388
+ export type WorkbenchCanvasGuideLineAxis = 'x' | 'y';
389
+ export type WorkbenchCanvasGuideLineSource = 'grid' | 'object';
390
+
391
+ export type WorkbenchCanvasGuideLayerProps = ComponentPropsWithRef<'div'>;
392
+
393
+ export function WorkbenchCanvasGuideLayer({ className, ...props }: WorkbenchCanvasGuideLayerProps) {
394
+ return <div className={cx('ui-workbench-canvas-guide-layer', className)} {...props} />;
395
+ }
396
+
397
+ export interface WorkbenchCanvasGuideLineProps extends ComponentPropsWithRef<'div'> {
398
+ axis: WorkbenchCanvasGuideLineAxis;
399
+ end: number | string;
400
+ position: number | string;
401
+ source?: WorkbenchCanvasGuideLineSource | undefined;
402
+ start: number | string;
403
+ }
404
+
405
+ export function WorkbenchCanvasGuideLine({
406
+ axis,
407
+ className,
408
+ end,
409
+ position,
410
+ source = 'object',
411
+ start,
412
+ style,
413
+ ...props
414
+ }: WorkbenchCanvasGuideLineProps) {
415
+ const lineStyle = {
416
+ '--ui-workbench-canvas-guide-line-position': toLengthValue(position),
417
+ '--ui-workbench-canvas-guide-line-start': toLengthValue(start),
418
+ '--ui-workbench-canvas-guide-line-length': toLineLengthValue(start, end),
419
+ ...style,
420
+ } as CSSProperties;
421
+
422
+ return (
423
+ <div
424
+ className={cx('ui-workbench-canvas-guide-line', className)}
425
+ data-axis={axis}
426
+ data-source={source}
427
+ style={lineStyle}
428
+ {...props}
429
+ />
430
+ );
431
+ }
432
+
433
+ export interface WorkbenchCanvasDragGhostProps extends ComponentPropsWithRef<'div'> {
434
+ height: number | string;
435
+ width: number | string;
436
+ x: number | string;
437
+ y: number | string;
438
+ zIndex?: number | string | undefined;
439
+ }
440
+
441
+ export function WorkbenchCanvasDragGhost({
442
+ className,
443
+ height,
444
+ style,
445
+ width,
446
+ x,
447
+ y,
448
+ zIndex,
449
+ ...props
450
+ }: WorkbenchCanvasDragGhostProps) {
451
+ const ghostStyle = {
452
+ '--ui-workbench-canvas-drag-ghost-x': toLengthValue(x),
453
+ '--ui-workbench-canvas-drag-ghost-y': toLengthValue(y),
454
+ '--ui-workbench-canvas-drag-ghost-width': toLengthValue(width),
455
+ '--ui-workbench-canvas-drag-ghost-height': toLengthValue(height),
456
+ ...(zIndex !== undefined ? { '--ui-workbench-canvas-drag-ghost-z-index': String(zIndex) } : {}),
457
+ ...style,
458
+ } as CSSProperties;
459
+
460
+ return (
461
+ <div
462
+ className={cx('ui-workbench-canvas-drag-ghost', className)}
463
+ style={ghostStyle}
464
+ {...props}
465
+ />
466
+ );
467
+ }
468
+
469
+ export interface WorkbenchCanvasDragGhostContentProps extends ComponentPropsWithRef<'div'> {
470
+ height: number | string;
471
+ width: number | string;
472
+ }
473
+
474
+ export function WorkbenchCanvasDragGhostContent({
475
+ className,
476
+ height,
477
+ style,
478
+ width,
479
+ ...props
480
+ }: WorkbenchCanvasDragGhostContentProps) {
481
+ const contentStyle = {
482
+ '--ui-workbench-canvas-drag-ghost-content-width': toLengthValue(width),
483
+ '--ui-workbench-canvas-drag-ghost-content-height': toLengthValue(height),
484
+ ...style,
485
+ } as CSSProperties;
486
+
487
+ return (
488
+ <div
489
+ className={cx('ui-workbench-canvas-drag-ghost-content', className)}
490
+ style={contentStyle}
491
+ {...props}
492
+ />
493
+ );
494
+ }
495
+
496
+ interface WorkbenchCanvasFrameHandleDrag {
497
+ pointerId: number;
498
+ startX: number;
499
+ startY: number;
500
+ }
501
+
502
+ export interface WorkbenchCanvasFrameHandleProps extends Omit<
503
+ ComponentPropsWithRef<'div'>,
504
+ | 'children'
505
+ | 'onDragEnd'
506
+ | 'onDragStart'
507
+ | 'onPointerCancel'
508
+ | 'onPointerDown'
509
+ | 'onPointerMove'
510
+ | 'onPointerUp'
511
+ > {
512
+ children?: ReactNode;
513
+ label?: ReactNode;
514
+ onDragCancel?: (event: ReactPointerEvent<HTMLDivElement>) => void;
515
+ onDragEnd?: (dx: number, dy: number, event: ReactPointerEvent<HTMLDivElement>) => void;
516
+ onDragMove?: (dx: number, dy: number, event: ReactPointerEvent<HTMLDivElement>) => void;
517
+ onDragStart?: (event: ReactPointerEvent<HTMLDivElement>) => void;
518
+ onPointerCancel?: (event: ReactPointerEvent<HTMLDivElement>) => void;
519
+ onPointerDown?: (event: ReactPointerEvent<HTMLDivElement>) => void;
520
+ onPointerMove?: (event: ReactPointerEvent<HTMLDivElement>) => void;
521
+ onPointerUp?: (event: ReactPointerEvent<HTMLDivElement>) => void;
522
+ stopPropagation?: boolean;
523
+ }
524
+
525
+ export function WorkbenchCanvasFrameHandle({
526
+ children,
527
+ className,
528
+ label,
529
+ onDragCancel,
530
+ onDragEnd,
531
+ onDragMove,
532
+ onDragStart,
533
+ onPointerCancel,
534
+ onPointerDown,
535
+ onPointerMove,
536
+ onPointerUp,
537
+ stopPropagation = true,
538
+ ...props
539
+ }: WorkbenchCanvasFrameHandleProps) {
540
+ const handleRef = useRef<HTMLDivElement>(null);
541
+ const dragRef = useRef<WorkbenchCanvasFrameHandleDrag | null>(null);
542
+ const content = children ?? label;
543
+
544
+ const handlePointerDown = (event: ReactPointerEvent<HTMLDivElement>) => {
545
+ onPointerDown?.(event);
546
+ if (event.defaultPrevented || event.button !== 0) return;
547
+
548
+ const element = handleRef.current;
549
+ if (!element) return;
550
+
551
+ if (stopPropagation) event.stopPropagation();
552
+ element.setPointerCapture(event.pointerId);
553
+ dragRef.current = {
554
+ pointerId: event.pointerId,
555
+ startX: event.clientX,
556
+ startY: event.clientY,
557
+ };
558
+ onDragStart?.(event);
559
+ };
560
+
561
+ const handlePointerMove = (event: ReactPointerEvent<HTMLDivElement>) => {
562
+ onPointerMove?.(event);
563
+ const drag = dragRef.current;
564
+ if (!drag || drag.pointerId !== event.pointerId) return;
565
+ onDragMove?.(event.clientX - drag.startX, event.clientY - drag.startY, event);
566
+ };
567
+
568
+ const handlePointerUp = (event: ReactPointerEvent<HTMLDivElement>) => {
569
+ onPointerUp?.(event);
570
+ const drag = dragRef.current;
571
+ if (!drag || drag.pointerId !== event.pointerId) return;
572
+
573
+ handleRef.current?.releasePointerCapture(event.pointerId);
574
+ dragRef.current = null;
575
+ const dx = event.clientX - drag.startX;
576
+ const dy = event.clientY - drag.startY;
577
+ if (dx !== 0 || dy !== 0) {
578
+ onDragEnd?.(dx, dy, event);
579
+ } else {
580
+ onDragCancel?.(event);
581
+ }
582
+ };
583
+
584
+ const handlePointerCancel = (event: ReactPointerEvent<HTMLDivElement>) => {
585
+ onPointerCancel?.(event);
586
+ const drag = dragRef.current;
587
+ if (!drag || drag.pointerId !== event.pointerId) return;
588
+
589
+ handleRef.current?.releasePointerCapture(event.pointerId);
590
+ dragRef.current = null;
591
+ onDragCancel?.(event);
592
+ };
593
+
594
+ return (
595
+ <div
596
+ ref={handleRef}
597
+ className={cx('ui-workbench-canvas-frame-handle', className)}
598
+ onPointerCancel={handlePointerCancel}
599
+ onPointerDown={handlePointerDown}
600
+ onPointerMove={handlePointerMove}
601
+ onPointerUp={handlePointerUp}
602
+ {...props}
603
+ >
604
+ <span className="ui-workbench-canvas-frame-handle__label">{content}</span>
605
+ </div>
606
+ );
607
+ }
608
+
609
+ export interface WorkbenchCanvasItemBadgeProps extends ComponentPropsWithRef<'span'> {
610
+ selected?: boolean | undefined;
611
+ }
612
+
613
+ export function WorkbenchCanvasItemBadge({
614
+ className,
615
+ selected = false,
616
+ ...props
617
+ }: WorkbenchCanvasItemBadgeProps) {
618
+ return (
619
+ <span
620
+ className={cx('ui-workbench-canvas-item-badge', className)}
621
+ data-selected={selected ? 'true' : 'false'}
622
+ {...props}
623
+ />
624
+ );
625
+ }
626
+
627
+ export interface WorkbenchCanvasResizeHandleProps extends Omit<
628
+ ComponentPropsWithRef<'button'>,
629
+ 'children'
630
+ > {
631
+ label?: string | undefined;
632
+ position?: WorkbenchCanvasResizeHandlePosition | undefined;
633
+ }
634
+
635
+ export type WorkbenchCanvasResizeHandlePosition = 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' | 'nw';
636
+
637
+ export function WorkbenchCanvasResizeHandle({
638
+ className,
639
+ label = 'Resize',
640
+ position = 'se',
641
+ type = 'button',
642
+ ...props
643
+ }: WorkbenchCanvasResizeHandleProps) {
644
+ return (
645
+ <button
646
+ aria-label={label}
647
+ className={cx('ui-workbench-canvas-resize-handle', className)}
648
+ data-position={position}
649
+ title={label}
650
+ type={type}
651
+ {...props}
652
+ />
653
+ );
654
+ }
655
+
656
+ export interface WorkbenchCanvasResizeFrameProps extends ComponentPropsWithRef<'div'> {
657
+ height: number | string;
658
+ width: number | string;
659
+ x: number | string;
660
+ y: number | string;
661
+ zIndex?: number | string;
662
+ }
663
+
664
+ export const WorkbenchCanvasResizeFrame = forwardRef<
665
+ HTMLDivElement,
666
+ WorkbenchCanvasResizeFrameProps
667
+ >(function WorkbenchCanvasResizeFrame(
668
+ { className, height, style, width, x, y, zIndex, ...props },
669
+ ref,
670
+ ) {
671
+ const frameStyle = {
672
+ '--ui-workbench-canvas-resize-frame-x': toLengthValue(x),
673
+ '--ui-workbench-canvas-resize-frame-y': toLengthValue(y),
674
+ '--ui-workbench-canvas-resize-frame-width': toLengthValue(width),
675
+ '--ui-workbench-canvas-resize-frame-height': toLengthValue(height),
676
+ ...(zIndex !== undefined
677
+ ? { '--ui-workbench-canvas-resize-frame-z-index': String(zIndex) }
678
+ : {}),
679
+ ...style,
680
+ } as CSSProperties;
681
+
682
+ return (
683
+ <div
684
+ ref={ref}
685
+ className={cx('ui-workbench-canvas-resize-frame', className)}
686
+ style={frameStyle}
687
+ {...props}
688
+ />
689
+ );
690
+ });
691
+
692
+ export interface WorkbenchCanvasResizePreviewProps extends ComponentPropsWithRef<'div'> {
693
+ height: number | string;
694
+ width: number | string;
695
+ x: number | string;
696
+ y: number | string;
697
+ zIndex?: number | string;
698
+ }
699
+
700
+ export function WorkbenchCanvasResizePreview({
701
+ className,
702
+ height,
703
+ style,
704
+ width,
705
+ x,
706
+ y,
707
+ zIndex,
708
+ ...props
709
+ }: WorkbenchCanvasResizePreviewProps) {
710
+ const previewStyle = {
711
+ '--ui-workbench-canvas-resize-preview-x': toLengthValue(x),
712
+ '--ui-workbench-canvas-resize-preview-y': toLengthValue(y),
713
+ '--ui-workbench-canvas-resize-preview-width': toLengthValue(width),
714
+ '--ui-workbench-canvas-resize-preview-height': toLengthValue(height),
715
+ ...(zIndex !== undefined
716
+ ? { '--ui-workbench-canvas-resize-preview-z-index': String(zIndex) }
717
+ : {}),
718
+ ...style,
719
+ } as CSSProperties;
720
+
721
+ return (
722
+ <div
723
+ className={cx('ui-workbench-canvas-resize-preview', className)}
724
+ style={previewStyle}
725
+ {...props}
726
+ />
727
+ );
728
+ }
729
+
730
+ export interface WorkbenchRenderSurfaceProps extends ComponentPropsWithRef<'div'> {
731
+ transparent?: boolean | undefined;
732
+ }
733
+
734
+ export function WorkbenchRenderSurface({
735
+ className,
736
+ transparent = false,
737
+ ...props
738
+ }: WorkbenchRenderSurfaceProps) {
739
+ return (
740
+ <div
741
+ className={cx('ui-workbench-render-surface', className)}
742
+ data-transparent={transparent ? 'true' : 'false'}
743
+ {...props}
744
+ />
745
+ );
746
+ }
747
+
748
+ export interface WorkbenchPreviewCanvasProps extends Omit<
749
+ ComponentPropsWithRef<'div'>,
750
+ 'children'
751
+ > {
752
+ children: ReactNode;
753
+ frameHeight: number;
754
+ frameTitle?: ReactNode;
755
+ frameWidth: number;
756
+ help?: ReactNode;
757
+ isPanning?: boolean;
758
+ onResetView?: () => void;
759
+ resetLabel?: ReactNode;
760
+ resetTitle?: string;
761
+ showViewportGrid?: boolean;
762
+ showWindowFrame?: boolean;
763
+ stageStyle?: CSSProperties;
764
+ viewportGridSize?: number;
765
+ viewportProps?: ComponentPropsWithRef<'div'>;
766
+ }
767
+
768
+ export function WorkbenchPreviewCanvas({
769
+ children,
770
+ className,
771
+ frameHeight,
772
+ frameTitle = 'Preview',
773
+ frameWidth,
774
+ help,
775
+ isPanning = false,
776
+ onResetView,
777
+ resetLabel = 'Reset',
778
+ resetTitle = 'Reset View',
779
+ showViewportGrid = false,
780
+ showWindowFrame = true,
781
+ stageStyle,
782
+ viewportGridSize = 8,
783
+ viewportProps,
784
+ ...props
785
+ }: WorkbenchPreviewCanvasProps) {
786
+ const {
787
+ className: viewportClassName,
788
+ style: viewportStyle,
789
+ ...restViewportProps
790
+ } = viewportProps ?? {};
791
+
792
+ return (
793
+ <div className={cx('ui-workbench-preview-canvas', className)} {...props}>
794
+ {onResetView ? (
795
+ <Button
796
+ compact
797
+ className="ui-workbench-preview-canvas__reset"
798
+ type="button"
799
+ onClick={onResetView}
800
+ title={resetTitle}
801
+ >
802
+ {resetLabel}
803
+ </Button>
804
+ ) : null}
805
+
806
+ <div
807
+ className="ui-workbench-preview-canvas__stage"
808
+ data-panning={isPanning ? 'true' : 'false'}
809
+ style={stageStyle}
810
+ >
811
+ <div
812
+ className="ui-workbench-preview-canvas__frame"
813
+ style={{
814
+ width: frameWidth,
815
+ height: frameHeight,
816
+ }}
817
+ >
818
+ {showWindowFrame ? (
819
+ <div className="ui-workbench-preview-canvas__titlebar">
820
+ <div className="ui-workbench-preview-canvas__window-controls">
821
+ <div className="ui-workbench-preview-canvas__dot" data-tone="close" />
822
+ <div className="ui-workbench-preview-canvas__dot" data-tone="minimize" />
823
+ <div className="ui-workbench-preview-canvas__dot" data-tone="maximize" />
824
+ </div>
825
+ <span className="ui-workbench-preview-canvas__title">{frameTitle}</span>
826
+ </div>
827
+ ) : null}
828
+ <div
829
+ className={cx('ui-workbench-preview-canvas__viewport', viewportClassName)}
830
+ data-grid={showViewportGrid ? 'true' : 'false'}
831
+ style={
832
+ showViewportGrid
833
+ ? ({
834
+ '--ui-workbench-preview-viewport-grid-size': `${viewportGridSize}px`,
835
+ ...viewportStyle,
836
+ } as CSSProperties)
837
+ : viewportStyle
838
+ }
839
+ {...restViewportProps}
840
+ >
841
+ {children}
842
+ </div>
843
+ </div>
844
+ </div>
845
+
846
+ {help ? <div className="ui-workbench-preview-canvas__help">{help}</div> : null}
847
+ </div>
848
+ );
849
+ }