@workbench-kit/react 0.0.2-prototype.0.2.5 → 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 (131) hide show
  1. package/README.md +87 -0
  2. package/package.json +20 -18
  3. package/src/index.ts +27 -27
  4. package/src/jdw/JsonCodeEditorPane.tsx +7 -6
  5. package/src/json-config/JsonConfigWorkbench.tsx +1 -1
  6. package/src/layout/sidebar/SidebarActionIconBar.tsx +3 -3
  7. package/src/layout/sidebar/WorkbenchSidebarActions.tsx +1 -1
  8. package/src/modal/Modal.tsx +55 -25
  9. package/src/modal/ModalTitlebar.tsx +8 -8
  10. package/src/modal/useModalFocusTrap.ts +142 -0
  11. package/src/modal/useModalWindowFrame.ts +2 -2
  12. package/src/primitives/absolute-box/AbsoluteBox.tsx +4 -4
  13. package/src/primitives/button/Button.tsx +4 -4
  14. package/src/primitives/catalog-browse-card/CatalogBrowseCard.tsx +6 -6
  15. package/src/primitives/catalog-browse-pane/CatalogBrowsePane.tsx +15 -15
  16. package/src/primitives/catalog-filter-overlay/CatalogFilterOverlay.tsx +2 -2
  17. package/src/primitives/checkbox/Checkbox.tsx +1 -1
  18. package/src/primitives/chip/Chip.tsx +2 -2
  19. package/src/primitives/codicon/Codicon.tsx +1 -1
  20. package/src/primitives/file-icon/FileIcon.tsx +1 -1
  21. package/src/primitives/icon-button/IconButton.tsx +1 -1
  22. package/src/primitives/library-detail-layout/LibraryDetailLayout.tsx +5 -5
  23. package/src/primitives/library-facet-filter-panel/LibraryFacetFilterPanel.tsx +12 -12
  24. package/src/primitives/library-facet-filter-strip/LibraryFacetFilterStrip.tsx +4 -4
  25. package/src/primitives/number-input/NumberInput.tsx +5 -5
  26. package/src/primitives/record-media-hero/RecordMediaHero.tsx +6 -6
  27. package/src/primitives/scroll-area/ScrollArea.tsx +5 -5
  28. package/src/primitives/scroll-area-infinite-load/useScrollAreaInfiniteLoad.ts +5 -5
  29. package/src/primitives/searchable-multi-select/SearchableMultiSelect.tsx +7 -7
  30. package/src/primitives/text-area/TextArea.tsx +1 -1
  31. package/src/primitives/text-input/TextInput.tsx +1 -1
  32. package/src/primitives/workbench-media-slot/WorkbenchMediaPlaceholder.tsx +2 -2
  33. package/src/primitives/workbench-media-slot/WorkbenchMediaSlot.tsx +9 -9
  34. package/src/primitives/workbench-thumbnail/WorkbenchThumbnail.tsx +4 -4
  35. package/src/styles.css +1 -2
  36. package/src/widget-tree/WidgetTreeWorkspaceShell.tsx +2 -2
  37. package/src/workbench/chat/ChatCommandProposalCard.tsx +4 -4
  38. package/src/workbench/chat/ChatConversationBar.tsx +3 -3
  39. package/src/workbench/chat/ChatHistoryMenu.tsx +1 -1
  40. package/src/workbench/chat/ChatMessageCollapsible.tsx +4 -0
  41. package/src/workbench/chat/ChatMessageItem.tsx +68 -10
  42. package/src/workbench/chat/ChatMessageList.tsx +1 -1
  43. package/src/workbench/chat/ChatPanel.tsx +32 -23
  44. package/src/workbench/chat/ChatPhasedRunProgress.tsx +86 -13
  45. package/src/workbench/chat/ChatRenameDialog.tsx +1 -1
  46. package/src/workbench/chat/chat-conversation.css +2 -2
  47. package/src/workbench/chat/chat-ui.css +8 -0
  48. package/src/workbench/chat/chatConversation.ts +2 -2
  49. package/src/workbench/chat/chatMessageMeta.tsx +4 -4
  50. package/src/workbench/chat/index.ts +1 -0
  51. package/src/workbench/chat/types.ts +7 -7
  52. package/src/workbench/chat/useCancelRuntimeOnUnmount.ts +4 -4
  53. package/src/workbench/chat/useChatPrependPagination.ts +10 -10
  54. package/src/workbench/chat/useSlashCommandSuggest.ts +1 -1
  55. package/src/workbench/{WorkbenchModalPortal.tsx → chrome/WorkbenchModalPortal.tsx} +1 -1
  56. package/src/workbench/chrome/workbench-chrome.css +4 -0
  57. package/src/workbench/{CommandGroupShell.tsx → commands/CommandGroupShell.tsx} +2 -2
  58. package/src/workbench/{CommandList.tsx → commands/CommandList.tsx} +5 -5
  59. package/src/workbench/{CommandPalette.tsx → commands/CommandPalette.tsx} +16 -42
  60. package/src/workbench/{ConfirmationFlow.tsx → commands/ConfirmationFlow.tsx} +5 -5
  61. package/src/workbench/{command-model.ts → commands/command-model.ts} +5 -1
  62. package/src/workbench/{commands.ts → commands/commands.ts} +1 -1
  63. package/src/workbench/{WorkbenchEditorTabs.tsx → editor/WorkbenchEditorTabs.tsx} +1 -1
  64. package/src/workbench/{editor-tabs-dnd.ts → editor/editor-tabs-dnd.ts} +1 -1
  65. package/src/workbench/{editorTabContextMenu.ts → editor/editorTabContextMenu.ts} +2 -2
  66. package/src/workbench/{useEditorTabsStripDnd.ts → editor/useEditorTabsStripDnd.ts} +1 -1
  67. package/src/workbench/{useWorkbenchEditorTabContextMenu.tsx → editor/useWorkbenchEditorTabContextMenu.tsx} +1 -1
  68. package/src/workbench/editor-tabs/index.ts +9 -9
  69. package/src/workbench/index.ts +93 -74
  70. package/src/workbench/management/ExtensionManagementPanel.tsx +31 -2
  71. package/src/workbench/management/ExtensionManagementSidebar.tsx +18 -1
  72. package/src/workbench/management/IntegrationsShell.tsx +1 -1
  73. package/src/workbench/management/WorkbenchDialogFrame.tsx +2 -2
  74. package/src/workbench/management/extension-install-approval.ts +72 -0
  75. package/src/workbench/management/index.ts +7 -0
  76. package/src/workbench/management/types.ts +14 -1
  77. package/src/workbench/{MarkdownPreview.tsx → markdown/MarkdownPreview.tsx} +22 -7
  78. package/src/workbench/markdown/markdownRemarkPlugins.ts +12 -0
  79. package/src/workbench/markdown/sanitizeMarkdownHref.ts +29 -0
  80. package/src/workbench/{ActivityBar.tsx → shell/ActivityBar.tsx} +8 -8
  81. package/src/workbench/{ArtifactShell.tsx → shell/ArtifactShell.tsx} +25 -25
  82. package/src/workbench/{SplitView.tsx → shell/SplitView.tsx} +3 -3
  83. package/src/workbench/{StatusBar.tsx → shell/StatusBar.tsx} +8 -8
  84. package/src/workbench/{StructuredArtifactEditor.tsx → shell/StructuredArtifactEditor.tsx} +9 -9
  85. package/src/workbench/{Timeline.tsx → shell/Timeline.tsx} +18 -18
  86. package/src/workbench/{WorkbenchCanvasShell.defaults.ts → shell/WorkbenchCanvasShell.defaults.ts} +1 -1
  87. package/src/workbench/{WorkbenchCanvasShell.model.ts → shell/WorkbenchCanvasShell.model.ts} +5 -5
  88. package/src/workbench/{WorkbenchCanvasShell.tsx → shell/WorkbenchCanvasShell.tsx} +6 -6
  89. package/src/workbench/{WorkbenchDesktopTitleBar.tsx → shell/WorkbenchDesktopTitleBar.tsx} +15 -15
  90. package/src/workbench/{WorkbenchShell.tsx → shell/WorkbenchShell.tsx} +5 -5
  91. package/src/workbench/{WorkbenchShellTitleBarLayoutControls.tsx → shell/WorkbenchShellTitleBarLayoutControls.tsx} +12 -12
  92. package/src/workbench/{WorkbenchStandaloneShell.tsx → shell/WorkbenchStandaloneShell.tsx} +4 -4
  93. package/src/workbench/{WorkbenchViewEditor.tsx → shell/WorkbenchViewEditor.tsx} +7 -7
  94. package/src/workbench/{WorkbenchViewSidebar.tsx → shell/WorkbenchViewSidebar.tsx} +7 -7
  95. package/src/workbench/{WorkbenchWindowChromeControls.tsx → shell/WorkbenchWindowChromeControls.tsx} +18 -15
  96. package/src/workbench/{shell.ts → shell/shell.ts} +18 -12
  97. package/src/workbench/{shellViewModel.ts → shell/shellViewModel.ts} +3 -3
  98. package/src/workbench/{standalone.ts → shell/standalone.ts} +2 -2
  99. package/src/workbench/{useDeferredWorkbenchMount.ts → shell/useDeferredWorkbenchMount.ts} +3 -3
  100. package/src/workbench/{useWorkbenchAppearanceDocumentSync.tsx → shell/useWorkbenchAppearanceDocumentSync.tsx} +1 -1
  101. package/src/workbench/{useWorkbenchSidebarActionBarDnd.ts → shell/useWorkbenchSidebarActionBarDnd.ts} +1 -1
  102. package/src/workbench/{useWorkbenchSidebarViewPlacementDropZone.ts → shell/useWorkbenchSidebarViewPlacementDropZone.ts} +2 -2
  103. package/src/workbench/{workbenchViewRouteState.ts → shell/workbenchViewRouteState.ts} +4 -4
  104. package/src/workbench/{WorkbenchThemeProvider.tsx → theme/WorkbenchThemeProvider.tsx} +4 -4
  105. package/src/workbench/{theme.ts → theme/theme.ts} +1 -1
  106. package/src/workbench/{themePresets.ts → theme/themePresets.ts} +2 -2
  107. package/src/workbench/workspace/WorkspaceEditorPanel.tsx +1 -1
  108. package/src/workbench/workspace/workspaceJsonDiagnostics.ts +6 -5
  109. package/src/workbench/jdw/jdw-editors.css +0 -4
  110. package/src/workbench/jdw/jdw.css +0 -2
  111. package/src/workbench/markdownRemarkPlugins.ts +0 -4
  112. package/src/workbench/workbench-chrome.css +0 -4
  113. /package/src/workbench/{WorkbenchPlatformContext.tsx → chrome/WorkbenchPlatformContext.tsx} +0 -0
  114. /package/src/workbench/{workbenchModalViewState.ts → chrome/workbenchModalViewState.ts} +0 -0
  115. /package/src/workbench/{workbenchOverlaysContext.tsx → chrome/workbenchOverlaysContext.tsx} +0 -0
  116. /package/src/workbench/{workbenchPlatformChrome.ts → chrome/workbenchPlatformChrome.ts} +0 -0
  117. /package/src/workbench/{ShortcutCommandBridge.tsx → commands/ShortcutCommandBridge.tsx} +0 -0
  118. /package/src/workbench/{command-execution-policy.ts → commands/command-execution-policy.ts} +0 -0
  119. /package/src/workbench/{keyboard.ts → commands/keyboard.ts} +0 -0
  120. /package/src/workbench/{workbenchContextMenu.ts → commands/workbenchContextMenu.ts} +0 -0
  121. /package/src/workbench/{activityBarOrder.ts → shell/activityBarOrder.ts} +0 -0
  122. /package/src/workbench/{appearanceLabels.ts → shell/appearanceLabels.ts} +0 -0
  123. /package/src/workbench/{hardReset.ts → shell/hardReset.ts} +0 -0
  124. /package/src/workbench/{shellPresets.ts → shell/shellPresets.ts} +0 -0
  125. /package/src/workbench/{shellState.ts → shell/shellState.ts} +0 -0
  126. /package/src/workbench/{sidebarViewPlacementDnd.ts → shell/sidebarViewPlacementDnd.ts} +0 -0
  127. /package/src/workbench/{status.ts → shell/status.ts} +0 -0
  128. /package/src/workbench/{useWorkbenchSidebarLayout.tsx → shell/useWorkbenchSidebarLayout.tsx} +0 -0
  129. /package/src/workbench/{useWorkbenchStandaloneShellStateSync.tsx → shell/useWorkbenchStandaloneShellStateSync.tsx} +0 -0
  130. /package/src/workbench/{workbenchSidebarLayoutContext.ts → shell/workbenchSidebarLayoutContext.ts} +0 -0
  131. /package/src/workbench/{workbenchStandaloneShellReactContext.tsx → shell/workbenchStandaloneShellReactContext.tsx} +0 -0
