Skip to content

Commit 469c6f7

Browse files
committed
Merge branch 'main' into stable
2 parents 77952fe + 262b6a6 commit 469c6f7

File tree

6 files changed

+114
-11
lines changed

6 files changed

+114
-11
lines changed

.github/workflows/release-cli.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ jobs:
6363
registry-url: 'https://registry.npmjs.org'
6464

6565
- uses: oven-sh/setup-bun@v2
66+
with:
67+
bun-version: 1.3.11
6668

6769
- name: Cache apt packages
6870
uses: actions/cache@v5

.github/workflows/release-sdk.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ jobs:
8888
registry-url: "https://registry.npmjs.org"
8989

9090
- uses: oven-sh/setup-bun@v2
91+
with:
92+
bun-version: 1.3.11
9193

9294
- uses: actions/setup-python@v5
9395
with:
@@ -234,6 +236,8 @@ jobs:
234236
registry-url: "https://registry.npmjs.org"
235237

236238
- uses: oven-sh/setup-bun@v2
239+
with:
240+
bun-version: 1.3.11
237241

238242
- uses: actions/setup-python@v5
239243
with:

packages/super-editor/src/editors/v1/core/types/ChainedCommands.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,10 @@ type Chainified<T> = {
7878
* but consumers who augment ExtensionCommandMap get their custom commands
7979
* on chain() for free.
8080
*/
81-
type AugmentedChainedCommands = {
82-
[K in keyof RegisteredCommands]: (...args: CommandArgs<K>) => ChainableCommandObject;
83-
};
81+
type AugmentedChainedCommands = Chainified<KnownCommandRecord>;
8482

85-
/** Same as AugmentedChainedCommands but with original return types for can(). */
86-
type AugmentedCanCommands = {
87-
[K in keyof RegisteredCommands]: (...args: CommandArgs<K>) => CommandResult<K>;
88-
};
83+
/** Same but with original return types for can(). */
84+
type AugmentedCanCommands = KnownCommandRecord;
8985

9086
/**
9187
* A chainable version of an editor command keyed by command name.

packages/superdoc/src/core/types/index.js

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,63 @@
8686
* @typedef {(ctx: LinkPopoverContext) => LinkPopoverResolution | null | undefined} LinkPopoverResolver
8787
*/
8888

89+
// ---------------------------------------------------------------------------
90+
// Context menu types
91+
// ---------------------------------------------------------------------------
92+
93+
/**
94+
* Context object passed to context menu callbacks (showWhen, render, action, menuProvider).
95+
* @typedef {Object} ContextMenuContext
96+
* @property {Editor} editor The editor instance
97+
* @property {string} selectedText Currently selected text (empty string if no selection)
98+
* @property {boolean} hasSelection Whether there is an expanded selection
99+
* @property {number} selectionStart ProseMirror start position of the selection
100+
* @property {number} selectionEnd ProseMirror end position of the selection
101+
* @property {'click' | 'slash'} trigger How the menu was opened
102+
* @property {boolean} isInTable Whether the cursor is inside a table
103+
* @property {boolean} isInList Whether the cursor is inside a list
104+
* @property {boolean} isInSectionNode Whether the cursor is inside a document section
105+
* @property {boolean} isCellSelection Whether a table cell selection is active
106+
* @property {string | null} tableSelectionKind Kind of table selection (row, column, etc.)
107+
* @property {string | null} currentNodeType ProseMirror node type name at the cursor
108+
* @property {string[]} activeMarks Names of marks active at the cursor
109+
* @property {boolean} isTrackedChange Whether the cursor is on a tracked change
110+
* @property {string | null} trackedChangeId ID of the tracked change at the cursor
111+
* @property {string} documentMode Current document mode (editing, viewing, suggesting)
112+
* @property {boolean} canUndo Whether undo is available
113+
* @property {boolean} canRedo Whether redo is available
114+
* @property {boolean} isEditable Whether the editor is editable
115+
* @property {{ x: number, y: number } | null} cursorPosition Screen coordinates of the cursor
116+
*/
117+
118+
/**
119+
* A single item inside a context menu section.
120+
* @typedef {Object} ContextMenuItem
121+
* @property {string} id Unique identifier for the menu item
122+
* @property {string} label Display text
123+
* @property {string} [icon] Icon identifier
124+
* @property {unknown} [component] Custom Vue component to render this item
125+
* @property {(editor: Editor, context: ContextMenuContext) => void} [action] Callback invoked when the item is clicked
126+
* @property {(context: ContextMenuContext) => boolean} [showWhen] Predicate controlling visibility
127+
* @property {(context: ContextMenuContext) => HTMLElement} [render] Custom renderer returning an HTML element
128+
* @property {string} [shortcut] Keyboard shortcut label displayed beside the item
129+
*/
130+
131+
/**
132+
* A section (group) of items in the context menu.
133+
* @typedef {Object} ContextMenuSection
134+
* @property {string} id Unique identifier for the section
135+
* @property {ContextMenuItem[]} items Menu items in this section
136+
*/
137+
138+
/**
139+
* Configuration for the context menu module.
140+
* @typedef {Object} ContextMenuConfig
141+
* @property {ContextMenuSection[]} [customItems] Custom menu sections appended (or merged by id) to the default menu
142+
* @property {(context: ContextMenuContext, sections: ContextMenuSection[]) => ContextMenuSection[] | null | undefined} [menuProvider] Advanced: transform the final section list before render. Return null/undefined to keep the original sections.
143+
* @property {boolean} [includeDefaultItems] Whether to include default menu items (default: true)
144+
*/
145+
89146
// ---------------------------------------------------------------------------
90147
// Surface system types
91148
// ---------------------------------------------------------------------------
@@ -469,10 +526,7 @@
469526
* @property {Object} [toolbar] Toolbar module configuration
470527
* @property {Object} [links] Link click popover configuration
471528
* @property {LinkPopoverResolver} [links.popoverResolver] Custom resolver for the link click popover.
472-
* @property {Object} [contextMenu] Context menu module configuration
473-
* @property {Array} [contextMenu.customItems] Array of custom menu sections with items
474-
* @property {Function} [contextMenu.menuProvider] Function to customize menu items
475-
* @property {boolean} [contextMenu.includeDefaultItems] Whether to include default menu items
529+
* @property {ContextMenuConfig} [contextMenu] Context menu module configuration
476530
* @property {Object} [slashMenu] @deprecated Use contextMenu instead
477531
* @property {SurfacesModuleConfig} [surfaces] Surface system configuration
478532
*/

packages/superdoc/src/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,11 @@ import { getSchemaIntrospection } from './helpers/schema-introspection.js';
162162
* @typedef {import('@superdoc/super-editor').ProofingStatus} ProofingStatus
163163
* @typedef {import('@superdoc/super-editor').ProofingError} ProofingError
164164
* @typedef {import('@superdoc/super-editor').PageStyles} PageStyles
165+
*
166+
* @typedef {import('./core/types/index.js').ContextMenuContext} ContextMenuContext
167+
* @typedef {import('./core/types/index.js').ContextMenuItem} ContextMenuItem
168+
* @typedef {import('./core/types/index.js').ContextMenuSection} ContextMenuSection
169+
* @typedef {import('./core/types/index.js').ContextMenuConfig} ContextMenuConfig
165170
*/
166171

167172
// Public exports

tests/consumer-typecheck/src/customer-scenario.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,12 @@ import type {
132132
ProofingStatus,
133133
ProofingError,
134134

135+
// Context menu
136+
ContextMenuContext,
137+
ContextMenuItem,
138+
ContextMenuSection,
139+
ContextMenuConfig,
140+
135141
// Other
136142
UnsupportedContentItem,
137143
PageStyles,
@@ -583,6 +589,41 @@ function testEditorContentMethods(editor: Editor) {
583589
editor.destroy();
584590
}
585591

592+
// ============================================
593+
// SECTION 12b: Context menu types (SD-2514)
594+
// ============================================
595+
596+
function testContextMenuTypes() {
597+
// action receives (editor, context) — both args
598+
const item: ContextMenuItem = {
599+
id: 'copy-text',
600+
label: 'Copy',
601+
icon: 'copy',
602+
action: (editor, context) => {
603+
editor.commands.selectAll();
604+
const text: string = context.selectedText;
605+
},
606+
showWhen: (ctx) => ctx.hasSelection && !ctx.isInTable,
607+
};
608+
609+
const section: ContextMenuSection = {
610+
id: 'custom-actions',
611+
items: [item],
612+
};
613+
614+
const config: ContextMenuConfig = {
615+
customItems: [section],
616+
includeDefaultItems: true,
617+
menuProvider: (ctx, sections) => sections.filter((s) => s.id !== 'clipboard'),
618+
};
619+
620+
// ContextMenuContext has the full runtime shape
621+
const ctx: ContextMenuContext = {} as ContextMenuContext;
622+
const _trigger: 'click' | 'slash' = ctx.trigger;
623+
const _mode: string = ctx.documentMode;
624+
const _marks: string[] = ctx.activeMarks;
625+
}
626+
586627
// ============================================
587628
// SECTION 13: Extensions, SuperDoc, and utilities
588629
// ============================================
@@ -679,6 +720,7 @@ export {
679720
testProofingProvider,
680721
testEditorStaticMethods,
681722
testEditorContentMethods,
723+
testContextMenuTypes,
682724
testExtensions,
683725
testSuperDoc,
684726
testUtilities,

0 commit comments

Comments
 (0)