@ankorar/nodex 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/README.md +228 -0
- package/package.json +54 -0
- package/src/components/mindMap/Background.tsx +39 -0
- package/src/components/mindMap/Board.tsx +159 -0
- package/src/components/mindMap/CentalNode.tsx +121 -0
- package/src/components/mindMap/DefaultNode.tsx +205 -0
- package/src/components/mindMap/Header.tsx +247 -0
- package/src/components/mindMap/ImageNode.tsx +345 -0
- package/src/components/mindMap/KeyboardHelpDialog.tsx +108 -0
- package/src/components/mindMap/MineMap.tsx +237 -0
- package/src/components/mindMap/NodeStylePopover.tsx +486 -0
- package/src/components/mindMap/Nodes.tsx +113 -0
- package/src/components/mindMap/Nodex.tsx +65 -0
- package/src/components/mindMap/SaveStatusIndicator.tsx +61 -0
- package/src/components/mindMap/Segments.tsx +270 -0
- package/src/components/mindMap/ZenCard.tsx +41 -0
- package/src/components/ui/dialog.tsx +141 -0
- package/src/components/ui/popover.tsx +46 -0
- package/src/components/ui/select.tsx +192 -0
- package/src/components/ui/toggle-group.tsx +83 -0
- package/src/components/ui/toggle.tsx +45 -0
- package/src/config/rootKeyBinds.ts +191 -0
- package/src/config/shortCuts.ts +28 -0
- package/src/contexts/MindMapNodeEditorContext.tsx +47 -0
- package/src/handlers/rootKeyBinds/handleAltEKeyBind.ts +6 -0
- package/src/handlers/rootKeyBinds/handleAltHKeyBind.ts +6 -0
- package/src/handlers/rootKeyBinds/handleAltWKeyBind.ts +6 -0
- package/src/handlers/rootKeyBinds/handleAltZKeyBind.ts +6 -0
- package/src/handlers/rootKeyBinds/handleArrowHorizontalRootKeyBind.ts +46 -0
- package/src/handlers/rootKeyBinds/handleArrowVerticalRootKeyBind.ts +44 -0
- package/src/handlers/rootKeyBinds/handleBackEspaceKeyBind.ts +12 -0
- package/src/handlers/rootKeyBinds/handleERootKeyBind.ts +16 -0
- package/src/handlers/rootKeyBinds/handleEnterRootKeyBind.ts +35 -0
- package/src/handlers/rootKeyBinds/handleEscapeKeyBind.ts +24 -0
- package/src/handlers/rootKeyBinds/handleEspaceKeyBind.ts +11 -0
- package/src/handlers/rootKeyBinds/handleMoveByWorldKeyBind.ts +6 -0
- package/src/handlers/rootKeyBinds/handleRedoRootKeyBind.ts +23 -0
- package/src/handlers/rootKeyBinds/handleTabRootKeyBind.ts +49 -0
- package/src/handlers/rootKeyBinds/handleTransformNodeKeyBind.ts +39 -0
- package/src/handlers/rootKeyBinds/handleUndoRootKeyBind.ts +23 -0
- package/src/handlers/rootKeyBinds/handleZoonByKeyBind.ts +31 -0
- package/src/helpers/centerNode.ts +19 -0
- package/src/helpers/getNodeSide.ts +16 -0
- package/src/hooks/mindMap/useHelpers.tsx +9 -0
- package/src/hooks/mindMap/useMindMapDebounce.ts +47 -0
- package/src/hooks/mindMap/useMindMapHistoryDebounce.ts +69 -0
- package/src/hooks/mindMap/useMindMapNode.tsx +203 -0
- package/src/hooks/mindMap/useMindMapNodeEditor.ts +91 -0
- package/src/hooks/mindMap/useMindMapNodeMouseHandlers.ts +24 -0
- package/src/hooks/mindMap/useRootKeyBindHandlers.ts +49 -0
- package/src/hooks/mindMap/useRootMouseHandlers.ts +124 -0
- package/src/hooks/mindMap/useUpdateCenter.ts +54 -0
- package/src/index.ts +76 -0
- package/src/lib/utils.ts +6 -0
- package/src/state/mindMap.ts +793 -0
- package/src/state/mindMapHistory.ts +96 -0
- package/src/styles.input.css +95 -0
- package/src/utils/exportMindMapAsHighQualityImage.ts +327 -0
- package/src/utils/exportMindMapAsMarkdown.ts +102 -0
- package/src/utils/exportMindMapAsPdf.ts +241 -0
- package/src/utils/getMindMapPreviewDataUrl.ts +60 -0
- package/styles.css +2 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { FocusEvent, FormEvent, RefObject } from "react";
|
|
2
|
+
import { useLayoutEffect } from "react";
|
|
3
|
+
import { useMindMapState } from "../../state/mindMap";
|
|
4
|
+
import { useMindMapNode } from "./useMindMapNode";
|
|
5
|
+
import { useShallow } from "zustand/react/shallow";
|
|
6
|
+
|
|
7
|
+
type UseMindMapNodeEditorParams = {
|
|
8
|
+
nodeId: string;
|
|
9
|
+
text: string;
|
|
10
|
+
textRef: RefObject<HTMLElement | null>;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type UseMindMapNodeEditorResult = {
|
|
14
|
+
onFocus: () => void;
|
|
15
|
+
onBlur: (event: FocusEvent<HTMLElement>) => void;
|
|
16
|
+
onInput: (event: FormEvent<HTMLElement>) => void;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export function useMindMapNodeEditor({
|
|
20
|
+
nodeId,
|
|
21
|
+
text,
|
|
22
|
+
textRef,
|
|
23
|
+
}: UseMindMapNodeEditorParams): UseMindMapNodeEditorResult {
|
|
24
|
+
const { node } = useMindMapNode({ nodeId });
|
|
25
|
+
const { editingNodeId, setEditingNode, readOnly } = useMindMapState(
|
|
26
|
+
useShallow((state) => ({
|
|
27
|
+
editingNodeId: state.editingNodeId,
|
|
28
|
+
setEditingNode: state.setEditingNode,
|
|
29
|
+
readOnly: state.readOnly,
|
|
30
|
+
})),
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
const isEditing = editingNodeId === nodeId;
|
|
34
|
+
|
|
35
|
+
useLayoutEffect(() => {
|
|
36
|
+
const element = textRef.current;
|
|
37
|
+
if (!element) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (!isEditing && element.textContent !== text) {
|
|
41
|
+
element.textContent = text;
|
|
42
|
+
}
|
|
43
|
+
}, [text, textRef, isEditing]);
|
|
44
|
+
|
|
45
|
+
useLayoutEffect(() => {
|
|
46
|
+
const element = textRef.current;
|
|
47
|
+
if (!element || !isEditing) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const focusText = () => {
|
|
51
|
+
element.focus();
|
|
52
|
+
const selection = window.getSelection();
|
|
53
|
+
if (!selection) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const range = document.createRange();
|
|
57
|
+
range.selectNodeContents(element);
|
|
58
|
+
range.collapse(false);
|
|
59
|
+
selection.removeAllRanges();
|
|
60
|
+
selection.addRange(range);
|
|
61
|
+
};
|
|
62
|
+
requestAnimationFrame(focusText);
|
|
63
|
+
}, [isEditing, textRef]);
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
onFocus: () => {
|
|
67
|
+
node?.select();
|
|
68
|
+
if (!readOnly) {
|
|
69
|
+
node?.edit();
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
onBlur: () => {
|
|
73
|
+
setEditingNode(null);
|
|
74
|
+
},
|
|
75
|
+
onInput: (event) => {
|
|
76
|
+
if (readOnly) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (!node) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const element = (event.currentTarget ??
|
|
84
|
+
textRef.current) as HTMLElement | null;
|
|
85
|
+
node
|
|
86
|
+
.chain()
|
|
87
|
+
.updateText(element?.textContent ?? "")
|
|
88
|
+
.commit();
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type MouseEvent } from "react";
|
|
2
|
+
import { useMindMapNode } from "./useMindMapNode";
|
|
3
|
+
import { useMindMapState } from "../../state/mindMap";
|
|
4
|
+
|
|
5
|
+
export function useMindMapNodeMouseHandlers(nodeId: string) {
|
|
6
|
+
const { node } = useMindMapNode({ nodeId });
|
|
7
|
+
const readOnly = useMindMapState((state) => state.readOnly);
|
|
8
|
+
|
|
9
|
+
return {
|
|
10
|
+
onMouseDown: (event: MouseEvent<HTMLDivElement>) => {
|
|
11
|
+
event.stopPropagation();
|
|
12
|
+
if (!readOnly) {
|
|
13
|
+
node?.select();
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
onDoubleClick: (event: MouseEvent<HTMLDivElement>) => {
|
|
17
|
+
event.stopPropagation();
|
|
18
|
+
if (!readOnly) {
|
|
19
|
+
node?.select();
|
|
20
|
+
node?.edit();
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import { useShallow } from "zustand/react/shallow";
|
|
3
|
+
import { useMindMapState } from "../../state/mindMap";
|
|
4
|
+
import { type RootKeyBinds, rootKeyBinds } from "../../config/rootKeyBinds";
|
|
5
|
+
|
|
6
|
+
export function useRootKeyBindHandlers() {
|
|
7
|
+
const { editingNodeId, readOnly } = useMindMapState(
|
|
8
|
+
useShallow((state) => ({
|
|
9
|
+
editingNodeId: state.editingNodeId,
|
|
10
|
+
readOnly: state.readOnly,
|
|
11
|
+
}))
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
const handleKeyDown = (e: KeyboardEvent) => {
|
|
16
|
+
if (readOnly) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const isEditing = !!editingNodeId;
|
|
21
|
+
let key = e.key;
|
|
22
|
+
|
|
23
|
+
if (e.ctrlKey) {
|
|
24
|
+
key = "Ctrl+" + e.key;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (e.altKey) {
|
|
28
|
+
key = "Alt+" + e.key;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const keyBind = rootKeyBinds[key as RootKeyBinds];
|
|
32
|
+
|
|
33
|
+
if (keyBind?.skipOnEditing && isEditing) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (keyBind?.handler) {
|
|
38
|
+
e.preventDefault();
|
|
39
|
+
keyBind.handler();
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const listenerOptions = { capture: true };
|
|
44
|
+
document.addEventListener("keydown", handleKeyDown, listenerOptions);
|
|
45
|
+
return () => {
|
|
46
|
+
document.removeEventListener("keydown", handleKeyDown, listenerOptions);
|
|
47
|
+
};
|
|
48
|
+
}, [editingNodeId, readOnly]);
|
|
49
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
MouseEvent,
|
|
3
|
+
RefObject,
|
|
4
|
+
WheelEvent as WheelReactEvent,
|
|
5
|
+
} from "react";
|
|
6
|
+
import { useEffect, useRef, useState } from "react";
|
|
7
|
+
|
|
8
|
+
import { useMindMapState } from "../../state/mindMap";
|
|
9
|
+
import { useShallow } from "zustand/react/shallow";
|
|
10
|
+
|
|
11
|
+
interface UseRootMouseHandlersProps {
|
|
12
|
+
rootRef: RefObject<HTMLDivElement | null>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function useRootMouseHandlers({ rootRef }: UseRootMouseHandlersProps) {
|
|
16
|
+
const {
|
|
17
|
+
offset,
|
|
18
|
+
scale,
|
|
19
|
+
clampScale,
|
|
20
|
+
setScale,
|
|
21
|
+
setOffset,
|
|
22
|
+
setSelectedNode,
|
|
23
|
+
setEditingNode,
|
|
24
|
+
selectedNodeId,
|
|
25
|
+
helpOpen,
|
|
26
|
+
} = useMindMapState(
|
|
27
|
+
useShallow((state) => ({
|
|
28
|
+
offset: state.offset,
|
|
29
|
+
scale: state.scale,
|
|
30
|
+
clampScale: state.clampScale,
|
|
31
|
+
setScale: state.setScale,
|
|
32
|
+
setOffset: state.setOffset,
|
|
33
|
+
setSelectedNode: state.setSelectedNode,
|
|
34
|
+
setEditingNode: state.setEditingNode,
|
|
35
|
+
selectedNodeId: state.selectedNodeId,
|
|
36
|
+
helpOpen: state.helpOpen,
|
|
37
|
+
})),
|
|
38
|
+
);
|
|
39
|
+
const isDraggingRef = useRef(false);
|
|
40
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
41
|
+
const dragStartRef = useRef({ x: 0, y: 0 });
|
|
42
|
+
const offsetStartRef = useRef({ x: 0, y: 0 });
|
|
43
|
+
|
|
44
|
+
const onWheel = (event: WheelReactEvent<HTMLDivElement>) => {
|
|
45
|
+
event.preventDefault();
|
|
46
|
+
if (helpOpen) return;
|
|
47
|
+
const zoomSpeed = event.ctrlKey ? 0.0005 : 0.0005;
|
|
48
|
+
const zoomDelta = -event.deltaY * zoomSpeed;
|
|
49
|
+
const nextScale = clampScale(scale + zoomDelta);
|
|
50
|
+
if (nextScale === scale) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const bounds = event.currentTarget.getBoundingClientRect();
|
|
54
|
+
const pointerX = event.clientX - bounds.left;
|
|
55
|
+
const pointerY = event.clientY - bounds.top;
|
|
56
|
+
const worldX = (pointerX - offset.x) / scale;
|
|
57
|
+
const worldY = (pointerY - offset.y) / scale;
|
|
58
|
+
const nextOffset = {
|
|
59
|
+
x: pointerX - worldX * nextScale,
|
|
60
|
+
y: pointerY - worldY * nextScale,
|
|
61
|
+
};
|
|
62
|
+
setScale(nextScale);
|
|
63
|
+
setOffset(nextOffset);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
const element = rootRef.current;
|
|
68
|
+
if (!element) return;
|
|
69
|
+
|
|
70
|
+
const handleWheel = (event: WheelEvent) => {
|
|
71
|
+
const e = event as unknown as WheelReactEvent<HTMLDivElement>;
|
|
72
|
+
onWheel(e);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
element.addEventListener("wheel", handleWheel, { passive: false });
|
|
76
|
+
|
|
77
|
+
return () => {
|
|
78
|
+
element.removeEventListener("wheel", handleWheel);
|
|
79
|
+
};
|
|
80
|
+
}, [onWheel]);
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
isDragging,
|
|
84
|
+
onMouseDown: (event: MouseEvent<HTMLDivElement>) => {
|
|
85
|
+
const target = event.target as Element | null;
|
|
86
|
+
const clickedNode = target?.closest?.("[data-nodex-node]");
|
|
87
|
+
const clickedUi = target?.closest?.("[data-nodex-ui]");
|
|
88
|
+
if (selectedNodeId && !clickedNode && !clickedUi) {
|
|
89
|
+
setSelectedNode(null);
|
|
90
|
+
setEditingNode(null);
|
|
91
|
+
}
|
|
92
|
+
if (clickedNode || clickedUi) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (event.button !== 0) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
isDraggingRef.current = true;
|
|
99
|
+
setIsDragging(true);
|
|
100
|
+
dragStartRef.current = { x: event.clientX, y: event.clientY };
|
|
101
|
+
offsetStartRef.current = { x: offset.x, y: offset.y };
|
|
102
|
+
},
|
|
103
|
+
onMouseMove: (event: MouseEvent<HTMLDivElement>) => {
|
|
104
|
+
if (!isDraggingRef.current) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const deltaX = event.clientX - dragStartRef.current.x;
|
|
108
|
+
const deltaY = event.clientY - dragStartRef.current.y;
|
|
109
|
+
setOffset({
|
|
110
|
+
x: offsetStartRef.current.x + deltaX,
|
|
111
|
+
y: offsetStartRef.current.y + deltaY,
|
|
112
|
+
});
|
|
113
|
+
},
|
|
114
|
+
onMouseUp: () => {
|
|
115
|
+
isDraggingRef.current = false;
|
|
116
|
+
setIsDragging(false);
|
|
117
|
+
},
|
|
118
|
+
onMouseLeave: () => {
|
|
119
|
+
isDraggingRef.current = false;
|
|
120
|
+
setIsDragging(false);
|
|
121
|
+
},
|
|
122
|
+
onWheel,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useMindMapState } from "../../state/mindMap";
|
|
2
|
+
import { type RefObject, useEffect } from "react";
|
|
3
|
+
import { useShallow } from "zustand/react/shallow";
|
|
4
|
+
import { useMindMapNode } from "./useMindMapNode";
|
|
5
|
+
import { useHelpers } from "./useHelpers";
|
|
6
|
+
|
|
7
|
+
interface UseUpdateCenterProps {
|
|
8
|
+
rootRef: RefObject<HTMLDivElement | null>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function useUpdateCenter({ rootRef }: UseUpdateCenterProps) {
|
|
12
|
+
const helpers = useHelpers();
|
|
13
|
+
const { getCentralNode, setOffset, editingNodeId } = useMindMapState(
|
|
14
|
+
useShallow((state) => ({
|
|
15
|
+
getCentralNode: state.getCentralNode,
|
|
16
|
+
setOffset: state.setOffset,
|
|
17
|
+
editingNodeId: state.editingNodeId,
|
|
18
|
+
}))
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
const { node } = useMindMapNode({ nodeId: editingNodeId });
|
|
22
|
+
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (node && node.text === "") {
|
|
25
|
+
helpers.centerNode(node);
|
|
26
|
+
}
|
|
27
|
+
}, [node]);
|
|
28
|
+
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
const updateCenter = () => {
|
|
31
|
+
const element = rootRef.current;
|
|
32
|
+
if (!element) return;
|
|
33
|
+
|
|
34
|
+
const centralNode = getCentralNode();
|
|
35
|
+
if (!centralNode) return;
|
|
36
|
+
|
|
37
|
+
const centralPos = centralNode.pos;
|
|
38
|
+
const centralSize = centralNode.style;
|
|
39
|
+
const bounds = element.getBoundingClientRect();
|
|
40
|
+
|
|
41
|
+
setOffset({
|
|
42
|
+
x: bounds.width / 2 - (centralPos.x + centralSize.w / 2),
|
|
43
|
+
y: bounds.height / 2 - (centralPos.y + centralSize.h / 2),
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
updateCenter();
|
|
48
|
+
window.addEventListener("resize", updateCenter);
|
|
49
|
+
|
|
50
|
+
return () => {
|
|
51
|
+
window.removeEventListener("resize", updateCenter);
|
|
52
|
+
};
|
|
53
|
+
}, [setOffset]);
|
|
54
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export {
|
|
2
|
+
useMindMapState,
|
|
3
|
+
layoutMindMapNodes,
|
|
4
|
+
wrapTextAtWords,
|
|
5
|
+
applyBranchColorsToNodes,
|
|
6
|
+
} from "./state/mindMap";
|
|
7
|
+
export {
|
|
8
|
+
useMindMapHistory,
|
|
9
|
+
createMindMapSnapshot,
|
|
10
|
+
clearMindMapHistory,
|
|
11
|
+
} from "./state/mindMapHistory";
|
|
12
|
+
export { useMindMapDebounce } from "./hooks/mindMap/useMindMapDebounce";
|
|
13
|
+
export { getMindMapPreviewDataUrl } from "./utils/getMindMapPreviewDataUrl";
|
|
14
|
+
export {
|
|
15
|
+
createMindMapExportCanvas,
|
|
16
|
+
exportMindMapAsHighQualityImage,
|
|
17
|
+
HIGH_QUALITY_EXPORT_SCALE,
|
|
18
|
+
type CreateMindMapCanvasOptions,
|
|
19
|
+
type ExportImageOptions,
|
|
20
|
+
} from "./utils/exportMindMapAsHighQualityImage";
|
|
21
|
+
export {
|
|
22
|
+
exportMindMapAsMarkdown,
|
|
23
|
+
mindMapToMarkdown,
|
|
24
|
+
type ExportMarkdownOptions,
|
|
25
|
+
} from "./utils/exportMindMapAsMarkdown";
|
|
26
|
+
export {
|
|
27
|
+
exportMindMapAsPdf,
|
|
28
|
+
type ExportPdfOptions,
|
|
29
|
+
} from "./utils/exportMindMapAsPdf";
|
|
30
|
+
export { useMindMapHistoryDebounce } from "./hooks/mindMap/useMindMapHistoryDebounce";
|
|
31
|
+
|
|
32
|
+
export { Background, type BackgroundProps } from "./components/mindMap/Background";
|
|
33
|
+
export {
|
|
34
|
+
Board,
|
|
35
|
+
type BoardProps,
|
|
36
|
+
type BoardStyleSlots,
|
|
37
|
+
} from "./components/mindMap/Board";
|
|
38
|
+
export { CentalNode } from "./components/mindMap/CentalNode";
|
|
39
|
+
export { DefaultNode } from "./components/mindMap/DefaultNode";
|
|
40
|
+
export {
|
|
41
|
+
Header as MindMapHeader,
|
|
42
|
+
type HeaderProps,
|
|
43
|
+
type HeaderStyleSlots,
|
|
44
|
+
} from "./components/mindMap/Header";
|
|
45
|
+
export {
|
|
46
|
+
SaveStatusIndicator,
|
|
47
|
+
type MindMapSaveStatus,
|
|
48
|
+
} from "./components/mindMap/SaveStatusIndicator";
|
|
49
|
+
export { ImageNode } from "./components/mindMap/ImageNode";
|
|
50
|
+
export {
|
|
51
|
+
KeyboardHelpDialog,
|
|
52
|
+
type KeyboardHelpDialogProps,
|
|
53
|
+
type KeyboardHelpDialogStyleSlots,
|
|
54
|
+
} from "./components/mindMap/KeyboardHelpDialog";
|
|
55
|
+
export {
|
|
56
|
+
MineMap,
|
|
57
|
+
type MineMapStyleSlots,
|
|
58
|
+
} from "./components/mindMap/MineMap";
|
|
59
|
+
export {
|
|
60
|
+
NodeStylePopover,
|
|
61
|
+
type NodeStylePopoverColorOption,
|
|
62
|
+
type NodeStylePopoverStyleSlots,
|
|
63
|
+
} from "./components/mindMap/NodeStylePopover";
|
|
64
|
+
export { Nodes } from "./components/mindMap/Nodes";
|
|
65
|
+
export { Nodex } from "./components/mindMap/Nodex";
|
|
66
|
+
export { Segments } from "./components/mindMap/Segments";
|
|
67
|
+
export { ZenCard, type ZenCardProps } from "./components/mindMap/ZenCard";
|
|
68
|
+
|
|
69
|
+
export type {
|
|
70
|
+
MindMapNode,
|
|
71
|
+
MindMapNodeStyle,
|
|
72
|
+
MindMapNodeType,
|
|
73
|
+
MindMapNodeTextAlign,
|
|
74
|
+
MindMapNodeFontSize,
|
|
75
|
+
} from "./state/mindMap";
|
|
76
|
+
export type { NodeEditorCustomButton } from "./contexts/MindMapNodeEditorContext";
|