package/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # `@workbench-kit/react`
2
+
3
+ React primitives and workbench chrome for integrating hosts (browser, desktop
4
+ shells, and other React hosts).
5
+
6
+ Published on npm with the **`prototype`** dist tag.
7
+
8
+ ## Install
9
+
10
+ ```powershell
11
+ pnpm add @workbench-kit/react@prototype @workbench-kit/tokens@prototype
12
+ ```
13
+
14
+ Peer: React 19.
15
+
16
+ ## Styles
17
+
18
+ Import once at app entry:
19
+
20
+ ```ts
21
+ import '@workbench-kit/tokens/styles.css';
22
+ import '@workbench-kit/react/styles.css';
23
+ import '@workbench-kit/react/primitives.css';
24
+ ```
25
+
26
+ ## Quick start
27
+
28
+ ```tsx
29
+ import { WorkbenchShell } from '@workbench-kit/react/workbench/shell';
30
+
31
+ export function AppShell() {
32
+ return (
33
+ <div className="ui-workbench-host-root" style={{ height: '100vh' }}>
34
+ <WorkbenchShell
35
+ activityBar={{
36
+ items: [
37
+ { id: 'explorer', icon: <i className="codicon codicon-files" />, label: 'Explorer' },
38
+ ],
39
+ }}
40
+ rootClassName="ide-root"
41
+ secondaryArea={<main>Editor region</main>}
42
+ statusSections={[]}
43
+ />
44
+ </div>
45
+ );
46
+ }
47
+ ```
48
+
49
+ Full walkthrough: [Getting Started](../../docs/guides/getting-started.md).
50
+
51
+ ## Common subpaths
52
+
53
+ | Subpath | Purpose |
54
+ | ------------------------------------------ | --------------------------------------- |
55
+ | `@workbench-kit/react/primitives` | Buttons, editor chrome, library layouts |
56
+ | `@workbench-kit/react/workbench/shell` | Workbench shell / activity bar |
57
+ | `@workbench-kit/react/workbench/workspace` | Explorer, workspace editor panel |
58
+ | `@workbench-kit/react/workbench/chat` | Chat panel and message surfaces |
59
+ | `@workbench-kit/react/overlay` | Context menus, anchored overlays |
60
+ | `@workbench-kit/react/modal` | Low-level modal frame |
61
+ | `@workbench-kit/react/jdw` | JDW preview bridges |
62
+ | `@workbench-kit/react/styles.css` | Shell chrome CSS |
63
+
64
+ Import **only** through `exports`. Do not deep-import `src/` paths.
65
+
66
+ ## Learn more
67
+
68
+ | Doc | Purpose |
69
+ | ---------------------------------------------------------------------- | ----------------------------- |
70
+ | [Getting Started](../../docs/guides/getting-started.md) | Install + minimal shell |
71
+ | [Component Map](../../docs/guides/component-map.md) | Surface → Storybook / sample |
72
+ | [Sample Screens](../../docs/guides/sample-screens.md) | Example screen recipes |
73
+ | [Consumer Capabilities](../../docs/workbench/consumer-capabilities.md) | Props / when-to-use contracts |
74
+ | [API Reference](../../docs/guides/api-reference.md) | Package export index |
75
+
76
+ ## Local verification (this monorepo)
77
+
78
+ ```powershell
79
+ pnpm install
80
+ pnpm build:workbench-extensions
81
+ pnpm dev
82
+ pnpm dev:storybook
83
+ ```
84
+
85
+ Storybook stays a curated set of interaction stories — not a full package gallery.
86
+ Demo and story modules under this package are for development; published consumers
87
+ rely on the `exports` map and CSS entry points above.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workbench-kit/react",
3
- "version": "0.0.2-prototype.0.2.5",
3
+ "version": "0.0.2-prototype.0.2.8",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "exports": {
@@ -20,17 +20,17 @@
20
20
  "./workbench/management": "./src/workbench/management/index.ts",
21
21
  "./workbench/settings": "./src/workbench/settings/index.ts",
22
22
  "./workbench": "./src/workbench/index.ts",
23
- "./workbench/activityBarOrder": "./src/workbench/activityBarOrder.ts",
24
- "./workbench/markdown-preview": "./src/workbench/MarkdownPreview.tsx",
25
- "./workbench/shell": "./src/workbench/shell.ts",
26
- "./workbench/theme-provider": "./src/workbench/WorkbenchThemeProvider.tsx",
27
- "./workbench/themePresets": "./src/workbench/themePresets.ts",
28
- "./workbench/split-view": "./src/workbench/SplitView.tsx",
23
+ "./workbench/activityBarOrder": "./src/workbench/shell/activityBarOrder.ts",
24
+ "./workbench/markdown-preview": "./src/workbench/markdown/MarkdownPreview.tsx",
25
+ "./workbench/shell": "./src/workbench/shell/shell.ts",
26
+ "./workbench/theme-provider": "./src/workbench/theme/WorkbenchThemeProvider.tsx",
27
+ "./workbench/themePresets": "./src/workbench/theme/themePresets.ts",
28
+ "./workbench/split-view": "./src/workbench/shell/SplitView.tsx",
29
29
  "./workbench/workspace": "./src/workbench/workspace/index.ts",
30
30
  "./workbench/workspace/editor": "./src/workbench/workspace/WorkspaceEditor.tsx",
31
31
  "./workbench/workspace/explorer": "./src/workbench/workspace/WorkspaceExplorer.tsx",
32
32
  "./workbench/workspace/file-icon": "./src/icons/file-icon.ts",
33
- "./workbench/commands": "./src/workbench/commands.ts",
33
+ "./workbench/commands": "./src/workbench/commands/commands.ts",
34
34
  "./jdw": "./src/jdw/index.ts",
35
35
  "./jdw/document": "./src/jdw/document.ts",
36
36
  "./jdw/parse": "./src/jdw/parse.ts",
@@ -57,15 +57,16 @@
57
57
  "@dnd-kit/core": "^6.3.1",
58
58
  "@vscode/codicons": "^0.0.45",
59
59
  "remark-gfm": "^4.0.1",
60
- "@workbench-kit/platform": "0.0.2-prototype.0.2.5",
61
- "@workbench-kit/adapters": "0.0.2-prototype.0.2.5",
62
- "@workbench-kit/monaco": "0.0.2-prototype.0.2.5",
63
- "@workbench-kit/runtime": "0.0.2-prototype.0.2.5",
64
- "@workbench-kit/services": "0.0.2-prototype.0.2.5",
65
- "@workbench-kit/jdw": "0.0.2-prototype.0.2.5",
66
- "@workbench-kit/contracts": "0.0.2-prototype.0.2.5",
67
- "@workbench-kit/tokens": "0.0.2-prototype.0.2.5",
68
- "@workbench-kit/workspace": "0.0.2-prototype.0.2.5"
60
+ "rehype-sanitize": "^6.0.0",
61
+ "@workbench-kit/contracts": "0.0.2-prototype.0.2.8",
62
+ "@workbench-kit/adapters": "0.0.2-prototype.0.2.8",
63
+ "@workbench-kit/monaco": "0.0.2-prototype.0.2.8",
64
+ "@workbench-kit/runtime": "0.0.2-prototype.0.2.8",
65
+ "@workbench-kit/services": "0.0.2-prototype.0.2.8",
66
+ "@workbench-kit/tokens": "0.0.2-prototype.0.2.8",
67
+ "@workbench-kit/platform": "0.0.2-prototype.0.2.8",
68
+ "@workbench-kit/jdw": "0.0.2-prototype.0.2.8",
69
+ "@workbench-kit/workspace": "0.0.2-prototype.0.2.8"
69
70
  },
