@workbench-kit/react 0.0.2-prototype.0.2.4 → 0.0.2-prototype.0.2.41

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 (221) hide show
  1. package/README.md +172 -0
  2. package/package.json +38 -21
  3. package/src/index.ts +74 -34
  4. package/src/jdw/JsonCodeEditorPane.tsx +7 -6
  5. package/src/jdw/builtins/renderBuiltinWidgetLeaf.tsx +1 -3
  6. package/src/jdw/createBuiltinJdwRegistry.ts +1 -4
  7. package/src/jdw/cssRenderBackend.tsx +1 -4
  8. package/src/jdw/fixtures/jdw-fixtures.ts +0 -15
  9. package/src/json-config/JsonConfigWorkbench.tsx +1 -1
  10. package/src/layout/index.ts +11 -2
  11. package/src/layout/panel/Panel.tsx +0 -3
  12. package/src/layout/panel/index.ts +0 -2
  13. package/src/layout/sidebar/SideBarTree.tsx +301 -0
  14. package/src/layout/sidebar/SidebarActionIconBar.tsx +3 -3
  15. package/src/layout/sidebar/WorkbenchSidebarActions.tsx +1 -1
  16. package/src/layout/sidebar/index.ts +13 -0
  17. package/src/modal/Modal.tsx +55 -25
  18. package/src/modal/ModalTitlebar.tsx +8 -8
  19. package/src/modal/modalPosition.ts +3 -6
  20. package/src/modal/useModalFocusTrap.ts +142 -0
  21. package/src/modal/useModalWindowFrame.ts +2 -2
  22. package/src/overlay/ContextMenu.tsx +133 -21
  23. package/src/overlay/context-menu-density.css +22 -0
  24. package/src/overlay/context-menu-item.ts +17 -0
  25. package/src/overlay/context-menu.css +6 -2
  26. package/src/overlay/index.ts +6 -1
  27. package/src/overlay/measureAnchoredOverlayPanel.ts +4 -6
  28. package/src/overlay/pointerPassthroughRegion.ts +17 -1
  29. package/src/overlay/usePointerPassthroughRegion.ts +35 -6
  30. package/src/primitives/absolute-box/AbsoluteBox.tsx +4 -4
  31. package/src/primitives/app-icon/AppIcon.tsx +33 -0
  32. package/src/primitives/app-icon/app-icon.css +28 -0
  33. package/src/primitives/button/Button.tsx +4 -4
  34. package/src/primitives/catalog-browse-card/CatalogBrowseCard.tsx +6 -6
  35. package/src/primitives/catalog-browse-pane/CatalogBrowsePane.tsx +39 -32
  36. package/src/primitives/catalog-browse-pane/catalog-browse-pane.css +4 -0
  37. package/src/primitives/catalog-filter-overlay/CatalogFilterOverlay.tsx +2 -2
  38. package/src/primitives/checkbox/Checkbox.tsx +1 -1
  39. package/src/primitives/chip/Chip.tsx +3 -12
  40. package/src/primitives/chip/index.ts +2 -2
  41. package/src/primitives/codicon/Codicon.tsx +1 -1
  42. package/src/primitives/file-icon/FileIcon.tsx +1 -1
  43. package/src/primitives/icon-button/IconButton.tsx +1 -1
  44. package/src/primitives/index.ts +7 -2
  45. package/src/primitives/library-detail-layout/LibraryDetailLayout.tsx +123 -9
  46. package/src/primitives/library-detail-layout/library-detail-layout.css +57 -0
  47. package/src/primitives/library-detail-layout/resolve-hero-cover-media.ts +80 -0
  48. package/src/primitives/library-facet-filter-panel/LibraryFacetFilterPanel.tsx +12 -12
  49. package/src/primitives/library-facet-filter-strip/LibraryFacetFilterStrip.tsx +4 -4
  50. package/src/primitives/number-input/NumberInput.tsx +5 -5
  51. package/src/primitives/primitives.css +1 -0
  52. package/src/primitives/record-media-hero/RecordMediaHero.tsx +10 -6
  53. package/src/primitives/scroll-area/ScrollArea.tsx +5 -5
  54. package/src/primitives/scroll-area-infinite-load/useScrollAreaInfiniteLoad.ts +5 -5
  55. package/src/primitives/searchable-multi-select/SearchableMultiSelect.tsx +7 -7
  56. package/src/primitives/select/Select.tsx +1 -13
  57. package/src/primitives/text-area/TextArea.tsx +1 -1
  58. package/src/primitives/text-input/TextInput.tsx +1 -1
  59. package/src/primitives/workbench-media-slot/WorkbenchMediaPlaceholder.tsx +2 -2
  60. package/src/primitives/workbench-media-slot/WorkbenchMediaSlot.tsx +16 -10
  61. package/src/primitives/workbench-thumbnail/WorkbenchThumbnail.tsx +4 -4
  62. package/src/scrollbars.css +2 -6
  63. package/src/styles/core.css +16 -0
  64. package/src/styles/foundation.css +4 -0
  65. package/src/styles/overlay.css +2 -0
  66. package/src/styles.css +1 -15
  67. package/src/utils/clamp.ts +4 -0
  68. package/src/utils/normalizeKeyToken.ts +13 -0
  69. package/src/utils/readNumber.ts +4 -0
  70. package/src/widget-tree/WidgetSourceEditor.tsx +0 -14
  71. package/src/widget-tree/WidgetTreeCanvasPreview.tsx +3 -10
  72. package/src/widget-tree/WidgetTreeLab.tsx +2 -23
  73. package/src/widget-tree/WidgetTreeSidePanel.tsx +0 -5
  74. package/src/widget-tree/WidgetTreeWorkspaceShell.tsx +2 -2
  75. package/src/widget-tree/index.ts +1 -5
  76. package/src/workbench/auth/WorkbenchLoginView.tsx +1 -2
  77. package/src/workbench/auth/auth-flows.css +14 -0
  78. package/src/workbench/chat/ChatCommandProposalCard.tsx +4 -4
  79. package/src/workbench/chat/ChatConversationBar.tsx +3 -3
  80. package/src/workbench/chat/ChatHistoryMenu.tsx +1 -1
  81. package/src/workbench/chat/ChatMessageCollapsible.tsx +4 -0
  82. package/src/workbench/chat/ChatMessageItem.tsx +68 -10
  83. package/src/workbench/chat/ChatMessageList.tsx +1 -1
  84. package/src/workbench/chat/ChatPanel.tsx +32 -23
  85. package/src/workbench/chat/ChatPhasedRunProgress.tsx +86 -13
  86. package/src/workbench/chat/ChatRenameDialog.tsx +1 -1
  87. package/src/workbench/chat/chat-conversation.css +2 -2
  88. package/src/workbench/chat/chat-ui.css +8 -0
  89. package/src/workbench/chat/chatConversation.ts +2 -2
  90. package/src/workbench/chat/chatMessageMeta.tsx +4 -4
  91. package/src/workbench/chat/index.ts +1 -0
  92. package/src/workbench/chat/types.ts +7 -7
  93. package/src/workbench/chat/useCancelRuntimeOnUnmount.ts +4 -4
  94. package/src/workbench/chat/useChatPrependPagination.ts +10 -10
  95. package/src/workbench/chat/useSlashCommandSuggest.ts +1 -1
  96. package/src/workbench/{WorkbenchModalPortal.tsx → chrome/WorkbenchModalPortal.tsx} +1 -1
  97. package/src/workbench/chrome/workbench-chrome.css +4 -0
  98. package/src/workbench/chrome/workbench-layout-regions.css +13 -0
  99. package/src/workbench/chrome/workbench-shell-titlebar.css +0 -8
  100. package/src/workbench/{CommandGroupShell.tsx → commands/CommandGroupShell.tsx} +2 -2
  101. package/src/workbench/{CommandList.tsx → commands/CommandList.tsx} +6 -5
  102. package/src/workbench/{CommandPalette.tsx → commands/CommandPalette.tsx} +16 -42
  103. package/src/workbench/{ConfirmationFlow.tsx → commands/ConfirmationFlow.tsx} +5 -5
  104. package/src/workbench/{ShortcutCommandBridge.tsx → commands/ShortcutCommandBridge.tsx} +17 -13
  105. package/src/workbench/commands/WorkbenchQuickOpen.tsx +462 -0
  106. package/src/workbench/{command-model.ts → commands/command-model.ts} +5 -1
  107. package/src/workbench/commands/command-ui.ts +3 -0
  108. package/src/workbench/{commands.ts → commands/commands.ts} +45 -1
  109. package/src/workbench/commands/createWorkspaceFilesQuickOpenProvider.ts +86 -0
  110. package/src/workbench/commands/quick-open-model.ts +66 -0
  111. package/src/workbench/{WorkbenchEditorTabs.tsx → editor/WorkbenchEditorTabs.tsx} +13 -3
  112. package/src/workbench/{editor-tabs-dnd.ts → editor/editor-tabs-dnd.ts} +1 -1
  113. package/src/workbench/{editorTabContextMenu.ts → editor/editorTabContextMenu.ts} +43 -4
  114. package/src/workbench/{useEditorTabsStripDnd.ts → editor/useEditorTabsStripDnd.ts} +1 -1
  115. package/src/workbench/{useWorkbenchEditorTabContextMenu.tsx → editor/useWorkbenchEditorTabContextMenu.tsx} +16 -2
  116. package/src/workbench/editor-tabs/index.ts +10 -9
  117. package/src/workbench/index.ts +114 -74
  118. package/src/workbench/management/CommandManagementSidebar.tsx +16 -30
  119. package/src/workbench/management/ExtensionManagementPanel.tsx +84 -46
  120. package/src/workbench/management/ExtensionManagementSidebar.tsx +79 -45
  121. package/src/workbench/management/IntegrationCommandActions.tsx +8 -1
  122. package/src/workbench/management/IntegrationSettingsSurface.tsx +2 -5
  123. package/src/workbench/management/IntegrationsShell.tsx +1 -1
  124. package/src/workbench/management/KeybindingCaptureField.tsx +1 -9
  125. package/src/workbench/management/WorkbenchDialogFrame.tsx +2 -2
  126. package/src/workbench/management/WorkbenchNotice.tsx +17 -12
  127. package/src/workbench/management/createWorkbenchNotify.tsx +88 -0
  128. package/src/workbench/management/extension-install-approval.ts +72 -0
  129. package/src/workbench/management/extension-management-filters.ts +38 -0
  130. package/src/workbench/management/index.ts +18 -3
  131. package/src/workbench/management/management.css +28 -0
  132. package/src/workbench/management/types.ts +23 -1
  133. package/src/workbench/management/useWorkbenchNotify.ts +10 -0
  134. package/src/workbench/{MarkdownPreview.tsx → markdown/MarkdownPreview.tsx} +22 -7
  135. package/src/workbench/markdown/markdownRemarkPlugins.ts +12 -0
  136. package/src/workbench/markdown/sanitizeMarkdownHref.ts +29 -0
  137. package/src/workbench/schema/workbenchDocumentRenderer.tsx +48 -121
  138. package/src/workbench/settings/StructuredDataForm.tsx +1 -4
  139. package/src/workbench/settings/StructuredDataSchemaPanel.tsx +39 -44
  140. package/src/workbench/settings/sectionedPanelScrollSpy.ts +0 -81
  141. package/src/workbench/settings/structuredDataFormModel.ts +2 -1
  142. package/src/workbench/settings/structuredDataSchema.ts +24 -13
  143. package/src/workbench/settings/structuredDataSchemaSection.ts +4 -0
  144. package/src/workbench/settings/structuredDataSchemaTable.ts +5 -2
  145. package/src/workbench/{ActivityBar.tsx → shell/ActivityBar.tsx} +8 -12
  146. package/src/workbench/{ArtifactShell.tsx → shell/ArtifactShell.tsx} +25 -25
  147. package/src/workbench/{SplitView.tsx → shell/SplitView.tsx} +3 -3
  148. package/src/workbench/{StatusBar.tsx → shell/StatusBar.tsx} +8 -8
  149. package/src/workbench/{StructuredArtifactEditor.tsx → shell/StructuredArtifactEditor.tsx} +9 -9
  150. package/src/workbench/{Timeline.tsx → shell/Timeline.tsx} +77 -20
  151. package/src/workbench/{WorkbenchCanvasShell.defaults.ts → shell/WorkbenchCanvasShell.defaults.ts} +1 -1
  152. package/src/workbench/{WorkbenchCanvasShell.model.ts → shell/WorkbenchCanvasShell.model.ts} +5 -5
  153. package/src/workbench/{WorkbenchCanvasShell.tsx → shell/WorkbenchCanvasShell.tsx} +6 -6
  154. package/src/workbench/{WorkbenchDesktopTitleBar.tsx → shell/WorkbenchDesktopTitleBar.tsx} +15 -15
  155. package/src/workbench/{WorkbenchShell.tsx → shell/WorkbenchShell.tsx} +45 -6
  156. package/src/workbench/{WorkbenchShellTitleBarLayoutControls.tsx → shell/WorkbenchShellTitleBarLayoutControls.tsx} +16 -19
  157. package/src/workbench/{WorkbenchStandaloneShell.tsx → shell/WorkbenchStandaloneShell.tsx} +15 -22
  158. package/src/workbench/{WorkbenchViewEditor.tsx → shell/WorkbenchViewEditor.tsx} +7 -7
  159. package/src/workbench/{WorkbenchViewSidebar.tsx → shell/WorkbenchViewSidebar.tsx} +7 -7
  160. package/src/workbench/{WorkbenchWindowChromeControls.tsx → shell/WorkbenchWindowChromeControls.tsx} +18 -15
  161. package/src/workbench/shell/activity-bar.css +47 -0
  162. package/src/workbench/{activityBarOrder.ts → shell/activityBarOrder.ts} +2 -1
  163. package/src/workbench/{shell.ts → shell/shell.ts} +20 -13
  164. package/src/workbench/{shellViewModel.ts → shell/shellViewModel.ts} +3 -3
  165. package/src/workbench/{standalone.ts → shell/standalone.ts} +14 -2
  166. package/src/workbench/{useDeferredWorkbenchMount.ts → shell/useDeferredWorkbenchMount.ts} +3 -3
  167. package/src/workbench/{useWorkbenchAppearanceDocumentSync.tsx → shell/useWorkbenchAppearanceDocumentSync.tsx} +1 -1
  168. package/src/workbench/{useWorkbenchSidebarActionBarDnd.ts → shell/useWorkbenchSidebarActionBarDnd.ts} +1 -1
  169. package/src/workbench/{useWorkbenchSidebarViewPlacementDropZone.ts → shell/useWorkbenchSidebarViewPlacementDropZone.ts} +2 -2
  170. package/src/workbench/{workbenchSidebarLayoutContext.ts → shell/workbenchSidebarLayoutContext.ts} +0 -6
  171. package/src/workbench/{workbenchViewRouteState.ts → shell/workbenchViewRouteState.ts} +4 -4
  172. package/src/workbench/{WorkbenchThemeProvider.tsx → theme/WorkbenchThemeProvider.tsx} +4 -4
  173. package/src/workbench/{theme.ts → theme/theme.ts} +1 -1
  174. package/src/workbench/{themePresets.ts → theme/themePresets.ts} +39 -64
  175. package/src/workbench/views/command-list-density.css +36 -0
  176. package/src/workbench/views/command-list.css +2 -0
  177. package/src/workbench/views/extensions-sidebar.css +2 -0
  178. package/src/workbench/views/view-hosts.css +3 -3
  179. package/src/workbench/workspace/WorkspaceEditorPanel.tsx +1 -1
  180. package/src/workbench/workspace/WorkspaceExplorer.tsx +105 -4
  181. package/src/workbench/workspace/createVirtualWorkspaceExplorerPort.ts +1 -14
  182. package/src/workbench/workspace/workspaceExplorerKeyboard.ts +109 -0
  183. package/src/workbench/workspace/workspaceJsonDiagnostics.ts +6 -5
  184. package/src/workbench-menu-surfaces.css +3 -57
  185. package/src/brand/TilepaperAppIcon.tsx +0 -181
  186. package/src/brand/index.ts +0 -2
  187. package/src/brand/tilepaper-app-icon-geometry.ts +0 -201
  188. package/src/primitives/absolute-box/index.ts +0 -1
  189. package/src/primitives/catalog-browse-card/index.ts +0 -1
  190. package/src/primitives/catalog-browse-pane/index.ts +0 -3
  191. package/src/primitives/catalog-filter-overlay/index.ts +0 -1
  192. package/src/primitives/codicon/index.ts +0 -1
  193. package/src/primitives/external-link-button/index.ts +0 -1
  194. package/src/primitives/library-detail-layout/index.ts +0 -1
  195. package/src/primitives/library-facet-filter-panel/index.ts +0 -1
  196. package/src/primitives/library-facet-filter-strip/index.ts +0 -1
  197. package/src/primitives/panel-loading/index.ts +0 -1
  198. package/src/primitives/scroll-area-infinite-load/index.ts +0 -2
  199. package/src/primitives/workbench-thumbnail/index.ts +0 -1
  200. package/src/test-utils/workbenchMonacoMock.tsx +0 -37
  201. package/src/workbench/jdw/jdw-editors.css +0 -4
  202. package/src/workbench/jdw/jdw.css +0 -2
  203. package/src/workbench/management/integration-command-action.ts +0 -25
  204. package/src/workbench/markdownRemarkPlugins.ts +0 -4
  205. package/src/workbench/workbench-chrome.css +0 -4
  206. /package/src/workbench/{WorkbenchPlatformContext.tsx → chrome/WorkbenchPlatformContext.tsx} +0 -0
  207. /package/src/workbench/{workbenchModalViewState.ts → chrome/workbenchModalViewState.ts} +0 -0
  208. /package/src/workbench/{workbenchOverlaysContext.tsx → chrome/workbenchOverlaysContext.tsx} +0 -0
  209. /package/src/workbench/{workbenchPlatformChrome.ts → chrome/workbenchPlatformChrome.ts} +0 -0
  210. /package/src/workbench/{command-execution-policy.ts → commands/command-execution-policy.ts} +0 -0
  211. /package/src/workbench/{keyboard.ts → commands/keyboard.ts} +0 -0
  212. /package/src/workbench/{workbenchContextMenu.ts → commands/workbenchContextMenu.ts} +0 -0
  213. /package/src/workbench/{appearanceLabels.ts → shell/appearanceLabels.ts} +0 -0
  214. /package/src/workbench/{hardReset.ts → shell/hardReset.ts} +0 -0
  215. /package/src/workbench/{shellPresets.ts → shell/shellPresets.ts} +0 -0
  216. /package/src/workbench/{shellState.ts → shell/shellState.ts} +0 -0
  217. /package/src/workbench/{sidebarViewPlacementDnd.ts → shell/sidebarViewPlacementDnd.ts} +0 -0
  218. /package/src/workbench/{status.ts → shell/status.ts} +0 -0
  219. /package/src/workbench/{useWorkbenchSidebarLayout.tsx → shell/useWorkbenchSidebarLayout.tsx} +0 -0
  220. /package/src/workbench/{useWorkbenchStandaloneShellStateSync.tsx → shell/useWorkbenchStandaloneShellStateSync.tsx} +0 -0
  221. /package/src/workbench/{workbenchStandaloneShellReactContext.tsx → shell/workbenchStandaloneShellReactContext.tsx} +0 -0
