mathlean-canvas 0.3.1 → 0.3.3
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 +213 -68
- package/dist/InlineMathLiveField.d.ts +17 -0
- package/dist/MathCanvas/components/CanvasOverlayViewport.d.ts +21 -0
- package/dist/MathCanvas/components/ObjectOverlays.d.ts +36 -0
- package/dist/MathCanvas/components/Toolbar.d.ts +34 -0
- package/dist/MathCanvas/components/icons.d.ts +58 -0
- package/dist/MathCanvas/constants.d.ts +70 -0
- package/dist/MathCanvas/core/hooks/useCanvasEditorFocus.d.ts +32 -0
- package/dist/MathCanvas/core/hooks/useCanvasGlobalActions.d.ts +41 -0
- package/dist/MathCanvas/core/hooks/useCanvasGlobalDragEffects.d.ts +35 -0
- package/dist/MathCanvas/core/hooks/useCanvasHistory.d.ts +13 -0
- package/dist/MathCanvas/core/hooks/useCanvasKeyboardShortcuts.d.ts +76 -0
- package/dist/MathCanvas/core/hooks/useCanvasSnapshot.d.ts +23 -0
- package/dist/MathCanvas/core/hooks/useCanvasStageInteractions.d.ts +103 -0
- package/dist/MathCanvas/core/hooks/useCanvasTransformers.d.ts +28 -0
- package/dist/MathCanvas/core/hooks/useCanvasViewport.d.ts +25 -0
- package/dist/MathCanvas/core/index.d.ts +9 -0
- package/dist/MathCanvas/features/geometry/components/CoordinatePlaneLayer.d.ts +15 -0
- package/dist/MathCanvas/features/geometry/components/GeometryLayer.d.ts +65 -0
- package/dist/MathCanvas/features/geometry/components/GeometryOverlays.d.ts +57 -0
- package/dist/MathCanvas/features/geometry/hooks/useGeometryCanvasActions.d.ts +29 -0
- package/dist/MathCanvas/features/geometry/hooks/useGeometryRenderData.d.ts +60 -0
- package/dist/MathCanvas/features/geometry/hooks/useGeometryState.d.ts +147 -0
- package/dist/MathCanvas/features/geometry/index.d.ts +6 -0
- package/dist/MathCanvas/features/graph/components/GraphLayer.d.ts +39 -0
- package/dist/MathCanvas/features/graph/components/GraphNodeEditor.d.ts +14 -0
- package/dist/MathCanvas/features/graph/hooks/useGraphCanvasActions.d.ts +44 -0
- package/dist/MathCanvas/features/graph/hooks/useGraphState.d.ts +77 -0
- package/dist/MathCanvas/features/graph/index.d.ts +4 -0
- package/dist/MathCanvas/features/grid/components/CellMathEditor.d.ts +17 -0
- package/dist/MathCanvas/features/grid/components/GridObjectOverlays.d.ts +71 -0
- package/dist/MathCanvas/features/grid/components/MatrixBlock.d.ts +20 -0
- package/dist/MathCanvas/features/grid/components/MatrixBrackets.d.ts +6 -0
- package/dist/MathCanvas/features/grid/components/MatrixEditorBlock.d.ts +50 -0
- package/dist/MathCanvas/features/grid/components/MatrixLayer.d.ts +31 -0
- package/dist/MathCanvas/features/grid/components/TableBlock.d.ts +21 -0
- package/dist/MathCanvas/features/grid/components/TableEditorBlock.d.ts +46 -0
- package/dist/MathCanvas/features/grid/hooks/useGridCanvasActions.d.ts +66 -0
- package/dist/MathCanvas/features/grid/hooks/useGridObjectState.d.ts +147 -0
- package/dist/MathCanvas/features/grid/index.d.ts +5 -0
- package/dist/MathCanvas/features/grid/utils/matrixOps.d.ts +36 -0
- package/dist/MathCanvas/features/stroke/components/StrokeLayer.d.ts +8 -0
- package/dist/MathCanvas/features/stroke/hooks/useStrokeState.d.ts +33 -0
- package/dist/MathCanvas/features/stroke/index.d.ts +2 -0
- package/dist/MathCanvas/features/text/components/BlockRenderers.d.ts +24 -0
- package/dist/MathCanvas/features/text/components/InlineMathBubble.d.ts +36 -0
- package/dist/MathCanvas/features/text/components/TextBlockEditor.d.ts +46 -0
- package/dist/MathCanvas/features/text/components/TextBlockMenu.d.ts +25 -0
- package/dist/MathCanvas/features/text/components/TextBlockView.d.ts +22 -0
- package/dist/MathCanvas/features/text/components/TextInteractionLayer.d.ts +29 -0
- package/dist/MathCanvas/features/text/hooks/useTextBlockActions.d.ts +40 -0
- package/dist/MathCanvas/features/text/hooks/useTextBlockEditingActions.d.ts +57 -0
- package/dist/MathCanvas/features/text/hooks/useTextBlockLayoutEffects.d.ts +62 -0
- package/dist/MathCanvas/features/text/hooks/useTextBlockRenderHelpers.d.ts +15 -0
- package/dist/MathCanvas/features/text/hooks/useTextboxResize.d.ts +19 -0
- package/dist/MathCanvas/features/text/index.d.ts +12 -0
- package/dist/MathCanvas/features/text/utils/textLayout.d.ts +33 -0
- package/dist/MathCanvas/types.d.ts +219 -0
- package/dist/MathCanvas/utils/geometryMath.d.ts +13 -0
- package/dist/MathCanvas/utils/graphDirection.d.ts +3 -0
- package/dist/MathCanvas/utils/latex.d.ts +20 -0
- package/dist/MathCanvas.d.ts +7 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +11777 -10143
- package/dist/inlineMathModel.d.ts +26 -0
- package/dist/useInlineMathSession.d.ts +67 -0
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -1,68 +1,213 @@
|
|
|
1
|
-
# mathlean-canvas
|
|
2
|
-
|
|
3
|
-
`mathlean-canvas` is a reusable React whiteboard canvas
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
npm
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
1
|
+
# mathlean-canvas
|
|
2
|
+
|
|
3
|
+
`mathlean-canvas` is a reusable React whiteboard canvas for math-heavy notes, diagrams, matrices, tables, graphs, and geometric constructions.
|
|
4
|
+
|
|
5
|
+
It is built as a single `MathCanvas` component. The component includes its own toolbar, drawing surface, object overlays, undo/redo history, light/dark themes, and state callback for saving canvas data.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- Pen and eraser drawing
|
|
10
|
+
- Text boxes with plain text, LaTeX rendering, inline math, formatting, colors, resizing, copy, and delete actions
|
|
11
|
+
- Graph nodes and directed relationships with fast keyboard creation and navigation
|
|
12
|
+
- Matrices with LaTeX export, grid selection, separators, region transforms, rotation, transpose, and identity fill
|
|
13
|
+
- Tables with spreadsheet-like editing, range selection, row/column operations, and copy/paste
|
|
14
|
+
- Geometry construction tools for points, segments, polygons, angles, circles, labels, midpoints, helpers, fixed lengths, regular polygons, right-angle markers, and equal-side markers
|
|
15
|
+
- Square grid and coordinate plane backgrounds
|
|
16
|
+
- Undo/redo and clear canvas controls
|
|
17
|
+
- Controlled persistence through `initialState` and `onStateChange`
|
|
18
|
+
|
|
19
|
+
For the full user-facing tool guide and shortcut reference, see [features.md](./features.md).
|
|
20
|
+
|
|
21
|
+
## Install
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install mathlean-canvas
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The package is built for React apps and uses:
|
|
28
|
+
|
|
29
|
+
- `react`
|
|
30
|
+
- `react-dom`
|
|
31
|
+
- `react-konva`
|
|
32
|
+
- `konva`
|
|
33
|
+
- `katex`
|
|
34
|
+
- `mathlive`
|
|
35
|
+
|
|
36
|
+
The current package version is built and tested with React 19, React DOM 19, React Konva 19, Konva 10, KaTeX 0.16, and MathLive 0.109.
|
|
37
|
+
|
|
38
|
+
If your app uses React 18 or older, check compatibility carefully. The safest setup is a React 19 app with the matching Konva/React Konva stack.
|
|
39
|
+
|
|
40
|
+
## Basic Usage
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import { MathCanvas } from "mathlean-canvas";
|
|
44
|
+
|
|
45
|
+
export default function App() {
|
|
46
|
+
return (
|
|
47
|
+
<div style={{ width: "100vw", height: "100vh" }}>
|
|
48
|
+
<MathCanvas />
|
|
49
|
+
</div>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`MathCanvas` fills its parent container, so give the parent an explicit width and height.
|
|
55
|
+
|
|
56
|
+
## Styles
|
|
57
|
+
|
|
58
|
+
The source imports KaTeX and MathLive styles for the built-in math editors. If your bundler does not include package CSS automatically, import the math styles in your app entry:
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
import "katex/dist/katex.min.css";
|
|
62
|
+
import "mathlive/fonts.css";
|
|
63
|
+
import "mathlive/static.css";
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Saving And Restoring State
|
|
67
|
+
|
|
68
|
+
Use `onStateChange` to receive the full canvas state whenever it changes, then pass that state back through `initialState` when you want to restore the canvas.
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
import { useState } from "react";
|
|
72
|
+
import { MathCanvas, type CanvasState } from "mathlean-canvas";
|
|
73
|
+
|
|
74
|
+
export default function NotesCanvas() {
|
|
75
|
+
const [savedState, setSavedState] = useState<CanvasState | undefined>();
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<div style={{ width: "100%", height: 600 }}>
|
|
79
|
+
<MathCanvas
|
|
80
|
+
initialState={savedState}
|
|
81
|
+
onStateChange={setSavedState}
|
|
82
|
+
/>
|
|
83
|
+
</div>
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`initialState` is read when the component initializes. If you need to switch between multiple documents at runtime, remount the component with a different `key`.
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
<MathCanvas
|
|
92
|
+
key={documentId}
|
|
93
|
+
initialState={document.canvasState}
|
|
94
|
+
onStateChange={saveCanvasState}
|
|
95
|
+
/>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Dark Mode
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
<MathCanvas darkMode />
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The component ships with built-in light and dark themes. Use `className` and `style` for layout-level styling around the canvas.
|
|
105
|
+
|
|
106
|
+
## API
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
type MathCanvasProps = {
|
|
110
|
+
darkMode?: boolean;
|
|
111
|
+
className?: string;
|
|
112
|
+
style?: React.CSSProperties;
|
|
113
|
+
initialState?: CanvasState;
|
|
114
|
+
onStateChange?: (state: CanvasState) => void;
|
|
115
|
+
};
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Exports:
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
export { MathCanvas };
|
|
122
|
+
export default MathCanvas;
|
|
123
|
+
export type { CanvasState, MathCanvasProps };
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Tools At A Glance
|
|
127
|
+
|
|
128
|
+
- Select: select, move, resize, and edit existing objects.
|
|
129
|
+
- Pan: drag the viewport.
|
|
130
|
+
- Pen: draw freehand strokes.
|
|
131
|
+
- Eraser: erase freehand strokes.
|
|
132
|
+
- Text: place text boxes and math text.
|
|
133
|
+
- Graph: create nodes and connect relationships.
|
|
134
|
+
- Matrix: create and edit matrices.
|
|
135
|
+
- Table: create and edit tables.
|
|
136
|
+
- Geometry: construct mathematical diagrams.
|
|
137
|
+
- Toggle LaTeX: switch text entry between plain and LaTeX-oriented rendering.
|
|
138
|
+
- Clear: clear the canvas.
|
|
139
|
+
|
|
140
|
+
See [features.md](./features.md) for detailed tutorials and shortcuts.
|
|
141
|
+
|
|
142
|
+
## Project Structure
|
|
143
|
+
|
|
144
|
+
```text
|
|
145
|
+
src/
|
|
146
|
+
MathCanvas.tsx canvas coordinator
|
|
147
|
+
MathCanvas/
|
|
148
|
+
core/ canvas-wide hooks
|
|
149
|
+
features/
|
|
150
|
+
text/ text boxes and inline math
|
|
151
|
+
graph/ graph nodes and edges
|
|
152
|
+
grid/ matrices and tables
|
|
153
|
+
geometry/ geometry construction tools
|
|
154
|
+
stroke/ pen and eraser strokes
|
|
155
|
+
components/ shared toolbar, overlays, icons
|
|
156
|
+
types.ts public and internal canvas state types
|
|
157
|
+
index.ts package entry
|
|
158
|
+
demo/ local Vite demo app
|
|
159
|
+
docs/ architecture and planning notes
|
|
160
|
+
tests/ Playwright tests
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
For contributor-facing architecture notes, see [docs/mathcanvas-architecture.md](./docs/mathcanvas-architecture.md).
|
|
164
|
+
|
|
165
|
+
## Local Development
|
|
166
|
+
|
|
167
|
+
Install dependencies:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
npm install
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Run the demo app:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
npm run dev
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Build the library package:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
npm run build
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Build the demo app:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
npm run build:demo
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Run lint:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
npm run lint
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Run Playwright tests:
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
npm run test:e2e
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Focused test scripts are also available for MathLive/textbox behavior:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
npm run test:e2e:placeholders
|
|
207
|
+
npm run test:e2e:exit
|
|
208
|
+
npm run test:e2e:mathlive
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## License
|
|
212
|
+
|
|
213
|
+
MIT
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type CSSProperties, type MouseEvent, type RefObject } from "react";
|
|
2
|
+
import type { MathfieldElement } from "mathlive";
|
|
3
|
+
type InlineMathLiveFieldProps = {
|
|
4
|
+
fieldRef: RefObject<MathfieldElement | null>;
|
|
5
|
+
bubbleRef: RefObject<HTMLDivElement | null>;
|
|
6
|
+
initialLatex: string;
|
|
7
|
+
style: CSSProperties;
|
|
8
|
+
onReady: () => void;
|
|
9
|
+
onLatexChange: (latex: string) => void;
|
|
10
|
+
onCommit: () => void;
|
|
11
|
+
onCancel: () => void;
|
|
12
|
+
onArrowExit: (direction: "before" | "after") => void;
|
|
13
|
+
onError: () => void;
|
|
14
|
+
onContextMenu?: (event: MouseEvent<MathfieldElement>) => void;
|
|
15
|
+
};
|
|
16
|
+
export default function InlineMathLiveField({ fieldRef, bubbleRef, initialLatex, style, onReady, onLatexChange, onCommit, onCancel, onArrowExit, onError, onContextMenu, }: InlineMathLiveFieldProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ComponentProps } from "react";
|
|
2
|
+
import type { TextBlock } from "../types";
|
|
3
|
+
import { GraphNodeEditor } from "../features/graph";
|
|
4
|
+
import { GridObjectOverlays } from "../features/grid";
|
|
5
|
+
import { InlineMathBubble, TextBlockEditor, TextBlockMenu, TextBlockView } from "../features/text";
|
|
6
|
+
type CanvasOverlayViewportProps = {
|
|
7
|
+
blocks: TextBlock[];
|
|
8
|
+
editingBlockId: string | null;
|
|
9
|
+
graphNodeEditorProps: ComponentProps<typeof GraphNodeEditor>;
|
|
10
|
+
gridObjectOverlaysProps: ComponentProps<typeof GridObjectOverlays>;
|
|
11
|
+
inlineMathBubbleProps: ComponentProps<typeof InlineMathBubble>;
|
|
12
|
+
textBlockEditorProps: ComponentProps<typeof TextBlockEditor>;
|
|
13
|
+
textBlockMenuProps: ComponentProps<typeof TextBlockMenu>;
|
|
14
|
+
textBlockViewProps: Omit<ComponentProps<typeof TextBlockView>, "block">;
|
|
15
|
+
viewport: {
|
|
16
|
+
x: number;
|
|
17
|
+
y: number;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
export default function CanvasOverlayViewport({ blocks, editingBlockId, graphNodeEditorProps, gridObjectOverlaysProps, inlineMathBubbleProps, textBlockEditorProps, textBlockMenuProps, textBlockViewProps, viewport, }: CanvasOverlayViewportProps): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { GraphNode, MathCanvasTheme, MatrixObject, TableObject, Tool } from "../types";
|
|
2
|
+
type MatrixLatexPopover = {
|
|
3
|
+
matrixId: string;
|
|
4
|
+
left: number;
|
|
5
|
+
top: number;
|
|
6
|
+
} | null;
|
|
7
|
+
type EraserPreview = {
|
|
8
|
+
visible: boolean;
|
|
9
|
+
x: number;
|
|
10
|
+
y: number;
|
|
11
|
+
radius: number;
|
|
12
|
+
};
|
|
13
|
+
type ObjectOverlaysProps = {
|
|
14
|
+
colors: MathCanvasTheme;
|
|
15
|
+
darkMode: boolean;
|
|
16
|
+
tool: Tool;
|
|
17
|
+
viewport: {
|
|
18
|
+
x: number;
|
|
19
|
+
y: number;
|
|
20
|
+
};
|
|
21
|
+
eraserPreview: EraserPreview;
|
|
22
|
+
matrixLatexPopover: MatrixLatexPopover;
|
|
23
|
+
matrixLatexPopoverMatrix: MatrixObject | null;
|
|
24
|
+
copyMatrixLatex: (matrix: MatrixObject) => Promise<void>;
|
|
25
|
+
selectedGraphNode: GraphNode | null;
|
|
26
|
+
editingGraphNode: GraphNode | null;
|
|
27
|
+
deleteSelectedGraphNode: () => void;
|
|
28
|
+
selectedMatrix: MatrixObject | null;
|
|
29
|
+
editingMatrix: MatrixObject | null;
|
|
30
|
+
deleteSelectedMatrix: () => void;
|
|
31
|
+
selectedTable: TableObject | null;
|
|
32
|
+
editingTable: TableObject | null;
|
|
33
|
+
deleteSelectedTable: () => void;
|
|
34
|
+
};
|
|
35
|
+
export default function ObjectOverlays({ colors, darkMode, tool, viewport, eraserPreview, matrixLatexPopover, matrixLatexPopoverMatrix, copyMatrixLatex, selectedGraphNode, editingGraphNode, deleteSelectedGraphNode, selectedMatrix, editingMatrix, deleteSelectedMatrix, selectedTable, editingTable, deleteSelectedTable, }: ObjectOverlaysProps): import("react/jsx-runtime").JSX.Element;
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Dispatch, SetStateAction } from "react";
|
|
2
|
+
import { PEN_SIZE_OPTIONS } from "../constants";
|
|
3
|
+
import type { CoordinatePlaneMode, GeometryMode, MathCanvasTheme, Tool } from "../types";
|
|
4
|
+
type ToolbarProps = {
|
|
5
|
+
colors: MathCanvasTheme;
|
|
6
|
+
darkMode: boolean;
|
|
7
|
+
tool: Tool;
|
|
8
|
+
setTool: Dispatch<SetStateAction<Tool>>;
|
|
9
|
+
renderMode: "plain" | "latex";
|
|
10
|
+
toggleLatexMode: () => void;
|
|
11
|
+
pastStateCount: number;
|
|
12
|
+
futureStateCount: number;
|
|
13
|
+
handleUndo: () => void;
|
|
14
|
+
handleRedo: () => void;
|
|
15
|
+
showPenSizes: boolean;
|
|
16
|
+
setShowPenSizes: Dispatch<SetStateAction<boolean>>;
|
|
17
|
+
penWidth: (typeof PEN_SIZE_OPTIONS)[number];
|
|
18
|
+
setPenWidth: Dispatch<SetStateAction<(typeof PEN_SIZE_OPTIONS)[number]>>;
|
|
19
|
+
penColor: string;
|
|
20
|
+
setPenColor: Dispatch<SetStateAction<string>>;
|
|
21
|
+
penColorOptions: readonly string[];
|
|
22
|
+
geometryMode: GeometryMode;
|
|
23
|
+
setGeometryMode: Dispatch<SetStateAction<GeometryMode>>;
|
|
24
|
+
clearGeometryDraft: () => void;
|
|
25
|
+
clearGeometryLabelEditing: () => void;
|
|
26
|
+
regularPolygonSides: number;
|
|
27
|
+
setRegularPolygonSides: Dispatch<SetStateAction<number>>;
|
|
28
|
+
coordinatePlaneMode: CoordinatePlaneMode;
|
|
29
|
+
setCoordinatePlaneMode: Dispatch<SetStateAction<CoordinatePlaneMode>>;
|
|
30
|
+
pushHistoryState: () => void;
|
|
31
|
+
clearCanvas: () => void;
|
|
32
|
+
};
|
|
33
|
+
export default function Toolbar({ colors, darkMode, tool, setTool, renderMode, toggleLatexMode, pastStateCount, futureStateCount, handleUndo, handleRedo, showPenSizes, setShowPenSizes, penWidth, setPenWidth, penColor, setPenColor, penColorOptions, geometryMode, setGeometryMode, clearGeometryDraft, clearGeometryLabelEditing, regularPolygonSides, setRegularPolygonSides, coordinatePlaneMode, setCoordinatePlaneMode, pushHistoryState, clearCanvas, }: ToolbarProps): import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { GeometryMode, MathCanvasTheme } from "../types";
|
|
2
|
+
export declare function DeleteIcon(): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
export declare function FormatTextIcon(): import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
export declare function ColorIcon(): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export declare function CopyIcon(): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export declare function PenIcon({ active }: {
|
|
7
|
+
active: boolean;
|
|
8
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export declare function EraserIcon({ active }: {
|
|
10
|
+
active: boolean;
|
|
11
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export declare function SelectIcon({ active }: {
|
|
13
|
+
active: boolean;
|
|
14
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export declare function ClearIcon(): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export declare function TextIcon({ active }: {
|
|
17
|
+
active: boolean;
|
|
18
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
export declare function PanIcon({ active }: {
|
|
20
|
+
active: boolean;
|
|
21
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
22
|
+
export declare function GeometryIcon({ active }: {
|
|
23
|
+
active: boolean;
|
|
24
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
export declare function GeometryModeSymbol({ mode }: {
|
|
26
|
+
mode: GeometryMode;
|
|
27
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
export declare function RenderKatexExpression({ expression, fallback, displayMode, }: {
|
|
29
|
+
expression: string;
|
|
30
|
+
fallback: string;
|
|
31
|
+
displayMode?: boolean;
|
|
32
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
export declare function GraphIcon({ active }: {
|
|
34
|
+
active: boolean;
|
|
35
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
36
|
+
export declare function MatrixIcon({ active }: {
|
|
37
|
+
active: boolean;
|
|
38
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
39
|
+
export declare function TableIcon({ active }: {
|
|
40
|
+
active: boolean;
|
|
41
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
42
|
+
export declare function LatexToggleIcon({ active }: {
|
|
43
|
+
active: boolean;
|
|
44
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
45
|
+
export declare function UndoIcon({ active }: {
|
|
46
|
+
active: boolean;
|
|
47
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
48
|
+
export declare function RedoIcon({ active }: {
|
|
49
|
+
active: boolean;
|
|
50
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
51
|
+
export declare function ToolButton({ active, disabled, label, onClick, children, colors, }: {
|
|
52
|
+
active: boolean;
|
|
53
|
+
disabled?: boolean;
|
|
54
|
+
label: string;
|
|
55
|
+
onClick: () => void;
|
|
56
|
+
children: React.ReactNode;
|
|
57
|
+
colors: MathCanvasTheme;
|
|
58
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { GraphDirection, MathCanvasTheme } from "./types";
|
|
2
|
+
export declare const DEFAULT_BLOCK_HEIGHT = 44;
|
|
3
|
+
export declare const MIN_BLOCK_WIDTH = 56;
|
|
4
|
+
export declare const CANVAS_PADDING = 24;
|
|
5
|
+
export declare const DEFAULT_BLOCK_WIDTH = 64;
|
|
6
|
+
export declare const TEXT_AUTO_WRAP_WIDTH = 420;
|
|
7
|
+
export declare const TEXT_MIN_FONT_SIZE = 12;
|
|
8
|
+
export declare const TEXT_MAX_FONT_SIZE = 72;
|
|
9
|
+
export declare const TEXTBOX_SELECTION_STROKE = "#b9b9b9";
|
|
10
|
+
export declare const TEXTBOX_SELECTION_HANDLE_FILL = "#f7f7f7";
|
|
11
|
+
export declare const TEXTBOX_SELECTION_HANDLE_STROKE = "#8f8f8f";
|
|
12
|
+
export declare const TEXTBOX_SELECTION_HANDLE_RADIUS = 2;
|
|
13
|
+
export declare const TEXT_LEFT_PADDING = 8;
|
|
14
|
+
export declare const TEXT_RIGHT_PADDING = 18;
|
|
15
|
+
export declare const TEXT_VERTICAL_PADDING = 6;
|
|
16
|
+
export declare const TEXT_GROWTH_BUFFER = 4;
|
|
17
|
+
export declare const TEXTBOX_CREATION_GUARD_PADDING = 14;
|
|
18
|
+
export declare const LATEX_PREVIEW_MARGIN = 10;
|
|
19
|
+
export declare const PEN_SIZE_OPTIONS: readonly [2, 4, 6, 8, 12];
|
|
20
|
+
export declare const LIGHT_PEN_DEFAULT = "#111111";
|
|
21
|
+
export declare const DARK_PEN_DEFAULT = "#ffffff";
|
|
22
|
+
export declare const SHARED_PEN_COLOR_OPTIONS: readonly ["#d14343", "#2f6fed", "#2f9e44", "#c89b0e", "#f2d21b"];
|
|
23
|
+
export declare const BASE_ERASER_RADIUS = 14;
|
|
24
|
+
export declare const MAX_ERASER_RADIUS = 34;
|
|
25
|
+
export declare const ERASER_SPEED_THRESHOLD = 0.9;
|
|
26
|
+
export declare const ERASER_SPEED_RANGE = 2.2;
|
|
27
|
+
export declare const DEFAULT_GRAPH_NODE_WIDTH = 56;
|
|
28
|
+
export declare const DEFAULT_GRAPH_NODE_HEIGHT = 56;
|
|
29
|
+
export declare const MIN_GRAPH_NODE_WIDTH = 48;
|
|
30
|
+
export declare const MIN_GRAPH_NODE_HEIGHT = 48;
|
|
31
|
+
export declare const GRAPH_NODE_OFFSET = 160;
|
|
32
|
+
export declare const GRAPH_NUDGE_DISTANCE = 8;
|
|
33
|
+
export declare const GRAPH_DIRECTION_OFFSETS: Record<GraphDirection, {
|
|
34
|
+
dx: number;
|
|
35
|
+
dy: number;
|
|
36
|
+
}>;
|
|
37
|
+
export declare const DEFAULT_MATRIX_SIZE = 2;
|
|
38
|
+
export declare const DEFAULT_TABLE_SIZE = 2;
|
|
39
|
+
export declare const MAX_MATRIX_SIZE = 10;
|
|
40
|
+
export declare const MAX_TABLE_SIZE = 50;
|
|
41
|
+
export declare const MATRIX_MIN_CELL_WIDTH = 26;
|
|
42
|
+
export declare const MATRIX_CELL_HEIGHT = 26;
|
|
43
|
+
export declare const MATRIX_CELL_GAP = 6;
|
|
44
|
+
export declare const MATRIX_BRACKET_PADDING = 14;
|
|
45
|
+
export declare const MATRIX_CELL_HORIZONTAL_PADDING = 6;
|
|
46
|
+
export declare const MATRIX_SEPARATOR_BUTTON_SIZE = 16;
|
|
47
|
+
export declare const MATRIX_HEADER_OFFSET = 18;
|
|
48
|
+
export declare const MATRIX_SEPARATOR_TRACK_OFFSET = 18;
|
|
49
|
+
export declare const LATEX_FONT_FAMILY = "KaTeX_Main, Computer Modern Serif, Latin Modern Roman, Times New Roman, serif";
|
|
50
|
+
export declare const LATEX_CODE_FONT_FAMILY = "SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier New, monospace";
|
|
51
|
+
export declare const DEFAULT_TEXT_FONT_SIZE = 24;
|
|
52
|
+
export declare const MATRIX_AXIS_SNAP_THRESHOLD = 18;
|
|
53
|
+
export declare const MATRIX_AXIS_SNAP_DISTANCE = 180;
|
|
54
|
+
export declare const GEOMETRY_POINT_RADIUS = 5;
|
|
55
|
+
export declare const GEOMETRY_POINT_HIT_RADIUS = 14;
|
|
56
|
+
export declare const GEOMETRY_SNAP_RADIUS = 18;
|
|
57
|
+
export declare const GEOMETRY_GRID_SIZE = 24;
|
|
58
|
+
export declare const GEOMETRY_NUDGE_DISTANCE = 2;
|
|
59
|
+
export declare const GEOMETRY_ARC_RADIUS = 28;
|
|
60
|
+
export declare const GEOMETRY_CIRCLE_DASH: number[];
|
|
61
|
+
export declare const GEOMETRY_LABEL_OFFSET = 16;
|
|
62
|
+
export declare const GEOMETRY_HELPER_LENGTH = 180;
|
|
63
|
+
export declare const GEOMETRY_RIGHT_ANGLE_SIZE = 18;
|
|
64
|
+
export declare const TABLE_INNER_BORDER_WIDTH = 1.5;
|
|
65
|
+
export declare const TABLE_OUTER_BORDER_WIDTH = 2;
|
|
66
|
+
export declare const LIGHT_THEME: MathCanvasTheme;
|
|
67
|
+
export declare const DARK_THEME: MathCanvasTheme;
|
|
68
|
+
export declare const getTableGridColor: (darkMode: boolean) => "#d6d6dc" | "#bcbcc4";
|
|
69
|
+
export declare const getTableOuterBorderColor: (darkMode: boolean) => "#efeff4" | "#8f8f96";
|
|
70
|
+
export declare const getMatrixSeparatorColor: (darkMode: boolean, colors: MathCanvasTheme) => string;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type Dispatch, type MutableRefObject, type SetStateAction } from "react";
|
|
2
|
+
import type { GeometryLabelTarget } from "../../types";
|
|
3
|
+
type GridCell = {
|
|
4
|
+
row: number;
|
|
5
|
+
col: number;
|
|
6
|
+
};
|
|
7
|
+
type UseCanvasEditorFocusOptions = {
|
|
8
|
+
editingBlockId: string | null;
|
|
9
|
+
editingGeometryLabel: GeometryLabelTarget | null;
|
|
10
|
+
editingGraphNodeId: string | null;
|
|
11
|
+
editingMatrixCell: GridCell | null;
|
|
12
|
+
editingMatrixId: string | null;
|
|
13
|
+
editingTableCell: GridCell | null;
|
|
14
|
+
editingTableId: string | null;
|
|
15
|
+
fixedLengthInputRef: MutableRefObject<HTMLInputElement | null>;
|
|
16
|
+
fixedLengthStartPointId: string | null;
|
|
17
|
+
geometryLabelInputRef: MutableRefObject<HTMLInputElement | null>;
|
|
18
|
+
graphInputRef: MutableRefObject<HTMLInputElement | null>;
|
|
19
|
+
lastEditingSelectionRangeRef: MutableRefObject<{
|
|
20
|
+
blockId: string;
|
|
21
|
+
start: number;
|
|
22
|
+
end: number;
|
|
23
|
+
} | null>;
|
|
24
|
+
matrixInputRefs: MutableRefObject<Record<string, HTMLInputElement | null>>;
|
|
25
|
+
setEditingHeight: Dispatch<SetStateAction<number>>;
|
|
26
|
+
setEditingSelection: Dispatch<SetStateAction<number>>;
|
|
27
|
+
setEditingSelectionEnd: Dispatch<SetStateAction<number>>;
|
|
28
|
+
tableInputRefs: MutableRefObject<Record<string, HTMLInputElement | null>>;
|
|
29
|
+
textareaRef: MutableRefObject<HTMLTextAreaElement | null>;
|
|
30
|
+
};
|
|
31
|
+
export declare function useCanvasEditorFocus({ editingBlockId, editingGeometryLabel, editingGraphNodeId, editingMatrixCell, editingMatrixId, editingTableCell, editingTableId, fixedLengthInputRef, fixedLengthStartPointId, geometryLabelInputRef, graphInputRef, lastEditingSelectionRangeRef, matrixInputRefs, setEditingHeight, setEditingSelection, setEditingSelectionEnd, tableInputRefs, textareaRef, }: UseCanvasEditorFocusOptions): void;
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Dispatch, MutableRefObject, SetStateAction } from "react";
|
|
2
|
+
import type { GeoAngle, GeoCircle, GeoHelperSegment, GeoPoint, GeoPolygon, GeoRightAngleMarker, GeoSegment, GraphEdge, GraphNode, MatrixObject, RenderMode, Stroke, TableObject, TextBlock } from "../../types";
|
|
3
|
+
type UseCanvasGlobalActionsOptions = {
|
|
4
|
+
clearEditing: () => void;
|
|
5
|
+
clearGeometryDraft: () => void;
|
|
6
|
+
clearGeometryLabelEditing: () => void;
|
|
7
|
+
clearGeometrySelection: () => void;
|
|
8
|
+
clearGraphEditing: () => void;
|
|
9
|
+
clearGraphSelection: () => void;
|
|
10
|
+
clearMatrixEditing: () => void;
|
|
11
|
+
clearMatrixSelection: () => void;
|
|
12
|
+
clearTableEditing: () => void;
|
|
13
|
+
clearTableSelection: () => void;
|
|
14
|
+
editingBlockId: string | null;
|
|
15
|
+
isDrawing: MutableRefObject<boolean>;
|
|
16
|
+
pushHistoryState: () => void;
|
|
17
|
+
renderMode: RenderMode;
|
|
18
|
+
selectedBlockId: string | null;
|
|
19
|
+
setBlocks: Dispatch<SetStateAction<TextBlock[]>>;
|
|
20
|
+
setGeoAngles: Dispatch<SetStateAction<GeoAngle[]>>;
|
|
21
|
+
setGeoCircles: Dispatch<SetStateAction<GeoCircle[]>>;
|
|
22
|
+
setGeoHelperSegments: Dispatch<SetStateAction<GeoHelperSegment[]>>;
|
|
23
|
+
setGeoPoints: Dispatch<SetStateAction<GeoPoint[]>>;
|
|
24
|
+
setGeoPolygons: Dispatch<SetStateAction<GeoPolygon[]>>;
|
|
25
|
+
setGeoRightAngleMarkers: Dispatch<SetStateAction<GeoRightAngleMarker[]>>;
|
|
26
|
+
setGeoSegments: Dispatch<SetStateAction<GeoSegment[]>>;
|
|
27
|
+
setGraphEdges: Dispatch<SetStateAction<GraphEdge[]>>;
|
|
28
|
+
setGraphNodes: Dispatch<SetStateAction<GraphNode[]>>;
|
|
29
|
+
setMatrices: Dispatch<SetStateAction<MatrixObject[]>>;
|
|
30
|
+
setRenderMode: Dispatch<SetStateAction<RenderMode>>;
|
|
31
|
+
setSelectedBlockId: Dispatch<SetStateAction<string | null>>;
|
|
32
|
+
setStrokes: Dispatch<SetStateAction<Stroke[]>>;
|
|
33
|
+
setTables: Dispatch<SetStateAction<TableObject[]>>;
|
|
34
|
+
updateBlock: (id: string, updater: (block: TextBlock) => TextBlock) => void;
|
|
35
|
+
};
|
|
36
|
+
export declare function useCanvasGlobalActions({ clearEditing, clearGeometryDraft, clearGeometryLabelEditing, clearGeometrySelection, clearGraphEditing, clearGraphSelection, clearMatrixEditing, clearMatrixSelection, clearTableEditing, clearTableSelection, editingBlockId, isDrawing, pushHistoryState, renderMode, selectedBlockId, setBlocks, setGeoAngles, setGeoCircles, setGeoHelperSegments, setGeoPoints, setGeoPolygons, setGeoRightAngleMarkers, setGeoSegments, setGraphEdges, setGraphNodes, setMatrices, setRenderMode, setSelectedBlockId, setStrokes, setTables, updateBlock, }: UseCanvasGlobalActionsOptions): {
|
|
37
|
+
clearCanvas: () => void;
|
|
38
|
+
handleRenderModeChange: (nextMode: RenderMode) => void;
|
|
39
|
+
toggleLatexMode: () => void;
|
|
40
|
+
};
|
|
41
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type Dispatch, type MutableRefObject, type SetStateAction } from "react";
|
|
2
|
+
import type { GeometryLabelOffset, GeometryLabelTarget } from "../../types";
|
|
3
|
+
type GridMoveDrag = {
|
|
4
|
+
kind: "matrix" | "table";
|
|
5
|
+
id: string;
|
|
6
|
+
mode: "row" | "column";
|
|
7
|
+
startIndex: number;
|
|
8
|
+
endIndex: number;
|
|
9
|
+
targetIndex: number;
|
|
10
|
+
};
|
|
11
|
+
type GridMovePreview = {
|
|
12
|
+
kind: "matrix" | "table";
|
|
13
|
+
id: string;
|
|
14
|
+
mode: "row" | "column";
|
|
15
|
+
targetIndex: number;
|
|
16
|
+
};
|
|
17
|
+
type GeometryLabelDrag = {
|
|
18
|
+
target: GeometryLabelTarget;
|
|
19
|
+
startX: number;
|
|
20
|
+
startY: number;
|
|
21
|
+
offset: GeometryLabelOffset;
|
|
22
|
+
didPushHistory: boolean;
|
|
23
|
+
};
|
|
24
|
+
type UseCanvasGlobalDragEffectsOptions = {
|
|
25
|
+
endGridSelectionDrag: () => void;
|
|
26
|
+
geometryLabelDragRef: MutableRefObject<GeometryLabelDrag | null>;
|
|
27
|
+
gridMoveDragRef: MutableRefObject<GridMoveDrag | null>;
|
|
28
|
+
moveGridSelectionRangeToIndex: (kind: "matrix" | "table", id: string, mode: "row" | "column", startIndex: number, endIndex: number, targetIndex: number) => void;
|
|
29
|
+
pushHistoryState: () => void;
|
|
30
|
+
setGridMovePreview: Dispatch<SetStateAction<GridMovePreview | null>>;
|
|
31
|
+
skipNextTextCreationResetRef: MutableRefObject<number | null>;
|
|
32
|
+
updateGeometryLabelOffset: (target: GeometryLabelTarget, offset: GeometryLabelOffset) => void;
|
|
33
|
+
};
|
|
34
|
+
export declare function useCanvasGlobalDragEffects({ endGridSelectionDrag, geometryLabelDragRef, gridMoveDragRef, moveGridSelectionRangeToIndex, pushHistoryState, setGridMovePreview, skipNextTextCreationResetRef, updateGeometryLabelOffset, }: UseCanvasGlobalDragEffectsOptions): void;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { CanvasState } from "../../types";
|
|
2
|
+
type UseCanvasHistoryOptions = {
|
|
3
|
+
getCanvasState: () => CanvasState;
|
|
4
|
+
restoreCanvasState: (state: CanvasState) => void;
|
|
5
|
+
};
|
|
6
|
+
export declare function useCanvasHistory({ getCanvasState, restoreCanvasState }: UseCanvasHistoryOptions): {
|
|
7
|
+
futureStateCount: number;
|
|
8
|
+
handleRedo: () => void;
|
|
9
|
+
handleUndo: () => void;
|
|
10
|
+
pastStateCount: number;
|
|
11
|
+
pushHistoryState: () => void;
|
|
12
|
+
};
|
|
13
|
+
export {};
|