@xom11/whiteboard 0.11.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -0
- package/dist/{ExcalidrawWithMenus-EAVPOPJZ.mjs → ExcalidrawWithMenus-KBLDWPM2.mjs} +2 -3
- package/dist/ExcalidrawWithMenus-KBLDWPM2.mjs.map +1 -0
- package/dist/catalog.json +57 -0
- package/dist/{chunk-PWIMZIB6.mjs → chunk-2SKXRBGS.mjs} +7 -8
- package/dist/chunk-2SKXRBGS.mjs.map +1 -0
- package/dist/chunk-33PEN2WC.mjs +57 -0
- package/dist/chunk-33PEN2WC.mjs.map +1 -0
- package/dist/chunk-3KBL77M6.mjs +127 -0
- package/dist/chunk-3KBL77M6.mjs.map +1 -0
- package/dist/chunk-5UTGXHLJ.mjs +57 -0
- package/dist/chunk-5UTGXHLJ.mjs.map +1 -0
- package/dist/chunk-6XUPIGVD.mjs +467 -0
- package/dist/chunk-6XUPIGVD.mjs.map +1 -0
- package/dist/chunk-7WG2KDRF.mjs +28 -0
- package/dist/chunk-7WG2KDRF.mjs.map +1 -0
- package/dist/chunk-FZY33J6Z.mjs +95 -0
- package/dist/chunk-FZY33J6Z.mjs.map +1 -0
- package/dist/chunk-HNQLZIEP.mjs +78 -0
- package/dist/chunk-HNQLZIEP.mjs.map +1 -0
- package/dist/chunk-NVJ7K3DK.mjs +29 -0
- package/dist/chunk-NVJ7K3DK.mjs.map +1 -0
- package/dist/chunk-O4WIZFRQ.mjs +11 -0
- package/dist/chunk-O4WIZFRQ.mjs.map +1 -0
- package/dist/{chunk-YVJP7NRG.mjs → chunk-O6QTYAKE.mjs} +7 -9
- package/dist/chunk-O6QTYAKE.mjs.map +1 -0
- package/dist/chunk-R5FL6S7L.mjs +22 -0
- package/dist/chunk-R5FL6S7L.mjs.map +1 -0
- package/dist/chunk-RBUILBX3.mjs +388 -0
- package/dist/chunk-RBUILBX3.mjs.map +1 -0
- package/dist/chunk-RD34F5PM.mjs +57 -0
- package/dist/chunk-RD34F5PM.mjs.map +1 -0
- package/dist/{chunk-7P7SQFOW.mjs → chunk-RXOFO64U.mjs} +3 -3
- package/dist/chunk-RXOFO64U.mjs.map +1 -0
- package/dist/chunk-TOOHCAWP.mjs +1167 -0
- package/dist/chunk-TOOHCAWP.mjs.map +1 -0
- package/dist/{chunk-C6SCVOMC.mjs → chunk-TQYQVXNW.mjs} +5 -41
- package/dist/chunk-TQYQVXNW.mjs.map +1 -0
- package/dist/chunk-VBJLUHCY.mjs +23 -0
- package/dist/chunk-VBJLUHCY.mjs.map +1 -0
- package/dist/chunk-VRWZILTG.mjs +205 -0
- package/dist/chunk-VRWZILTG.mjs.map +1 -0
- package/dist/chunk-XVSO7FBM.mjs +61 -0
- package/dist/chunk-XVSO7FBM.mjs.map +1 -0
- package/dist/geometry-2d.d.mts +3 -6
- package/dist/geometry-2d.d.ts +3 -6
- package/dist/geometry-2d.js +5069 -2651
- package/dist/geometry-2d.js.map +1 -1
- package/dist/geometry-2d.mjs +8 -4
- package/dist/geometry-3d.d.mts +4 -7
- package/dist/geometry-3d.d.ts +4 -7
- package/dist/geometry-3d.js +3053 -2150
- package/dist/geometry-3d.js.map +1 -1
- package/dist/geometry-3d.mjs +7 -4
- package/dist/graph-2d.d.mts +4 -7
- package/dist/graph-2d.d.ts +4 -7
- package/dist/graph-2d.js +3363 -1670
- package/dist/graph-2d.js.map +1 -1
- package/dist/graph-2d.mjs +10 -3
- package/dist/host-3N4E4KJH.mjs +1142 -0
- package/dist/host-3N4E4KJH.mjs.map +1 -0
- package/dist/{host-Z3TEJKZA.mjs → host-6SNSZ332.mjs} +4 -4
- package/dist/{host-Z3TEJKZA.mjs.map → host-6SNSZ332.mjs.map} +1 -1
- package/dist/host-EVJT3LIF.mjs +3198 -0
- package/dist/host-EVJT3LIF.mjs.map +1 -0
- package/dist/host-HN4X3TBC.mjs +2374 -0
- package/dist/host-HN4X3TBC.mjs.map +1 -0
- package/dist/index.css +4 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +659 -19
- package/dist/index.d.ts +659 -19
- package/dist/index.js +11741 -9420
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1467 -336
- package/dist/index.mjs.map +1 -1
- package/dist/latex.d.mts +3 -4
- package/dist/latex.d.ts +3 -4
- package/dist/latex.js +33 -18
- package/dist/latex.js.map +1 -1
- package/dist/latex.mjs +2 -3
- package/dist/render-OCVGDKK6.mjs +8 -0
- package/dist/render-OCVGDKK6.mjs.map +1 -0
- package/dist/serialize-GKN6OVPM.mjs +6 -0
- package/dist/serialize-GKN6OVPM.mjs.map +1 -0
- package/dist/{types-CinstD7T.d.mts → types-rA4slL08.d.mts} +69 -4
- package/dist/{types-CinstD7T.d.ts → types-rA4slL08.d.ts} +69 -4
- package/package.json +24 -5
- package/dist/ExcalidrawWithMenus-EAVPOPJZ.mjs.map +0 -1
- package/dist/chunk-74VEEZBV.mjs +0 -619
- package/dist/chunk-74VEEZBV.mjs.map +0 -1
- package/dist/chunk-7P7SQFOW.mjs.map +0 -1
- package/dist/chunk-BJTO5JO5.mjs +0 -11
- package/dist/chunk-BJTO5JO5.mjs.map +0 -1
- package/dist/chunk-C6SCVOMC.mjs.map +0 -1
- package/dist/chunk-D257NCQW.mjs +0 -58
- package/dist/chunk-D257NCQW.mjs.map +0 -1
- package/dist/chunk-G7FR3AIV.mjs +0 -193
- package/dist/chunk-G7FR3AIV.mjs.map +0 -1
- package/dist/chunk-HTBLO5JO.mjs +0 -41
- package/dist/chunk-HTBLO5JO.mjs.map +0 -1
- package/dist/chunk-PWIMZIB6.mjs.map +0 -1
- package/dist/chunk-SBDMF4NQ.mjs +0 -212
- package/dist/chunk-SBDMF4NQ.mjs.map +0 -1
- package/dist/chunk-WQOABS6N.mjs +0 -197
- package/dist/chunk-WQOABS6N.mjs.map +0 -1
- package/dist/chunk-YVJP7NRG.mjs.map +0 -1
- package/dist/host-N6ACNJKI.mjs +0 -3226
- package/dist/host-N6ACNJKI.mjs.map +0 -1
- package/dist/host-NKGV6RF2.mjs +0 -1134
- package/dist/host-NKGV6RF2.mjs.map +0 -1
- package/dist/host-XVK7UCRE.mjs +0 -2908
- package/dist/host-XVK7UCRE.mjs.map +0 -1
|
@@ -1,6 +1,69 @@
|
|
|
1
1
|
import { ReactNode, ComponentType, RefAttributes } from 'react';
|
|
2
2
|
import { ExcalidrawElement } from '@excalidraw/excalidraw/element/types';
|
|
3
3
|
|
|
4
|
+
type SceneObject<A = Record<string, unknown>> = {
|
|
5
|
+
id: string;
|
|
6
|
+
kind: string;
|
|
7
|
+
label: string;
|
|
8
|
+
visible: boolean;
|
|
9
|
+
locked: boolean;
|
|
10
|
+
layer: string;
|
|
11
|
+
schemaVersion: number;
|
|
12
|
+
attrs: A;
|
|
13
|
+
};
|
|
14
|
+
type View2D = {
|
|
15
|
+
readonly bbox: readonly [number, number, number, number];
|
|
16
|
+
readonly showAxis: boolean;
|
|
17
|
+
readonly showGrid: boolean;
|
|
18
|
+
};
|
|
19
|
+
type View3D = {
|
|
20
|
+
readonly bbox3D: readonly [number, number, number, number, number, number];
|
|
21
|
+
readonly azimuth: number;
|
|
22
|
+
readonly elevation: number;
|
|
23
|
+
};
|
|
24
|
+
type ViewGraph2D = {
|
|
25
|
+
readonly xMin: number;
|
|
26
|
+
readonly xMax: number;
|
|
27
|
+
readonly yMin: number;
|
|
28
|
+
readonly yMax: number;
|
|
29
|
+
readonly showAxis: boolean;
|
|
30
|
+
readonly showGrid: boolean;
|
|
31
|
+
};
|
|
32
|
+
type StateMeta = {
|
|
33
|
+
readonly domain: '2d';
|
|
34
|
+
readonly version: number;
|
|
35
|
+
readonly view: View2D;
|
|
36
|
+
} | {
|
|
37
|
+
readonly domain: '3d';
|
|
38
|
+
readonly version: number;
|
|
39
|
+
readonly view: View3D;
|
|
40
|
+
} | {
|
|
41
|
+
readonly domain: 'graph2d';
|
|
42
|
+
readonly version: number;
|
|
43
|
+
readonly view: ViewGraph2D;
|
|
44
|
+
};
|
|
45
|
+
type State = {
|
|
46
|
+
readonly objects: Readonly<Record<string, SceneObject>>;
|
|
47
|
+
readonly order: readonly string[];
|
|
48
|
+
readonly counter: number;
|
|
49
|
+
readonly meta: StateMeta;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/** Minimal client-safe response required by the geometry AI editor. */
|
|
53
|
+
type AiFigureUiResult = {
|
|
54
|
+
ok: true;
|
|
55
|
+
state: State;
|
|
56
|
+
} | {
|
|
57
|
+
ok: false;
|
|
58
|
+
message: string;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Consumer-provided bridge to a server-side `generateFigure()` call.
|
|
62
|
+
* Implementations must keep API credentials outside the browser bundle.
|
|
63
|
+
*/
|
|
64
|
+
type GenerateGeometryFigure = (problem: string, options: {
|
|
65
|
+
signal: AbortSignal;
|
|
66
|
+
}) => Promise<AiFigureUiResult>;
|
|
4
67
|
/**
|
|
5
68
|
* Kết quả trả về từ `restoreFileFromCustomData`. Chứa đủ thông tin để
|
|
6
69
|
* consumer gọi `api.addFiles(...)`.
|
|
@@ -37,6 +100,8 @@ interface StampHostProps {
|
|
|
37
100
|
onClose: () => void;
|
|
38
101
|
/** Dark theme flag. */
|
|
39
102
|
isDark: boolean;
|
|
103
|
+
/** Optional client-safe bridge for the geometry-2d AI prompt editor. */
|
|
104
|
+
generateGeometryFigure?: GenerateGeometryFigure;
|
|
40
105
|
}
|
|
41
106
|
/**
|
|
42
107
|
* Imperative API mà main view truy cập qua ref:
|
|
@@ -63,7 +128,7 @@ type StampHostComponent = ComponentType<StampHostProps & RefAttributes<StampHost
|
|
|
63
128
|
*
|
|
64
129
|
* Main view dispatch generic: `<stamp.Host ... />` — không cần biết kind.
|
|
65
130
|
*/
|
|
66
|
-
interface StampType {
|
|
131
|
+
interface StampType<TCustomData extends BaseStampCustomData = BaseStampCustomData> {
|
|
67
132
|
/** Unique kind. VD: 'geometry', 'latex'. Phải khớp với customData.kind. */
|
|
68
133
|
kind: string;
|
|
69
134
|
/** Phím tắt mở/đóng stamp (lowercase, 1 ký tự). VD: 'g', 'l'. */
|
|
@@ -77,14 +142,14 @@ interface StampType {
|
|
|
77
142
|
/** Test data-testid cho nút toolbar (optional). */
|
|
78
143
|
toolbarTestId?: string;
|
|
79
144
|
/** Type guard: customData có thuộc về stamp này không. */
|
|
80
|
-
matchesCustomData(data: unknown):
|
|
145
|
+
matchesCustomData(data: unknown): data is TCustomData;
|
|
81
146
|
/**
|
|
82
147
|
* Re-render SVG từ customData. Dùng khi restore math-stamp file sau reload
|
|
83
148
|
* page (Excalidraw không persist binary file payload, chỉ giữ fileId trong
|
|
84
149
|
* element). SVG render với light palette (nét đậm) — Excalidraw tự đảo
|
|
85
150
|
* màu trong dark mode qua CSS filter.
|
|
86
151
|
*/
|
|
87
|
-
renderSvgFromCustomData(data:
|
|
152
|
+
renderSvgFromCustomData(data: TCustomData): Promise<string>;
|
|
88
153
|
/**
|
|
89
154
|
* Regenerate file SVG/PNG cho element thuộc stamp này khi reload từ persisted
|
|
90
155
|
* snapshot. Trả về `RestoredStampFile` để consumer gọi `api.addFiles`, hoặc
|
|
@@ -107,4 +172,4 @@ interface StampType {
|
|
|
107
172
|
experimental?: boolean;
|
|
108
173
|
}
|
|
109
174
|
|
|
110
|
-
export type { BaseStampCustomData as B, StampType as S };
|
|
175
|
+
export type { AiFigureUiResult as A, BaseStampCustomData as B, GenerateGeometryFigure as G, StampType as S, State as a };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xom11/whiteboard",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Excalidraw + JSXGraph + KaTeX whiteboard component (drawing, geometry stamps, LaTeX stamps).",
|
|
6
6
|
"license": "MIT",
|
|
@@ -47,13 +47,19 @@
|
|
|
47
47
|
"*.css"
|
|
48
48
|
],
|
|
49
49
|
"scripts": {
|
|
50
|
-
"build": "tsup && node scripts/inject-use-client.mjs",
|
|
51
|
-
"
|
|
50
|
+
"build": "tsup && node scripts/inject-use-client.mjs && node scripts/build-catalog.mjs",
|
|
51
|
+
"build:catalog": "node scripts/build-catalog.mjs",
|
|
52
|
+
"dev": "tsup --watch --onSuccess \"node scripts/inject-use-client.mjs && node scripts/build-catalog.mjs\"",
|
|
52
53
|
"test": "jest",
|
|
53
54
|
"test:e2e": "playwright test",
|
|
54
55
|
"typecheck": "tsc --noEmit",
|
|
56
|
+
"lint": "eslint .",
|
|
57
|
+
"lint:fix": "eslint . --fix",
|
|
55
58
|
"clean": "rm -rf dist .yalc yalc.lock",
|
|
56
|
-
"demo": "vite --config scripts/demo/vite.config.ts"
|
|
59
|
+
"demo": "vite --config scripts/demo/vite.config.ts",
|
|
60
|
+
"ai:eval": "tsx scripts/eval-ai.ts",
|
|
61
|
+
"ai:smoke": "tsx scripts/smoke-ai.ts",
|
|
62
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
57
63
|
},
|
|
58
64
|
"peerDependencies": {
|
|
59
65
|
"@excalidraw/excalidraw": "^0.18.1",
|
|
@@ -63,6 +69,7 @@
|
|
|
63
69
|
"react-dom": ">=18.0.0"
|
|
64
70
|
},
|
|
65
71
|
"devDependencies": {
|
|
72
|
+
"@eslint/js": "^9.39.4",
|
|
66
73
|
"@playwright/test": "^1.60.0",
|
|
67
74
|
"@tailwindcss/vite": "^4.3.0",
|
|
68
75
|
"@testing-library/jest-dom": "^6.9.1",
|
|
@@ -73,8 +80,14 @@
|
|
|
73
80
|
"@types/node": "^22.0.0",
|
|
74
81
|
"@types/react": "^19.0.0",
|
|
75
82
|
"@types/react-dom": "^19.0.0",
|
|
83
|
+
"@typescript-eslint/eslint-plugin": "^8.59.4",
|
|
84
|
+
"@typescript-eslint/parser": "^8.59.4",
|
|
76
85
|
"@vitejs/plugin-react": "^6.0.2",
|
|
86
|
+
"eslint": "^9.39.4",
|
|
87
|
+
"eslint-plugin-react": "^7.37.5",
|
|
88
|
+
"eslint-plugin-react-hooks": "^5.2.0",
|
|
77
89
|
"fake-indexeddb": "^6.0.0",
|
|
90
|
+
"globals": "^15.15.0",
|
|
78
91
|
"jest": "^29.7.0",
|
|
79
92
|
"jest-environment-jsdom": "^29.7.0",
|
|
80
93
|
"next": "16.1.6",
|
|
@@ -83,10 +96,16 @@
|
|
|
83
96
|
"tailwindcss": "^4.3.0",
|
|
84
97
|
"ts-jest": "^29.4.9",
|
|
85
98
|
"tsup": "^8.3.5",
|
|
99
|
+
"tsx": "^4.22.3",
|
|
86
100
|
"typescript": "^5.6.0",
|
|
101
|
+
"typescript-eslint": "^8.59.4",
|
|
87
102
|
"vite": "^8.0.13"
|
|
88
103
|
},
|
|
89
104
|
"dependencies": {
|
|
90
|
-
"
|
|
105
|
+
"@anthropic-ai/sdk": "^0.98.0",
|
|
106
|
+
"immer": "^10.2.0",
|
|
107
|
+
"pdfjs-dist": "^5.7.284",
|
|
108
|
+
"zod": "^3.23.8",
|
|
109
|
+
"zod-to-json-schema": "^3.25.2"
|
|
91
110
|
}
|
|
92
111
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ExcalidrawWithMenus.tsx"],"names":[],"mappings":";;;;AAiBO,SAAS,oBAAoB,KAAA,EAAwB;AAC1D,EAAA,MAAM,EAAE,QAAA,EAAU,GAAG,IAAA,EAAK,GAAI,KAAA;AAC9B,EAAA,uBACE,IAAA,CAAC,UAAA,EAAA,EAAY,GAAG,IAAA,EAEd,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,QAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,QAAA,CAAS,YAAA,CAAa,SAAA,EAAtB,EAAgC,CAAA;AAAA,sBACjC,GAAA,CAAC,QAAA,CAAS,YAAA,CAAa,WAAA,EAAtB,EAAkC,CAAA;AAAA,sBACnC,GAAA,CAAC,QAAA,CAAS,YAAA,CAAa,WAAA,EAAtB,EAAkC,CAAA;AAAA,sBACnC,GAAA,CAAC,QAAA,CAAS,YAAA,CAAa,WAAA,EAAtB,EAAkC;AAAA,KAAA,EACrC,CAAA;AAAA,oBAEA,GAAA,CAAC,MAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EACR,CAAA;AAAA,oBAGA,GAAA,CAAC,aAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EACR,CAAA;AAAA,IACC;AAAA,GAAA,EACH,CAAA;AAEJ","file":"ExcalidrawWithMenus-EAVPOPJZ.mjs","sourcesContent":["'use client';\n\n// Client-only wrapper around Excalidraw that lets us reach for static helpers\n// like `MainMenu.DefaultItems.*`. Whiteboard dynamic-imports this\n// file so SSR never evaluates @excalidraw/excalidraw, while inside this file we\n// can use plain static imports (the entire module loads on the client).\n\nimport React from 'react';\nimport {\n Excalidraw,\n MainMenu,\n Footer,\n WelcomeScreen,\n} from '@excalidraw/excalidraw';\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype ExcalidrawProps = any;\n\nexport function ExcalidrawWithMenus(props: ExcalidrawProps) {\n const { children, ...rest } = props;\n return (\n <Excalidraw {...rest}>\n {/* Replace default menu with curated items — no socials/help/branding */}\n <MainMenu>\n <MainMenu.DefaultItems.LoadScene />\n <MainMenu.DefaultItems.SaveAsImage />\n <MainMenu.DefaultItems.ClearCanvas />\n <MainMenu.DefaultItems.ToggleTheme />\n </MainMenu>\n {/* Footer slot with no content suppresses default \"Made with Excalidraw\" link */}\n <Footer>\n <span />\n </Footer>\n {/* WelcomeScreen slot (empty) prevents the default Excalidraw welcome panel\n * (which includes the Excalidraw logo and social links) from appearing. */}\n <WelcomeScreen>\n <span />\n </WelcomeScreen>\n {children}\n </Excalidraw>\n );\n}\n"]}
|