kakidash 0.2.0 → 0.2.2

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.md CHANGED
@@ -20,6 +20,7 @@ Master the shortcuts and expand your mind map at the speed of thought.
20
20
  - Font size adjustment.
21
21
  - Bold (`Bold`), Italic (`Italic`).
22
22
  - Color changes via palette (Style Editor).
23
+ - **Themes**: Switch between multiple built-in themes (Default, Simple, Colorful, Dark).
23
24
  - **Icon Settings**: Add/Remove flat icons via Command Palette (`m` key).
24
25
  - **Interaction**:
25
26
  - Drag and drop for node movement and reordering.
@@ -27,7 +28,11 @@ Master the shortcuts and expand your mind map at the speed of thought.
27
28
  - Zoom, Pan (Screen navigation).
28
29
  - **Image Support**: Paste images from the clipboard.
29
30
  - **Auto Link**: Automatically detects URLs in node text and converts them to clickable links.
30
- - **Import/Export**: Save and load data in JSON format (including focus state).
31
+ - **Import/Export**:
32
+ - Save and load data in JSON format.
33
+ - Import from XMind files (.xmind).
34
+ - **Image Export**: Export mind map as PNG or SVG image (Command Palette > Export).
35
+ - **Markdown Export**: Export mind map as a Markdown file (Command Palette > Export > Markdown).
31
36
  - **For Developers**:
32
37
  - TypeScript support.
33
38
  - Read-only mode.
@@ -40,6 +45,7 @@ pnpm add kakidash
40
45
  ```
41
46
 
42
47
  ## Usage
48
+
43
49
  ### 1. HTML Preparation
44
50
 
45
51
  Prepare a container element (e.g., `div`) to display `kakidash`.
@@ -48,26 +54,28 @@ Prepare a container element (e.g., `div`) to display `kakidash`.
48
54
  ```html
49
55
  <!DOCTYPE html>
50
56
  <html lang="en">
51
- <head>
52
- <meta charset="UTF-8">
57
+ <head>
58
+ <meta charset="UTF-8" />
53
59
  <title>Kakidash Demo</title>
54
60
  <style>
55
- /* Container size is required */
56
- #mindmap-container {
57
- width: 100vw;
58
- height: 100vh;
59
- border: 1px solid #ccc;
60
- margin: 0;
61
- padding: 0;
62
- overflow: hidden; /* Prevent scrolling within container */
63
- }
64
- body { margin: 0; }
61
+ /* Container size is required */
62
+ #mindmap-container {
63
+ width: 100vw;
64
+ height: 100vh;
65
+ border: 1px solid #ccc;
66
+ margin: 0;
67
+ padding: 0;
68
+ overflow: hidden; /* Prevent scrolling within container */
69
+ }
70
+ body {
71
+ margin: 0;
72
+ }
65
73
  </style>
66
- </head>
67
- <body>
74
+ </head>
75
+ <body>
68
76
  <div id="mindmap-container"></div>
69
77
  <!-- Script Injection Here -->
70
- </body>
78
+ </body>
71
79
  </html>
72
80
  ```
73
81
 
@@ -79,7 +87,7 @@ Prepare a container element (e.g., `div`) to display `kakidash`.
79
87
  pnpm add kakidash
80
88
  ```
81
89
 
82
- ```typescript
90
+ ````typescript
83
91
  import { Kakidash } from 'kakidash';
84
92
 
85
93
  // Get container
@@ -96,7 +104,16 @@ const kakidash = new Kakidash(container, {
96
104
 
97
105
  // Add initial data or nodes if needed
98
106
  kakidash.addNode(kakidash.getRootId(), 'Hello World');
99
- ```
107
+
108
+ ### 3. Theme Selection
109
+
110
+ You can switch themes dynamically:
111
+
112
+ ```typescript
113
+ kakidash.setTheme('dark'); // 'default', 'simple', 'colorful', 'dark'
114
+ ````
115
+
116
+ ````
100
117
 
101
118
  #### B. Browser Direct Import (Script Tag / CDN)
102
119
 
@@ -116,10 +133,10 @@ Use the built `umd` file. The library will be exposed under the global variable
116
133
  // Initialize
117
134
  const container = document.getElementById('mindmap-container');
118
135
  const kakidash = new Kakidash(container);
119
-
136
+
120
137
  console.log('Kakidash initialized:', kakidash);
121
138
  </script>
122
- ```
139
+ ````
123
140
 
124
141
  ## Custom Styling
125
142
 
