@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
@@ -0,0 +1,66 @@
1
+ export interface QuickOpenItem {
2
+ /** Stable within its provider (often a workspace path). */
3
+ id: string;
4
+ label: string;
5
+ description?: string | undefined;
6
+ detail?: string | undefined;
7
+ icon?: string | undefined;
8
+ disabled?: boolean | undefined;
9
+ /** Provider-specific payload (e.g. `{ path }`). */
10
+ data?: unknown;
11
+ }
12
+
13
+ export interface QuickOpenSearchContext {
14
+ /** Aborted when the query, provider set, or open state changes. */
15
+ signal: AbortSignal;
16
+ }
17
+
18
+ export interface QuickOpenProvider {
19
+ /** Unique within the provider set passed to Quick Open. */
20
+ id: string;
21
+ label: string;
22
+ search: (
23
+ query: string,
24
+ context?: QuickOpenSearchContext,
25
+ ) => Promise<QuickOpenItem[]> | QuickOpenItem[];
26
+ }
27
+
28
+ export interface QuickOpenSelectContext {
29
+ index: number;
30
+ providerId: string;
31
+ query: string;
32
+ }
33
+
34
+ export function isQuickOpenItemSelectable(item: QuickOpenItem) {
35
+ return !item.disabled;
36
+ }
37
+
38
+ export function getNextQuickOpenItemIndex({
39
+ currentIndex,
40
+ direction,
41
+ items,
42
+ }: {
43
+ currentIndex: number;
44
+ direction: 'next' | 'previous';
45
+ items: readonly QuickOpenItem[];
46
+ }) {
47
+ if (items.length === 0) {
48
+ return -1;
49
+ }
50
+
51
+ const step = direction === 'next' ? 1 : -1;
52
+ let nextIndex = currentIndex;
53
+
54
+ for (let attempt = 0; attempt < items.length; attempt += 1) {
55
+ nextIndex = (nextIndex + step + items.length) % items.length;
56
+ const item = items[nextIndex];
57
+ if (item && isQuickOpenItemSelectable(item)) {
58
+ return nextIndex;
59
+ }
60
+ }
61
+
62
+ return -1;
63
+ }
64
+
65
+ /** Default debounce for provider search while typing. */
66
+ export const DEFAULT_QUICK_OPEN_SEARCH_DEBOUNCE_MS = 200;
@@ -1,7 +1,11 @@
1
- import { EditorTabs, type EditorTabsProps } from '../primitives/workbench-editor';
1
+ import { EditorTabs, type EditorTabsProps } from '../../primitives/workbench-editor';
2
+ import type { ContextMenuItem } from '../../overlay/ContextMenu';
2
3
  import { useWorkbenchEditorTabContextMenu } from './useWorkbenchEditorTabContextMenu';
3
4
 
