@q9labsai/chalk-whiteboard 4.1.16 → 5.0.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/LICENSE +21 -0
- package/dist/{chunk-F4B4ANIZ.js → chunk-6ZV7GBAC.js} +208 -161
- package/dist/{chunk-4XG2ABSP.js → chunk-W4FLPXAX.js} +4 -4
- package/dist/collab/engine.d.ts +14 -5
- package/dist/collab/files.d.ts +2 -26
- package/dist/collab/index.js +2 -2
- package/dist/collab/order.d.ts +6 -0
- package/dist/collab/syncable.d.ts +2 -0
- package/dist/collab/wire.d.ts +6 -0
- package/dist/embedded/chalk-whiteboard/asset-manifest.json +2 -2
- package/dist/embedded/chalk-whiteboard/renderer.js +510 -510
- package/dist/embedded/controller.d.ts +0 -12
- package/dist/embedded/index.js +4 -55
- package/dist/embedded/renderer-bridge.d.ts +0 -7
- package/dist/embedded/renderer.d.ts +0 -1
- package/dist/{engine-5XZHDUXG.js → engine-BIJ57YN3.js} +1 -1
- package/dist/index.js +2 -2
- package/dist/react/WhiteboardCanvas.d.ts +2 -0
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js +77 -59
- package/package.json +2 -3
|
@@ -35,18 +35,6 @@ export type ChalkEmbeddedWhiteboardTransportEvent = {
|
|
|
35
35
|
readonly reason: "scene_changed" | "cursor_expired" | "gap";
|
|
36
36
|
};
|
|
37
37
|
export interface ChalkEmbeddedWhiteboardFileTransport {
|
|
38
|
-
readonly initiateUpload: (input: {
|
|
39
|
-
readonly fileId: string;
|
|
40
|
-
readonly mimeType: string;
|
|
41
|
-
readonly byteLength: number;
|
|
42
|
-
readonly sha256: string;
|
|
43
|
-
}) => Promise<{
|
|
44
|
-
readonly uploadId: string;
|
|
45
|
-
readonly method: "PUT";
|
|
46
|
-
readonly uploadUrl: string;
|
|
47
|
-
readonly headers: Readonly<Record<string, string>>;
|
|
48
|
-
}>;
|
|
49
|
-
readonly finalizeUpload: (uploadId: string) => Promise<void>;
|
|
50
38
|
readonly getDownloadUrl: (fileId: string) => Promise<{
|
|
51
39
|
readonly downloadUrl: string;
|
|
52
40
|
}>;
|
package/dist/embedded/index.js
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
// src/embedded/controller.ts
|
|
2
|
-
import { sha256 } from "@noble/hashes/sha2.js";
|
|
3
|
-
import { bytesToHex } from "@noble/hashes/utils.js";
|
|
4
|
-
|
|
5
1
|
// src/embedded/protocol.ts
|
|
6
2
|
var CHALK_EMBEDDED_WHITEBOARD_BRIDGE_VERSION = 1;
|
|
7
3
|
var CHALK_EMBEDDED_WHITEBOARD_EXCALIDRAW_VERSION = "0.18.1";
|
|
@@ -337,32 +333,7 @@ var ChalkWhiteboardController = class {
|
|
|
337
333
|
async #writeFile(message) {
|
|
338
334
|
const payload = requireFileWrite(message.payload);
|
|
339
335
|
await this.#operation(payload.requestId, async () => {
|
|
340
|
-
|
|
341
|
-
const abortController = this.#beginFileTransfer(payload.requestId);
|
|
342
|
-
try {
|
|
343
|
-
const blob = await this.#dataURLBlob(payload.dataURL);
|
|
344
|
-
if (blob.size !== payload.byteLength) throw new Error("whiteboard file byte length does not match");
|
|
345
|
-
const validated = await validateFileBlob(blob, payload.mimeType);
|
|
346
|
-
if (bytesToHex(sha256(validated.bytes)) !== payload.sha256.toLowerCase()) {
|
|
347
|
-
throw new Error("whiteboard file digest does not match");
|
|
348
|
-
}
|
|
349
|
-
const upload = await this.options.transport.files.initiateUpload({
|
|
350
|
-
fileId: payload.fileId,
|
|
351
|
-
mimeType: validated.mimeType,
|
|
352
|
-
byteLength: payload.byteLength,
|
|
353
|
-
sha256: payload.sha256
|
|
354
|
-
});
|
|
355
|
-
const response = await this.#fetch(upload.uploadUrl, {
|
|
356
|
-
method: upload.method,
|
|
357
|
-
headers: upload.headers,
|
|
358
|
-
body: blob,
|
|
359
|
-
signal: abortController.signal
|
|
360
|
-
});
|
|
361
|
-
if (!response.ok) throw new Error(`whiteboard file upload failed with HTTP ${response.status}`);
|
|
362
|
-
await this.options.transport.files.finalizeUpload(upload.uploadId);
|
|
363
|
-
} finally {
|
|
364
|
-
this.#finishFileTransfer(payload.requestId, abortController);
|
|
365
|
-
}
|
|
336
|
+
throw new Error("Board uploads are unavailable.");
|
|
366
337
|
});
|
|
367
338
|
}
|
|
368
339
|
async #readFile(message) {
|
|
@@ -516,28 +487,6 @@ var ChalkWhiteboardController = class {
|
|
|
516
487
|
const message = safeErrorMessage(cause);
|
|
517
488
|
this.options.onError?.({ code: "invalid_renderer_message", message, recoverable: false });
|
|
518
489
|
}
|
|
519
|
-
async #dataURLBlob(dataURL) {
|
|
520
|
-
if (!dataURL.startsWith("data:") || dataURL.length > Math.ceil(MAX_FILE_BYTES * 4 / 3) + 1024) {
|
|
521
|
-
throw new Error("whiteboard file data is invalid");
|
|
522
|
-
}
|
|
523
|
-
const separator = dataURL.indexOf(",");
|
|
524
|
-
if (separator < 0) throw new Error("whiteboard file data is invalid");
|
|
525
|
-
const metadata = dataURL.slice(5, separator).split(";");
|
|
526
|
-
const mimeType = normalizeMimeType(metadata[0] ?? "");
|
|
527
|
-
if (metadata.length !== 2 || metadata[1]?.toLowerCase() !== "base64") {
|
|
528
|
-
throw new Error("whiteboard file data must use base64 encoding");
|
|
529
|
-
}
|
|
530
|
-
let decoded;
|
|
531
|
-
try {
|
|
532
|
-
decoded = atob(dataURL.slice(separator + 1));
|
|
533
|
-
} catch {
|
|
534
|
-
throw new Error("whiteboard file data is not valid base64");
|
|
535
|
-
}
|
|
536
|
-
const bytes = Uint8Array.from(decoded, (character) => character.charCodeAt(0));
|
|
537
|
-
const blob = new Blob([bytes], { type: mimeType });
|
|
538
|
-
if (blob.size > MAX_FILE_BYTES) throw new Error("whiteboard file exceeds the renderer transfer limit");
|
|
539
|
-
return blob;
|
|
540
|
-
}
|
|
541
490
|
#beginFileTransfer(requestId) {
|
|
542
491
|
if (this.#fileTransfers.has(requestId)) throw new Error("whiteboard file request is already active");
|
|
543
492
|
const abortController = new AbortController();
|
|
@@ -614,8 +563,8 @@ function requireRequest(value) {
|
|
|
614
563
|
function requireFileWrite(value) {
|
|
615
564
|
const record = requireRecord(value, ["requestId", "fileId", "mimeType", "byteLength", "sha256", "dataURL"]);
|
|
616
565
|
const byteLength = record.byteLength;
|
|
617
|
-
const
|
|
618
|
-
if (!Number.isSafeInteger(byteLength) || Number(byteLength) <= 0 || Number(byteLength) > MAX_FILE_BYTES || !/^[\da-f]{64}$/iu.test(
|
|
566
|
+
const sha256 = requireString(record.sha256, "file digest");
|
|
567
|
+
if (!Number.isSafeInteger(byteLength) || Number(byteLength) <= 0 || Number(byteLength) > MAX_FILE_BYTES || !/^[\da-f]{64}$/iu.test(sha256)) {
|
|
619
568
|
throw new Error("embedded whiteboard file metadata is invalid");
|
|
620
569
|
}
|
|
621
570
|
return {
|
|
@@ -623,7 +572,7 @@ function requireFileWrite(value) {
|
|
|
623
572
|
fileId: requireString(record.fileId, "file ID"),
|
|
624
573
|
mimeType: normalizeMimeType(requireString(record.mimeType, "MIME type")),
|
|
625
574
|
byteLength: Number(byteLength),
|
|
626
|
-
sha256:
|
|
575
|
+
sha256: sha256.toLowerCase(),
|
|
627
576
|
dataURL: requireString(record.dataURL, "file data", Math.ceil(MAX_FILE_BYTES * 4 / 3) + 1024)
|
|
628
577
|
};
|
|
629
578
|
}
|
|
@@ -22,13 +22,6 @@ export declare class ChalkEmbeddedWhiteboardRendererBridge {
|
|
|
22
22
|
}): Promise<WhiteboardCommit>;
|
|
23
23
|
requestSnapshot(): Promise<void>;
|
|
24
24
|
clear(): Promise<WhiteboardCommit>;
|
|
25
|
-
uploadFile(input: {
|
|
26
|
-
readonly fileId: string;
|
|
27
|
-
readonly mimeType: string;
|
|
28
|
-
readonly byteLength: number;
|
|
29
|
-
readonly sha256: string;
|
|
30
|
-
readonly dataURL: string;
|
|
31
|
-
}): Promise<void>;
|
|
32
25
|
downloadFile(fileId: string): Promise<{
|
|
33
26
|
readonly mimeType: string;
|
|
34
27
|
readonly dataURL: string;
|
|
@@ -14,7 +14,6 @@ export declare function createCollaborationBridge(rendererBridge: ChalkEmbeddedW
|
|
|
14
14
|
requestSnapshot: () => Promise<void>;
|
|
15
15
|
clear: () => Promise<import("..").WhiteboardCommit>;
|
|
16
16
|
fileTransfer: {
|
|
17
|
-
upload: (input: Parameters<ChalkEmbeddedWhiteboardRendererBridge["uploadFile"]>[0]) => Promise<void>;
|
|
18
17
|
download: (fileId: string) => Promise<{
|
|
19
18
|
readonly mimeType: string;
|
|
20
19
|
readonly dataURL: string;
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
mergeWhiteboardElements
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-W4FLPXAX.js";
|
|
4
4
|
import {
|
|
5
5
|
fromWireElement,
|
|
6
6
|
isWireElement,
|
|
7
7
|
toWireElement
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-6ZV7GBAC.js";
|
|
9
9
|
export {
|
|
10
10
|
fromWireElement,
|
|
11
11
|
isWireElement,
|
|
@@ -42,6 +42,8 @@ export interface WhiteboardCanvasProps {
|
|
|
42
42
|
onExcalidrawApiReady?: (api: ExcalidrawImperativeAPI) => void;
|
|
43
43
|
onLoadError?: (error: Error) => void;
|
|
44
44
|
}
|
|
45
|
+
/** Starts loading the board's stylesheet before anyone opens the board, so the board opens without waiting for it. */
|
|
46
|
+
export declare function preloadWhiteboardStylesheet(href?: string): void;
|
|
45
47
|
declare function WhiteboardCanvasBase(props: WhiteboardCanvasProps): React.JSX.Element;
|
|
46
48
|
export declare const WhiteboardCanvas: import("react").MemoExoticComponent<typeof WhiteboardCanvasBase>;
|
|
47
49
|
export {};
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { WhiteboardCanvas } from "./WhiteboardCanvas.js";
|
|
1
|
+
export { WhiteboardCanvas, preloadWhiteboardStylesheet } from "./WhiteboardCanvas.js";
|
|
2
2
|
export type { WhiteboardCanvasClassNames, WhiteboardCanvasIcons, WhiteboardCanvasProps, WhiteboardCollaborationOptions } from "./WhiteboardCanvas.js";
|
|
3
3
|
export { appendOrReplaceMathElement, CHALK_MATH_CUSTOM_DATA_KEY, CHALK_MATH_RENDERER, createMathFileId, createMathImageAsset, getChalkMathData, getInsertionPoint, getSelectedMathElement, isChalkMathElement, svgToDataUrl } from "./math-elements.js";
|
|
4
4
|
export type { ChalkMathCustomData, MathImageAsset } from "./math-elements.js";
|
package/dist/react/index.js
CHANGED
|
@@ -294,28 +294,48 @@ function useWhiteboardCanvasConfiguration(props) {
|
|
|
294
294
|
function valueOr(value, fallback) {
|
|
295
295
|
return value === void 0 ? fallback : value;
|
|
296
296
|
}
|
|
297
|
-
|
|
297
|
+
var STYLESHEET_ID = "chalk-excalidraw-styles";
|
|
298
|
+
function preloadWhiteboardStylesheet(href = DEFAULT_EXCALIDRAW_CSS) {
|
|
299
|
+
if (typeof document !== "undefined") boardStylesheet(href);
|
|
300
|
+
}
|
|
301
|
+
function boardStylesheet(href) {
|
|
302
|
+
const existing = document.getElementById(STYLESHEET_ID) ?? document.querySelector('link[href*="excalidraw"], style[data-href*="excalidraw"]');
|
|
303
|
+
if (existing) return existing;
|
|
304
|
+
const link = document.createElement("link");
|
|
305
|
+
link.id = STYLESHEET_ID;
|
|
306
|
+
link.rel = "stylesheet";
|
|
307
|
+
link.href = href;
|
|
308
|
+
link.addEventListener("load", () => link.dataset.state = "loaded");
|
|
309
|
+
link.addEventListener("error", () => link.dataset.state = "failed");
|
|
310
|
+
document.head.appendChild(link);
|
|
311
|
+
return link;
|
|
312
|
+
}
|
|
313
|
+
function isManagedStylesheet(element) {
|
|
314
|
+
return element instanceof HTMLLinkElement && element.id === STYLESHEET_ID;
|
|
315
|
+
}
|
|
316
|
+
function useExternalStylesheet(href) {
|
|
298
317
|
const [loaded, setLoaded] = useState2(false);
|
|
299
318
|
const [error, setError] = useState2(null);
|
|
300
319
|
useEffect(() => {
|
|
301
|
-
|
|
302
|
-
const
|
|
303
|
-
|
|
320
|
+
const element = boardStylesheet(href);
|
|
321
|
+
const fail = () => setError(`Failed to load ${href}`);
|
|
322
|
+
const ownLink = isManagedStylesheet(element);
|
|
323
|
+
if (!ownLink || element.dataset.state === "loaded") {
|
|
304
324
|
setLoaded(true);
|
|
305
325
|
return;
|
|
306
326
|
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
327
|
+
if (element.dataset.state === "failed") {
|
|
328
|
+
fail();
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
const load = () => setLoaded(true);
|
|
332
|
+
element.addEventListener("load", load);
|
|
333
|
+
element.addEventListener("error", fail);
|
|
314
334
|
return () => {
|
|
315
|
-
|
|
316
|
-
|
|
335
|
+
element.removeEventListener("load", load);
|
|
336
|
+
element.removeEventListener("error", fail);
|
|
317
337
|
};
|
|
318
|
-
}, [href
|
|
338
|
+
}, [href]);
|
|
319
339
|
return { error, loaded };
|
|
320
340
|
}
|
|
321
341
|
function useExcalidrawModule(onLoadError, setLoadError) {
|
|
@@ -347,7 +367,7 @@ function useWhiteboardInitialData(theme, localParticipantColor) {
|
|
|
347
367
|
[localParticipantColor, theme]
|
|
348
368
|
);
|
|
349
369
|
}
|
|
350
|
-
function useWhiteboardUiOptions(
|
|
370
|
+
function useWhiteboardUiOptions() {
|
|
351
371
|
return useMemo(
|
|
352
372
|
() => ({
|
|
353
373
|
canvasActions: {
|
|
@@ -359,16 +379,16 @@ function useWhiteboardUiOptions(canDraw) {
|
|
|
359
379
|
saveToActiveFile: false,
|
|
360
380
|
toggleTheme: false
|
|
361
381
|
},
|
|
362
|
-
tools: { image:
|
|
382
|
+
tools: { image: false },
|
|
363
383
|
welcomeScreen: false
|
|
364
384
|
}),
|
|
365
|
-
[
|
|
385
|
+
[]
|
|
366
386
|
);
|
|
367
387
|
}
|
|
368
388
|
function useWhiteboardCollaboration(options) {
|
|
369
389
|
const apiRef = useRef(null);
|
|
370
390
|
const refs = useCollaborationRefs(options.collab, options.canDraw);
|
|
371
|
-
const initializeEngine = useCollaborationEngineLoader(refs, options.onLoadError, options.setLoadError);
|
|
391
|
+
const initializeEngine = useCollaborationEngineLoader(refs, apiRef, options.onLoadError, options.setLoadError);
|
|
372
392
|
const handleApiReady = useExcalidrawApiReady(apiRef, initializeEngine, options.onExcalidrawApiReady);
|
|
373
393
|
const handlers = useExcalidrawSceneHandlers(apiRef, refs.engineRef, options.onSelectedLatexChange);
|
|
374
394
|
useCollaborationCanDraw(refs.engineRef, options.canDraw);
|
|
@@ -386,46 +406,42 @@ function useCollaborationRefs(collab, canDraw) {
|
|
|
386
406
|
collabOptionsRef.current = collab;
|
|
387
407
|
return useMemo(() => ({ canDrawRef, collabOptionsRef, enginePromiseRef, engineRef, isMountedRef }), [canDrawRef, collabOptionsRef, enginePromiseRef, engineRef, isMountedRef]);
|
|
388
408
|
}
|
|
389
|
-
function useCollaborationEngineLoader(refs, onLoadError, setLoadError) {
|
|
390
|
-
return useCallback(
|
|
391
|
-
(
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
onFileSyncStateChange: collab.onFileSyncStateChange,
|
|
409
|
-
onSubmissionError: collab.onSubmissionError
|
|
410
|
-
});
|
|
411
|
-
}).catch((reason) => {
|
|
412
|
-
if (!refs.isMountedRef.current) return;
|
|
413
|
-
const error = reason instanceof Error ? reason : new Error("Failed to load whiteboard collaboration");
|
|
414
|
-
setLoadError(error.message);
|
|
415
|
-
onLoadError?.(error);
|
|
416
|
-
}).finally(() => {
|
|
417
|
-
refs.enginePromiseRef.current = null;
|
|
409
|
+
function useCollaborationEngineLoader(refs, apiRef, onLoadError, setLoadError) {
|
|
410
|
+
return useCallback(() => {
|
|
411
|
+
if (!refs.collabOptionsRef.current || refs.engineRef.current || refs.enginePromiseRef.current) return;
|
|
412
|
+
refs.enginePromiseRef.current = import("../engine-BIJ57YN3.js").then(({ ExcalidrawCollabEngine }) => {
|
|
413
|
+
const api = apiRef.current;
|
|
414
|
+
const collab = refs.collabOptionsRef.current;
|
|
415
|
+
if (!refs.isMountedRef.current || !api || !collab) return;
|
|
416
|
+
refs.engineRef.current = new ExcalidrawCollabEngine({
|
|
417
|
+
excalidrawAPI: api,
|
|
418
|
+
canDraw: refs.canDrawRef.current,
|
|
419
|
+
submitUpdate: collab.submitUpdate,
|
|
420
|
+
sendCursor: collab.sendCursor,
|
|
421
|
+
requestSnapshot: collab.requestSnapshot,
|
|
422
|
+
clear: collab.clear,
|
|
423
|
+
fileTransfer: collab.fileTransfer,
|
|
424
|
+
presignDownload: collab.presignDownload,
|
|
425
|
+
subscribe: collab.subscribe,
|
|
426
|
+
onFileSyncStateChange: collab.onFileSyncStateChange,
|
|
427
|
+
onSubmissionError: collab.onSubmissionError
|
|
418
428
|
});
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
|
|
429
|
+
}).catch((reason) => {
|
|
430
|
+
if (!refs.isMountedRef.current) return;
|
|
431
|
+
const error = reason instanceof Error ? reason : new Error("Failed to load whiteboard collaboration");
|
|
432
|
+
setLoadError(error.message);
|
|
433
|
+
onLoadError?.(error);
|
|
434
|
+
}).finally(() => {
|
|
435
|
+
refs.enginePromiseRef.current = null;
|
|
436
|
+
});
|
|
437
|
+
}, [apiRef, onLoadError, refs, setLoadError]);
|
|
422
438
|
}
|
|
423
439
|
function useExcalidrawApiReady(apiRef, initializeEngine, onExcalidrawApiReady) {
|
|
424
440
|
const didReportApiRef = useRef(false);
|
|
425
441
|
return useCallback(
|
|
426
442
|
(api) => {
|
|
427
443
|
apiRef.current = api;
|
|
428
|
-
initializeEngine(
|
|
444
|
+
initializeEngine();
|
|
429
445
|
if (!didReportApiRef.current) {
|
|
430
446
|
didReportApiRef.current = true;
|
|
431
447
|
onExcalidrawApiReady?.(api);
|
|
@@ -484,7 +500,7 @@ function useCollaborationInitialization(collab, apiRef, engineRef, initializeEng
|
|
|
484
500
|
engineRef.current = null;
|
|
485
501
|
return;
|
|
486
502
|
}
|
|
487
|
-
if (apiRef.current) initializeEngine(
|
|
503
|
+
if (apiRef.current) initializeEngine();
|
|
488
504
|
}, [apiRef, collab, engineRef, initializeEngine]);
|
|
489
505
|
}
|
|
490
506
|
function useWhiteboardMath({ apiRef, canDraw, excalidraw, isCollaborating, selectedLatex, setSelectedLatex, syncScene }) {
|
|
@@ -511,14 +527,14 @@ function useWhiteboardMath({ apiRef, canDraw, excalidraw, isCollaborating, selec
|
|
|
511
527
|
},
|
|
512
528
|
[apiRef, closeMath, excalidraw, isCollaborating, setSelectedLatex, syncScene]
|
|
513
529
|
);
|
|
514
|
-
return { closeMath, handleSubmitMath, isMathOpen, openMath, selectedLatex };
|
|
530
|
+
return { closeMath, handleSubmitMath, initialLatex: selectedLatex ?? DEFAULT_LATEX, isMathOpen, openMath, selectedLatex };
|
|
515
531
|
}
|
|
516
532
|
function useWhiteboardCanvasState(props) {
|
|
517
533
|
const configuration = useWhiteboardCanvasConfiguration(props);
|
|
518
534
|
const [loadError, setLoadError] = useState2(null);
|
|
519
535
|
const [selectedLatex, setSelectedLatex] = useState2(null);
|
|
520
536
|
const excalidraw = useExcalidrawModule(props.onLoadError, setLoadError);
|
|
521
|
-
const stylesheet = useExternalStylesheet(
|
|
537
|
+
const stylesheet = useExternalStylesheet(configuration.excalidrawCssPath);
|
|
522
538
|
const collaboration = useWhiteboardCollaboration({
|
|
523
539
|
canDraw: configuration.canDraw,
|
|
524
540
|
collab: props.collab,
|
|
@@ -537,7 +553,7 @@ function useWhiteboardCanvasState(props) {
|
|
|
537
553
|
syncScene: collaboration.syncScene
|
|
538
554
|
});
|
|
539
555
|
const initialData = useWhiteboardInitialData(configuration.theme, props.localParticipantColor);
|
|
540
|
-
const uiOptions = useWhiteboardUiOptions(
|
|
556
|
+
const uiOptions = useWhiteboardUiOptions();
|
|
541
557
|
const resolvedLoadError = loadError ?? stylesheet.error;
|
|
542
558
|
return {
|
|
543
559
|
collaboration,
|
|
@@ -553,7 +569,7 @@ function useWhiteboardCanvasState(props) {
|
|
|
553
569
|
function WhiteboardCanvasView({ state }) {
|
|
554
570
|
const { collaboration, configuration, excalidraw, initialData, isReady, math, resolvedLoadError, uiOptions } = state;
|
|
555
571
|
return /* @__PURE__ */ jsxs2("div", { className: configuration.rootClassName, hidden: !configuration.isVisible, children: [
|
|
556
|
-
/* @__PURE__ */ jsx2(WhiteboardMathToolbar, { canDraw: configuration.canDraw, classNames: configuration.classNames, isReady, onOpenMath: math.openMath, selectedLatex: math.selectedLatex }),
|
|
572
|
+
/* @__PURE__ */ jsx2(WhiteboardMathToolbar, { canDraw: configuration.canDraw && !configuration.isCollaborating, classNames: configuration.classNames, isReady, onOpenMath: math.openMath, selectedLatex: math.selectedLatex }),
|
|
557
573
|
/* @__PURE__ */ jsx2(WhiteboardCanvasStatus, { classNames: configuration.classNames, error: resolvedLoadError, icons: configuration.icons, isReady }),
|
|
558
574
|
excalidraw && /* @__PURE__ */ jsx2(
|
|
559
575
|
WhiteboardScene,
|
|
@@ -569,12 +585,13 @@ function WhiteboardCanvasView({ state }) {
|
|
|
569
585
|
uiOptions
|
|
570
586
|
}
|
|
571
587
|
),
|
|
572
|
-
math.isMathOpen && /* @__PURE__ */ jsx2(MathEditor, { initialLatex: math.
|
|
588
|
+
math.isMathOpen && /* @__PURE__ */ jsx2(MathEditor, { initialLatex: math.initialLatex, isEditing: Boolean(math.selectedLatex), classNames: configuration.classNames, icons: configuration.icons, onClose: math.closeMath, onSubmit: math.handleSubmitMath })
|
|
573
589
|
] });
|
|
574
590
|
}
|
|
575
591
|
function WhiteboardMathToolbar({ canDraw, classNames, isReady, onOpenMath, selectedLatex }) {
|
|
576
|
-
if (!isReady) return null;
|
|
577
|
-
|
|
592
|
+
if (!isReady || !canDraw) return null;
|
|
593
|
+
const label = selectedLatex ? "Edit math equation" : "Insert math equation";
|
|
594
|
+
return /* @__PURE__ */ jsx2("div", { className: classNames.toolbar, style: { position: "absolute", top: 12, left: 12, zIndex: 20, display: "flex" }, children: /* @__PURE__ */ jsx2("button", { type: "button", onClick: onOpenMath, disabled: !canDraw, className: classNames.toolbarButton, "aria-label": label, title: label, children: "\u2211" }) });
|
|
578
595
|
}
|
|
579
596
|
function WhiteboardCanvasStatus({ classNames, error, icons, isReady }) {
|
|
580
597
|
if (error) return /* @__PURE__ */ jsx2(WhiteboardLoadError, { className: classNames.error, error });
|
|
@@ -620,6 +637,7 @@ export {
|
|
|
620
637
|
getRenderedSvgSize,
|
|
621
638
|
getSelectedMathElement,
|
|
622
639
|
isChalkMathElement,
|
|
640
|
+
preloadWhiteboardStylesheet,
|
|
623
641
|
renderLatexToSvg,
|
|
624
642
|
svgToDataUrl
|
|
625
643
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@q9labsai/chalk-whiteboard",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -63,7 +63,6 @@
|
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
65
|
"@excalidraw/excalidraw": "0.18.1",
|
|
66
|
-
"@noble/hashes": "2.3.0",
|
|
67
66
|
"mathjax": "4.1.3"
|
|
68
67
|
},
|
|
69
68
|
"devDependencies": {
|
|
@@ -89,7 +88,7 @@
|
|
|
89
88
|
"dev": "tsup ./src/index.ts ./src/react/index.ts ./src/collab/index.ts ./src/embedded/index.ts --format esm --out-dir ./dist --platform browser --splitting --external react --external react-dom --external @excalidraw/excalidraw --watch",
|
|
90
89
|
"test": "pnpm exec vitest run && pnpm run test:declarations",
|
|
91
90
|
"test:declarations": "node --test scripts/rewrite-declaration-specifiers-proof.mjs",
|
|
92
|
-
"check-types": "tsc --noEmit",
|
|
91
|
+
"check-types": "tsc-rs --noEmit",
|
|
93
92
|
"lint": "pnpm exec oxfmt --check . && tsc --noEmit",
|
|
94
93
|
"clean": "rm -rf dist"
|
|
95
94
|
}
|