@@ -130,28 +147,28 @@ You can define custom styles using `updateGlobalStyles`. These settings are pers
130
147
  // These settings are saved internally.
131
148
  kakidash.updateGlobalStyles({
132
149
  // Root node style
133
- rootNode: {
150
+ rootNode: {
134
151
  border: '4px solid gold',
135
152
  background: '#ffeeee',
136
- color: '#333' // Font color
153
+ color: '#333', // Font color
137
154
  },
138
-
155
+
139
156
  // Child nodes style
140
- childNode: {
141
- border: '2px dashed blue',
157
+ childNode: {
158
+ border: '2px dashed blue',
142
159
  background: 'white',
143
- color: '#555' // Font color
160
+ color: '#555', // Font color
144
161
  },
145
-
162
+
146
163
  // Connection line color
147
- connection: {
148
- color: 'orange'
164
+ connection: {
165
+ color: 'orange',
149
166
  },
150
-
167
+
151
168
  // Entire canvas background
152
169
  canvas: {
153
- background: '#fafafa' // Use 'transparent' for transparency
154
- }
170
+ background: '#fafafa', // Use 'transparent' for transparency
171
+ },
155
172
  });
156
173
 
157
174
  // 2. Activate the custom theme to see your changes
@@ -162,13 +179,13 @@ kakidash.setTheme('custom');
162
179
 
163
180
  All values accept standard CSS strings.
164
181
 
165
- | Object | Property | Description | Example |
166
- | --- | --- | --- | --- |
167
- | `rootNode`, `childNode` | `border` | Node border | `'2px solid red'`, `'none'` |
168
- | | `background` | Node background | `'#ffffff'`, `'rgba(0,0,0,0.5)'`, `'transparent'` |
169
- | | `color` | Text color | `'#333'`, `'black'` |
170
- | `connection` | `color` | Connection line color | `'#ccc'`, `'orange'` |
171
- | `canvas` | `background` | Canvas background | `'#f0f0f0'`, `'transparent'` |
182
+ | Object | Property | Description | Example |
183
+ | ----------------------- | ------------ | --------------------- | ------------------------------------------------- |
184
+ | `rootNode`, `childNode` | `border` | Node border | `'2px solid red'`, `'none'` |
185
+ | | `background` | Node background | `'#ffffff'`, `'rgba(0,0,0,0.5)'`, `'transparent'` |
186
+ | | `color` | Text color | `'#333'`, `'black'` |
187
+ | `connection` | `color` | Connection line color | `'#ccc'`, `'orange'` |
188
+ | `canvas` | `background` | Canvas background | `'#f0f0f0'`, `'transparent'` |
172
189
 
173
190
  ## API Reference
174
191
 
@@ -196,15 +213,15 @@ All values accept standard CSS strings.
196
213
 
197
214
  ### Events
198
215
 
199
- | Event Name | Payload | Description |
200
- | --- | --- | --- |
201
- | `node:select` | `string \| null` | Fired when a node is selected. |
202
- | `node:add` | `{ id: string; topic: string }` | Fired when a new node is added. |
203
- | `node:remove` | `string` | Fired when a node is removed. |
204
- | `node:update` | `{ id: string; topic?: string; icon?: string }` | Fired when a node is updated. |
205
- | `node:move` | `{ nodeId: string; newParentId: string; position?: string }` | Fired when a node is moved. |
206
- | `model:load` | `MindMapData` | Fired when data is loaded. |
207
- | `model:change` | `void` | Fired when the data model changes. |
216
+ | Event Name | Payload | Description |
217
+ | -------------- | ------------------------------------------------------------ | ---------------------------------- |
218
+ | `node:select` | `string \| null` | Fired when a node is selected. |
219
+ | `node:add` | `{ id: string; topic: string }` | Fired when a new node is added. |
220
+ | `node:remove` | `string` | Fired when a node is removed. |
221
+ | `node:update` | `{ id: string; topic?: string; icon?: string }` | Fired when a node is updated. |
222
+ | `node:move` | `{ nodeId: string; newParentId: string; position?: string }` | Fired when a node is moved. |
223
+ | `model:load` | `MindMapData` | Fired when data is loaded. |
224
+ | `model:change` | `void` | Fired when the data model changes. |
208
225
 
209
226
  ```typescript
210
227
  kakidash.on('node:select', (nodeId) => {
@@ -223,7 +240,7 @@ const kakidash = new Kakidash(container, {
223
240
  shortcuts: {
224
241
  // Override 'addChild' to Ctrl+N
225
242
  addChild: [{ key: 'n', ctrlKey: true }],
226
- }
243
+ },
227
244
  });
228
245
  ```
229
246
 
@@ -233,41 +250,19 @@ Here is the complete default configuration. You can partially override these key
233
250
 
234
251
  ```json
235
252
  {
236
- "navUp": [
237
- { "key": "ArrowUp" },
238
- { "key": "k" }
239
- ],
240
- "navDown": [
241
- { "key": "ArrowDown" },
242
- { "key": "j" }
243
- ],
244
- "navLeft": [
245
- { "key": "ArrowLeft" },
246
- { "key": "h" }
247
- ],
248
- "navRight": [
249
- { "key": "ArrowRight" },
250
- { "key": "l" }
251
- ],
252
- "addChild": [
253
- { "key": "Tab" },
254
- { "key": "a" }
255
- ],
253
+ "navUp": [{ "key": "ArrowUp" }, { "key": "k" }],
254
+ "navDown": [{ "key": "ArrowDown" }, { "key": "j" }],
255
+ "navLeft": [{ "key": "ArrowLeft" }, { "key": "h" }],
256
+ "navRight": [{ "key": "ArrowRight" }, { "key": "l" }],
257
+ "addChild": [{ "key": "Tab" }, { "key": "a" }],
256
258
  "insertParent": [
257
259
  { "key": "Tab", "shiftKey": true },
258
260
  { "key": "a", "shiftKey": true }
259
261
  ],
260
262
  "addSibling": [{ "key": "Enter" }],
261
263
  "addSiblingBefore": [{ "key": "Enter", "shiftKey": true }],
262
- "deleteNode": [
263
- { "key": "Delete" },
264
- { "key": "Backspace" }
265
- ],
266
- "beginEdit": [
267
- { "key": "i" },
268
- { "key": " " },
269
- { "key": "F2" }
270
- ],
264
+ "deleteNode": [{ "key": "Delete" }, { "key": "Backspace" }],
265
+ "beginEdit": [{ "key": "i" }, { "key": " " }, { "key": "F2" }],
271
266
  "copy": [
272
267
  { "key": "c", "ctrlKey": true },
273
268
  { "key": "c", "metaKey": true }
@@ -292,14 +287,8 @@ Here is the complete default configuration. You can partially override these key
292
287
  ],
293
288
  "bold": [{ "key": "b", "shiftKey": true }],
294
289
  "italic": [{ "key": "i", "shiftKey": true }],
295
- "increaseFontSize": [
296
- { "key": ">", "shiftKey": true },
297
- { "key": "." }
298
- ],
299
- "decreaseFontSize": [
300
- { "key": "<", "shiftKey": true },
301
- { "key": "," }
302
- ],
290
+ "increaseFontSize": [{ "key": ">", "shiftKey": true }, { "key": "." }],
291
+ "decreaseFontSize": [{ "key": "<", "shiftKey": true }, { "key": "," }],
303
292
  "zoomIn": [{ "key": "[" }],
304
293
  "zoomOut": [{ "key": "]" }],
305
294
  "resetZoom": [{ "key": ":" }],
@@ -318,51 +307,55 @@ Here is the complete default configuration. You can partially override these key
318
307
  ## Shortcuts
319
308
 
320
309
  ### General
321
- | Key | Description |
322
- | --- | --- |
323
- | `m` | Command Palette (Search / Icons) |
324
- | `Arrow Keys` | Navigate between nodes |
325
- | `h` / `j` / `k` / `l` | Navigate between nodes (Vim-style) |
326
- | `F2` / `DblClick` / `Space` / `i` | Start editing node (Space triggers zoom if image) |
327
- | `Enter` | Add sibling node (below) |
328
- | `Shift + Enter` | Add sibling node (above) |
329
- | `Tab` / `a` | Add child node |
330
- | `Shift + Tab` / `Shift + a` | Insert parent node |
331
- | `Delete` / `Backspace` | Delete node |
332
- | `Ctrl/Cmd + z` | Undo |
333
- | `Ctrl/Cmd + Shift + z` / `Ctrl + y` | Redo |
334
- | `Ctrl/Cmd + C` | Copy |
335
- | `Ctrl/Cmd + X` | Cut |
336
- | `Ctrl/Cmd + V` | Paste (Images supported) |
337
- | `Drag` (Canvas) | Pan screen |
338
- | `Wheel` | Vertical scroll (Pan) |
339
- | `Shift + Wheel` | Horizontal scroll (Pan) |
340
- | `Ctrl/Cmd + Wheel` | Zoom in/out |
341
- | `[` | Canvas Zoom In |
342
- | `]` | Canvas Zoom Out |
343
- | `:` | Reset Zoom |
344
- | Click `+/-` / `f` | Toggle node folding |
310
+
311
+ | Key | Description |
312
+ | ----------------------------------- | ------------------------------------------------- |
313
+ | `m` | Command Palette (Search / Icons) |
314
+ | `Arrow Keys` | Navigate between nodes |
315
+ | `h` / `j` / `k` / `l` | Navigate between nodes (Vim-style) |
316
+ | `F2` / `DblClick` / `Space` / `i` | Start editing node (Space triggers zoom if image) |
317
+ | `Enter` | Add sibling node (below) |
318
+ | `Shift + Enter` | Add sibling node (above) |
319
+ | `Tab` / `a` | Add child node |
320
+ | `Shift + Tab` / `Shift + a` | Insert parent node |
321
+ | `Delete` / `Backspace` | Delete node |
322
+ | `Ctrl/Cmd + z` | Undo |
323
+ | `Ctrl/Cmd + Shift + z` / `Ctrl + y` | Redo |
324
+ | `Ctrl/Cmd + C` | Copy |
325
+ | `Ctrl/Cmd + X` | Cut |
326
+ | `Ctrl/Cmd + V` | Paste (Images supported) |
327
+ | `Drag` (Canvas) | Pan screen |
328
+ | `Wheel` | Vertical scroll (Pan) |
329
+ | `Shift + Wheel` | Horizontal scroll (Pan) |
330
+ | `Ctrl/Cmd + Wheel` | Zoom in/out |
331
+ | `[` | Canvas Zoom In |
332
+ | `]` | Canvas Zoom Out |
333
+ | `:` | Reset Zoom |
334
+ | Click `+/-` / `f` | Toggle node folding |
345
335
 
346
336
  ### Editing (Text Input)
347
- | Key | Description |
348
- | --- | --- |
349
- | `Enter` | Confirm edit |
350
- | `Shift + Enter` | New line |
351
- | `Esc` | Cancel edit |
337
+
338
+ | Key | Description |
339
+ | --------------- | ------------ |
340
+ | `Enter` | Confirm edit |
341
+ | `Shift + Enter` | New line |
342
+ | `Esc` | Cancel edit |
352
343
 
353
344
  ### Styling (Since selection)
354
- | Key | Description |
355
- | --- | --- |
356
- | `Shift + b` | Toggle Bold |
357
- | `Shift + i` | Toggle Italic |
358
- | `Shift + . (>)` / `.` | Increase font size |
359
- | `Shift + , (<)` / `,` | Decrease font size |
360
- | `Shift + ArrowLeft / Right` | Adjust node width |
361
- | `1` - `7` | Change node color (Palette order) |
345
+
346
+ | Key | Description |
347
+ | --------------------------- | --------------------------------- |
348
+ | `Shift + b` | Toggle Bold |
349
+ | `Shift + i` | Toggle Italic |
350
+ | `Shift + . (>)` / `.` | Increase font size |
351
+ | `Shift + , (<)` / `,` | Decrease font size |
352
+ | `Shift + ArrowLeft / Right` | Adjust node width |
353
+ | `1` - `7` | Change node color (Palette order) |
362
354
 
363
355
  ## Architecture
364
356
 
365
357
  For details on the software architecture and internal module dependencies, please refer to:
358
+
366
359
  - [Software Architecture Design](./docs/SOFTWARE_ARCHITECTURE.md)
367
360
 
368
361
  ## Development
@@ -411,6 +404,10 @@ pnpm test:e2e
411
404
  pnpm turbo run test:e2e
412
405
  ```
413
406
 
407
+ > [!NOTE]
408
+ > Running E2E tests requires browsers and system dependencies to be installed. If you run them for the first time or encounter dependency errors, run the following command:
409
+ > `npx playwright install --with-deps`
410
+
414
411
  ### Lint
415
412
 
416
413
  ```bash
package/dist/index.d.ts CHANGED
@@ -1,4 +1,24 @@
1
- declare type Direction = 'Up' | 'Down' | 'Left' | 'Right';
1
+ export declare type Direction = 'Up' | 'Down' | 'Left' | 'Right';
2
+
3
+ /**
4
+ * Interface for handling file Import/Export operations.
5
+ * Allows external systems (like VS Code Extension) to override default browser behaviors.
6
+ */
7
+ export declare interface FileHandler {
8
+ /**
9
+ * Request to import a file.
10
+ * @param format The expected file format (e.g., 'xmind').
11
+ * @returns The file content as ArrayBuffer (binary) or string (text), or null if cancelled.
12
+ */
13
+ onImportFile(format: string): Promise<ArrayBuffer | string | null>;
14
+ /**
15
+ * Request to export a file.
16
+ * @param data The data to export (Blob or string).
17
+ * @param filename The suggested filename.
18
+ * @param format The file format (e.g., 'png', 'svg', 'markdown').
19
+ */
20
+ onExportFile(data: Blob | string, filename: string, format: string): Promise<void>;
21
+ }
2
22
 
3
23
  /**
4
24
  * The main class for the Kakidash mind map library.
@@ -77,6 +97,11 @@ export declare class Kakidash extends TypedEventEmitter<KakidashEventMap> {
77
97
  getRootId(): string;
78
98
  }
79
99
 
100
+ declare type KakidashCommandArgs = {
101
+ name: string;
102
+ args?: any;
103
+ };
104
+
80
105
  export declare type KakidashEventMap = {
81
106
  'node:select': string | null;
82
107
  'node:add': {
@@ -95,6 +120,7 @@ export declare type KakidashEventMap = {
95
120
  };
96
121
  'model:load': MindMapData;
97
122
  'model:change': void;
123
+ command: KakidashCommandArgs;
98
124
  };
99
125
 
100
126
  export declare interface KakidashOptions {
@@ -108,9 +134,15 @@ export declare interface KakidashOptions {
108
134
  * Custom styles to apply to the mind map initially.
109
135
  */
110
136
  customStyles?: MindMapStyles;
137
+ /**
138
+ * Optional handler for file I/O operations.
139
+ * If provided, this handler will be used instead of default browser DOM APIs
140
+ * for importing and exporting files.
141
+ */
142
+ fileHandler?: FileHandler;
111
143
  }
112
144
 
113
- declare interface KeyBinding {
145
+ export declare interface KeyBinding {
114
146
  key: string;
115
147
  ctrlKey?: boolean;
116
148
  metaKey?: boolean;
@@ -140,7 +172,7 @@ export declare interface MindMapData {
140
172
  selectedId?: string;
141
173
  }
142
174
 
143
- declare interface MindMapNodeData {
175
+ export declare interface MindMapNodeData {
144
176
  id: string;
145
177
  topic: string;
146
178
  style?: {
@@ -163,7 +195,7 @@ declare interface MindMapNodeData {
163
195
  customWidth?: number;
164
196
  }
165
197
 
166
- declare interface MindMapStyles {
198
+ export declare interface MindMapStyles {
167
199
  rootNode?: {
168
200
  border?: string;
169
201
  background?: string;
@@ -208,8 +240,9 @@ declare class Node_2 {
208
240
  removeChild(nodeId: string): void;
209
241
  updateTopic(topic: string): void;
210
242
  }
243
+ export { Node_2 as Node }
211
244
 
212
- declare interface NodeStyle {
245
+ export declare interface NodeStyle {
213
246
  color?: string;
214
247
  background?: string;
215
248
  fontSize?: string;
@@ -217,11 +250,20 @@ declare interface NodeStyle {
217
250
  fontStyle?: string;
218
251
  }
219
252
 
220
- 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';
253
+ 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';
221
254
 
222
255
  export declare type ShortcutConfig = Partial<Record<ShortcutAction, KeyBinding[]>>;
223
256
 
224
- declare type Theme = 'default' | 'simple' | 'colorful' | 'custom';
257
+ export declare class SvgGenerator {
258
+ /**
259
+ * Generates an SVG string representation of the mind map content within the given container.
260
+ * @param container The element containing the mind map layers.
261
+ * @returns A string containing the serialized SVG.
262
+ */
263
+ generate(container: HTMLElement): string;
264
+ }
265
+
266
+ export declare type Theme = 'default' | 'simple' | 'colorful' | 'custom';
225
267
 
226
268
  declare class TypedEventEmitter<EventMap extends Record<string, any>> {
227
269
  private listeners;
@@ -232,4 +274,11 @@ declare class TypedEventEmitter<EventMap extends Record<string, any>> {
232
274
  protected emit<K extends keyof EventMap>(event: K, payload: EventMap[K]): void;
233
275
  }
234
276
 
277
+ export declare class XMindImporter {
278
+ private idGenerator;
279
+ constructor();
280
+ extractMindMapData(data: ArrayBuffer | Blob | Uint8Array | string): Promise<MindMapData>;
281
+ private transformTopic;
282
+ }
283
+
235
284
  export { }