kakidash 0.2.2 → 0.3.0
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.
- package/README.ja.md +41 -7
- package/README.md +39 -5
- package/dist/index.d.ts +715 -8
- package/dist/kakidash.cjs +19 -18
- package/dist/kakidash.es.js +4268 -3369
- package/dist/kakidash.umd.js +19 -18
- package/package.json +8 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,155 @@
|
|
|
1
|
+
declare class ClipboardService {
|
|
2
|
+
private mindMap;
|
|
3
|
+
private idGenerator;
|
|
4
|
+
private clipboard;
|
|
5
|
+
constructor(mindMap: MindMap, idGenerator: IdGenerator);
|
|
6
|
+
copyNodes(nodeIds: string[]): void;
|
|
7
|
+
getClipboardNodes(): Node_2[];
|
|
8
|
+
createPastedNodes(parentId: string): Node_2[];
|
|
9
|
+
private deepCloneNode;
|
|
10
|
+
private regenerateIds;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
declare type Command = {
|
|
14
|
+
type: 'addNode';
|
|
15
|
+
parentId: string;
|
|
16
|
+
} | {
|
|
17
|
+
type: 'addSibling';
|
|
18
|
+
nodeId: string;
|
|
19
|
+
position: 'before' | 'after';
|
|
20
|
+
} | {
|
|
21
|
+
type: 'deleteNode';
|
|
22
|
+
nodeId: string;
|
|
23
|
+
} | {
|
|
24
|
+
type: 'insertParent';
|
|
25
|
+
nodeId: string;
|
|
26
|
+
} | {
|
|
27
|
+
type: 'dropNode';
|
|
28
|
+
draggedId: string;
|
|
29
|
+
targetId: string;
|
|
30
|
+
position: 'top' | 'bottom' | 'left' | 'right';
|
|
31
|
+
} | {
|
|
32
|
+
type: 'updateNode';
|
|
33
|
+
nodeId: string;
|
|
34
|
+
topic: string;
|
|
35
|
+
} | {
|
|
36
|
+
type: 'navigate';
|
|
37
|
+
nodeId: string | null;
|
|
38
|
+
direction: Direction_2;
|
|
39
|
+
extendSelection?: boolean;
|
|
40
|
+
} | {
|
|
41
|
+
type: 'pan';
|
|
42
|
+
dx: number;
|
|
43
|
+
dy: number;
|
|
44
|
+
} | {
|
|
45
|
+
type: 'copyNode';
|
|
46
|
+
nodeId: string;
|
|
47
|
+
} | {
|
|
48
|
+
type: 'pasteNode';
|
|
49
|
+
parentId: string;
|
|
50
|
+
} | {
|
|
51
|
+
type: 'cutNode';
|
|
52
|
+
nodeId: string;
|
|
53
|
+
} | {
|
|
54
|
+
type: 'pasteImage';
|
|
55
|
+
parentId: string;
|
|
56
|
+
imageData: string;
|
|
57
|
+
width: number;
|
|
58
|
+
height: number;
|
|
59
|
+
} | {
|
|
60
|
+
type: 'zoom';
|
|
61
|
+
delta: number;
|
|
62
|
+
x: number;
|
|
63
|
+
y: number;
|
|
64
|
+
} | {
|
|
65
|
+
type: 'zoomReset';
|
|
66
|
+
} | {
|
|
67
|
+
type: 'undo';
|
|
68
|
+
} | {
|
|
69
|
+
type: 'redo';
|
|
70
|
+
} | {
|
|
71
|
+
type: 'styleAction';
|
|
72
|
+
nodeId: string;
|
|
73
|
+
action: StyleAction;
|
|
74
|
+
} | {
|
|
75
|
+
type: 'editNode';
|
|
76
|
+
nodeId: string;
|
|
77
|
+
} | {
|
|
78
|
+
type: 'editEnd';
|
|
79
|
+
nodeId: string;
|
|
80
|
+
} | {
|
|
81
|
+
type: 'setTheme';
|
|
82
|
+
theme: Theme;
|
|
83
|
+
} | {
|
|
84
|
+
type: 'setLayoutMode';
|
|
85
|
+
mode: LayoutMode;
|
|
86
|
+
} | {
|
|
87
|
+
type: 'toggleFold';
|
|
88
|
+
nodeId: string;
|
|
89
|
+
} | {
|
|
90
|
+
type: 'toggleCommandPalette';
|
|
91
|
+
} | {
|
|
92
|
+
type: 'updateNodeWidth';
|
|
93
|
+
nodeId: string;
|
|
94
|
+
increment: number;
|
|
95
|
+
} | {
|
|
96
|
+
type: 'selectNode';
|
|
97
|
+
nodeId: string | null;
|
|
98
|
+
extendSelection?: boolean;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
declare class CommandBus {
|
|
102
|
+
private handlers;
|
|
103
|
+
on<T extends Command['type']>(type: T, handler: CommandHandler<T>): void;
|
|
104
|
+
off<T extends Command['type']>(type: T, handler: CommandHandler<T>): void;
|
|
105
|
+
dispatch(command: Command): void;
|
|
106
|
+
destroy(): void;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
declare type CommandHandler<T extends Command['type']> = (command: Extract<Command, {
|
|
110
|
+
type: T;
|
|
111
|
+
}>) => void;
|
|
112
|
+
|
|
113
|
+
declare interface ConnectionLayout {
|
|
114
|
+
fromX: number;
|
|
115
|
+
fromY: number;
|
|
116
|
+
toX: number;
|
|
117
|
+
toY: number;
|
|
118
|
+
toNodeId: string;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Dependencies required to construct a MindMapController.
|
|
123
|
+
* Consolidates constructor parameters for readability.
|
|
124
|
+
*/
|
|
125
|
+
declare interface ControllerDependencies {
|
|
126
|
+
mindMap: MindMap;
|
|
127
|
+
service: MindMapService;
|
|
128
|
+
renderer: Renderer;
|
|
129
|
+
styleEditor: StyleEditor;
|
|
130
|
+
eventBus: IMindMapEventBus;
|
|
131
|
+
historyService: HistoryService;
|
|
132
|
+
clipboardService: ClipboardService;
|
|
133
|
+
searchService: SearchService;
|
|
134
|
+
viewportService: ViewportService;
|
|
135
|
+
navigationService: NavigationService;
|
|
136
|
+
fileIOService: FileIOService;
|
|
137
|
+
themeService: ThemeService;
|
|
138
|
+
commandBus: CommandBus;
|
|
139
|
+
locale?: 'en' | 'ja';
|
|
140
|
+
commandPaletteFeatures?: ('search' | 'icon' | 'import' | 'export')[];
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export declare interface CustomCommand {
|
|
144
|
+
id: string;
|
|
145
|
+
topic: string;
|
|
146
|
+
execute: (selectedNodeId: string | null) => void;
|
|
147
|
+
}
|
|
148
|
+
|
|
1
149
|
export declare type Direction = 'Up' | 'Down' | 'Left' | 'Right';
|
|
2
150
|
|
|
151
|
+
declare type Direction_2 = 'Up' | 'Down' | 'Left' | 'Right';
|
|
152
|
+
|
|
3
153
|
/**
|
|
4
154
|
* Interface for handling file Import/Export operations.
|
|
5
155
|
* Allows external systems (like VS Code Extension) to override default browser behaviors.
|
|
@@ -20,13 +170,122 @@ export declare interface FileHandler {
|
|
|
20
170
|
onExportFile(data: Blob | string, filename: string, format: string): Promise<void>;
|
|
21
171
|
}
|
|
22
172
|
|
|
173
|
+
declare class FileIOService {
|
|
174
|
+
private mindMap;
|
|
175
|
+
private renderer;
|
|
176
|
+
private eventBus;
|
|
177
|
+
private fileHandler?;
|
|
178
|
+
constructor(deps: FileIOServiceDependencies);
|
|
179
|
+
exportPng(): Promise<void>;
|
|
180
|
+
exportSvg(): Promise<void>;
|
|
181
|
+
exportMarkdown(): Promise<void>;
|
|
182
|
+
importXMind(): Promise<MindMapData | null>;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
declare interface FileIOServiceDependencies {
|
|
186
|
+
mindMap: MindMap;
|
|
187
|
+
renderer: Renderer;
|
|
188
|
+
eventBus: IMindMapEventBus;
|
|
189
|
+
fileHandler?: FileHandler;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
declare class HistoryService {
|
|
193
|
+
private historyManager;
|
|
194
|
+
constructor(maxHistorySize?: number);
|
|
195
|
+
saveState(state: MindMapData): void;
|
|
196
|
+
undo(currentState: MindMapData): MindMapData | null;
|
|
197
|
+
redo(currentState: MindMapData): MindMapData | null;
|
|
198
|
+
get canUndo(): boolean;
|
|
199
|
+
get canRedo(): boolean;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
declare interface IdGenerator {
|
|
203
|
+
generate(): string;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
declare interface IMindMapEventBus {
|
|
207
|
+
emit<K extends keyof KakidashEventMap>(event: K, payload: KakidashEventMap[K]): void;
|
|
208
|
+
on<K extends keyof KakidashEventMap>(event: K, handler: (payload: KakidashEventMap[K]) => void): void;
|
|
209
|
+
off<K extends keyof KakidashEventMap>(event: K, handler: (payload: KakidashEventMap[K]) => void): void;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
declare interface InteractionOptions {
|
|
213
|
+
onNodeClick: (nodeId: string, shiftKey?: boolean) => void;
|
|
214
|
+
onAddChild: (parentId: string) => void;
|
|
215
|
+
onAddSibling: (nodeId: string, position: 'before' | 'after') => void;
|
|
216
|
+
onInsertParent?: (nodeId: string) => void;
|
|
217
|
+
onDeleteNode: (nodeId: string) => void;
|
|
218
|
+
onDropNode: (draggedId: string, targetId: string, position: 'top' | 'bottom' | 'left' | 'right') => void;
|
|
219
|
+
onUpdateNode?: (nodeId: string, topic: string) => void;
|
|
220
|
+
onNavigate?: (nodeId: string | null, direction: Direction, extendSelection?: boolean) => void;
|
|
221
|
+
onPan?: (dx: number, dy: number) => void;
|
|
222
|
+
onCopyNode?: (nodeId: string) => void;
|
|
223
|
+
onPasteNode?: (parentId: string) => void;
|
|
224
|
+
onCutNode?: (nodeId: string) => void;
|
|
225
|
+
onPasteImage?: (parentId: string, imageData: string, width: number, height: number) => void;
|
|
226
|
+
onZoom?: (delta: number, x: number, y: number) => void;
|
|
227
|
+
onZoomReset?: () => void;
|
|
228
|
+
onUndo?: () => void;
|
|
229
|
+
onRedo?: () => void;
|
|
230
|
+
onStyleAction?: (nodeId: string, action: StyleAction) => void;
|
|
231
|
+
onEditEnd?: (nodeId: string) => void;
|
|
232
|
+
onToggleFold?: (nodeId: string) => void;
|
|
233
|
+
onToggleCommandPalette?: () => void;
|
|
234
|
+
onUpdateNodeWidth?: (nodeId: string, increment: number) => void;
|
|
235
|
+
shortcuts?: ShortcutConfig;
|
|
236
|
+
allowReadOnly?: boolean;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
declare class InteractionOrchestrator {
|
|
240
|
+
private container;
|
|
241
|
+
private commandBus;
|
|
242
|
+
private mindMap;
|
|
243
|
+
readonly options: InteractionOptions;
|
|
244
|
+
private keyboardHandler;
|
|
245
|
+
private zoomPanHandler;
|
|
246
|
+
private dragDropHandler;
|
|
247
|
+
private nodeEditor;
|
|
248
|
+
private cleanupFns;
|
|
249
|
+
private isReadOnly;
|
|
250
|
+
private _maxWidth;
|
|
251
|
+
private _getNodeElement;
|
|
252
|
+
private _zoomNode;
|
|
253
|
+
private getSelectedNodeId;
|
|
254
|
+
constructor(deps: InteractionOrchestratorDeps);
|
|
255
|
+
get isReadOnlyState(): boolean;
|
|
256
|
+
getShortcuts(): ShortcutConfig_2;
|
|
257
|
+
setReadOnly(readOnly: boolean): void;
|
|
258
|
+
focus(): void;
|
|
259
|
+
set maxWidth(width: number);
|
|
260
|
+
get maxWidth(): number;
|
|
261
|
+
editNode(nodeId: string): void;
|
|
262
|
+
getNodeElement(nodeId: string): HTMLElement | undefined;
|
|
263
|
+
zoomNode(nodeId: string): void;
|
|
264
|
+
updateSelection(_nodeId: string | null): void;
|
|
265
|
+
destroy(): void;
|
|
266
|
+
private attachEvents;
|
|
267
|
+
private startEditing;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
declare interface InteractionOrchestratorDeps {
|
|
271
|
+
container: HTMLElement;
|
|
272
|
+
options: InteractionOptions;
|
|
273
|
+
commandBus: CommandBus;
|
|
274
|
+
mindMap: MindMap;
|
|
275
|
+
getSelectedNodeId: () => string | null;
|
|
276
|
+
getNodeElement: (nodeId: string) => HTMLElement | undefined;
|
|
277
|
+
zoomNode: (nodeId: string) => void;
|
|
278
|
+
}
|
|
279
|
+
|
|
23
280
|
/**
|
|
24
281
|
* The main class for the Kakidash mind map library.
|
|
25
282
|
* It manages the mind map data, interaction, and rendering.
|
|
26
283
|
*/
|
|
27
284
|
export declare class Kakidash extends TypedEventEmitter<KakidashEventMap> {
|
|
28
285
|
private mindMap;
|
|
29
|
-
|
|
286
|
+
controller: MindMapController;
|
|
287
|
+
interactionOrchestrator: InteractionOrchestrator;
|
|
288
|
+
commandBus: CommandBus;
|
|
30
289
|
constructor(container: HTMLElement, options?: KakidashOptions);
|
|
31
290
|
addNode(parentId: string, topic?: string, layoutSide?: 'left' | 'right', options?: {
|
|
32
291
|
emitChange?: boolean;
|
|
@@ -50,6 +309,11 @@ export declare class Kakidash extends TypedEventEmitter<KakidashEventMap> {
|
|
|
50
309
|
* Toggles the visibility of the command palette.
|
|
51
310
|
*/
|
|
52
311
|
toggleCommandPalette(): void;
|
|
312
|
+
/**
|
|
313
|
+
* Registers a custom command to be displayed in the command palette.
|
|
314
|
+
* @param command The custom command definition.
|
|
315
|
+
*/
|
|
316
|
+
registerCommand(command: CustomCommand): void;
|
|
53
317
|
/**
|
|
54
318
|
* Opens the command palette (alias for toggleCommandPalette).
|
|
55
319
|
*/
|
|
@@ -99,11 +363,12 @@ export declare class Kakidash extends TypedEventEmitter<KakidashEventMap> {
|
|
|
99
363
|
|
|
100
364
|
declare type KakidashCommandArgs = {
|
|
101
365
|
name: string;
|
|
102
|
-
args?:
|
|
366
|
+
args?: unknown;
|
|
103
367
|
};
|
|
104
368
|
|
|
105
369
|
export declare type KakidashEventMap = {
|
|
106
370
|
'node:select': string | null;
|
|
371
|
+
'selection:change': string[];
|
|
107
372
|
'node:add': {
|
|
108
373
|
id: string;
|
|
109
374
|
topic: string;
|
|
@@ -140,6 +405,14 @@ export declare interface KakidashOptions {
|
|
|
140
405
|
* for importing and exporting files.
|
|
141
406
|
*/
|
|
142
407
|
fileHandler?: FileHandler;
|
|
408
|
+
/**
|
|
409
|
+
* Locale for UI text (help modal, etc.). Defaults to 'en'.
|
|
410
|
+
*/
|
|
411
|
+
locale?: 'en' | 'ja';
|
|
412
|
+
/**
|
|
413
|
+
* Features to disable in the command palette.
|
|
414
|
+
*/
|
|
415
|
+
disabledCommandPaletteFeatures?: ('search' | 'icon' | 'import' | 'export')[];
|
|
143
416
|
}
|
|
144
417
|
|
|
145
418
|
export declare interface KeyBinding {
|
|
@@ -150,26 +423,204 @@ export declare interface KeyBinding {
|
|
|
150
423
|
altKey?: boolean;
|
|
151
424
|
}
|
|
152
425
|
|
|
426
|
+
declare interface KeyBinding_2 {
|
|
427
|
+
key: string;
|
|
428
|
+
ctrlKey?: boolean;
|
|
429
|
+
metaKey?: boolean;
|
|
430
|
+
shiftKey?: boolean;
|
|
431
|
+
altKey?: boolean;
|
|
432
|
+
}
|
|
433
|
+
|
|
153
434
|
export declare type LayoutMode = 'Right' | 'Left' | 'Both';
|
|
154
435
|
|
|
436
|
+
declare interface LayoutResult {
|
|
437
|
+
nodes: NodeLayout[];
|
|
438
|
+
connections: ConnectionLayout[];
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
declare class LayoutSwitcher {
|
|
442
|
+
container: HTMLElement;
|
|
443
|
+
element: HTMLDivElement;
|
|
444
|
+
options: LayoutSwitcherOptions;
|
|
445
|
+
currentMode: LayoutMode;
|
|
446
|
+
currentTheme: Theme;
|
|
447
|
+
layoutButtons: Map<LayoutMode, HTMLButtonElement>;
|
|
448
|
+
themeButtons: Map<Theme, HTMLButtonElement>;
|
|
449
|
+
constructor(container: HTMLElement, options: LayoutSwitcherOptions);
|
|
450
|
+
private render;
|
|
451
|
+
private addSeparator;
|
|
452
|
+
private createLayoutButton;
|
|
453
|
+
private createThemeButton;
|
|
454
|
+
private createIconActionButton;
|
|
455
|
+
private styleButton;
|
|
456
|
+
private updateActiveButtons;
|
|
457
|
+
setMode(mode: LayoutMode): void;
|
|
458
|
+
setTheme(theme: Theme): void;
|
|
459
|
+
getIconDescriptions(locale: 'en' | 'ja'): Array<{
|
|
460
|
+
id: string;
|
|
461
|
+
desc: string;
|
|
462
|
+
}>;
|
|
463
|
+
getRightIcon(): string;
|
|
464
|
+
getLeftIcon(): string;
|
|
465
|
+
getBothIcon(): string;
|
|
466
|
+
getThemeDefaultIcon(): string;
|
|
467
|
+
getThemeSimpleIcon(): string;
|
|
468
|
+
getThemeColorfulIcon(): string;
|
|
469
|
+
getThemeCustomIcon(): string;
|
|
470
|
+
getZoomResetIcon(): string;
|
|
471
|
+
getHelpIcon(): string;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
declare interface LayoutSwitcherOptions {
|
|
475
|
+
onLayoutChange: (mode: LayoutMode) => void;
|
|
476
|
+
onThemeChange: (theme: Theme) => void;
|
|
477
|
+
onZoomReset?: () => void;
|
|
478
|
+
onShowHelp?: () => void;
|
|
479
|
+
}
|
|
480
|
+
|
|
155
481
|
declare class MindMap {
|
|
156
482
|
root: Node_2;
|
|
157
483
|
theme: Theme;
|
|
484
|
+
private nodeIndex;
|
|
158
485
|
constructor(rootNode: Node_2);
|
|
486
|
+
/**
|
|
487
|
+
* Rebuild the entire node index from the current root tree.
|
|
488
|
+
* Should be called after root replacement (e.g., importData).
|
|
489
|
+
*/
|
|
490
|
+
rebuildIndex(): void;
|
|
491
|
+
private indexSubtree;
|
|
492
|
+
/**
|
|
493
|
+
* Register a node and its entire subtree into the index.
|
|
494
|
+
* Call after adding a node (or subtree) to the tree.
|
|
495
|
+
*/
|
|
496
|
+
registerNode(node: Node_2): void;
|
|
497
|
+
/**
|
|
498
|
+
* Unregister a node and its entire subtree from the index.
|
|
499
|
+
* Call after removing a node (or subtree) from the tree.
|
|
500
|
+
*/
|
|
501
|
+
unregisterNode(node: Node_2): void;
|
|
502
|
+
private removeFromIndex;
|
|
159
503
|
findNode(id: string): Node_2 | null;
|
|
160
|
-
private findNodeRecursive;
|
|
161
504
|
moveNode(nodeId: string, newParentId: string): boolean;
|
|
162
505
|
addSibling(referenceId: string, newNode: Node_2, position: 'before' | 'after'): boolean;
|
|
163
506
|
insertParent(targetId: string, newParentNode: Node_2): boolean;
|
|
164
507
|
private isDescendant;
|
|
165
508
|
}
|
|
166
509
|
|
|
510
|
+
declare class MindMapController {
|
|
511
|
+
private mindMap;
|
|
512
|
+
private service;
|
|
513
|
+
private renderer;
|
|
514
|
+
private eventBus;
|
|
515
|
+
private styleEditor;
|
|
516
|
+
private commandPalette;
|
|
517
|
+
private locale;
|
|
518
|
+
private interactionOrchestrator;
|
|
519
|
+
private layoutSwitcher;
|
|
520
|
+
private fileIOService;
|
|
521
|
+
private themeService;
|
|
522
|
+
private commandBus;
|
|
523
|
+
private historyService;
|
|
524
|
+
private clipboardService;
|
|
525
|
+
private searchService;
|
|
526
|
+
private viewportService;
|
|
527
|
+
private navigationService;
|
|
528
|
+
private anchorNodeId;
|
|
529
|
+
private selectedNodeId;
|
|
530
|
+
private selectedNodeIds;
|
|
531
|
+
private layoutMode;
|
|
532
|
+
private isBatching;
|
|
533
|
+
private maxWidth;
|
|
534
|
+
private pendingNodeCreation;
|
|
535
|
+
constructor(deps: ControllerDependencies);
|
|
536
|
+
private subscribeToModel;
|
|
537
|
+
private subscribeToCommands;
|
|
538
|
+
setInteractionOrchestrator(orchestrator: InteractionOrchestrator): void;
|
|
539
|
+
setLayoutSwitcher(switcher: LayoutSwitcher): void;
|
|
540
|
+
init(containerWidth: number, containerHeight: number): void;
|
|
541
|
+
destroy(): void;
|
|
542
|
+
getData(): MindMapData;
|
|
543
|
+
loadData(data: MindMapData): void;
|
|
544
|
+
batch(callback: () => void): void;
|
|
545
|
+
getSelectedNodeId(): string | null;
|
|
546
|
+
getSelectedNodeIds(): string[];
|
|
547
|
+
private getIdsToActOn;
|
|
548
|
+
private saveState;
|
|
549
|
+
addNode(parentId: string, topic?: string, layoutSide?: 'left' | 'right', options?: {
|
|
550
|
+
emitChange?: boolean;
|
|
551
|
+
}): Node_2 | null;
|
|
552
|
+
addSibling(referenceId: string, position?: 'before' | 'after', topic?: string, options?: {
|
|
553
|
+
emitChange?: boolean;
|
|
554
|
+
}): Node_2 | null;
|
|
555
|
+
insertParent(targetId: string, topic?: string, options?: {
|
|
556
|
+
emitChange?: boolean;
|
|
557
|
+
}): Node_2 | null;
|
|
558
|
+
deleteNode(nodeId: string): void;
|
|
559
|
+
updateNode(nodeId: string, updates: {
|
|
560
|
+
topic?: string;
|
|
561
|
+
style?: Partial<NodeStyle>;
|
|
562
|
+
icon?: string;
|
|
563
|
+
}): void;
|
|
564
|
+
updateNodeWidth(nodeId: string, increment: number): void;
|
|
565
|
+
addChildNode(parentId: string): void;
|
|
566
|
+
addSiblingNode(nodeId: string, position?: 'before' | 'after'): void;
|
|
567
|
+
insertParentNode(nodeId: string): void;
|
|
568
|
+
removeNode(nodeId: string): void;
|
|
569
|
+
selectNode(nodeId: string | null): void;
|
|
570
|
+
selectNodes(nodeIds: string[]): void;
|
|
571
|
+
private updateSelectionState;
|
|
572
|
+
private restoreSelection;
|
|
573
|
+
private findTargetIdAfterRemoval;
|
|
574
|
+
moveNode(nodeId: string, targetId: string, position: 'top' | 'bottom' | 'left' | 'right'): void;
|
|
575
|
+
updateNodeTopic(nodeId: string, topic: string): void;
|
|
576
|
+
render(): void;
|
|
577
|
+
/**
|
|
578
|
+
* Fast path: update selection styles without full DOM rebuild.
|
|
579
|
+
*/
|
|
580
|
+
private renderSelection;
|
|
581
|
+
setLayoutMode(mode: LayoutMode): void;
|
|
582
|
+
getLayoutMode(): LayoutMode;
|
|
583
|
+
setMaxNodeWidth(width: number): void;
|
|
584
|
+
getMaxNodeWidth(): number;
|
|
585
|
+
updateGlobalStyles(styles: MindMapStyles): void;
|
|
586
|
+
setTheme(theme: Theme, options?: {
|
|
587
|
+
saveState?: boolean;
|
|
588
|
+
emitChange?: boolean;
|
|
589
|
+
}): void;
|
|
590
|
+
resetZoom(): void;
|
|
591
|
+
panBoard(dx: number, dy: number): void;
|
|
592
|
+
zoomBoard(delta: number, clientX: number, clientY: number): void;
|
|
593
|
+
setReadOnly(readOnly: boolean): void;
|
|
594
|
+
undo(): void;
|
|
595
|
+
redo(): void;
|
|
596
|
+
toggleFold(nodeId: string): void;
|
|
597
|
+
navigateNode(nodeId: string | null, direction: Direction, extendSelection?: boolean): void;
|
|
598
|
+
selectRangeTo(targetId: string): void;
|
|
599
|
+
private selectRange;
|
|
600
|
+
copyNode(nodeId: string): void;
|
|
601
|
+
pasteNode(parentId: string): void;
|
|
602
|
+
cutNode(nodeId: string): void;
|
|
603
|
+
pasteImage(parentId: string, imageData: string, width?: number, height?: number): void;
|
|
604
|
+
onEditEnd(): void;
|
|
605
|
+
onStyleAction(nodeId: string, action: StyleAction): void;
|
|
606
|
+
toggleCommandPalette(): void;
|
|
607
|
+
registerCommand(command: CustomCommand): void;
|
|
608
|
+
searchNodes(query: string): Node_2[];
|
|
609
|
+
private handleSearchInput;
|
|
610
|
+
private handleSearchResultSelect;
|
|
611
|
+
private handleIconSelect;
|
|
612
|
+
private handleCommandSelect;
|
|
613
|
+
private ensureNodeVisible;
|
|
614
|
+
showHelpModal(): void;
|
|
615
|
+
}
|
|
616
|
+
|
|
167
617
|
export declare interface MindMapData {
|
|
168
618
|
nodeData: MindMapNodeData;
|
|
169
619
|
linkData?: any;
|
|
170
620
|
theme?: Theme;
|
|
171
621
|
direction?: number;
|
|
172
622
|
selectedId?: string;
|
|
623
|
+
selectedIds?: string[];
|
|
173
624
|
}
|
|
174
625
|
|
|
175
626
|
export declare interface MindMapNodeData {
|
|
@@ -195,6 +646,31 @@ export declare interface MindMapNodeData {
|
|
|
195
646
|
customWidth?: number;
|
|
196
647
|
}
|
|
197
648
|
|
|
649
|
+
declare class MindMapService {
|
|
650
|
+
mindMap: MindMap;
|
|
651
|
+
private idGenerator;
|
|
652
|
+
constructor(mindMap: MindMap, idGenerator: IdGenerator);
|
|
653
|
+
addNode(parentId: string, topic?: string, layoutSide?: 'left' | 'right'): Node_2 | null;
|
|
654
|
+
addImageNode(parentId: string, imageData: string, width?: number, height?: number): Node_2 | null;
|
|
655
|
+
removeNode(id: string): boolean;
|
|
656
|
+
removeNodes(ids: string[]): boolean;
|
|
657
|
+
updateNodeTopic(id: string, topic: string): boolean;
|
|
658
|
+
updateNodeStyle(id: string, style: Partial<NodeStyle>): boolean;
|
|
659
|
+
updateNodesStyle(ids: string[], style: Partial<NodeStyle>): boolean;
|
|
660
|
+
toggleNodeFold(id: string): boolean;
|
|
661
|
+
setTheme(theme: Theme): void;
|
|
662
|
+
updateNodeCustomWidth(id: string, width: number | undefined): boolean;
|
|
663
|
+
moveNode(nodeId: string, newParentId: string, layoutSide?: 'left' | 'right'): boolean;
|
|
664
|
+
addSibling(referenceId: string, position: 'before' | 'after', topic?: string): Node_2 | null;
|
|
665
|
+
reorderNode(nodeId: string, targetId: string, position: 'before' | 'after'): boolean;
|
|
666
|
+
insertNodeAsParent(nodeId: string, targetId: string): boolean;
|
|
667
|
+
insertParent(targetId: string, topic?: string): Node_2 | null;
|
|
668
|
+
updateNodeIcon(id: string, icon: string): boolean;
|
|
669
|
+
addExistingNodes(parentId: string, nodes: Node_2[]): boolean;
|
|
670
|
+
exportData(): MindMapData;
|
|
671
|
+
importData(data: MindMapData): void;
|
|
672
|
+
}
|
|
673
|
+
|
|
198
674
|
export declare interface MindMapStyles {
|
|
199
675
|
rootNode?: {
|
|
200
676
|
border?: string;
|
|
@@ -215,6 +691,33 @@ export declare interface MindMapStyles {
|
|
|
215
691
|
[key: string]: any;
|
|
216
692
|
}
|
|
217
693
|
|
|
694
|
+
/**
|
|
695
|
+
* Handles navigation logic (keyboard arrow navigation) within the mind map.
|
|
696
|
+
* Extracted from MindMapController to follow Single Responsibility Principle.
|
|
697
|
+
*/
|
|
698
|
+
declare class NavigationService {
|
|
699
|
+
private mindMap;
|
|
700
|
+
private layoutMode;
|
|
701
|
+
constructor(mindMap: MindMap);
|
|
702
|
+
/** Set current layout mode */
|
|
703
|
+
setLayoutMode(mode: LayoutMode): void;
|
|
704
|
+
/** Get current layout mode */
|
|
705
|
+
getLayoutMode(): LayoutMode;
|
|
706
|
+
/**
|
|
707
|
+
* Navigate from a node in the given direction.
|
|
708
|
+
* Returns the target node ID, or undefined if navigation is not possible.
|
|
709
|
+
*/
|
|
710
|
+
navigate(nodeId: string, direction: Direction): string | undefined;
|
|
711
|
+
/** Get the directional side of a node (left or right) */
|
|
712
|
+
getNodeDirection(node: Node_2): 'left' | 'right';
|
|
713
|
+
/** Ensure all root children have explicit layout sides in Both mode */
|
|
714
|
+
ensureExplicitLayoutSides(parent: Node_2): void;
|
|
715
|
+
private navigateLeft;
|
|
716
|
+
private navigateRight;
|
|
717
|
+
private navigateUp;
|
|
718
|
+
private navigateDown;
|
|
719
|
+
}
|
|
720
|
+
|
|
218
721
|
declare class Node_2 {
|
|
219
722
|
id: string;
|
|
220
723
|
topic: string;
|
|
@@ -227,10 +730,8 @@ declare class Node_2 {
|
|
|
227
730
|
width: number;
|
|
228
731
|
height: number;
|
|
229
732
|
};
|
|
230
|
-
layoutSide?: 'left' | 'right';
|
|
231
|
-
isFolded: boolean;
|
|
232
733
|
icon?: string;
|
|
233
|
-
|
|
734
|
+
presentation: NodePresentationData;
|
|
234
735
|
constructor(id: string, topic: string, parentId?: string | null, isRoot?: boolean, image?: string, layoutSide?: 'left' | 'right', isFolded?: boolean, icon?: string, imageSize?: {
|
|
235
736
|
width: number;
|
|
236
737
|
height: number;
|
|
@@ -242,18 +743,126 @@ declare class Node_2 {
|
|
|
242
743
|
}
|
|
243
744
|
export { Node_2 as Node }
|
|
244
745
|
|
|
746
|
+
declare interface NodeLayout {
|
|
747
|
+
nodeId: string;
|
|
748
|
+
x: number;
|
|
749
|
+
y: number;
|
|
750
|
+
width: number;
|
|
751
|
+
height: number;
|
|
752
|
+
direction: 'left' | 'right';
|
|
753
|
+
isRoot: boolean;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
declare interface NodePresentationData {
|
|
757
|
+
layoutSide?: 'left' | 'right';
|
|
758
|
+
isFolded: boolean;
|
|
759
|
+
customWidth?: number;
|
|
760
|
+
}
|
|
761
|
+
|
|
245
762
|
export declare interface NodeStyle {
|
|
246
763
|
color?: string;
|
|
247
764
|
background?: string;
|
|
248
765
|
fontSize?: string;
|
|
249
766
|
fontWeight?: string;
|
|
250
767
|
fontStyle?: string;
|
|
768
|
+
textDecoration?: string;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
declare interface Renderer {
|
|
772
|
+
container: HTMLElement;
|
|
773
|
+
maxWidth: number;
|
|
774
|
+
renderFromLayout(layout: LayoutResult, mindMap: MindMap, selectedNodeIds: Set<string>, layoutMode: LayoutMode): void;
|
|
775
|
+
updateTransform(x: number, y: number, scale: number): void;
|
|
776
|
+
measureNode(node: Node_2, mindMap?: MindMap): {
|
|
777
|
+
width: number;
|
|
778
|
+
height: number;
|
|
779
|
+
};
|
|
780
|
+
updateSelection(selectedNodeIds: Set<string>): void;
|
|
781
|
+
getNodeElement(nodeId: string): HTMLElement | undefined;
|
|
251
782
|
}
|
|
252
783
|
|
|
253
|
-
|
|
784
|
+
declare class SearchService {
|
|
785
|
+
private mindMap;
|
|
786
|
+
constructor(mindMap: MindMap);
|
|
787
|
+
searchNodes(query: string): Node_2[];
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
export declare type ShortcutAction = 'navUp' | 'navDown' | 'navLeft' | 'navRight' | 'addChild' | 'insertParent' | 'addSibling' | 'addSiblingBefore' | 'deleteNode' | 'beginEdit' | 'copy' | 'paste' | 'cut' | 'undo' | 'redo' | 'bold' | 'italic' | 'increaseFontSize' | 'decreaseFontSize' | 'zoomIn' | 'zoomOut' | 'resetZoom' | 'toggleFold' | 'centerMap' | 'selectColor1' | 'selectColor2' | 'selectColor3' | 'selectColor4' | 'selectColor5' | 'selectColor6' | 'selectColor7' | 'openCommandPalette' | 'increaseNodeWidth' | 'decreaseNodeWidth' | 'strikethrough';
|
|
791
|
+
|
|
792
|
+
declare type ShortcutAction_2 =
|
|
793
|
+
| 'navUp'
|
|
794
|
+
| 'navDown'
|
|
795
|
+
| 'navLeft'
|
|
796
|
+
| 'navRight'
|
|
797
|
+
| 'addChild'
|
|
798
|
+
| 'insertParent'
|
|
799
|
+
| 'addSibling'
|
|
800
|
+
| 'addSiblingBefore'
|
|
801
|
+
| 'deleteNode'
|
|
802
|
+
| 'beginEdit' // F2, etc
|
|
803
|
+
| 'copy'
|
|
804
|
+
| 'paste'
|
|
805
|
+
| 'cut'
|
|
806
|
+
| 'undo'
|
|
807
|
+
| 'redo'
|
|
808
|
+
| 'bold'
|
|
809
|
+
| 'italic'
|
|
810
|
+
| 'increaseFontSize'
|
|
811
|
+
| 'decreaseFontSize'
|
|
812
|
+
| 'zoomIn'
|
|
813
|
+
| 'zoomOut'
|
|
814
|
+
| 'resetZoom'
|
|
815
|
+
| 'toggleFold'
|
|
816
|
+
| 'centerMap'
|
|
817
|
+
| 'selectColor1'
|
|
818
|
+
| 'selectColor2'
|
|
819
|
+
| 'selectColor3'
|
|
820
|
+
| 'selectColor4'
|
|
821
|
+
| 'selectColor5'
|
|
822
|
+
| 'selectColor6'
|
|
823
|
+
| 'selectColor7'
|
|
824
|
+
| 'openCommandPalette'
|
|
825
|
+
| 'increaseNodeWidth'
|
|
826
|
+
| 'decreaseNodeWidth'
|
|
827
|
+
| 'strikethrough';
|
|
254
828
|
|
|
255
829
|
export declare type ShortcutConfig = Partial<Record<ShortcutAction, KeyBinding[]>>;
|
|
256
830
|
|
|
831
|
+
declare type ShortcutConfig_2 = Partial<Record<ShortcutAction_2, KeyBinding_2[]>>;
|
|
832
|
+
|
|
833
|
+
declare type StyleAction = {
|
|
834
|
+
type: 'bold';
|
|
835
|
+
} | {
|
|
836
|
+
type: 'italic';
|
|
837
|
+
} | {
|
|
838
|
+
type: 'increaseSize';
|
|
839
|
+
} | {
|
|
840
|
+
type: 'decreaseSize';
|
|
841
|
+
} | {
|
|
842
|
+
type: 'strikethrough';
|
|
843
|
+
} | {
|
|
844
|
+
type: 'color';
|
|
845
|
+
index: number;
|
|
846
|
+
};
|
|
847
|
+
|
|
848
|
+
declare class StyleEditor {
|
|
849
|
+
container: HTMLElement;
|
|
850
|
+
editorEl: HTMLElement;
|
|
851
|
+
currentNodeId: string | null;
|
|
852
|
+
onUpdate?: (nodeId: string, style: Partial<NodeStyle>) => void;
|
|
853
|
+
static readonly FONT_SIZES: {
|
|
854
|
+
label: string;
|
|
855
|
+
value: string;
|
|
856
|
+
}[];
|
|
857
|
+
static readonly PALETTE: string[];
|
|
858
|
+
constructor(container: HTMLElement);
|
|
859
|
+
private createEditor;
|
|
860
|
+
private updateActivePaletteItem;
|
|
861
|
+
private updateButtonState;
|
|
862
|
+
show(nodeId: string, currentStyle: NodeStyle): void;
|
|
863
|
+
hide(): void;
|
|
864
|
+
}
|
|
865
|
+
|
|
257
866
|
export declare class SvgGenerator {
|
|
258
867
|
/**
|
|
259
868
|
* Generates an SVG string representation of the mind map content within the given container.
|
|
@@ -265,7 +874,59 @@ export declare class SvgGenerator {
|
|
|
265
874
|
|
|
266
875
|
export declare type Theme = 'default' | 'simple' | 'colorful' | 'custom';
|
|
267
876
|
|
|
268
|
-
|
|
877
|
+
/**
|
|
878
|
+
* Service for handling Theme and Style updates for the MindMap.
|
|
879
|
+
*/
|
|
880
|
+
declare class ThemeService {
|
|
881
|
+
private mindMap;
|
|
882
|
+
private service;
|
|
883
|
+
private renderer;
|
|
884
|
+
private eventBus;
|
|
885
|
+
private layoutSwitcher?;
|
|
886
|
+
private savedCustomStyles;
|
|
887
|
+
/**
|
|
888
|
+
* Initializes a new instance of the ThemeService.
|
|
889
|
+
* @param deps Dependencies required for Theme/Style operations
|
|
890
|
+
*/
|
|
891
|
+
constructor(deps: ThemeServiceDependencies);
|
|
892
|
+
/**
|
|
893
|
+
* Sets the optional layoutSwitcher reference to propagate theme changes
|
|
894
|
+
* @param switcher LayoutSwitcher instance
|
|
895
|
+
*/
|
|
896
|
+
setLayoutSwitcher(switcher: LayoutSwitcher): void;
|
|
897
|
+
/**
|
|
898
|
+
* Applies the mind map's initial theme upon loading.
|
|
899
|
+
*/
|
|
900
|
+
applyInitialTheme(): void;
|
|
901
|
+
/**
|
|
902
|
+
* Updates global styles and persists them to savedCustomStyles.
|
|
903
|
+
* Emits a command and change events.
|
|
904
|
+
* @param styles MindMapStyles to update
|
|
905
|
+
*/
|
|
906
|
+
updateGlobalStyles(styles: MindMapStyles): void;
|
|
907
|
+
/**
|
|
908
|
+
* Applies the given theme, updates underlying models and the layout.
|
|
909
|
+
* @param theme Theme to apply
|
|
910
|
+
* @param options Execution Options (saveState, emitChange)
|
|
911
|
+
*/
|
|
912
|
+
setTheme(theme: Theme, options?: {
|
|
913
|
+
saveState?: boolean;
|
|
914
|
+
emitChange?: boolean;
|
|
915
|
+
}): void;
|
|
916
|
+
/**
|
|
917
|
+
* Getter for currently saved custom styles.
|
|
918
|
+
*/
|
|
919
|
+
getSavedCustomStyles(): MindMapStyles;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
declare interface ThemeServiceDependencies {
|
|
923
|
+
mindMap: MindMap;
|
|
924
|
+
service: MindMapService;
|
|
925
|
+
renderer: Renderer;
|
|
926
|
+
eventBus: IMindMapEventBus;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
export declare class TypedEventEmitter<EventMap extends Record<string, any>> {
|
|
269
930
|
private listeners;
|
|
270
931
|
on<K extends keyof EventMap>(event: K, listener: (payload: EventMap[K]) => void): void;
|
|
271
932
|
addListener<K extends keyof EventMap>(event: K, listener: (payload: EventMap[K]) => void): void;
|
|
@@ -274,6 +935,52 @@ declare class TypedEventEmitter<EventMap extends Record<string, any>> {
|
|
|
274
935
|
protected emit<K extends keyof EventMap>(event: K, payload: EventMap[K]): void;
|
|
275
936
|
}
|
|
276
937
|
|
|
938
|
+
/**
|
|
939
|
+
* Manages viewport state (pan, zoom, scale) and animation.
|
|
940
|
+
* Extracted from MindMapController to follow Single Responsibility Principle.
|
|
941
|
+
*/
|
|
942
|
+
declare class ViewportService {
|
|
943
|
+
private panX;
|
|
944
|
+
private panY;
|
|
945
|
+
private targetPanX;
|
|
946
|
+
private targetPanY;
|
|
947
|
+
private scale;
|
|
948
|
+
private animationFrameId;
|
|
949
|
+
private renderer;
|
|
950
|
+
constructor(renderer: Renderer);
|
|
951
|
+
/** Get current scale factor */
|
|
952
|
+
getScale(): number;
|
|
953
|
+
/** Get current pan position */
|
|
954
|
+
getPan(): {
|
|
955
|
+
x: number;
|
|
956
|
+
y: number;
|
|
957
|
+
};
|
|
958
|
+
/** Get target pan position (for animation destination) */
|
|
959
|
+
getTargetPan(): {
|
|
960
|
+
x: number;
|
|
961
|
+
y: number;
|
|
962
|
+
};
|
|
963
|
+
/** Set initial pan position (used during initialization) */
|
|
964
|
+
setInitialPan(x: number, y: number): void;
|
|
965
|
+
/** Pan the viewport by delta values */
|
|
966
|
+
pan(dx: number, dy: number): void;
|
|
967
|
+
/** Zoom centered on a specific screen coordinate */
|
|
968
|
+
zoom(delta: number, clientX: number, clientY: number): void;
|
|
969
|
+
/** Reset zoom to 1.0 scale */
|
|
970
|
+
resetZoom(): void;
|
|
971
|
+
/** Apply current transform to the renderer */
|
|
972
|
+
applyTransform(): void;
|
|
973
|
+
/**
|
|
974
|
+
* Ensure a node is visible in the viewport.
|
|
975
|
+
* Pans the viewport to make the node visible if it's offscreen.
|
|
976
|
+
*/
|
|
977
|
+
ensureNodeVisible(nodeId: string, centerIfOffscreen?: boolean, immediate?: boolean): void;
|
|
978
|
+
/** Start the smooth animation loop for pan transitions */
|
|
979
|
+
startAnimationLoop(): void;
|
|
980
|
+
/** Stop animation loop and clean up */
|
|
981
|
+
destroy(): void;
|
|
982
|
+
}
|
|
983
|
+
|
|
277
984
|
export declare class XMindImporter {
|
|
278
985
|
private idGenerator;
|
|
279
986
|
constructor();
|