4
5
  export interface WorkbenchEditorTabsProps extends EditorTabsProps {
6
+ /** Additional host actions appended after the built-in close group. */
7
+ readonly getExtraTabContextMenuItems?:
8
+ ((tabId: string) => readonly ContextMenuItem[] | undefined) | undefined;
5
9
  /**
6
10
  * Optional bulk close. Defaults to calling `onClose` for every closable tab.
7
11
  */
@@ -10,26 +14,32 @@ export interface WorkbenchEditorTabsProps extends EditorTabsProps {
10
14
  * Optional close-others. Defaults to calling `onClose` for every other closable tab.
11
15
  */
12
16
  readonly onCloseOthers?: ((tabId: string) => void) | undefined;
17
+ /** Optional close-to-right override. Defaults to closing each later closable tab. */
18
+ readonly onCloseToRight?: ((tabId: string) => void) | undefined;
13
19
  }
14
20
 
15
21
  /**
16
- * Editor tab strip with a built-in Close / Close others / Close all context menu.
22
+ * Editor tab strip with a built-in Close / Close others / Close to the right / Close all menu.
17
23
  * Intended for `WorkbenchStandaloneShell` secondary areas that own tab state in the host.
18
- * Tabs with `closable: false` keep Close disabled and are skipped by Close others / Close all.
24
+ * Tabs with `closable: false` keep Close disabled and are skipped by every bulk close action.
19
25
  */
20
26
  export function WorkbenchEditorTabs({
27
+ getExtraTabContextMenuItems,
21
28
  onClose,
22
29
  onCloseAll,
23
30
  onCloseOthers,
31
+ onCloseToRight,
24
32
  onSelect,
25
33
  onTabContextMenu,
26
34
  tabs,
27
35
  ...props
28
36
  }: WorkbenchEditorTabsProps) {
29
37
  const tabContextMenu = useWorkbenchEditorTabContextMenu({
38
+ getExtraTabContextMenuItems,
30
39
  onClose: onClose ?? (() => undefined),
31
40
  onCloseAll,
32
41
  onCloseOthers,
42
+ onCloseToRight,
33
43
  onSelectTab: onSelect,
34
44
  tabs,
35
45
  });
@@ -1,4 +1,4 @@
1
- import type { EditorTabDropPosition } from '../primitives/workbench-editor';
1
+ import type { EditorTabDropPosition } from '../../primitives/workbench-editor';
2
2
 
3
3
  export const EDITOR_TAB_DRAG_DATA_TYPE = 'application/x-workbench-kit-editor-tab' as const;
4
4
 
@@ -4,14 +4,14 @@ import {
4
4
  resolveCommandMenuItems,
5
5
  } from '@workbench-kit/platform';
6
6
 
7
- import type { ContextMenuItem } from '../overlay/ContextMenu';
7
+ import type { ContextMenuItem } from '../../overlay/ContextMenu';
8
8
  import {
9
9
  WORKBENCH_COMMAND_SURFACE_EDITOR,
10
10
  commandMenuItemsToContextMenuItems,
11
11
  createWorkbenchEditorCommands,
12
12
  createWorkbenchStandaloneEditorTabMenuEntries,
13
13
  type WorkbenchEditorCommandContext,
14
- } from './commands';
14
+ } from '../commands/commands';
15
15
 
16
16
  const editorCommandRegistry = createCommandRegistry(createWorkbenchEditorCommands());
17
17
  const standaloneEditorTabMenuEntries = createWorkbenchStandaloneEditorTabMenuEntries();
@@ -29,25 +29,41 @@ export interface CreateWorkbenchStandaloneEditorTabCommandContextInput {
29
29
  readonly onClose: (tabId: string) => void;
30
30
  readonly onCloseAll?: (() => void) | undefined;
31
31
  readonly onCloseOthers?: ((tabId: string) => void) | undefined;
32
+ readonly onCloseToRight?: ((tabId: string) => void) | undefined;
32
33
  readonly tabId: string;
33
34
  readonly tabs: readonly WorkbenchStandaloneEditorTabLike[];
34
35
  }
35
36
 
37
+ export interface CreateWorkbenchStandaloneEditorTabContextMenuItemsInput extends CreateWorkbenchStandaloneEditorTabCommandContextInput {
38
+ readonly getExtraTabContextMenuItems?:
39
+ ((tabId: string) => readonly ContextMenuItem[] | undefined) | undefined;
40
+ }
41
+
36
42
  export function createWorkbenchStandaloneEditorTabCommandContext({
37
43
  onClose,
38
44
  onCloseAll,
39
45
  onCloseOthers,
46
+ onCloseToRight,
40
47
  tabId,
41
48
  tabs,
42
49
  }: CreateWorkbenchStandaloneEditorTabCommandContextInput): WorkbenchEditorCommandContext {
43
50
  const targetTab = tabs.find((tab) => tab.id === tabId);
51
+ const targetIndex = tabs.findIndex((tab) => tab.id === tabId);
44
52
  const closableTabIds = tabs.filter(isWorkbenchEditorTabClosable).map((tab) => tab.id);
45
53
  const otherClosableTabIds = closableTabIds.filter((id) => id !== tabId);
54
+ const rightClosableTabIds =
55
+ targetIndex < 0
56
+ ? []
57
+ : tabs
58
+ .slice(targetIndex + 1)
59
+ .filter(isWorkbenchEditorTabClosable)
60
+ .map((tab) => tab.id);
46
61
  const canCloseTarget = Boolean(targetTab && isWorkbenchEditorTabClosable(targetTab));
47
62
 
48
63
  return {
49
64
  canCloseAll: closableTabIds.length > 0,
50
65
  canCloseOthers: otherClosableTabIds.length > 0,
66
+ canCloseToRight: rightClosableTabIds.length > 0,
51
67
  canClosePath: canCloseTarget,
52
68
  canCopyPath: false,
53
69
  canDeletePath: false,
@@ -74,6 +90,18 @@ export function createWorkbenchStandaloneEditorTabCommandContext({
74
90
  onClose(id);
75
91
  }
76
92
  },
93
+ closeToRight: () => {
94
+ if (rightClosableTabIds.length === 0) {
95
+ return;
96
+ }
97
+ if (onCloseToRight) {
98
+ onCloseToRight(tabId);
99
+ return;
100
+ }
101
+ for (const id of rightClosableTabIds) {
102
+ onClose(id);
103
+ }
104
+ },
77
105
  closePath: () => {
78
106
  if (canCloseTarget) {
79
107
  onClose(tabId);
@@ -95,11 +123,11 @@ export function createWorkbenchStandaloneEditorTabCommandContext({
95
123
  }
96
124
 
97
125
  export function createWorkbenchStandaloneEditorTabContextMenuItems(
98
- input: CreateWorkbenchStandaloneEditorTabCommandContextInput,
126
+ input: CreateWorkbenchStandaloneEditorTabContextMenuItemsInput,
99
127
  ): ContextMenuItem[] {
100
128
  const context = createWorkbenchStandaloneEditorTabCommandContext(input);
101
129
 
102
- return commandMenuItemsToContextMenuItems(
130
+ const builtInItems = commandMenuItemsToContextMenuItems(
103
131
  resolveCommandMenuItems({
104
132
  context,
105
133
  entries: standaloneEditorTabMenuEntries,
@@ -108,4 +136,15 @@ export function createWorkbenchStandaloneEditorTabContextMenuItems(
108
136
  }),
109
137
  (commandId) => executeCommand(editorCommandRegistry, commandId, context),
110
138
  );
139
+ const extraItems = input.getExtraTabContextMenuItems?.(input.tabId) ?? [];
140
+
141
+ if (extraItems.length === 0) {
142
+ return builtInItems;
143
+ }
144
+
145
+ return [
146
+ ...builtInItems,
147
+ { id: 'standalone-tab-extra-separator', type: 'separator' },
148
+ ...extraItems,
149
+ ];
111
150
  }
@@ -1,7 +1,7 @@
1
1
  import { useCallback, useMemo, useRef, useState } from 'react';
2
2
  import type { DragEvent as ReactDragEvent } from 'react';
3
3
 
4
- import type { EditorTabDropPosition, EditorTabsProps } from '../primitives/workbench-editor';
4
+ import type { EditorTabDropPosition, EditorTabsProps } from '../../primitives/workbench-editor';
5
5
  import {
6
6
  EDITOR_TAB_DRAG_DATA_TYPE,
7
7
  isEditorTabsScrollerEventTarget,
@@ -1,15 +1,18 @@
1
1
  import { useCallback, useState, type MouseEvent as ReactMouseEvent, type ReactNode } from 'react';
2
2
 
3
- import { ContextMenu } from '../overlay/ContextMenu';
3
+ import { ContextMenu, type ContextMenuItem } from '../../overlay/ContextMenu';
4
4
  import {
5
5
  createWorkbenchStandaloneEditorTabContextMenuItems,
6
6
  type WorkbenchStandaloneEditorTabLike,
7
7
  } from './editorTabContextMenu';
8
8
 
9
9
  export interface UseWorkbenchEditorTabContextMenuOptions {
10
+ readonly getExtraTabContextMenuItems?:
11
+ ((tabId: string) => readonly ContextMenuItem[] | undefined) | undefined;
10
12
  readonly onClose: (tabId: string) => void;
11
13
  readonly onCloseAll?: (() => void) | undefined;
12
14
  readonly onCloseOthers?: ((tabId: string) => void) | undefined;
15
+ readonly onCloseToRight?: ((tabId: string) => void) | undefined;
13
16
  readonly onSelectTab?: ((tabId: string) => void) | undefined;
14
17
  readonly tabs: readonly WorkbenchStandaloneEditorTabLike[];
15
18
  }
@@ -20,13 +23,16 @@ export interface UseWorkbenchEditorTabContextMenuResult {
20
23
  }
21
24
 
22
25
  export function useWorkbenchEditorTabContextMenu({
26
+ getExtraTabContextMenuItems,
23
27
  onClose,
24
28
  onCloseAll,
25
29
  onCloseOthers,
30
+ onCloseToRight,
26
31
  onSelectTab,
27
32
  tabs,
28
33
  }: UseWorkbenchEditorTabContextMenuOptions): UseWorkbenchEditorTabContextMenuResult {
29
34
  const [menuState, setMenuState] = useState<{
35
+ returnFocusTarget: HTMLElement;
30
36
  tabId: string;
31
37
  x: number;
32
38
  y: number;
@@ -37,7 +43,12 @@ export function useWorkbenchEditorTabContextMenu({
37
43
  event.preventDefault();
38
44
  event.stopPropagation();
39
45
  onSelectTab?.(tabId);
40
- setMenuState({ tabId, x: event.clientX, y: event.clientY });
46
+ setMenuState({
47
+ returnFocusTarget: event.currentTarget,
48
+ tabId,
49
+ x: event.clientX,
50
+ y: event.clientY,
51
+ });
41
52
  },
42
53
  [onSelectTab],
43
54
  );
@@ -47,12 +58,15 @@ export function useWorkbenchEditorTabContextMenu({
47
58
  <ContextMenu
48
59
  ariaLabel="Editor tab menu"
49
60
  items={createWorkbenchStandaloneEditorTabContextMenuItems({
61
+ getExtraTabContextMenuItems,
50
62
  onClose,
51
63
  onCloseAll,
52
64
  onCloseOthers,
65
+ onCloseToRight,
53
66
  tabId: menuState.tabId,
54
67
  tabs,
55
68
  })}
69
+ returnFocusTarget={menuState.returnFocusTarget}
56
70
  x={menuState.x}
57
71
  y={menuState.y}
58
72
  onClose={() => setMenuState(null)}
@@ -1,22 +1,23 @@
1
- export { normalizeEditorTabReorderIndex } from '../editor-tabs-dnd';
1
+ export { normalizeEditorTabReorderIndex } from '../editor/editor-tabs-dnd';
2
2
  export {
3
3
  createWorkbenchStandaloneEditorTabCommandContext,
4
4
  createWorkbenchStandaloneEditorTabContextMenuItems,
5
5
  isWorkbenchEditorTabClosable,
6
- } from '../editorTabContextMenu';
6
+ } from '../editor/editorTabContextMenu';
7
7
  export type {
8
8
  CreateWorkbenchStandaloneEditorTabCommandContextInput,
9
+ CreateWorkbenchStandaloneEditorTabContextMenuItemsInput,
9
10
  WorkbenchStandaloneEditorTabLike,
10
- } from '../editorTabContextMenu';
11
- export { useEditorTabsStripDnd } from '../useEditorTabsStripDnd';
11
+ } from '../editor/editorTabContextMenu';
12
+ export { useEditorTabsStripDnd } from '../editor/useEditorTabsStripDnd';
12
13
  export type {
13
14
  UseEditorTabsStripDndOptions,
14
15
  UseEditorTabsStripDndResult,
15
- } from '../useEditorTabsStripDnd';
16
- export { useWorkbenchEditorTabContextMenu } from '../useWorkbenchEditorTabContextMenu';
16
+ } from '../editor/useEditorTabsStripDnd';
17
+ export { useWorkbenchEditorTabContextMenu } from '../editor/useWorkbenchEditorTabContextMenu';
17
18
  export type {
18
19
  UseWorkbenchEditorTabContextMenuOptions,
19
20
  UseWorkbenchEditorTabContextMenuResult,
20
- } from '../useWorkbenchEditorTabContextMenu';
21
- export { WorkbenchEditorTabs } from '../WorkbenchEditorTabs';
22
- export type { WorkbenchEditorTabsProps } from '../WorkbenchEditorTabs';
21
+ } from '../editor/useWorkbenchEditorTabContextMenu';
22
+ export { WorkbenchEditorTabs } from '../editor/WorkbenchEditorTabs';
23
+ export type { WorkbenchEditorTabsProps } from '../editor/WorkbenchEditorTabs';