kakidash 0.0.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 hiroooo000
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.ja.md ADDED
@@ -0,0 +1,216 @@
1
+ [English](./README.md)
2
+
3
+ # kakidash
4
+
5
+ Mindmap Typescript/Javascript Library.
6
+
7
+ ## Concept
8
+
9
+ **「思考を、ダッシュで書き出す」**
10
+
11
+ Kakidashのミッションは、**アウトプット速度の最大化**です。
12
+
13
+ 脳内に浮かぶ膨大な思考やアイデアを、ボトルネックなくすべて書き出し切るために。
14
+
15
+ キーボードショートカットを駆使し、思考のスピードでマインドマップを広げていく体験を提供します。
16
+
17
+ ## Features
18
+
19
+ - **マインドマップ作成**: ノードの追加、兄弟ノード、子ノードの操作
20
+ - **レイアウト**: 標準 (Standard/Both)、左揃え (Left)、右揃え (Right)
21
+ - **スタイリング**:
22
+ - フォントサイズ変更
23
+ - 太字 (Bold)、斜体 (Italic)
24
+ - カラーパレットによる色変更 (Style Editor)
25
+ - **インタラクション**:
26
+ - ドラッグ&ドロップによるノード移動・並び替え
27
+ - キーボードショートカットによる高速操作
28
+ - ズーム、パン (画面移動)
29
+ - **画像対応**: クリップボードからの画像貼り付け
30
+ - **インポート/エクスポート**: JSON形式でのデータ保存・読み込み
31
+ - **開発者向け**:
32
+ - TypeScript対応
33
+ - 読み取り専用 (Read-only) モード
34
+ - イベントシステム
35
+
36
+ ## Installation
37
+
38
+ ```bash
39
+ npm install kakidash
40
+ ```
41
+
42
+ ## Usage
43
+
44
+ ### 1. HTMLの準備
45
+
46
+ `kakidash` を表示するためのコンテナ要素 (`div` など) を用意します。
47
+ **重要**: コンテナには必ず `width` と `height` を CSS で指定してください。
48
+
49
+ ```html
50
+ <!DOCTYPE html>
51
+ <html lang="ja">
52
+ <head>
53
+ <meta charset="UTF-8">
54
+ <title>Kakidash Demo</title>
55
+ <style>
56
+ /* コンテナのサイズ指定は必須です */
57
+ #mindmap-container {
58
+ width: 100vw;
59
+ height: 100vh;
60
+ border: 1px solid #ccc; /* 境界線はお好みで */
61
+ margin: 0;
62
+ padding: 0;
63
+ overflow: hidden; /* コンテナ内でのスクロールを防ぐため */
64
+ }
65
+ body { margin: 0; }
66
+ </style>
67
+ </head>
68
+ <body>
69
+ <div id="mindmap-container"></div>
70
+ <!-- Script挿入場所 -->
71
+ </body>
72
+ </html>
73
+ ```
74
+
75
+ ### 2. ライブラリの読み込みと初期化
76
+
77
+ #### A. NPM プロジェクト (Vite / Webpack など)
78
+
79
+ ```bash
80
+ npm install kakidash
81
+ ```
82
+
83
+ ```typescript
84
+ import { Kakidash } from 'kakidash';
85
+
86
+ // コンテナ取得
87
+ const container = document.getElementById('mindmap-container');
88
+
89
+ // インスタンス化
90
+ const board = new Kakidash(container);
91
+
92
+ // 必要に応じて初期データをロードしたり、ノードを追加したりします
93
+ board.addNode(board.getRootId(), 'Hello World');
94
+ ```
95
+
96
+ #### B. ブラウザ直接読み込み (Script Tag / CDN)
97
+
98
+ ビルド済みの `umd` ファイルを使用します。
99
+ グローバル変数 `window.kakidash` にライブラリが格納されます。
100
+
101
+ ```html
102
+ <!-- ローカルのビルド済みファイルを読み込む場合 -->
103
+ <script src="./dist/kakidash.umd.js"></script>
104
+
105
+ <!-- または CDN (例: unpkg) 経由 (パッケージ公開後) -->
106
+ <!-- <script src="https://unpkg.com/kakidash/dist/kakidash.umd.js"></script> -->
107
+
108
+ <script>
109
+ // UMDビルドでは window.kakidash オブジェクトの下にクラスがエクスポートされます
110
+ const { Kakidash } = window.kakidash;
111
+
112
+ // 初期化
113
+ const container = document.getElementById('mindmap-container');
114
+ const board = new Kakidash(container);
115
+
116
+ // 動作確認
117
+ console.log('Kakidash initialized:', board);
118
+ </script>
119
+ ```
120
+
121
+ ## API Reference
122
+
123
+ ### Methods
124
+
125
+ - **`new Kakidash(container: HTMLElement)`**: インスタンスを生成します。
126
+ - **`board.addNode(parentId, topic)`**: 指定した親ノードに新しい子ノードを追加します。
127
+ - **`board.getData()`**: 現在のマインドマップデータをJSONオブジェクトとして取得します。
128
+ - **`board.loadData(data)`**: JSONデータを読み込み、マインドマップを描画します。
129
+ - **`board.updateLayout(mode)`**: レイアウトモードを変更します ('Standard', 'Left', 'Right')。
130
+ - **`board.setReadOnly(boolean)`**: 読み取り専用モードを切り替えます。
131
+
132
+ ### Events
133
+
134
+ ```typescript
135
+ board.on('node:select', (nodeId) => {
136
+ console.log('Selected:', nodeId);
137
+ });
138
+
139
+ board.on('node:add', (payload) => {
140
+ console.log('Added:', payload);
141
+ });
142
+
143
+ board.on('model:change', () => {
144
+ console.log('Data changed');
145
+ });
146
+ ```
147
+
148
+ ## Shortcuts
149
+
150
+ ### General
151
+ | Key | Description |
152
+ | --- | --- |
153
+ | `Arrow Keys` | ノード間の移動 |
154
+ | `h` / `j` / `k` / `l` | ノード間の移動 (Vim風) |
155
+ | `F2` / `DblClick` | ノードの編集を開始 |
156
+ | `Enter` | 兄弟ノードを追加 (下) |
157
+ | `Shift + Enter` | 兄弟ノードを追加 (上) |
158
+ | `Tab` | 子ノードを追加 |
159
+ | `Shift + Tab` | 親ノードを挿入 |
160
+ | `Delete` / `Backspace` | ノードを削除 |
161
+ | `Ctrl/Cmd + Z` | 元に戻す (Undo) |
162
+ | `Ctrl/Cmd + C` | コピー |
163
+ | `Ctrl/Cmd + X` | 切り取り |
164
+ | `Ctrl/Cmd + V` | 貼り付け (画像も可) |
165
+ | `Drag` (Canvas) | 画面のパン (移動) |
166
+ | `Wheel` | 上下スクロール (パン) |
167
+ | `Shift + Wheel` | 左右スクロール (パン) |
168
+ | `Ctrl/Cmd + Wheel` | ズームイン/アウト |
169
+
170
+ ### Editing (Text Input)
171
+ | Key | Description |
172
+ | --- | --- |
173
+ | `Enter` | 編集を確定 |
174
+ | `Shift + Enter` | 改行 |
175
+ | `Esc` | 編集をキャンセル |
176
+
177
+ ### Styling (Since selection)
178
+ | Key | Description |
179
+ | --- | --- |
180
+ | `Ctrl/Cmd + B` | 太字 (Bold) 切り替え |
181
+ | `Ctrl/Cmd + I` | 斜体 (Italic) 切り替え |
182
+ | `+` | フォントサイズ拡大 |
183
+ | `-` | フォントサイズ縮小 |
184
+ | `1` - `7` | ノードの色を変更 (パレット順) |
185
+
186
+ ## Development
187
+
188
+ ### Setup
189
+
190
+ ```bash
191
+ npm install
192
+ ```
193
+
194
+ ### Dev Server
195
+
196
+ ```bash
197
+ npm run dev
198
+ ```
199
+
200
+ ### Build
201
+
202
+ ```bash
203
+ npm run build
204
+ ```
205
+
206
+ ### Test
207
+
208
+ ```bash
209
+ npm test
210
+ ```
211
+
212
+ ### Lint
213
+
214
+ ```bash
215
+ npm run lint
216
+ ```
package/README.md ADDED
@@ -0,0 +1,211 @@
1
+ [日本語](./README.ja.md)
2
+
3
+ # kakidash
4
+
5
+ Mindmap Typescript / Javascript Library.
6
+
7
+ ## Concept
8
+
9
+ **"Dash through your thoughts"**
10
+
11
+ Kakidash's mission is to **maximize output speed**.
12
+ It is designed to capture every fleeing thought and vast idea without bottlenecks.
13
+ Master the shortcuts and expand your mind map at the speed of thought.
14
+
15
+ ## Features
16
+
17
+ - **Mindmap Creation**: Add nodes, manipulate siblings and child nodes.
18
+ - **Layouts**: Standard (Standard/Both), Left aligned (Left), Right aligned (Right).
19
+ - **Styling**:
20
+ - Font size adjustment.
21
+ - Bold (`Bold`), Italic (`Italic`).
22
+ - Color changes via palette (Style Editor).
23
+ - **Interaction**:
24
+ - Drag and drop for node movement and reordering.
25
+ - Keyboard shortcuts for rapid operation.
26
+ - Zoom, Pan (Screen navigation).
27
+ - **Image Support**: Paste images from the clipboard.
28
+ - **Import/Export**: Save and load data in JSON format.
29
+ - **For Developers**:
30
+ - TypeScript support.
31
+ - Read-only mode.
32
+ - Event system.
33
+
34
+ ## Installation
35
+
36
+ ```bash
37
+ npm install kakidash
38
+ ```
39
+
40
+ ## Usage
41
+ ### 1. HTML Preparation
42
+
43
+ Prepare a container element (e.g., `div`) to display `kakidash`.
44
+ **Important**: You MUST specify `width` and `height` for the container via CSS.
45
+
46
+ ```html
47
+ <!DOCTYPE html>
48
+ <html lang="en">
49
+ <head>
50
+ <meta charset="UTF-8">
51
+ <title>Kakidash Demo</title>
52
+ <style>
53
+ /* Container size is required */
54
+ #mindmap-container {
55
+ width: 100vw;
56
+ height: 100vh;
57
+ border: 1px solid #ccc;
58
+ margin: 0;
59
+ padding: 0;
60
+ overflow: hidden; /* Prevent scrolling within container */
61
+ }
62
+ body { margin: 0; }
63
+ </style>
64
+ </head>
65
+ <body>
66
+ <div id="mindmap-container"></div>
67
+ <!-- Script Injection Here -->
68
+ </body>
69
+ </html>
70
+ ```
71
+
72
+ ### 2. Loading and Initialization
73
+
74
+ #### A. NPM Project (Vite / Webpack etc.)
75
+
76
+ ```bash
77
+ npm install kakidash
78
+ ```
79
+
80
+ ```typescript
81
+ import { Kakidash } from 'kakidash';
82
+
83
+ // Get container
84
+ const container = document.getElementById('mindmap-container');
85
+
86
+ // Instantiate
87
+ const board = new Kakidash(container);
88
+
89
+ // Add initial data or nodes if needed
90
+ board.addNode(board.getRootId(), 'Hello World');
91
+ ```
92
+
93
+ #### B. Browser Direct Import (Script Tag / CDN)
94
+
95
+ Use the built `umd` file. The library will be exposed under the global variable `window.kakidash`.
96
+
97
+ ```html
98
+ <!-- Load local built file -->
99
+ <script src="./dist/kakidash.umd.js"></script>
100
+
101
+ <!-- Or via CDN (e.g. unpkg) once published -->
102
+ <!-- <script src="https://unpkg.com/kakidash/dist/kakidash.umd.js"></script> -->
103
+
104
+ <script>
105
+ // In UMD build, classes are exported under window.kakidash object
106
+ const { Kakidash } = window.kakidash;
107
+
108
+ // Initialize
109
+ const container = document.getElementById('mindmap-container');
110
+ const board = new Kakidash(container);
111
+
112
+ console.log('Kakidash initialized:', board);
113
+ </script>
114
+ ```
115
+
116
+ ## API Reference
117
+
118
+ ### Methods
119
+
120
+ - **`new Kakidash(container: HTMLElement)`**: Creates a new instance.
121
+ - **`board.addNode(parentId, topic)`**: Adds a new child node to the specified parent node.
122
+ - **`board.getData()`**: Retrieves current mindmap data as a JSON object.
123
+ - **`board.loadData(data)`**: Loads JSON data and renders the mindmap.
124
+ - **`board.updateLayout(mode)`**: Changes layout mode ('Standard', 'Left', 'Right').
125
+ - **`board.setReadOnly(boolean)`**: Toggles read-only mode.
126
+
127
+ ### Events
128
+
129
+ ```typescript
130
+ board.on('node:select', (nodeId) => {
131
+ console.log('Selected:', nodeId);
132
+ });
133
+
134
+ board.on('node:add', (payload) => {
135
+ console.log('Added:', payload);
136
+ });
137
+
138
+ board.on('model:change', () => {
139
+ console.log('Data changed');
140
+ });
141
+ ```
142
+
143
+ ## Shortcuts
144
+
145
+ ### General
146
+ | Key | Description |
147
+ | --- | --- |
148
+ | `Arrow Keys` | Navigate between nodes |
149
+ | `h` / `j` / `k` / `l` | Navigate between nodes (Vim-style) |
150
+ | `F2` / `DblClick` | Start editing node |
151
+ | `Enter` | Add sibling node (below) |
152
+ | `Shift + Enter` | Add sibling node (above) |
153
+ | `Tab` | Add child node |
154
+ | `Shift + Tab` | Insert parent node |
155
+ | `Delete` / `Backspace` | Delete node |
156
+ | `Ctrl/Cmd + Z` | Undo |
157
+ | `Ctrl/Cmd + C` | Copy |
158
+ | `Ctrl/Cmd + X` | Cut |
159
+ | `Ctrl/Cmd + V` | Paste (Images supported) |
160
+ | `Drag` (Canvas) | Pan screen |
161
+ | `Wheel` | Vertical scroll (Pan) |
162
+ | `Shift + Wheel` | Horizontal scroll (Pan) |
163
+ | `Ctrl/Cmd + Wheel` | Zoom in/out |
164
+
165
+ ### Editing (Text Input)
166
+ | Key | Description |
167
+ | --- | --- |
168
+ | `Enter` | Confirm edit |
169
+ | `Shift + Enter` | New line |
170
+ | `Esc` | Cancel edit |
171
+
172
+ ### Styling (Since selection)
173
+ | Key | Description |
174
+ | --- | --- |
175
+ | `Ctrl/Cmd + B` | Toggle Bold |
176
+ | `Ctrl/Cmd + I` | Toggle Italic |
177
+ | `+` | Increase font size |
178
+ | `-` | Decrease font size |
179
+ | `1` - `7` | Change node color (Palette order) |
180
+
181
+ ## Development
182
+
183
+ ### Setup
184
+
185
+ ```bash
186
+ npm install
187
+ ```
188
+
189
+ ### Dev Server
190
+
191
+ ```bash
192
+ npm run dev
193
+ ```
194
+
195
+ ### Build
196
+
197
+ ```bash
198
+ npm run build
199
+ ```
200
+
201
+ ### Test
202
+
203
+ ```bash
204
+ npm test
205
+ ```
206
+
207
+ ### Lint
208
+
209
+ ```bash
210
+ npm run lint
211
+ ```
@@ -0,0 +1,190 @@
1
+ declare type Direction = 'Up' | 'Down' | 'Left' | 'Right';
2
+
3
+ export declare class Kakidash extends TypedEventEmitter<KakidashEventMap> {
4
+ private mindMap;
5
+ private service;
6
+ private renderer;
7
+ private interactionHandler;
8
+ private styleEditor;
9
+ private layoutSwitcher;
10
+ private layoutMode;
11
+ private selectedNodeId;
12
+ private panX;
13
+ private panY;
14
+ private targetPanX;
15
+ private targetPanY;
16
+ private scale;
17
+ private isBatching;
18
+ private animationFrameId;
19
+ constructor(container: HTMLElement);
20
+ /**
21
+ * Adds a new child node to the specified parent.
22
+ * This is a pure data operation and does not trigger UI actions like auto-focus or scroll.
23
+ */
24
+ addNode(parentId: string, topic?: string, layoutSide?: 'left' | 'right'): Node_2 | null;
25
+ /**
26
+ * Adds a sibling node relative to the reference node.
27
+ * This is a pure data operation.
28
+ */
29
+ addSibling(referenceId: string, position?: 'before' | 'after', topic?: string): Node_2 | null;
30
+ /**
31
+ * Inserts a parent node above the specified node.
32
+ * This is a pure data operation.
33
+ */
34
+ insertParent(targetId: string, topic?: string): Node_2 | null;
35
+ /**
36
+ * Removes a node.
37
+ * This is a pure data operation.
38
+ * (Previously removeNode, keeping alias or usage consistent)
39
+ */
40
+ deleteNode(nodeId: string): void;
41
+ /**
42
+ * Updates a node's topic or style.
43
+ * This is a pure data operation.
44
+ */
45
+ /**
46
+ * Updates a node's topic or style.
47
+ * This is a pure data operation.
48
+ */
49
+ updateNode(nodeId: string, updates: {
50
+ topic?: string;
51
+ style?: Partial<NodeStyle>;
52
+ }): void;
53
+ updateNodeStyle(nodeId: string, style: Partial<NodeStyle>): void;
54
+ setTheme(theme: Theme): void;
55
+ getMindMap(): MindMap;
56
+ getNode(nodeId: string): Node_2 | undefined;
57
+ getRoot(): Node_2;
58
+ findNodes(predicate: (node: Node_2) => boolean): Node_2[];
59
+ setReadOnly(readOnly: boolean): void;
60
+ destroy(): void;
61
+ batch(callback: () => void): void;
62
+ addChildNode(parentId: string): void;
63
+ addSiblingNode(nodeId: string, position?: 'before' | 'after'): void;
64
+ insertParentNode(nodeId: string): void;
65
+ /**
66
+ * Wrapper for deleteNode that handles selection update (Interaction concern).
67
+ */
68
+ removeNode(nodeId: string): void;
69
+ /**
70
+ * Helper to ensure sides are locked when modifying Root children in Both mode.
71
+ * (Kept as private helper for internal use)
72
+ */
73
+ private ensureExplicitLayoutSides;
74
+ moveNode(nodeId: string, targetId: string, position: 'top' | 'bottom' | 'left' | 'right'): void;
75
+ updateNodeTopic(nodeId: string, topic: string): void;
76
+ selectNode(nodeId: string | null): void;
77
+ panBoard(dx: number, dy: number): void;
78
+ zoomBoard(delta: number, clientX: number, clientY: number): void;
79
+ resetZoom(): void;
80
+ copyNode(nodeId: string): void;
81
+ pasteNode(parentId: string): void;
82
+ pasteImage(parentId: string, imageData: string): void;
83
+ cutNode(nodeId: string): void;
84
+ private render;
85
+ updateLayout(mode: 'Standard' | 'Left' | 'Right'): void;
86
+ setLayoutMode(mode: LayoutMode): void;
87
+ getLayoutMode(): LayoutMode;
88
+ navigateNode(nodeId: string, direction: Direction): void;
89
+ getData(): MindMapData;
90
+ loadData(data: MindMapData): void;
91
+ getRootId(): string;
92
+ private getNodeDirection;
93
+ private startAnimationLoop;
94
+ private ensureNodeVisible;
95
+ }
96
+
97
+ export declare type KakidashEventMap = {
98
+ 'node:select': string | null;
99
+ 'node:add': {
100
+ id: string;
101
+ topic: string;
102
+ };
103
+ 'node:remove': string;
104
+ 'node:update': {
105
+ id: string;
106
+ topic: string;
107
+ };
108
+ 'node:move': {
109
+ nodeId: string;
110
+ newParentId: string;
111
+ position?: string;
112
+ };
113
+ 'model:load': MindMapData;
114
+ 'model:change': void;
115
+ };
116
+
117
+ export declare type LayoutMode = 'Right' | 'Left' | 'Both';
118
+
119
+ declare class MindMap {
120
+ root: Node_2;
121
+ theme: Theme;
122
+ constructor(rootNode: Node_2);
123
+ findNode(id: string): Node_2 | null;
124
+ private findNodeRecursive;
125
+ moveNode(nodeId: string, newParentId: string): boolean;
126
+ addSibling(referenceId: string, newNode: Node_2, position: 'before' | 'after'): boolean;
127
+ insertParent(targetId: string, newParentNode: Node_2): boolean;
128
+ private isDescendant;
129
+ }
130
+
131
+ export declare interface MindMapData {
132
+ nodeData: MindMapNodeData;
133
+ linkData?: any;
134
+ theme?: Theme;
135
+ direction?: number;
136
+ }
137
+
138
+ declare interface MindMapNodeData {
139
+ id: string;
140
+ topic: string;
141
+ style?: {
142
+ fontSize?: string;
143
+ color?: string;
144
+ background?: string;
145
+ fontWeight?: string;
146
+ };
147
+ children?: MindMapNodeData[];
148
+ root?: boolean;
149
+ expanded?: boolean;
150
+ parentId?: string;
151
+ image?: string;
152
+ layoutSide?: 'left' | 'right';
153
+ }
154
+
155
+ declare class Node_2 {
156
+ id: string;
157
+ topic: string;
158
+ children: Node_2[];
159
+ style: NodeStyle;
160
+ parentId: string | null;
161
+ isRoot: boolean;
162
+ image?: string;
163
+ layoutSide?: 'left' | 'right';
164
+ constructor(id: string, topic: string, parentId?: string | null, isRoot?: boolean, image?: string, layoutSide?: 'left' | 'right');
165
+ addChild(node: Node_2): void;
166
+ insertChild(node: Node_2, index: number): void;
167
+ removeChild(nodeId: string): void;
168
+ updateTopic(topic: string): void;
169
+ }
170
+
171
+ declare interface NodeStyle {
172
+ color?: string;
173
+ background?: string;
174
+ fontSize?: string;
175
+ fontWeight?: string;
176
+ fontStyle?: string;
177
+ }
178
+
179
+ declare type Theme = 'default' | 'simple' | 'colorful';
180
+
181
+ declare class TypedEventEmitter<EventMap extends Record<string, any>> {
182
+ private listeners;
183
+ on<K extends keyof EventMap>(event: K, listener: (payload: EventMap[K]) => void): void;
184
+ addListener<K extends keyof EventMap>(event: K, listener: (payload: EventMap[K]) => void): void;
185
+ off<K extends keyof EventMap>(event: K, listener: (payload: EventMap[K]) => void): void;
186
+ removeListener<K extends keyof EventMap>(event: K, listener: (payload: EventMap[K]) => void): void;
187
+ protected emit<K extends keyof EventMap>(event: K, payload: EventMap[K]): void;
188
+ }
189
+
190
+ export { }