70
71
  "peerDependencies": {
71
72
  "react": "^19.0.0",
@@ -89,6 +90,7 @@
89
90
  },
90
91
  "scripts": {
91
92
  "test": "pnpm exec vitest run --config ../../vitest.config.ts src/widget-tree",
92
- "typecheck": "tsc -p tsconfig.json --noEmit"
93
+ "typecheck": "tsc -p tsconfig.json --noEmit",
94
+ "typecheck:exact-optional": "tsc -p typecheck-exact-optional/tsconfig.emit.json && tsc -p typecheck-exact-optional/tsconfig.json --noEmit"
93
95
  }
94
96
  }
package/src/index.ts CHANGED
@@ -20,7 +20,7 @@ export type {
20
20
  WorkbenchIconRenderProps,
21
21
  WorkbenchIconResolver,
22
22
  } from './icons';
23
- export { commandMenuItemsToContextMenuItems } from './workbench/commands';
23
+ export { commandMenuItemsToContextMenuItems } from './workbench/commands/commands';
24
24
  export {
25
25
  WorkbenchArtifactModeControls,
26
26
  WorkbenchArtifactPreview,
@@ -31,7 +31,7 @@ export {
31
31
  getWorkbenchPreviewRenderer,
32
32
  getWorkbenchPreviewRendererMatch,
33
33
  selectWorkbenchPreviewRenderer,
34
- } from './workbench/ArtifactShell';
34
+ } from './workbench/shell/ArtifactShell';
35
35
  export type {
36
36
  WorkbenchArtifactDescriptor,
37
37
  WorkbenchArtifactMode,
@@ -44,7 +44,7 @@ export type {
44
44
  WorkbenchPreviewRendererContext,
45
45
  WorkbenchPreviewRendererMatch,
46
46
  WorkbenchPreviewRendererMatchReason,
47
- } from './workbench/ArtifactShell';
47
+ } from './workbench/shell/ArtifactShell';
48
48
  export {
49
49
  WorkbenchCommandGroupShell,
50
50
  WorkbenchCommandList,
@@ -58,7 +58,7 @@ export {
58
58
  getWorkbenchCommandStatusLabel,
59
59
  groupWorkbenchCommands,
60
60
  isWorkbenchCommandRunnable,
61
- } from './workbench/CommandPalette';
61
+ } from './workbench/commands/CommandPalette';
62
62
  export {
63
63
  WorkbenchShortcutCommandBridge,
64
64
  getWorkbenchShortcutCommandBindings,
@@ -66,7 +66,7 @@ export {
66
66
  matchesWorkbenchShortcut,
67
67
  runWorkbenchShortcutCommand,
68
68
  useWorkbenchShortcutCommands,
69
- } from './workbench/ShortcutCommandBridge';
69
+ } from './workbench/commands/ShortcutCommandBridge';
70
70
  export type {
71
71
  WorkbenchCommandDescriptor,
72
72
  WorkbenchCommandDescriptorOverrides,
@@ -86,7 +86,7 @@ export type {
86
86
  WorkbenchCommandSideEffect,
87
87
  WorkbenchCommandStatus,
88
88
  WorkbenchCommandSuggestProps,
89
- } from './workbench/CommandPalette';
89
+ } from './workbench/commands/CommandPalette';
90
90
  export type {
91
91
  UseWorkbenchShortcutCommandsOptions,
92
92
  WorkbenchShortcutCommandBinding,
@@ -98,7 +98,7 @@ export type {
98
98
  WorkbenchShortcutEventLike,
99
99
  WorkbenchShortcutMatchInput,
100
100
  WorkbenchShortcutPlatform,
101
- } from './workbench/ShortcutCommandBridge';
101
+ } from './workbench/commands/ShortcutCommandBridge';
102
102
  export {
103
103
  WorkbenchConfirmationFlow,
104
104
  getWorkbenchConfirmationButtonVariant,
@@ -107,7 +107,7 @@ export {
107
107
  getWorkbenchConfirmationStatus,
108
108
  getWorkbenchConfirmationVariant,
109
109
  isWorkbenchConfirmationActionDisabled,
110
- } from './workbench/ConfirmationFlow';
110
+ } from './workbench/commands/ConfirmationFlow';
111
111
  export type {
112
112
  WorkbenchConfirmationAction,
113
113
  WorkbenchConfirmationCancelContext,
@@ -118,7 +118,7 @@ export type {
118
118
  WorkbenchConfirmationReason,
119
119
  WorkbenchConfirmationSideEffect,
120
120
  WorkbenchConfirmationVariant,
121
- } from './workbench/ConfirmationFlow';
121
+ } from './workbench/commands/ConfirmationFlow';
122
122
  export {
123
123
  WorkbenchAuthGate,
124
124
  WorkbenchLoginBrandMark,
@@ -161,7 +161,7 @@ export {
161
161
  getWorkbenchTimelineEventLabel,
162
162
  getWorkbenchTimelineEventStatus,
163
163
  getWorkbenchTimelineMetadataEntries,
164
- } from './workbench/Timeline';
164
+ } from './workbench/shell/Timeline';
165
165
  export type {
166
166
  WorkbenchTimelineEvent,
167
167
  WorkbenchTimelineEventKind,
@@ -173,7 +173,7 @@ export type {
173
173
  WorkbenchTimelineRenderMetadata,
174
174
  WorkbenchTimelineRenderPayload,
175
175
  WorkbenchTimelineVariant,
176
- } from './workbench/Timeline';
176
+ } from './workbench/shell/Timeline';
177
177
  export { ConfirmDialog } from './modal/ConfirmDialog';