@@ -8,23 +8,23 @@ import {
8
8
  } from './chatScroll';
9
9
 
10
10
  export interface UseChatPrependPaginationOptions {
11
- autoScrollBottomThreshold?: number | undefined;
12
- getScrollContainer?: ((listElement: HTMLDivElement | null) => HTMLElement | null) | undefined;
13
- initialVisibleItemCount?: number | undefined;
14
- isStreaming?: boolean | undefined;
11
+ autoScrollBottomThreshold?: number;
12
+ getScrollContainer?: (listElement: HTMLDivElement | null) => HTMLElement | null;
13
+ initialVisibleItemCount?: number;
14
+ isStreaming?: boolean;
15
15
  itemCount: number;
16
- lastItemId?: string | undefined;
16
+ lastItemId?: string;
17
17
  /** Content revision for the trailing item (e.g. streaming chunk updates). */
18
- lastItemRevision?: string | undefined;
19
- paginationKey?: string | undefined;
20
- rootMargin?: string | undefined;
18
+ lastItemRevision?: string;
19
+ paginationKey?: string;
20
+ rootMargin?: string;
21
21
  /**
22
22
  * - `true` (default): always scroll to the latest message
23
23
  * - `'auto'`: scroll only when the container is already near the bottom
24
24
  * - `false`: never auto-scroll
25
25
  */
26
- stickToBottom?: boolean | 'auto' | undefined;
27
- visibleItemPageSize?: number | undefined;
26
+ stickToBottom?: boolean | 'auto';
27
+ visibleItemPageSize?: number;
28
28
  }
