@xom11/whiteboard 0.11.0 → 0.24.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 +67 -0
- package/dist/{ExcalidrawWithMenus-EAVPOPJZ.mjs → ExcalidrawWithMenus-WENZRYYE.mjs} +2 -3
- package/dist/ExcalidrawWithMenus-WENZRYYE.mjs.map +1 -0
- package/dist/catalog.json +57 -0
- package/dist/chunk-4D5CSIJO.mjs +1167 -0
- package/dist/chunk-4D5CSIJO.mjs.map +1 -0
- package/dist/chunk-5UTGXHLJ.mjs +57 -0
- package/dist/chunk-5UTGXHLJ.mjs.map +1 -0
- package/dist/chunk-6V4SH4JJ.mjs +1801 -0
- package/dist/chunk-6V4SH4JJ.mjs.map +1 -0
- package/dist/chunk-AZIARTGX.mjs +23 -0
- package/dist/chunk-AZIARTGX.mjs.map +1 -0
- package/dist/chunk-BKSXPNPQ.mjs +348 -0
- package/dist/chunk-BKSXPNPQ.mjs.map +1 -0
- package/dist/{chunk-YVJP7NRG.mjs → chunk-CRAPWQKJ.mjs} +7 -9
- package/dist/chunk-CRAPWQKJ.mjs.map +1 -0
- package/dist/chunk-CSCF3YFZ.mjs +388 -0
- package/dist/chunk-CSCF3YFZ.mjs.map +1 -0
- package/dist/chunk-HNQLZIEP.mjs +78 -0
- package/dist/chunk-HNQLZIEP.mjs.map +1 -0
- package/dist/chunk-IBTRMWD6.mjs +28 -0
- package/dist/chunk-IBTRMWD6.mjs.map +1 -0
- package/dist/chunk-ICR4CVOE.mjs +57 -0
- package/dist/chunk-ICR4CVOE.mjs.map +1 -0
- package/dist/chunk-LVNCYP4J.mjs +57 -0
- package/dist/chunk-LVNCYP4J.mjs.map +1 -0
- package/dist/chunk-MFOGFFIL.mjs +95 -0
- package/dist/chunk-MFOGFFIL.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-C6SCVOMC.mjs → chunk-QGNU34T7.mjs} +5 -41
- package/dist/chunk-QGNU34T7.mjs.map +1 -0
- package/dist/chunk-R5FL6S7L.mjs +22 -0
- package/dist/chunk-R5FL6S7L.mjs.map +1 -0
- package/dist/{chunk-7P7SQFOW.mjs → chunk-SGFJLHHG.mjs} +3 -3
- package/dist/chunk-SGFJLHHG.mjs.map +1 -0
- package/dist/{chunk-PWIMZIB6.mjs → chunk-WWMQ2VHZ.mjs} +7 -8
- package/dist/chunk-WWMQ2VHZ.mjs.map +1 -0
- package/dist/chunk-YIPI3WUL.mjs +61 -0
- package/dist/chunk-YIPI3WUL.mjs.map +1 -0
- package/dist/chunk-ZBJBQKJ2.mjs +330 -0
- package/dist/chunk-ZBJBQKJ2.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 +7007 -2633
- 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 +5446 -2507
- 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 +5300 -1677
- package/dist/graph-2d.js.map +1 -1
- package/dist/graph-2d.mjs +10 -3
- package/dist/host-DOAYVL35.mjs +3199 -0
- package/dist/host-DOAYVL35.mjs.map +1 -0
- package/dist/host-GKNQBBUE.mjs +1142 -0
- package/dist/host-GKNQBBUE.mjs.map +1 -0
- package/dist/{host-Z3TEJKZA.mjs → host-QS2EOTRJ.mjs} +4 -4
- package/dist/{host-Z3TEJKZA.mjs.map → host-QS2EOTRJ.mjs.map} +1 -1
- package/dist/host-TLIXN4CF.mjs +2374 -0
- package/dist/host-TLIXN4CF.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 +13736 -9491
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1465 -342
- 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-SA4JTOW3.mjs +8 -0
- package/dist/render-SA4JTOW3.mjs.map +1 -0
- package/dist/serialize-3NZS6A6Q.mjs +6 -0
- package/dist/serialize-3NZS6A6Q.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 +34 -6
- 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
package/README.md
CHANGED
|
@@ -61,6 +61,55 @@ export function ClassroomBoard() {
|
|
|
61
61
|
}
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
+
### AI dựng hình học 2D (opt-in)
|
|
65
|
+
|
|
66
|
+
Textarea AI chỉ xuất hiện khi truyền `generateGeometryFigure`. Callback này chạy từ client nên phải gọi một server boundary của ứng dụng; không đưa `ANTHROPIC_API_KEY` vào component hoặc biến môi trường public.
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
'use client';
|
|
70
|
+
|
|
71
|
+
import { Whiteboard, type GenerateGeometryFigure } from '@xom11/whiteboard';
|
|
72
|
+
|
|
73
|
+
const generateGeometryFigure: GenerateGeometryFigure = async (problem, { signal }) => {
|
|
74
|
+
const response = await fetch('/api/geometry/ai', {
|
|
75
|
+
method: 'POST',
|
|
76
|
+
headers: { 'content-type': 'application/json' },
|
|
77
|
+
body: JSON.stringify({ problem }),
|
|
78
|
+
signal,
|
|
79
|
+
});
|
|
80
|
+
return response.json();
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export function ClassroomBoard() {
|
|
84
|
+
return <Whiteboard generateGeometryFigure={generateGeometryFigure} />;
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Ví dụ route phía server trong Next.js:
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
import { generateFigure } from '@xom11/whiteboard';
|
|
92
|
+
|
|
93
|
+
export async function POST(request: Request) {
|
|
94
|
+
const { problem } = await request.json();
|
|
95
|
+
const result = await generateFigure(problem, {
|
|
96
|
+
apiKey: process.env.ANTHROPIC_API_KEY ?? '',
|
|
97
|
+
});
|
|
98
|
+
return Response.json(
|
|
99
|
+
result.ok
|
|
100
|
+
? { ok: true, state: result.state }
|
|
101
|
+
: { ok: false, message: result.message },
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Trong repo package, chạy smoke/eval với API key chỉ ở local shell:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
ANTHROPIC_API_KEY=... npm run ai:smoke
|
|
110
|
+
ANTHROPIC_API_KEY=... npm run ai:eval -- --limit 5
|
|
111
|
+
```
|
|
112
|
+
|
|
64
113
|
## Migration to v0.8.0 (geometry-3d redesign)
|
|
65
114
|
|
|
66
115
|
`geometry3dStamp` được viết lại theo UX của GeoGebra 3D Calculator:
|
|
@@ -110,6 +159,24 @@ import { latexStamp } from '@xom11/whiteboard/latex';
|
|
|
110
159
|
|
|
111
160
|
`next` không còn là peer dependency. Whiteboard dùng `React.lazy + Suspense` thuần. Consumer cần Next.js App Router vẫn hoạt động (dist có sẵn `'use client'` directive).
|
|
112
161
|
|
|
162
|
+
## Extending — thêm stamp mới
|
|
163
|
+
|
|
164
|
+
Fork repo + viết stamp mới trong ~30 phút. Tham khảo:
|
|
165
|
+
|
|
166
|
+
- **Howto:** [`docs/superpowers/specs/add-new-stamp-howto.md`](./docs/superpowers/specs/add-new-stamp-howto.md) — 6 bước có sẵn lệnh.
|
|
167
|
+
- **Template:** [`examples/stamp-template/`](./examples/stamp-template/) — skeleton "color-swatch" stamp, copy + đổi `kind`.
|
|
168
|
+
- **Contract test:** mỗi stamp PHẢI pass `runStampContract` (xem [`src/stamps/shared/__tests__/stamp-contract.ts`](./src/stamps/shared/__tests__/stamp-contract.ts)) để đảm bảo `matchesCustomData` / `renderSvgFromCustomData` / roundtrip restore không break.
|
|
169
|
+
- **Catalog:** thêm entry vào [`src/stamps/shared/catalog.ts`](./src/stamps/shared/catalog.ts). Bundle size tự tính qua `scripts/build-catalog.mjs` khi `npm run build`.
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
import { STAMP_CATALOG, findCatalogEntry } from '@xom11/whiteboard';
|
|
173
|
+
|
|
174
|
+
// Render admin UI từ catalog
|
|
175
|
+
STAMP_CATALOG.forEach((entry) => {
|
|
176
|
+
console.log(entry.id, entry.title, entry.bundleSize.js + 'KB gzip');
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
113
180
|
## Development
|
|
114
181
|
|
|
115
182
|
```bash
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import './chunk-BJTO5JO5.mjs';
|
|
3
2
|
import { Excalidraw, MainMenu, Footer, WelcomeScreen } from '@excalidraw/excalidraw';
|
|
4
3
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
4
|
|
|
@@ -19,5 +18,5 @@ function ExcalidrawWithMenus(props) {
|
|
|
19
18
|
}
|
|
20
19
|
|
|
21
20
|
export { ExcalidrawWithMenus };
|
|
22
|
-
//# sourceMappingURL=ExcalidrawWithMenus-
|
|
23
|
-
//# sourceMappingURL=ExcalidrawWithMenus-
|
|
21
|
+
//# sourceMappingURL=ExcalidrawWithMenus-WENZRYYE.mjs.map
|
|
22
|
+
//# sourceMappingURL=ExcalidrawWithMenus-WENZRYYE.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
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-WENZRYYE.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 \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"]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"generatedAt": "2026-05-26T06:25:42.573Z",
|
|
3
|
+
"entries": [
|
|
4
|
+
{
|
|
5
|
+
"id": "geometry",
|
|
6
|
+
"title": "Hình học 2D (JSXGraph)",
|
|
7
|
+
"version": 1,
|
|
8
|
+
"experimental": false,
|
|
9
|
+
"runtimeDeps": [
|
|
10
|
+
"jsxgraph"
|
|
11
|
+
],
|
|
12
|
+
"bundleSize": {
|
|
13
|
+
"js": 60.33,
|
|
14
|
+
"css": 0
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"id": "latex",
|
|
19
|
+
"title": "Công thức LaTeX (KaTeX)",
|
|
20
|
+
"version": 1,
|
|
21
|
+
"experimental": false,
|
|
22
|
+
"runtimeDeps": [
|
|
23
|
+
"katex"
|
|
24
|
+
],
|
|
25
|
+
"bundleSize": {
|
|
26
|
+
"js": 8.93,
|
|
27
|
+
"css": 0
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": "geometry3d",
|
|
32
|
+
"title": "Hình học 3D (JSXGraph view3d)",
|
|
33
|
+
"version": 2,
|
|
34
|
+
"experimental": true,
|
|
35
|
+
"runtimeDeps": [
|
|
36
|
+
"jsxgraph"
|
|
37
|
+
],
|
|
38
|
+
"bundleSize": {
|
|
39
|
+
"js": 50.73,
|
|
40
|
+
"css": 0
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"id": "graph2d",
|
|
45
|
+
"title": "Đồ thị hàm số 2D (JSXGraph)",
|
|
46
|
+
"version": 2,
|
|
47
|
+
"experimental": true,
|
|
48
|
+
"runtimeDeps": [
|
|
49
|
+
"jsxgraph"
|
|
50
|
+
],
|
|
51
|
+
"bundleSize": {
|
|
52
|
+
"js": 42.91,
|
|
53
|
+
"css": 0
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
}
|