178
178
  export type { ConfirmDialogProps } from './modal/ConfirmDialog';
179
179
  export { ContextMenu } from './overlay/ContextMenu';
@@ -216,12 +216,12 @@ export {
216
216
  isWorkbenchStatusDisabled,
217
217
  isWorkbenchStatusUnavailable,
218
218
  workbenchStatusFromLifecycleStatus,
219
- } from './workbench/status';
219
+ } from './workbench/shell/status';
220
220
  export type {
221
221
  WorkbenchStatus,
222
222
  WorkbenchStatusDescriptor,
223
223
  WorkbenchStatusVariant,
224
- } from './workbench/status';
224
+ } from './workbench/shell/status';
225
225
  export {
226
226
  FilterBar,
227
227
  FilterBarActiveChips,
@@ -567,7 +567,7 @@ export {
567
567
  StatusBar as WorkbenchStatusBar,
568
568
  StatusBarItem as WorkbenchStatusBarItem,
569
569
  StatusBarSection as WorkbenchStatusBarSection,
570
- } from './workbench/StatusBar';
570
+ } from './workbench/shell/StatusBar';
571
571
  export type {
572
572
  StatusBarItemModel as WorkbenchStatusBarItemModel,
573
573
  StatusBarItemProps as WorkbenchStatusBarItemProps,
@@ -575,7 +575,7 @@ export type {
575
575
  StatusBarSectionAlign as WorkbenchStatusBarSectionAlign,
576
576
  StatusBarSectionModel as WorkbenchStatusBarSectionModel,
577
577
  StatusBarSectionProps as WorkbenchStatusBarSectionProps,
578
- } from './workbench/StatusBar';
578
+ } from './workbench/shell/StatusBar';
579
579
  export { AbsoluteBox } from './primitives';