29
29
 
30
30
  export interface UseChatPrependPaginationResult {
@@ -5,7 +5,7 @@ import {
5
5
  getNextWorkbenchCommandIndex,
6
6
  isWorkbenchCommandRunnable,
7
7
  type WorkbenchCommandDescriptor,
8
- } from '../CommandPalette';
8
+ } from '../commands/CommandPalette';
9
9
  import { getSlashCommandQuery, isSlashCommandInput } from './slashCommand';
10
10
 
11
11
  type SlashCommandSuggestKeyboardEvent = Pick<
@@ -1,7 +1,7 @@
1
1
  import { useLayoutEffect, useRef, useState, type ReactNode } from 'react';
2
2
  import { createPortal } from 'react-dom';
3
3
 
4
- import { WORKBENCH_OVERLAYS_CLASS } from '../modal/modalContainer';
4
+ import { WORKBENCH_OVERLAYS_CLASS } from '../../modal/modalContainer';
5
5
  import { useWorkbenchOverlaysContainer } from './workbenchOverlaysContext';
6
6
 
7
7
  export interface WorkbenchModalPortalProps {
@@ -0,0 +1,4 @@
1
+ /* Workbench shell and platform chrome */
2
+ @import '../shell/index.css';
3
+ @import './index.css';
4
+ @import '../command-palette/command-palette.css';
@@ -40,3 +40,16 @@
40
40
  --panel-bg-75: var(--color-primary-side-bar-bg-75);
41
41
  background: var(--panel-bg);
42
42
  }
