@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.
Files changed (112) hide show
  1. package/README.md +67 -0
  2. package/dist/{ExcalidrawWithMenus-EAVPOPJZ.mjs → ExcalidrawWithMenus-WENZRYYE.mjs} +2 -3
  3. package/dist/ExcalidrawWithMenus-WENZRYYE.mjs.map +1 -0
  4. package/dist/catalog.json +57 -0
  5. package/dist/chunk-4D5CSIJO.mjs +1167 -0
  6. package/dist/chunk-4D5CSIJO.mjs.map +1 -0
  7. package/dist/chunk-5UTGXHLJ.mjs +57 -0
  8. package/dist/chunk-5UTGXHLJ.mjs.map +1 -0
  9. package/dist/chunk-6V4SH4JJ.mjs +1801 -0
  10. package/dist/chunk-6V4SH4JJ.mjs.map +1 -0
  11. package/dist/chunk-AZIARTGX.mjs +23 -0
  12. package/dist/chunk-AZIARTGX.mjs.map +1 -0
  13. package/dist/chunk-BKSXPNPQ.mjs +348 -0
  14. package/dist/chunk-BKSXPNPQ.mjs.map +1 -0
  15. package/dist/{chunk-YVJP7NRG.mjs → chunk-CRAPWQKJ.mjs} +7 -9
  16. package/dist/chunk-CRAPWQKJ.mjs.map +1 -0
  17. package/dist/chunk-CSCF3YFZ.mjs +388 -0
  18. package/dist/chunk-CSCF3YFZ.mjs.map +1 -0
  19. package/dist/chunk-HNQLZIEP.mjs +78 -0
  20. package/dist/chunk-HNQLZIEP.mjs.map +1 -0
  21. package/dist/chunk-IBTRMWD6.mjs +28 -0
  22. package/dist/chunk-IBTRMWD6.mjs.map +1 -0
  23. package/dist/chunk-ICR4CVOE.mjs +57 -0
  24. package/dist/chunk-ICR4CVOE.mjs.map +1 -0
  25. package/dist/chunk-LVNCYP4J.mjs +57 -0
  26. package/dist/chunk-LVNCYP4J.mjs.map +1 -0
  27. package/dist/chunk-MFOGFFIL.mjs +95 -0
  28. package/dist/chunk-MFOGFFIL.mjs.map +1 -0
  29. package/dist/chunk-NVJ7K3DK.mjs +29 -0
  30. package/dist/chunk-NVJ7K3DK.mjs.map +1 -0
  31. package/dist/chunk-O4WIZFRQ.mjs +11 -0
  32. package/dist/chunk-O4WIZFRQ.mjs.map +1 -0
  33. package/dist/{chunk-C6SCVOMC.mjs → chunk-QGNU34T7.mjs} +5 -41
  34. package/dist/chunk-QGNU34T7.mjs.map +1 -0
  35. package/dist/chunk-R5FL6S7L.mjs +22 -0
  36. package/dist/chunk-R5FL6S7L.mjs.map +1 -0
  37. package/dist/{chunk-7P7SQFOW.mjs → chunk-SGFJLHHG.mjs} +3 -3
  38. package/dist/chunk-SGFJLHHG.mjs.map +1 -0
  39. package/dist/{chunk-PWIMZIB6.mjs → chunk-WWMQ2VHZ.mjs} +7 -8
  40. package/dist/chunk-WWMQ2VHZ.mjs.map +1 -0
  41. package/dist/chunk-YIPI3WUL.mjs +61 -0
  42. package/dist/chunk-YIPI3WUL.mjs.map +1 -0
  43. package/dist/chunk-ZBJBQKJ2.mjs +330 -0
  44. package/dist/chunk-ZBJBQKJ2.mjs.map +1 -0
  45. package/dist/geometry-2d.d.mts +3 -6
  46. package/dist/geometry-2d.d.ts +3 -6
  47. package/dist/geometry-2d.js +7007 -2633
  48. package/dist/geometry-2d.js.map +1 -1
  49. package/dist/geometry-2d.mjs +8 -4
  50. package/dist/geometry-3d.d.mts +4 -7
  51. package/dist/geometry-3d.d.ts +4 -7
  52. package/dist/geometry-3d.js +5446 -2507
  53. package/dist/geometry-3d.js.map +1 -1
  54. package/dist/geometry-3d.mjs +7 -4
  55. package/dist/graph-2d.d.mts +4 -7
  56. package/dist/graph-2d.d.ts +4 -7
  57. package/dist/graph-2d.js +5300 -1677
  58. package/dist/graph-2d.js.map +1 -1
  59. package/dist/graph-2d.mjs +10 -3
  60. package/dist/host-DOAYVL35.mjs +3199 -0
  61. package/dist/host-DOAYVL35.mjs.map +1 -0
  62. package/dist/host-GKNQBBUE.mjs +1142 -0
  63. package/dist/host-GKNQBBUE.mjs.map +1 -0
  64. package/dist/{host-Z3TEJKZA.mjs → host-QS2EOTRJ.mjs} +4 -4
  65. package/dist/{host-Z3TEJKZA.mjs.map → host-QS2EOTRJ.mjs.map} +1 -1
  66. package/dist/host-TLIXN4CF.mjs +2374 -0
  67. package/dist/host-TLIXN4CF.mjs.map +1 -0
  68. package/dist/index.css +4 -1
  69. package/dist/index.css.map +1 -1
  70. package/dist/index.d.mts +659 -19
  71. package/dist/index.d.ts +659 -19
  72. package/dist/index.js +13736 -9491
  73. package/dist/index.js.map +1 -1
  74. package/dist/index.mjs +1465 -342
  75. package/dist/index.mjs.map +1 -1
  76. package/dist/latex.d.mts +3 -4
  77. package/dist/latex.d.ts +3 -4
  78. package/dist/latex.js +33 -18
  79. package/dist/latex.js.map +1 -1
  80. package/dist/latex.mjs +2 -3
  81. package/dist/render-SA4JTOW3.mjs +8 -0
  82. package/dist/render-SA4JTOW3.mjs.map +1 -0
  83. package/dist/serialize-3NZS6A6Q.mjs +6 -0
  84. package/dist/serialize-3NZS6A6Q.mjs.map +1 -0
  85. package/dist/{types-CinstD7T.d.mts → types-rA4slL08.d.mts} +69 -4
  86. package/dist/{types-CinstD7T.d.ts → types-rA4slL08.d.ts} +69 -4
  87. package/package.json +34 -6
  88. package/dist/ExcalidrawWithMenus-EAVPOPJZ.mjs.map +0 -1
  89. package/dist/chunk-74VEEZBV.mjs +0 -619
  90. package/dist/chunk-74VEEZBV.mjs.map +0 -1
  91. package/dist/chunk-7P7SQFOW.mjs.map +0 -1
  92. package/dist/chunk-BJTO5JO5.mjs +0 -11
  93. package/dist/chunk-BJTO5JO5.mjs.map +0 -1
  94. package/dist/chunk-C6SCVOMC.mjs.map +0 -1
  95. package/dist/chunk-D257NCQW.mjs +0 -58
  96. package/dist/chunk-D257NCQW.mjs.map +0 -1
  97. package/dist/chunk-G7FR3AIV.mjs +0 -193
  98. package/dist/chunk-G7FR3AIV.mjs.map +0 -1
  99. package/dist/chunk-HTBLO5JO.mjs +0 -41
  100. package/dist/chunk-HTBLO5JO.mjs.map +0 -1
  101. package/dist/chunk-PWIMZIB6.mjs.map +0 -1
  102. package/dist/chunk-SBDMF4NQ.mjs +0 -212
  103. package/dist/chunk-SBDMF4NQ.mjs.map +0 -1
  104. package/dist/chunk-WQOABS6N.mjs +0 -197
  105. package/dist/chunk-WQOABS6N.mjs.map +0 -1
  106. package/dist/chunk-YVJP7NRG.mjs.map +0 -1
  107. package/dist/host-N6ACNJKI.mjs +0 -3226
  108. package/dist/host-N6ACNJKI.mjs.map +0 -1
  109. package/dist/host-NKGV6RF2.mjs +0 -1134
  110. package/dist/host-NKGV6RF2.mjs.map +0 -1
  111. package/dist/host-XVK7UCRE.mjs +0 -2908
  112. 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-EAVPOPJZ.mjs.map
23
- //# sourceMappingURL=ExcalidrawWithMenus-EAVPOPJZ.mjs.map
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
+ }