580
580
  export type { AbsoluteBoxProps, WorkbenchRect } from './primitives';
581
581
  export { Badge } from './primitives';
@@ -685,8 +685,8 @@ export type {
685
685
  WorkspaceDraftsContextValue,
686
686
  WorkspaceDraftsProviderProps,
687
687
  } from './workbench/workspace/WorkspaceDraftsContext';
688
- export { StructuredArtifactEditor } from './workbench/StructuredArtifactEditor';
689
- export type { StructuredArtifactEditorProps } from './workbench/StructuredArtifactEditor';
688
+ export { StructuredArtifactEditor } from './workbench/shell/StructuredArtifactEditor';
689
+ export type { StructuredArtifactEditorProps } from './workbench/shell/StructuredArtifactEditor';
690
690
  export { createStringDragMime, createTypedDragMime } from './utils/dragMime';
691
691
  export type { TypedDragMime, TypedDragMimeOptions } from './utils/dragMime';
692
692
  export {
@@ -698,29 +698,29 @@ export {
698
698
  readEditorTabDragPayload,
699
699
  resolveEditorTabDropTarget,
700
700
  resolveEditorTabStripDropTarget,
701
- } from './workbench/editor-tabs-dnd';
702
- export type { EditorTabDragPayload, EditorTabDropTarget } from './workbench/editor-tabs-dnd';
703
- export { useEditorTabsStripDnd } from './workbench/useEditorTabsStripDnd';
701
+ } from './workbench/editor/editor-tabs-dnd';
702
+ export type { EditorTabDragPayload, EditorTabDropTarget } from './workbench/editor/editor-tabs-dnd';
703
+ export { useEditorTabsStripDnd } from './workbench/editor/useEditorTabsStripDnd';
704
704
  export type {
705
705
  UseEditorTabsStripDndOptions,
706
706
  UseEditorTabsStripDndResult,
707
- } from './workbench/useEditorTabsStripDnd';
708
- export { WorkbenchEditorTabs } from './workbench/WorkbenchEditorTabs';
709
- export type { WorkbenchEditorTabsProps } from './workbench/WorkbenchEditorTabs';
707
+ } from './workbench/editor/useEditorTabsStripDnd';
708
+ export { WorkbenchEditorTabs } from './workbench/editor/WorkbenchEditorTabs';
709
+ export type { WorkbenchEditorTabsProps } from './workbench/editor/WorkbenchEditorTabs';
710
710
  export {
711
711
  createWorkbenchStandaloneEditorTabCommandContext,
712
712
  createWorkbenchStandaloneEditorTabContextMenuItems,
713
713
  isWorkbenchEditorTabClosable,
714
- } from './workbench/editorTabContextMenu';
714
+ } from './workbench/editor/editorTabContextMenu';
715
715
  export type {
716
716
  CreateWorkbenchStandaloneEditorTabCommandContextInput,
717
717
  WorkbenchStandaloneEditorTabLike,
718
- } from './workbench/editorTabContextMenu';
719
- export { useWorkbenchEditorTabContextMenu } from './workbench/useWorkbenchEditorTabContextMenu';
718
+ } from './workbench/editor/editorTabContextMenu';
719
+ export { useWorkbenchEditorTabContextMenu } from './workbench/editor/useWorkbenchEditorTabContextMenu';
720
720
  export type {
721
721
  UseWorkbenchEditorTabContextMenuOptions,
722
722
  UseWorkbenchEditorTabContextMenuResult,
723
- } from './workbench/useWorkbenchEditorTabContextMenu';
723
+ } from './workbench/editor/useWorkbenchEditorTabContextMenu';
724
724
  export {
725
725
  clampPreviewViewportZoom,
726
726
  computePreviewViewportFitScale,
@@ -20,7 +20,7 @@ import {
20
20
  StatusBar as WorkbenchStatusBar,
21
21
  StatusBarItem as WorkbenchStatusBarItem,
22
22
  StatusBarSection as WorkbenchStatusBarSection,
23
- } from '../workbench/StatusBar';
23
+ } from '../workbench/shell/StatusBar';
24
24
  import { WorkspaceEditor, type WorkspaceEditorTheme } from '../workbench/workspace/WorkspaceEditor';