43
+
44
+ /* Primary-sidebar residency owns its intentionally hidden native scrollbars. */
45
+ .workbench-primary-sidebar .ui-sidebar-view__body,
46
+ .workbench-primary-sidebar .ui-workbench-sidebar-section__content {
47
+ scrollbar-gutter: auto;
48
+ scrollbar-width: none;
49
+ }
50
+
51
+ .workbench-primary-sidebar .ui-sidebar-view__body::-webkit-scrollbar,
52
+ .workbench-primary-sidebar .ui-workbench-sidebar-section__content::-webkit-scrollbar {
53
+ width: 0;
54
+ height: 0;
55
+ }
@@ -60,18 +60,10 @@
60
60
  object-position: center;
61
61
  }
62
62
 
63
- .workbench-shell-titlebar__app-icon > .tilepaper-app-icon,
64
63
  .workbench-shell-titlebar__app-icon > svg {
65
64
  shape-rendering: geometricPrecision;
66
65
  }
67
66
 
68
- .tilepaper-app-icon {
69
- display: block;
70
- width: 100%;
71
- height: 100%;
72
- overflow: visible;
73
- }
74
-
75
67
  .workbench-shell-titlebar__title {
76
68
  min-width: 0;
77
69
  overflow: hidden;
@@ -1,6 +1,6 @@
1
1
  import { useId, useMemo, type ComponentPropsWithRef, type ReactNode } from 'react';
2
- import { EmptyState } from '../primitives/empty-state';
3
- import { cx } from '../utils/cx';
2
+ import { EmptyState } from '../../primitives/empty-state';
3
+ import { cx } from '../../utils/cx';
4
4
  import { WorkbenchCommandList } from './CommandList';
5
5
  import {
6
6
  filterWorkbenchCommands,
@@ -1,8 +1,9 @@
1
+ import '../views/command-list.css';
1
2
  import { useEffect, useId, useRef, type ComponentPropsWithRef, type ReactNode } from 'react';
2
- import { Button } from '../primitives/button';
3
- import { EmptyState } from '../primitives/empty-state';
4
- import { cxCodicon } from '../utils/codicon';
5
- import { cx } from '../utils/cx';
3
+ import { Button } from '../../primitives/button';
4
+ import { EmptyState } from '../../primitives/empty-state';
5
+ import { cxCodicon } from '../../utils/codicon';
6
+ import { cx } from '../../utils/cx';
6
7
  import {
7
8
  getWorkbenchCommandExecutionLabel,
8
9
  getWorkbenchCommandStatusLabel,
@@ -11,7 +12,7 @@ import {
11
12
  type WorkbenchCommandRunContext,
12
13
  type WorkbenchCommandRunSource,
13
14
  } from './command-model';
14
- import { isWorkbenchStatusBusy } from './status';
15
+ import { isWorkbenchStatusBusy } from '../shell/status';
15
16
 
16
17
  function commandIcon(command: WorkbenchCommandDescriptor) {
17
18
  if (!command.icon) return null;
@@ -9,9 +9,10 @@ import {
9
9
  type KeyboardEvent,
10
10
  type ReactNode,
11
11
  } from 'react';
12
- import { IconButton } from '../primitives/icon-button';
13
- import { TextInput } from '../primitives/text-input';
14
- import { cx } from '../utils/cx';
12
+ import { useModalFocusTrap } from '../../modal/useModalFocusTrap';
13
+ import { IconButton } from '../../primitives/icon-button';
14
+ import { TextInput } from '../../primitives/text-input';
15
+ import { cx } from '../../utils/cx';
15
16
  import {
16
17
  filterWorkbenchCommands,
17
18
  getNextWorkbenchCommandIndex,
@@ -130,8 +131,8 @@ export function WorkbenchCommandPalette({
130
131
  }: WorkbenchCommandPaletteProps) {
131
132
  const titleId = useId();
132
133
  const listId = useId();
134
+ const dialogRef = useRef<HTMLDivElement>(null);
133
135
  const inputRef = useRef<HTMLInputElement>(null);
134
- const previousFocusRef = useRef<HTMLElement | null>(null);
135
136
  const [uncontrolledActiveCommandId, setUncontrolledActiveCommandId] = useState<string>();
136
137
  const [resolvedQuery, setResolvedQuery] = useControllableCommandQuery({
137
138
  defaultQuery,
@@ -164,15 +165,13 @@ export function WorkbenchCommandPalette({
164
165
  [activeCommandId, onActiveCommandChange],
165
166
  );
166
167
 
167
- const restoreFocus = useCallback(() => {
168
- if (!restoreFocusOnClose) return;
169
- previousFocusRef.current?.focus();
170
- }, [restoreFocusOnClose]);
171
-
172
- const closePalette = useCallback(() => {
173
- restoreFocus();
174
- onClose();
175
- }, [onClose, restoreFocus]);
168
+ useModalFocusTrap({
169
+ enabled: open,
170
+ containerRef: dialogRef,
171
+ initialFocusRef: inputRef,
172
+ onClose,
173
+ restoreFocusOnClose,
174
+ });
176
175
 
177
176
  const runCommand = useCallback(
178
177
  (command: WorkbenchCommandDescriptor, context: WorkbenchCommandRunContext) => {
@@ -182,18 +181,6 @@ export function WorkbenchCommandPalette({
182
181
  [onRunCommand],
183
182
  );
184
183
 
185
- useEffect(() => {
186
- if (!open) return;
187
-
188
- previousFocusRef.current = document.activeElement as HTMLElement | null;
189
- const frame = window.requestAnimationFrame(() => inputRef.current?.focus());
190
-
191
- return () => {
192
- window.cancelAnimationFrame(frame);
193
- restoreFocus();
194
- };
195
- }, [open, restoreFocus]);
196
-
197
184
  useEffect(() => {
198
185
  if (!open) return;
199
186
  if (activeCommandId !== undefined) return;
@@ -207,12 +194,6 @@ export function WorkbenchCommandPalette({
207
194
 
208
195
  const handlePaletteKeyDown = useCallback(
209
196
  (event: WorkbenchCommandPaletteKeyEvent) => {
210
- if (event.key === 'Escape') {
211
- event.preventDefault();
212
- closePalette();
213
- return;
214
- }
215
-
216
197
  if (
217
198
  event.key !== 'ArrowDown' &&
218
199
  event.key !== 'ArrowUp' &&
@@ -275,15 +256,7 @@ export function WorkbenchCommandPalette({
275
256
  updateActiveCommand(filteredCommands[nextIndex]?.id);
276
257
  }
277
258
  },
278
- [
279
- activeCommand,
280
- activeIndex,
281
- closePalette,
282
- commandQuery,
283
- filteredCommands,
284
- runCommand,
285
- updateActiveCommand,
286
- ],
259
+ [activeCommand, activeIndex, commandQuery, filteredCommands, runCommand, updateActiveCommand],
287
260
  );
288
261
 
289
262
  useEffect(() => {
@@ -308,13 +281,14 @@ export function WorkbenchCommandPalette({
308
281
  if (!open) return null;
309
282
 
310
283
  return (
311
- <div className="ui-workbench-command-palette-overlay" onClick={closePalette}>
284
+ <div className="ui-workbench-command-palette-overlay" onClick={onClose}>
312
285
  <div
313
286
  aria-labelledby={titleId}
314
287
  aria-modal="true"
315
288
  className={cx('ui-workbench-command-palette', className)}
316
289
  role="dialog"
317
290
  {...props}
291
+ ref={dialogRef}
318
292
  onClick={(event) => event.stopPropagation()}
319
293
  >
320
294
  <div className="ui-workbench-command-palette__header">
@@ -325,7 +299,7 @@ export function WorkbenchCommandPalette({
325
299
  className="ui-workbench-command-palette__close"
326
300
  icon="codicon-close"
327
301
  label={closeLabel}
328
- onClick={closePalette}
302
+ onClick={onClose}
329
303
  />
330
304
  </div>
331
305
  <div className="ui-workbench-command-palette__search">
@@ -1,14 +1,14 @@
1
1
  import { useState, type FormEvent, type ReactNode } from 'react';
2
- import './shell/confirmation-flow.css';
3
- import { Modal } from '../modal/Modal';
4
- import { Button } from '../primitives/button';
5
- import { cx } from '../utils/cx';
2
+ import '../shell/confirmation-flow.css';
3
+ import { Modal } from '../../modal/Modal';
4
+ import { Button } from '../../primitives/button';
5
+ import { cx } from '../../utils/cx';
6
6
  import {
7
7
  getWorkbenchStatusLabel,
8
8
  isWorkbenchStatusBusy,
9
9
  isWorkbenchStatusDisabled,
10
10
  type WorkbenchStatus,
11
- } from './status';
11
+ } from '../shell/status';
12
12
 
13
13
  export type WorkbenchConfirmationVariant = 'default' | 'danger';
14
14
 
@@ -5,6 +5,7 @@ import {
5
5
  type CommandRegistry,
6
6
  type CommandValue,
7
7
  } from '@workbench-kit/platform';
8
+ import { normalizeKeyToken } from '../../utils/normalizeKeyToken';
8
9
 
9
10
  export type WorkbenchShortcutPlatform = 'linux' | 'mac' | 'unknown' | 'windows';
10
11
 
@@ -105,19 +106,6 @@ function getDefaultShortcutPlatform(): WorkbenchShortcutPlatform {
105
106
  return 'unknown';
106
107
  }
107
108
 
108
- function normalizeKeyToken(token: string) {
109
- const key = token.trim().toLowerCase();
110
- if (key === 'del') return 'delete';
111
- if (key === 'esc') return 'escape';
112
- if (key === 'return') return 'enter';
113
- if (key === 'spacebar' || key === 'space') return 'space';
114
- if (key === 'arrowup' || key === 'up') return 'arrowup';
115
- if (key === 'arrowdown' || key === 'down') return 'arrowdown';
116
- if (key === 'arrowleft' || key === 'left') return 'arrowleft';
117
- if (key === 'arrowright' || key === 'right') return 'arrowright';
118
- return key;
119
- }
120
-
121
109
  function normalizeEventKey(key: string) {
122
110
  if (key === ' ') return 'space';
123
111
  return normalizeKeyToken(key);
@@ -225,6 +213,22 @@ export function matchesWorkbenchShortcut({
225
213
  );
226
214
  }
227
215
 
216
+ export function matchesWorkbenchCommandPaletteShortcut(event: WorkbenchShortcutEventLike) {
217
+ return matchesWorkbenchShortcut({ event, shortcut: 'Ctrl/Cmd+Shift+P' });
218
+ }
219
+
220
+ export function matchesWorkbenchQuickAccessShortcut(event: WorkbenchShortcutEventLike) {
221
+ return matchesWorkbenchShortcut({ event, shortcut: 'Ctrl/Cmd+P' });
222
+ }
223
+
224
+ export function getWorkbenchCommandPaletteShortcutLabel() {
225
+ return 'Ctrl+Shift+P';
226
+ }
227
+
228
+ export function getWorkbenchQuickAccessShortcutLabel() {
229
+ return 'Ctrl+P';
230
+ }
231
+
228
232
  export function getWorkbenchShortcutCommandBindings<TContext>({
229
233
  commandIds,
230
234
  context,