25
25
  import type { WorkspaceFile } from '../workbench/workspace/types';
26
26
 
@@ -245,11 +245,12 @@ export function JsonCodeEditorPane({
245
245
  const configureJsonSchema = (monaco: WorkbenchMonaco, path: string) => {
246
246
  if (!jsonSchema) return;
247
247
 
248
- const jsonDefaults = (
249
- monaco.languages.json as unknown as {
250
- jsonDefaults?: { setDiagnosticsOptions: (options: unknown) => void };
251
- }
252
- ).jsonDefaults;
248
+ const jsonLanguage = monaco.languages.json as unknown as
249
+ | {
250
+ jsonDefaults?: { setDiagnosticsOptions: (options: unknown) => void };
251
+ }
252
+ | undefined;
253
+ const jsonDefaults = jsonLanguage?.jsonDefaults;
253
254
  if (!jsonDefaults) return;
254
255
 
255
256
  jsonDefaults.setDiagnosticsOptions({
@@ -9,7 +9,7 @@ import { IconButton } from '../primitives/icon-button';
9
9
  import { Toolbar } from '../primitives/toolbar';
10
10
  import { JsonCodeEditorPane, JsonConfigValidationBanner } from '../jdw/JsonCodeEditorPane.js';
11
11
  import { JdwPreview } from '../jdw/JdwPreview.js';
12
- import { SplitView } from '../workbench/SplitView';
12
+ import { SplitView } from '../workbench/shell/SplitView';
13
13
  import { WorkbenchStructuredDataSchemaPanel } from '../workbench/settings/StructuredDataSchemaPanel';
14
14
  import { type WorkbenchStructuredDataSchemaDocument } from '../workbench/settings/StructuredDataForm';
15
15
  import { type WorkspaceEditorTheme } from '../workbench/workspace/WorkspaceEditor';
@@ -12,14 +12,14 @@ import { IconButton } from '../../primitives/icon-button';
12
12
 
13
13
  import { cx } from '../../utils/cx';
14
14
 
15
- import { type ActivityBarOrientation } from '../../workbench/activityBarOrder';
15
+ import { type ActivityBarOrientation } from '../../workbench/shell/activityBarOrder';
16
16
 
17
17
  import {
18
18
  mergeWorkbenchSidebarViewPlacementDropZoneProps,
19
19
  useWorkbenchSidebarViewPlacementDropZone,
20
- } from '../../workbench/useWorkbenchSidebarViewPlacementDropZone';
20
+ } from '../../workbench/shell/useWorkbenchSidebarViewPlacementDropZone';
21
21
 
22
- import { useWorkbenchSidebarActionBarDnd } from '../../workbench/useWorkbenchSidebarActionBarDnd';
22
+ import { useWorkbenchSidebarActionBarDnd } from '../../workbench/shell/useWorkbenchSidebarActionBarDnd';
23
23
 
24
24
  import { SidebarToolbar } from './SidebarToolbar';
25
25
 
@@ -8,7 +8,7 @@ import {
8
8
  isWorkbenchStatusBusy,
9
9
  isWorkbenchStatusDisabled,
10
10
  type WorkbenchStatus,
11
- } from '../../workbench/status';
11
+ } from '../../workbench/shell/status';
12
12
  import {
13
13
  SideBarList,
14
14
  SideBarListItem,
@@ -1,18 +1,22 @@
1
1
  import {
2
+ useCallback,
2
3
  useId,
4
+ useRef,
3
5
  type CSSProperties,
4
6
  type FormEventHandler,
5
7
  type MouseEvent,
6
8
  type ReactNode,
9
+ type RefObject,
7
10
  } from 'react';
8
11
  import { cx } from '../utils/cx';
9
12
  import { ModalResizeHandles } from './ModalResizeHandles';
10
13
  import { ModalTitlebar } from './ModalTitlebar';
14
+ import { useModalFocusTrap } from './useModalFocusTrap';
11
15
  import { useModalWindowFrame } from './useModalWindowFrame';
12
16
  import {
13
17
  resolveWorkbenchWindowChromeDataAttributes,
14
18
  type WorkbenchWindowChromeMode,
15
- } from '../workbench/workbenchPlatformChrome';
19
+ } from '../workbench/chrome/workbenchPlatformChrome';
16
20
 
17
21
  export type { ModalBounds, ModalPosition, ModalSize } from './modalTypes';
18
22
 
@@ -20,44 +24,50 @@ export type ModalBodyLayout = 'block' | 'stack';
20
24
  export type ModalBodyPadding = 'none' | 'md' | 'lg';
21
25
 
22
26
  export interface ModalProps {
23
- chrome?: WorkbenchWindowChromeMode | undefined;
27
+ chrome?: WorkbenchWindowChromeMode;
24
28
  title: ReactNode;
25
- titleSuffix?: ReactNode | undefined;
29
+ titleSuffix?: ReactNode;
26
30
  children: ReactNode;
27
- footer?: ReactNode | undefined;
28
- className?: string | undefined;
29
- bodyClassName?: string | undefined;
30
- bodyLayout?: ModalBodyLayout | undefined;
31
- bodyPadding?: ModalBodyPadding | undefined;
32
- bodyScroll?: 'auto' | 'hidden' | undefined;
33
- closeLabel?: string | undefined;
34
- defaultHeight?: number | undefined;
35
- defaultMaximized?: boolean | undefined;
36
- defaultWidth?: number | undefined;
37
- labelledBy?: string | undefined;
38
- maximizeLabel?: string | undefined;
39
- minHeight?: number | undefined;
40
- minWidth?: number | undefined;
31
+ footer?: ReactNode;
32
+ className?: string;
33
+ bodyClassName?: string;
34
+ bodyLayout?: ModalBodyLayout;
35
+ bodyPadding?: ModalBodyPadding;
36
+ bodyScroll?: 'auto' | 'hidden';
37
+ /** When true (default), Escape calls `onClose`. */
38
+ closeOnEscape?: boolean;
39
+ closeLabel?: string;
40
+ defaultHeight?: number;
41
+ defaultMaximized?: boolean;
42
+ defaultWidth?: number;
43
+ /** Optional element to focus when the modal mounts (must be inside the dialog). */
44
+ initialFocusRef?: RefObject<HTMLElement | null>;
45
+ labelledBy?: string;
46
+ maximizeLabel?: string;
47
+ minHeight?: number;
48
+ minWidth?: number;
41
49
  onClose: () => void;
42
- onSubmit?: FormEventHandler<HTMLFormElement> | undefined;
43
- restoreLabel?: string | undefined;
50
+ onSubmit?: FormEventHandler<HTMLFormElement>;
51
+ /** When true (default), restore focus to the previously focused element on unmount. */
52
+ restoreFocusOnClose?: boolean;
53
+ restoreLabel?: string;
44
54
  }
45
55
 
46
56
  interface ModalFrameProps {
47
- bodyClassName?: string | undefined;
57
+ bodyClassName?: string;
48
58
  bodyLayout: ModalBodyLayout;
49
59
  bodyPadding: ModalBodyPadding;
50
60
  bodyScroll: 'auto' | 'hidden';
51
61
  children: ReactNode;
52
62
  dataAttrs: Record<string, string | undefined>;
53
- footer?: ReactNode | undefined;
63
+ footer?: ReactNode;
54
64
  frameRef: (node: HTMLDivElement | HTMLFormElement | null) => void;
55
65
  modalClassName: string;
56
66
  resolvedLabelledBy: string;
57
- resizeHandles?: ReactNode | undefined;
58
- style?: CSSProperties | undefined;
67
+ resizeHandles?: ReactNode;
68
+ style?: CSSProperties;
59
69
  titlebar: ReactNode;
60
- onSubmit?: FormEventHandler<HTMLFormElement> | undefined;
70
+ onSubmit?: FormEventHandler<HTMLFormElement>;
61
71
  }
62
72
 
63
73
  function ModalFrame({
@@ -133,22 +143,26 @@ export function Modal({
133
143
  bodyLayout = 'block',
134
144
  bodyPadding = 'none',
135
145
  bodyScroll = 'hidden',
146
+ closeOnEscape = true,
136
147
  closeLabel,
137
148
  defaultHeight,
138
149
  defaultMaximized = false,
139
150
  defaultWidth,
151
+ initialFocusRef,
140
152
  labelledBy,
141
153
  maximizeLabel,
142
154
  minHeight = 200,
143
155
  minWidth = 320,
144
156
  onClose,
145
157
  onSubmit,
158
+ restoreFocusOnClose = true,
146
159
  restoreLabel,
147
160
  }: ModalProps) {
148
161
  const modalClassName = cx('ui-modal', className);
149
162
  const chromeAttributes = resolveWorkbenchWindowChromeDataAttributes(chrome);
150
163
  const generatedLabelId = useId();
151
164
  const resolvedLabelledBy = labelledBy ?? generatedLabelId;
165
+ const dialogRef = useRef<HTMLElement | null>(null);
152
166
 
153
167
  const {
154
168
  assignFrameRef,
@@ -167,6 +181,22 @@ export function Modal({
167
181
  minWidth,
168
182
  });
169
183
 
184
+ const setFrameRef = useCallback(
185
+ (node: HTMLDivElement | HTMLFormElement | null) => {
186
+ dialogRef.current = node;
187
+ assignFrameRef(node);
188
+ },
189
+ [assignFrameRef],
190
+ );
191
+
192
+ useModalFocusTrap({
193
+ closeOnEscape,
194
+ containerRef: dialogRef,
195
+ initialFocusRef,
196
+ onClose,
197
+ restoreFocusOnClose,
198
+ });
199
+
170
200
  const isPositioned = bounds !== null || maximized;
171
201
 
172
202
  return (
@@ -183,7 +213,7 @@ export function Modal({
183
213
  ...(chromeAttributes ?? {}),
184
214
  }}
185
215
  footer={footer}
186
- frameRef={assignFrameRef}
216
+ frameRef={setFrameRef}
187
217
  modalClassName={modalClassName}
188
218
  resolvedLabelledBy={resolvedLabelledBy}
189
219
  resizeHandles={maximized ? null : <ModalResizeHandles onResizeStart={handleResizeStart} />}
@@ -1,28 +1,28 @@
1
1
  import type { PointerEvent as ReactPointerEvent, ReactNode } from 'react';
2
2
 
3
- import { useWorkbenchHostPlatform } from '../workbench/WorkbenchPlatformContext';
3
+ import { useWorkbenchHostPlatform } from '../workbench/chrome/WorkbenchPlatformContext';
4
4
  import {
5
5
  shouldUseDarwinPlatformChrome,
6
6
  WorkbenchWindowChromeControls,
7
- } from '../workbench/WorkbenchWindowChromeControls';
7
+ } from '../workbench/shell/WorkbenchWindowChromeControls';
8
8
  import {
9
9
  resolveWorkbenchWindowChromeDataAttributes,
10
10
  type WorkbenchWindowChromeMode,
11
- } from '../workbench/workbenchPlatformChrome';
11
+ } from '../workbench/chrome/workbenchPlatformChrome';
12
12
 
13
13
  export interface ModalTitlebarProps {
14
- chrome?: WorkbenchWindowChromeMode | undefined;
15
- closeLabel?: string | undefined;
14
+ chrome?: WorkbenchWindowChromeMode;
15
+ closeLabel?: string;
16
16
  labelledBy: string;
17
17
  maximized: boolean;
18
- maximizeLabel?: string | undefined;
18
+ maximizeLabel?: string;
19
19
  onClose: () => void;
20
20
  onDoubleClick: () => void;
21
21
  onPointerDown: (event: ReactPointerEvent<HTMLDivElement>) => void;
22
22
  onToggleMaximized: () => void;
23
- restoreLabel?: string | undefined;
23
+ restoreLabel?: string;
24
24
  title: ReactNode;
25
- titleSuffix?: ReactNode | undefined;
25
+ titleSuffix?: ReactNode;
26
26
  }
27
27
 
28
28
  export function ModalTitlebar({