@haklex/rich-ext-tldraw 0.0.31 → 0.0.33

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.
@@ -0,0 +1,6 @@
1
+ import { FC } from 'react';
2
+ export interface TldrawStaticRendererProps {
3
+ snapshot: string;
4
+ }
5
+ export declare const TldrawDisplayRenderer: FC<TldrawStaticRendererProps>;
6
+ //# sourceMappingURL=TldrawDisplayRenderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TldrawDisplayRenderer.d.ts","sourceRoot":"","sources":["../src/TldrawDisplayRenderer.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAa,KAAK,EAAE,EAAkB,MAAM,OAAO,CAAA;AAM1D,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,yBAAyB,CAsC/D,CAAA"}
@@ -0,0 +1,14 @@
1
+ import { SlashMenuItemConfig } from '@haklex/rich-editor';
2
+ import { EditorConfig, LexicalEditor, LexicalNode, NodeKey } from 'lexical';
3
+ import { ReactElement } from 'react';
4
+ import { SerializedTldrawNode, TldrawNode } from './TldrawNode';
5
+ export declare class TldrawEditNode extends TldrawNode {
6
+ static slashMenuItems: SlashMenuItemConfig[];
7
+ static clone(node: TldrawEditNode): TldrawEditNode;
8
+ constructor(snapshot: string, key?: NodeKey);
9
+ static importJSON(serializedNode: SerializedTldrawNode): TldrawEditNode;
10
+ decorate(editor: LexicalEditor, _config: EditorConfig): ReactElement;
11
+ }
12
+ export declare function $createTldrawEditNode(snapshot: string): TldrawEditNode;
13
+ export declare function $isTldrawEditNode(node: LexicalNode | null | undefined): node is TldrawEditNode;
14
+ //# sourceMappingURL=TldrawEditNode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TldrawEditNode.d.ts","sourceRoot":"","sources":["../src/TldrawEditNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAGhF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AAGzC,OAAO,EAAE,KAAK,oBAAoB,EAAC,UAAU,EAAE,MAAM,cAAc,CAAA;AAanE,qBAAa,cAAe,SAAQ,UAAU;IAC5C,MAAM,CAAC,cAAc,EAAE,mBAAmB,EAAE,CAa3C;IAED,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,cAAc,GAAG,cAAc;gBAItC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO;IAI3C,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,oBAAoB,GAAG,cAAc;IAIvE,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,GAAG,YAAY;CAsCrE;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAEtE;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GACnC,IAAI,IAAI,cAAc,CAExB"}
@@ -1 +1 @@
1
- {"version":3,"file":"TldrawEditRenderer.d.ts","sourceRoot":"","sources":["../src/TldrawEditRenderer.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAA;AAO/B,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAA;IAChB,gBAAgB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;CAC7C;AA0TD,eAAO,MAAM,kBAAkB,EAAE,EAAE,CAAC,uBAAuB,CAuH1D,CAAA"}
1
+ {"version":3,"file":"TldrawEditRenderer.d.ts","sourceRoot":"","sources":["../src/TldrawEditRenderer.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAA;AAO/B,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAA;IAChB,gBAAgB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;CAC7C;AA2TD,eAAO,MAAM,kBAAkB,EAAE,EAAE,CAAC,uBAAuB,CAwH1D,CAAA"}
@@ -1,4 +1,3 @@
1
- import { SlashMenuItemConfig } from '@haklex/rich-editor';
2
1
  import { EditorConfig, LexicalEditor, LexicalNode, NodeKey, SerializedLexicalNode, Spread, DecoratorNode } from 'lexical';
3
2
  import { ReactElement } from 'react';
4
3
  export type SerializedTldrawNode = Spread<{
@@ -6,7 +5,6 @@ export type SerializedTldrawNode = Spread<{
6
5
  }, SerializedLexicalNode>;
7
6
  export declare class TldrawNode extends DecoratorNode<ReactElement> {
8
7
  __snapshot: string;
9
- static slashMenuItems: SlashMenuItemConfig[];
10
8
  static getType(): string;
11
9
  static clone(node: TldrawNode): TldrawNode;
12
10
  constructor(snapshot: string, key?: NodeKey);
@@ -17,7 +15,7 @@ export declare class TldrawNode extends DecoratorNode<ReactElement> {
17
15
  exportJSON(): SerializedTldrawNode;
18
16
  getSnapshot(): string;
19
17
  setSnapshot(snapshot: string): void;
20
- decorate(editor: LexicalEditor, _config: EditorConfig): ReactElement;
18
+ decorate(_editor: LexicalEditor, _config: EditorConfig): ReactElement;
21
19
  }
22
20
  export declare function $createTldrawNode(snapshot: string): TldrawNode;
23
21
  export declare function $isTldrawNode(node: LexicalNode | null | undefined): node is TldrawNode;
@@ -1 +1 @@
1
- {"version":3,"file":"TldrawNode.d.ts","sourceRoot":"","sources":["../src/TldrawNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAC9D,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,WAAW,EACX,OAAO,EACP,qBAAqB,EACrB,MAAM,EACP,MAAM,SAAS,CAAA;AAChB,OAAO,EAA+B,aAAa,EAAE,MAAM,SAAS,CAAA;AAEpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AAczC,MAAM,MAAM,oBAAoB,GAAG,MAAM,CACvC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,EACpB,qBAAqB,CACtB,CAAA;AAED,qBAAa,UAAW,SAAQ,aAAa,CAAC,YAAY,CAAC;IACzD,UAAU,EAAE,MAAM,CAAA;IAElB,MAAM,CAAC,cAAc,EAAE,mBAAmB,EAAE,CAa3C;IAED,MAAM,CAAC,OAAO,IAAI,MAAM;IAIxB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU;gBAI9B,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO;IAK3C,SAAS,CAAC,OAAO,EAAE,YAAY,GAAG,WAAW;IAM7C,SAAS,IAAI,OAAO;IAIpB,QAAQ,IAAI,OAAO;IAInB,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,oBAAoB,GAAG,UAAU;IAInE,UAAU,IAAI,oBAAoB;IASlC,WAAW,IAAI,MAAM;IAIrB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKnC,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,GAAG,YAAY;CAsCrE;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAE9D;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GACnC,IAAI,IAAI,UAAU,CAEpB"}
1
+ {"version":3,"file":"TldrawNode.d.ts","sourceRoot":"","sources":["../src/TldrawNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,WAAW,EACX,OAAO,EACP,qBAAqB,EACrB,MAAM,EACP,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AAKzC,MAAM,MAAM,oBAAoB,GAAG,MAAM,CACvC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,EACpB,qBAAqB,CACtB,CAAA;AAED,qBAAa,UAAW,SAAQ,aAAa,CAAC,YAAY,CAAC;IACzD,UAAU,EAAE,MAAM,CAAA;IAElB,MAAM,CAAC,OAAO,IAAI,MAAM;IAIxB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU;gBAI9B,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO;IAK3C,SAAS,CAAC,OAAO,EAAE,YAAY,GAAG,WAAW;IAM7C,SAAS,IAAI,OAAO;IAIpB,QAAQ,IAAI,OAAO;IAInB,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,oBAAoB,GAAG,UAAU;IAInE,UAAU,IAAI,oBAAoB;IASlC,WAAW,IAAI,MAAM;IAIrB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKnC,QAAQ,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,GAAG,YAAY;CAKtE;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAE9D;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GACnC,IAAI,IAAI,UAAU,CAEpB"}
@@ -1,3 +1,3 @@
1
- export type { TldrawStaticRendererProps as TldrawRendererProps } from './TldrawStaticRenderer';
2
- export { TldrawStaticRenderer as TldrawRenderer } from './TldrawStaticRenderer';
1
+ export type { TldrawStaticRendererProps as TldrawRendererProps } from './TldrawDisplayRenderer';
2
+ export { TldrawDisplayRenderer as TldrawRenderer } from './TldrawDisplayRenderer';
3
3
  //# sourceMappingURL=TldrawRenderer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TldrawRenderer.d.ts","sourceRoot":"","sources":["../src/TldrawRenderer.tsx"],"names":[],"mappings":"AAAA,YAAY,EAAE,yBAAyB,IAAI,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAC9F,OAAO,EAAE,oBAAoB,IAAI,cAAc,EAAE,MAAM,wBAAwB,CAAA"}
1
+ {"version":3,"file":"TldrawRenderer.d.ts","sourceRoot":"","sources":["../src/TldrawRenderer.tsx"],"names":[],"mappings":"AAAA,YAAY,EAAE,yBAAyB,IAAI,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAC/F,OAAO,EAAE,qBAAqB,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAA"}
@@ -0,0 +1,6 @@
1
+ import { FC } from 'react';
2
+ export interface TldrawSSRRendererProps {
3
+ snapshot: string;
4
+ }
5
+ export declare const TldrawSSRRenderer: FC<TldrawSSRRendererProps>;
6
+ //# sourceMappingURL=TldrawSSRRenderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TldrawSSRRenderer.d.ts","sourceRoot":"","sources":["../src/TldrawSSRRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAA;AAE/B,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,sBAAsB,CAqCxD,CAAA"}
package/dist/index.d.ts CHANGED
@@ -1,13 +1,18 @@
1
1
  export type { TldrawConfig } from './TldrawConfigContext';
2
2
  export { TldrawConfigProvider, useTldrawConfig } from './TldrawConfigContext';
3
+ export type { TldrawStaticRendererProps as TldrawDisplayRendererProps } from './TldrawDisplayRenderer';
4
+ export { TldrawDisplayRenderer } from './TldrawDisplayRenderer';
5
+ export { $createTldrawEditNode, $isTldrawEditNode, TldrawEditNode, } from './TldrawEditNode';
3
6
  export type { TldrawEditRendererProps } from './TldrawEditRenderer';
4
7
  export { TldrawEditRenderer } from './TldrawEditRenderer';
5
8
  export type { SerializedTldrawNode } from './TldrawNode';
6
9
  export { $createTldrawNode, $isTldrawNode, TldrawNode } from './TldrawNode';
7
10
  export { INSERT_TLDRAW_COMMAND, TldrawPlugin } from './TldrawPlugin';
8
- export type { TldrawStaticRendererProps } from './TldrawStaticRenderer';
9
- export { TldrawStaticRenderer } from './TldrawStaticRenderer';
11
+ export type { TldrawSSRRendererProps } from './TldrawSSRRenderer';
12
+ export { TldrawSSRRenderer } from './TldrawSSRRenderer';
10
13
  export { TLDRAW_BLOCK_TRANSFORMER } from './transformer';
11
- export type { TldrawStaticRendererProps as TldrawRendererProps } from './TldrawStaticRenderer';
12
- export { TldrawStaticRenderer as TldrawRenderer } from './TldrawStaticRenderer';
14
+ export type { TldrawStaticRendererProps } from './TldrawDisplayRenderer';
15
+ export type { TldrawStaticRendererProps as TldrawRendererProps } from './TldrawDisplayRenderer';
16
+ export { TldrawDisplayRenderer as TldrawStaticRenderer } from './TldrawDisplayRenderer';
17
+ export { TldrawDisplayRenderer as TldrawRenderer } from './TldrawDisplayRenderer';
13
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAC7E,YAAY,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAA;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,YAAY,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAC3E,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AACpE,YAAY,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAA;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAA;AAGxD,YAAY,EAAE,yBAAyB,IAAI,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAC9F,OAAO,EAAE,oBAAoB,IAAI,cAAc,EAAE,MAAM,wBAAwB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAC7E,YAAY,EAAE,yBAAyB,IAAI,0BAA0B,EAAE,MAAM,yBAAyB,CAAA;AACtG,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAC/D,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,GACf,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAA;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,YAAY,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAC3E,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AACpE,YAAY,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAA;AAGxD,YAAY,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAA;AACxE,YAAY,EAAE,yBAAyB,IAAI,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAC/F,OAAO,EAAE,qBAAqB,IAAI,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AACvF,OAAO,EAAE,qBAAqB,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAA"}
package/dist/index.mjs CHANGED
@@ -2,11 +2,11 @@ var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
4
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
5
- import { createContext, use, useMemo, useState, useEffect, useRef, useCallback, lazy, createElement, Suspense, Component } from "react";
5
+ import { createContext, use, useMemo, useState, useEffect, useRef, useCallback, Component, createElement, lazy, Suspense } from "react";
6
6
  import { useColorScheme } from "@haklex/rich-editor";
7
7
  import { presentDialog, SegmentedControl } from "@haklex/rich-editor-ui";
8
8
  import { usePortalTheme } from "@haklex/rich-style-token";
9
- import { Pencil, Upload, Download, Clipboard, X, PenTool, ZoomIn, ZoomOut, ScanSearch, Maximize2 } from "lucide-react";
9
+ import { ZoomIn, ZoomOut, ScanSearch, Maximize2, X, PenTool, Pencil, Upload, Download, Clipboard } from "lucide-react";
10
10
  import { DecoratorNode, $insertNodes, $getNodeByKey, createCommand, COMMAND_PRIORITY_EDITOR } from "lexical";
11
11
  import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
12
12
  import { TLDRAW_BLOCK_TRANSFORMER } from "@haklex/rich-headless/transformers";
@@ -115,6 +115,357 @@ function useTldrawData(data) {
115
115
  }
116
116
  return { snapshot: void 0, loading: false, error: "" };
117
117
  }
118
+ const TldrawDisplayRenderer = ({
119
+ snapshot
120
+ }) => {
121
+ const theme = useColorScheme();
122
+ const containerRef = useRef(null);
123
+ const [hasEnteredView, setHasEnteredView] = useState(false);
124
+ useEffect(() => {
125
+ if (hasEnteredView) return;
126
+ const target = containerRef.current;
127
+ if (!target) return;
128
+ const observer = new IntersectionObserver(
129
+ (entries) => {
130
+ if (entries.some((e) => e.isIntersecting)) {
131
+ setHasEnteredView(true);
132
+ observer.disconnect();
133
+ }
134
+ },
135
+ { rootMargin: "200px 0px", threshold: 0.1 }
136
+ );
137
+ observer.observe(target);
138
+ return () => observer.disconnect();
139
+ }, [hasEnteredView]);
140
+ if (!hasEnteredView) {
141
+ return /* @__PURE__ */ jsx("div", { ref: containerRef, className: tldrawStaticContainer, children: /* @__PURE__ */ jsx("div", { className: tldrawLoading, children: "Loading tldraw..." }) });
142
+ }
143
+ return /* @__PURE__ */ jsx("div", { ref: containerRef, children: /* @__PURE__ */ jsx(TldrawStaticCanvas, { snapshot, theme }) });
144
+ };
145
+ const TldrawExpandContent = ({ dismiss, TldrawComponent, data, theme }) => /* @__PURE__ */ jsxs(Fragment, { children: [
146
+ /* @__PURE__ */ jsxs("div", { className: tldrawDialogHeader, children: [
147
+ /* @__PURE__ */ jsx("span", { className: tldrawDialogTitle, children: "Whiteboard" }),
148
+ /* @__PURE__ */ jsx("span", { className: tldrawDialogMeta, children: "tldraw" }),
149
+ /* @__PURE__ */ jsx("button", { type: "button", className: tldrawHeaderClose, onClick: dismiss, children: /* @__PURE__ */ jsx(X, { size: 18 }) })
150
+ ] }),
151
+ /* @__PURE__ */ jsx("div", { className: tldrawDialogCanvas, children: /* @__PURE__ */ jsx(
152
+ TldrawComponent,
153
+ {
154
+ snapshot: data,
155
+ hideUi: true,
156
+ onMount: (editor) => {
157
+ editor.updateInstanceState({ isReadonly: true });
158
+ editor.setCurrentTool("hand");
159
+ editor.user.updateUserPreferences({ colorScheme: theme });
160
+ setTimeout(() => editor.zoomToFit({ animate: false }), 100);
161
+ }
162
+ }
163
+ ) })
164
+ ] });
165
+ const TldrawStaticCanvas = ({ snapshot, theme }) => {
166
+ const {
167
+ snapshot: data,
168
+ loading: dataLoading,
169
+ error: dataError
170
+ } = useTldrawData(snapshot);
171
+ const [TldrawComponent, setTldrawComponent] = useState(null);
172
+ const [libLoading, setLibLoading] = useState(true);
173
+ const editorRef = useRef(null);
174
+ const { className: portalClassName } = usePortalTheme();
175
+ useEffect(() => {
176
+ import("tldraw").then((mod) => {
177
+ setTldrawComponent(() => mod.Tldraw);
178
+ setLibLoading(false);
179
+ }).catch(() => setLibLoading(false));
180
+ }, []);
181
+ useEffect(() => {
182
+ if (editorRef.current?.user?.updateUserPreferences) {
183
+ editorRef.current.user.updateUserPreferences({ colorScheme: theme });
184
+ }
185
+ }, [theme]);
186
+ const handleMount = useCallback(
187
+ (editor) => {
188
+ editorRef.current = editor;
189
+ editor.updateInstanceState({ isReadonly: true });
190
+ editor.setCurrentTool("hand");
191
+ editor.user.updateUserPreferences({ colorScheme: theme });
192
+ setTimeout(() => {
193
+ editor.zoomToFit({ animate: false });
194
+ }, 100);
195
+ },
196
+ [theme]
197
+ );
198
+ const handleExpand = useCallback(() => {
199
+ if (!TldrawComponent || !data) return;
200
+ presentDialog({
201
+ content: ({ dismiss }) => /* @__PURE__ */ jsx(
202
+ TldrawExpandContent,
203
+ {
204
+ dismiss,
205
+ TldrawComponent,
206
+ data,
207
+ theme
208
+ }
209
+ ),
210
+ className: tldrawFullscreenPopup,
211
+ portalClassName,
212
+ theme,
213
+ showCloseButton: false,
214
+ clickOutsideToDismiss: true
215
+ });
216
+ }, [TldrawComponent, data, theme, portalClassName]);
217
+ const loading = dataLoading || libLoading;
218
+ if (loading) {
219
+ return /* @__PURE__ */ jsx("div", { className: tldrawStaticContainer, children: /* @__PURE__ */ jsx("div", { className: tldrawLoading, children: "Loading tldraw..." }) });
220
+ }
221
+ if (dataError || !data) {
222
+ return /* @__PURE__ */ jsx("div", { className: tldrawStaticContainer, children: /* @__PURE__ */ jsx("div", { className: tldrawError, children: dataError || "No data" }) });
223
+ }
224
+ if (!TldrawComponent) {
225
+ return /* @__PURE__ */ jsx("div", { className: tldrawStaticContainer, children: /* @__PURE__ */ jsx("div", { className: tldrawError, children: "Failed to load tldraw" }) });
226
+ }
227
+ return /* @__PURE__ */ jsxs(
228
+ "div",
229
+ {
230
+ className: tldrawStaticContainer,
231
+ "data-theme": theme,
232
+ "data-color-scheme": theme,
233
+ children: [
234
+ /* @__PURE__ */ jsx(
235
+ TldrawErrorBoundary,
236
+ {
237
+ fallback: /* @__PURE__ */ jsx("div", { className: tldrawError, children: "Failed to render tldraw" }),
238
+ children: /* @__PURE__ */ jsx(TldrawComponent, { snapshot: data, hideUi: true, onMount: handleMount })
239
+ }
240
+ ),
241
+ /* @__PURE__ */ jsxs("div", { className: tldrawActionGroup, children: [
242
+ /* @__PURE__ */ jsx(
243
+ "button",
244
+ {
245
+ type: "button",
246
+ className: tldrawActionButton,
247
+ title: "Zoom In",
248
+ onClick: () => editorRef.current?.zoomIn(),
249
+ children: /* @__PURE__ */ jsx(ZoomIn, { size: 20 })
250
+ }
251
+ ),
252
+ /* @__PURE__ */ jsx(
253
+ "button",
254
+ {
255
+ type: "button",
256
+ className: tldrawActionButton,
257
+ title: "Zoom Out",
258
+ onClick: () => editorRef.current?.zoomOut(),
259
+ children: /* @__PURE__ */ jsx(ZoomOut, { size: 20 })
260
+ }
261
+ ),
262
+ /* @__PURE__ */ jsx(
263
+ "button",
264
+ {
265
+ type: "button",
266
+ className: tldrawActionButton,
267
+ title: "Fit to Content",
268
+ onClick: () => editorRef.current?.zoomToFit(),
269
+ children: /* @__PURE__ */ jsx(ScanSearch, { size: 20 })
270
+ }
271
+ ),
272
+ /* @__PURE__ */ jsx(
273
+ "button",
274
+ {
275
+ type: "button",
276
+ className: tldrawActionButton,
277
+ title: "Expand",
278
+ onClick: handleExpand,
279
+ children: /* @__PURE__ */ jsx(Maximize2, { size: 20 })
280
+ }
281
+ )
282
+ ] })
283
+ ]
284
+ }
285
+ );
286
+ };
287
+ class TldrawErrorBoundary extends Component {
288
+ constructor() {
289
+ super(...arguments);
290
+ __publicField(this, "state", { hasError: false });
291
+ }
292
+ static getDerivedStateFromError() {
293
+ return { hasError: true };
294
+ }
295
+ render() {
296
+ return this.state.hasError ? this.props.fallback : this.props.children;
297
+ }
298
+ }
299
+ const TldrawDisplayRenderer$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
300
+ __proto__: null,
301
+ TldrawDisplayRenderer
302
+ }, Symbol.toStringTag, { value: "Module" }));
303
+ const TldrawSSRRenderer = ({ snapshot }) => {
304
+ let label = "Tldraw Whiteboard";
305
+ try {
306
+ const data = JSON.parse(snapshot);
307
+ if (data && typeof data === "object") {
308
+ const shapeCount = Object.keys(data).filter(
309
+ (k) => k.startsWith("shape:")
310
+ ).length;
311
+ if (shapeCount > 0) {
312
+ label = `Tldraw Whiteboard (${shapeCount} shapes)`;
313
+ }
314
+ }
315
+ } catch {
316
+ }
317
+ return /* @__PURE__ */ jsx(
318
+ "div",
319
+ {
320
+ className: "rich-tldraw-ssr-placeholder",
321
+ style: {
322
+ position: "relative",
323
+ width: "100%",
324
+ aspectRatio: "16 / 10",
325
+ display: "flex",
326
+ alignItems: "center",
327
+ justifyContent: "center",
328
+ backgroundColor: "var(--rich-tldraw-bg, #f5f5f5)",
329
+ borderRadius: "8px",
330
+ border: "1px solid var(--rich-tldraw-border, #e5e5e5)",
331
+ color: "var(--rich-tldraw-fg, #737373)",
332
+ fontSize: "14px"
333
+ },
334
+ "aria-label": label,
335
+ children: /* @__PURE__ */ jsx("span", { children: label })
336
+ }
337
+ );
338
+ };
339
+ class TldrawNode extends DecoratorNode {
340
+ constructor(snapshot, key) {
341
+ super(key);
342
+ __publicField(this, "__snapshot");
343
+ this.__snapshot = snapshot;
344
+ }
345
+ static getType() {
346
+ return "tldraw";
347
+ }
348
+ static clone(node) {
349
+ return new TldrawNode(node.__snapshot, node.__key);
350
+ }
351
+ createDOM(_config) {
352
+ const div = document.createElement("div");
353
+ div.className = "rich-tldraw-wrapper";
354
+ return div;
355
+ }
356
+ updateDOM() {
357
+ return false;
358
+ }
359
+ isInline() {
360
+ return false;
361
+ }
362
+ static importJSON(serializedNode) {
363
+ return $createTldrawNode(serializedNode.snapshot);
364
+ }
365
+ exportJSON() {
366
+ return {
367
+ ...super.exportJSON(),
368
+ type: "tldraw",
369
+ snapshot: this.__snapshot,
370
+ version: 1
371
+ };
372
+ }
373
+ getSnapshot() {
374
+ return this.__snapshot;
375
+ }
376
+ setSnapshot(snapshot) {
377
+ const writable = this.getWritable();
378
+ writable.__snapshot = snapshot;
379
+ }
380
+ decorate(_editor, _config) {
381
+ return createElement(TldrawSSRRenderer, {
382
+ snapshot: this.__snapshot
383
+ });
384
+ }
385
+ }
386
+ function $createTldrawNode(snapshot) {
387
+ return new TldrawNode(snapshot);
388
+ }
389
+ function $isTldrawNode(node) {
390
+ return node instanceof TldrawNode;
391
+ }
392
+ const LazyDisplayRenderer = lazy(
393
+ () => Promise.resolve().then(() => TldrawDisplayRenderer$1).then((m) => ({
394
+ default: m.TldrawDisplayRenderer
395
+ }))
396
+ );
397
+ const LazyEditRenderer = lazy(
398
+ () => Promise.resolve().then(() => TldrawEditRenderer$1).then((m) => ({
399
+ default: m.TldrawEditRenderer
400
+ }))
401
+ );
402
+ const _TldrawEditNode = class _TldrawEditNode extends TldrawNode {
403
+ static clone(node) {
404
+ return new _TldrawEditNode(node.__snapshot, node.__key);
405
+ }
406
+ constructor(snapshot, key) {
407
+ super(snapshot, key);
408
+ }
409
+ static importJSON(serializedNode) {
410
+ return new _TldrawEditNode(serializedNode.snapshot);
411
+ }
412
+ decorate(editor, _config) {
413
+ const nodeKey = this.__key;
414
+ const isEditable = editor.isEditable();
415
+ const fallback = createElement("div", {
416
+ className: "rich-tldraw-loading",
417
+ style: {
418
+ position: "relative",
419
+ width: "100%",
420
+ aspectRatio: "16 / 10",
421
+ margin: "1rem 0"
422
+ }
423
+ });
424
+ if (isEditable) {
425
+ return createElement(
426
+ Suspense,
427
+ { fallback },
428
+ createElement(LazyEditRenderer, {
429
+ snapshot: this.__snapshot,
430
+ onSnapshotChange: (newSnapshot) => {
431
+ editor.update(() => {
432
+ const node = $getNodeByKey(nodeKey);
433
+ if (node) {
434
+ node.setSnapshot(newSnapshot);
435
+ }
436
+ });
437
+ }
438
+ })
439
+ );
440
+ }
441
+ return createElement(
442
+ Suspense,
443
+ { fallback },
444
+ createElement(LazyDisplayRenderer, { snapshot: this.__snapshot })
445
+ );
446
+ }
447
+ };
448
+ __publicField(_TldrawEditNode, "slashMenuItems", [
449
+ {
450
+ title: "Whiteboard",
451
+ icon: createElement(PenTool, { size: 20 }),
452
+ description: "Tldraw whiteboard canvas",
453
+ keywords: ["tldraw", "whiteboard", "draw", "canvas"],
454
+ section: "MEDIA",
455
+ onSelect: (editor) => {
456
+ editor.update(() => {
457
+ $insertNodes([$createTldrawEditNode("{}")]);
458
+ });
459
+ }
460
+ }
461
+ ]);
462
+ let TldrawEditNode = _TldrawEditNode;
463
+ function $createTldrawEditNode(snapshot) {
464
+ return new TldrawEditNode(snapshot);
465
+ }
466
+ function $isTldrawEditNode(node) {
467
+ return node instanceof TldrawEditNode;
468
+ }
118
469
  const SAVE_DEBOUNCE_MS = 2e3;
119
470
  const TldrawEditorDialogContent = ({
120
471
  dismiss,
@@ -256,10 +607,11 @@ const TldrawEditorDialogContent = ({
256
607
  )
257
608
  ] }),
258
609
  portalClassName,
610
+ theme,
259
611
  showCloseButton: false,
260
612
  clickOutsideToDismiss: false
261
613
  });
262
- }, [handleDiscard, handleSaveAndClose, portalClassName]);
614
+ }, [handleDiscard, handleSaveAndClose, portalClassName, theme]);
263
615
  useEffect(() => {
264
616
  const handleKeyDown = (e) => {
265
617
  if (e.key === "Escape") {
@@ -402,301 +754,39 @@ const TldrawEditorDialogContent = ({
402
754
  className: tldrawHeaderClose,
403
755
  onClick: attemptClose,
404
756
  children: /* @__PURE__ */ jsx(X, { size: 18 })
405
- }
406
- )
407
- ] }),
408
- /* @__PURE__ */ jsx("div", { className: tldrawDialogCanvas, children: /* @__PURE__ */ jsx(TldrawComponent, { snapshot: initialData, onMount: handleMount }) })
409
- ] });
410
- };
411
- const TldrawEditRenderer = ({
412
- snapshot,
413
- onSnapshotChange
414
- }) => {
415
- const theme = useColorScheme();
416
- const { saveSnapshot } = useTldrawConfig();
417
- const {
418
- snapshot: initialData,
419
- loading: dataLoading,
420
- error: dataError
421
- } = useTldrawData(snapshot);
422
- const [TldrawComponent, setTldrawComponent] = useState(null);
423
- const [libLoading, setLibLoading] = useState(true);
424
- const previewEditorRef = useRef(null);
425
- const initialDataRef = useRef(void 0);
426
- const onSnapshotChangeRef = useRef(onSnapshotChange);
427
- onSnapshotChangeRef.current = onSnapshotChange;
428
- const saveSnapshotRef = useRef(saveSnapshot);
429
- saveSnapshotRef.current = saveSnapshot;
430
- const snapshotRef = useRef(snapshot);
431
- snapshotRef.current = snapshot;
432
- const { className: portalClassName } = usePortalTheme();
433
- useEffect(() => {
434
- if (initialData && !initialDataRef.current) {
435
- initialDataRef.current = initialData;
436
- }
437
- }, [initialData]);
438
- useEffect(() => {
439
- import("tldraw").then((mod) => {
440
- setTldrawComponent(() => mod.Tldraw);
441
- setLibLoading(false);
442
- }).catch(() => setLibLoading(false));
443
- }, []);
444
- useEffect(() => {
445
- if (previewEditorRef.current?.user?.updateUserPreferences) {
446
- previewEditorRef.current.user.updateUserPreferences({
447
- colorScheme: theme
448
- });
449
- }
450
- }, [theme]);
451
- const handlePreviewMount = useCallback(
452
- (editor) => {
453
- previewEditorRef.current = editor;
454
- editor.updateInstanceState({ isReadonly: true });
455
- editor.setCurrentTool("hand");
456
- editor.user.updateUserPreferences({ colorScheme: theme });
457
- setTimeout(() => editor.zoomToFit({ animate: false }), 100);
458
- },
459
- [theme]
460
- );
461
- const handleOpenEditor = useCallback(() => {
462
- if (!TldrawComponent) return;
463
- presentDialog({
464
- content: ({ dismiss }) => /* @__PURE__ */ jsx(
465
- TldrawEditorDialogContent,
466
- {
467
- dismiss,
468
- TldrawComponent,
469
- initialData: initialDataRef.current,
470
- initialSnapshot: snapshotRef.current,
471
- theme,
472
- onSave: (ref) => onSnapshotChangeRef.current(ref),
473
- saveSnapshot: saveSnapshotRef.current,
474
- onClose: (doc) => {
475
- if (doc) initialDataRef.current = doc;
476
- }
477
- }
478
- ),
479
- className: tldrawFullscreenPopup,
480
- portalClassName,
481
- showCloseButton: false,
482
- clickOutsideToDismiss: false
483
- });
484
- }, [TldrawComponent, theme, portalClassName]);
485
- const loading = dataLoading || libLoading;
486
- if (loading || !TldrawComponent) {
487
- return /* @__PURE__ */ jsx("div", { className: tldrawEditorContainer, children: /* @__PURE__ */ jsx("div", { className: tldrawLoading, children: "Loading tldraw editor..." }) });
488
- }
489
- if (dataError) {
490
- return /* @__PURE__ */ jsx("div", { className: tldrawEditorContainer, children: /* @__PURE__ */ jsx("div", { className: tldrawError, children: dataError }) });
491
- }
492
- return /* @__PURE__ */ jsxs("div", { className: tldrawEditorContainer, children: [
493
- /* @__PURE__ */ jsx(
494
- TldrawComponent,
495
- {
496
- snapshot: initialDataRef.current,
497
- hideUi: true,
498
- onMount: handlePreviewMount
499
- }
500
- ),
501
- /* @__PURE__ */ jsx(
502
- "button",
503
- {
504
- type: "button",
505
- className: tldrawEditOverlay,
506
- onClick: handleOpenEditor,
507
- children: /* @__PURE__ */ jsxs("span", { className: tldrawEditLabel, children: [
508
- /* @__PURE__ */ jsx(Pencil, { size: 16 }),
509
- "Edit Whiteboard"
510
- ] })
511
- }
512
- )
513
- ] });
514
- };
515
- const TldrawEditRenderer$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
516
- __proto__: null,
517
- TldrawEditRenderer
518
- }, Symbol.toStringTag, { value: "Module" }));
519
- const LazyStaticRenderer = lazy(
520
- () => Promise.resolve().then(() => TldrawStaticRenderer$1).then((m) => ({
521
- default: m.TldrawStaticRenderer
522
- }))
523
- );
524
- const LazyEditRenderer = lazy(
525
- () => Promise.resolve().then(() => TldrawEditRenderer$1).then((m) => ({
526
- default: m.TldrawEditRenderer
527
- }))
528
- );
529
- const _TldrawNode = class _TldrawNode extends DecoratorNode {
530
- constructor(snapshot, key) {
531
- super(key);
532
- __publicField(this, "__snapshot");
533
- this.__snapshot = snapshot;
534
- }
535
- static getType() {
536
- return "tldraw";
537
- }
538
- static clone(node) {
539
- return new _TldrawNode(node.__snapshot, node.__key);
540
- }
541
- createDOM(_config) {
542
- const div = document.createElement("div");
543
- div.className = "rich-tldraw-wrapper";
544
- return div;
545
- }
546
- updateDOM() {
547
- return false;
548
- }
549
- isInline() {
550
- return false;
551
- }
552
- static importJSON(serializedNode) {
553
- return $createTldrawNode(serializedNode.snapshot);
554
- }
555
- exportJSON() {
556
- return {
557
- ...super.exportJSON(),
558
- type: "tldraw",
559
- snapshot: this.__snapshot,
560
- version: 1
561
- };
562
- }
563
- getSnapshot() {
564
- return this.__snapshot;
565
- }
566
- setSnapshot(snapshot) {
567
- const writable = this.getWritable();
568
- writable.__snapshot = snapshot;
569
- }
570
- decorate(editor, _config) {
571
- const nodeKey = this.__key;
572
- const isEditable = editor.isEditable();
573
- const fallback = createElement("div", {
574
- className: "rich-tldraw-loading",
575
- style: {
576
- position: "relative",
577
- width: "100%",
578
- aspectRatio: "16 / 10",
579
- margin: "1rem 0"
580
- }
581
- });
582
- if (isEditable) {
583
- return createElement(
584
- Suspense,
585
- { fallback },
586
- createElement(LazyEditRenderer, {
587
- snapshot: this.__snapshot,
588
- onSnapshotChange: (newSnapshot) => {
589
- editor.update(() => {
590
- const node = $getNodeByKey(nodeKey);
591
- if (node) {
592
- node.setSnapshot(newSnapshot);
593
- }
594
- });
595
- }
596
- })
597
- );
598
- }
599
- return createElement(
600
- Suspense,
601
- { fallback },
602
- createElement(LazyStaticRenderer, { snapshot: this.__snapshot })
603
- );
604
- }
757
+ }
758
+ )
759
+ ] }),
760
+ /* @__PURE__ */ jsx("div", { className: tldrawDialogCanvas, children: /* @__PURE__ */ jsx(TldrawComponent, { snapshot: initialData, onMount: handleMount }) })
761
+ ] });
605
762
  };
606
- __publicField(_TldrawNode, "slashMenuItems", [
607
- {
608
- title: "Whiteboard",
609
- icon: createElement(PenTool, { size: 20 }),
610
- description: "Tldraw whiteboard canvas",
611
- keywords: ["tldraw", "whiteboard", "draw", "canvas"],
612
- section: "MEDIA",
613
- onSelect: (editor) => {
614
- editor.update(() => {
615
- $insertNodes([$createTldrawNode("{}")]);
616
- });
617
- }
618
- }
619
- ]);
620
- let TldrawNode = _TldrawNode;
621
- function $createTldrawNode(snapshot) {
622
- return new TldrawNode(snapshot);
623
- }
624
- function $isTldrawNode(node) {
625
- return node instanceof TldrawNode;
626
- }
627
- const INSERT_TLDRAW_COMMAND = createCommand("INSERT_TLDRAW");
628
- function TldrawPlugin() {
629
- const [editor] = useLexicalComposerContext();
630
- useEffect(() => {
631
- return editor.registerCommand(
632
- INSERT_TLDRAW_COMMAND,
633
- (snapshot) => {
634
- const node = $createTldrawNode(snapshot);
635
- $insertNodes([node]);
636
- return true;
637
- },
638
- COMMAND_PRIORITY_EDITOR
639
- );
640
- }, [editor]);
641
- return null;
642
- }
643
- const TldrawStaticRenderer = ({
644
- snapshot
763
+ const TldrawEditRenderer = ({
764
+ snapshot,
765
+ onSnapshotChange
645
766
  }) => {
646
767
  const theme = useColorScheme();
647
- const containerRef = useRef(null);
648
- const [hasEnteredView, setHasEnteredView] = useState(false);
649
- useEffect(() => {
650
- if (hasEnteredView) return;
651
- const target = containerRef.current;
652
- if (!target) return;
653
- const observer = new IntersectionObserver(
654
- (entries) => {
655
- if (entries.some((e) => e.isIntersecting)) {
656
- setHasEnteredView(true);
657
- observer.disconnect();
658
- }
659
- },
660
- { rootMargin: "200px 0px", threshold: 0.1 }
661
- );
662
- observer.observe(target);
663
- return () => observer.disconnect();
664
- }, [hasEnteredView]);
665
- if (!hasEnteredView) {
666
- return /* @__PURE__ */ jsx("div", { ref: containerRef, className: tldrawStaticContainer, children: /* @__PURE__ */ jsx("div", { className: tldrawLoading, children: "Loading tldraw..." }) });
667
- }
668
- return /* @__PURE__ */ jsx("div", { ref: containerRef, children: /* @__PURE__ */ jsx(TldrawStaticCanvas, { snapshot, theme }) });
669
- };
670
- const TldrawExpandContent = ({ dismiss, TldrawComponent, data, theme }) => /* @__PURE__ */ jsxs(Fragment, { children: [
671
- /* @__PURE__ */ jsxs("div", { className: tldrawDialogHeader, children: [
672
- /* @__PURE__ */ jsx("span", { className: tldrawDialogTitle, children: "Whiteboard" }),
673
- /* @__PURE__ */ jsx("span", { className: tldrawDialogMeta, children: "tldraw" }),
674
- /* @__PURE__ */ jsx("button", { type: "button", className: tldrawHeaderClose, onClick: dismiss, children: /* @__PURE__ */ jsx(X, { size: 18 }) })
675
- ] }),
676
- /* @__PURE__ */ jsx("div", { className: tldrawDialogCanvas, children: /* @__PURE__ */ jsx(
677
- TldrawComponent,
678
- {
679
- snapshot: data,
680
- hideUi: true,
681
- onMount: (editor) => {
682
- editor.updateInstanceState({ isReadonly: true });
683
- editor.setCurrentTool("hand");
684
- editor.user.updateUserPreferences({ colorScheme: theme });
685
- setTimeout(() => editor.zoomToFit({ animate: false }), 100);
686
- }
687
- }
688
- ) })
689
- ] });
690
- const TldrawStaticCanvas = ({ snapshot, theme }) => {
768
+ const { saveSnapshot } = useTldrawConfig();
691
769
  const {
692
- snapshot: data,
770
+ snapshot: initialData,
693
771
  loading: dataLoading,
694
772
  error: dataError
695
773
  } = useTldrawData(snapshot);
696
774
  const [TldrawComponent, setTldrawComponent] = useState(null);
697
775
  const [libLoading, setLibLoading] = useState(true);
698
- const editorRef = useRef(null);
776
+ const previewEditorRef = useRef(null);
777
+ const initialDataRef = useRef(void 0);
778
+ const onSnapshotChangeRef = useRef(onSnapshotChange);
779
+ onSnapshotChangeRef.current = onSnapshotChange;
780
+ const saveSnapshotRef = useRef(saveSnapshot);
781
+ saveSnapshotRef.current = saveSnapshot;
782
+ const snapshotRef = useRef(snapshot);
783
+ snapshotRef.current = snapshot;
699
784
  const { className: portalClassName } = usePortalTheme();
785
+ useEffect(() => {
786
+ if (initialData && !initialDataRef.current) {
787
+ initialDataRef.current = initialData;
788
+ }
789
+ }, [initialData]);
700
790
  useEffect(() => {
701
791
  import("tldraw").then((mod) => {
702
792
  setTldrawComponent(() => mod.Tldraw);
@@ -704,136 +794,112 @@ const TldrawStaticCanvas = ({ snapshot, theme }) => {
704
794
  }).catch(() => setLibLoading(false));
705
795
  }, []);
706
796
  useEffect(() => {
707
- if (editorRef.current?.user?.updateUserPreferences) {
708
- editorRef.current.user.updateUserPreferences({ colorScheme: theme });
797
+ if (previewEditorRef.current?.user?.updateUserPreferences) {
798
+ previewEditorRef.current.user.updateUserPreferences({
799
+ colorScheme: theme
800
+ });
709
801
  }
710
802
  }, [theme]);
711
- const handleMount = useCallback(
803
+ const handlePreviewMount = useCallback(
712
804
  (editor) => {
713
- editorRef.current = editor;
805
+ previewEditorRef.current = editor;
714
806
  editor.updateInstanceState({ isReadonly: true });
715
807
  editor.setCurrentTool("hand");
716
808
  editor.user.updateUserPreferences({ colorScheme: theme });
717
- setTimeout(() => {
718
- editor.zoomToFit({ animate: false });
719
- }, 100);
809
+ setTimeout(() => editor.zoomToFit({ animate: false }), 100);
720
810
  },
721
811
  [theme]
722
812
  );
723
- const handleExpand = useCallback(() => {
724
- if (!TldrawComponent || !data) return;
813
+ const handleOpenEditor = useCallback(() => {
814
+ if (!TldrawComponent) return;
725
815
  presentDialog({
726
816
  content: ({ dismiss }) => /* @__PURE__ */ jsx(
727
- TldrawExpandContent,
817
+ TldrawEditorDialogContent,
728
818
  {
729
819
  dismiss,
730
820
  TldrawComponent,
731
- data,
732
- theme
821
+ initialData: initialDataRef.current,
822
+ initialSnapshot: snapshotRef.current,
823
+ theme,
824
+ onSave: (ref) => onSnapshotChangeRef.current(ref),
825
+ saveSnapshot: saveSnapshotRef.current,
826
+ onClose: (doc) => {
827
+ if (doc) initialDataRef.current = doc;
828
+ }
733
829
  }
734
830
  ),
735
831
  className: tldrawFullscreenPopup,
736
832
  portalClassName,
833
+ theme,
737
834
  showCloseButton: false,
738
- clickOutsideToDismiss: true
835
+ clickOutsideToDismiss: false
739
836
  });
740
- }, [TldrawComponent, data, theme, portalClassName]);
837
+ }, [TldrawComponent, theme, portalClassName]);
741
838
  const loading = dataLoading || libLoading;
742
- if (loading) {
743
- return /* @__PURE__ */ jsx("div", { className: tldrawStaticContainer, children: /* @__PURE__ */ jsx("div", { className: tldrawLoading, children: "Loading tldraw..." }) });
744
- }
745
- if (dataError || !data) {
746
- return /* @__PURE__ */ jsx("div", { className: tldrawStaticContainer, children: /* @__PURE__ */ jsx("div", { className: tldrawError, children: dataError || "No data" }) });
839
+ if (loading || !TldrawComponent) {
840
+ return /* @__PURE__ */ jsx("div", { className: tldrawEditorContainer, children: /* @__PURE__ */ jsx("div", { className: tldrawLoading, children: "Loading tldraw editor..." }) });
747
841
  }
748
- if (!TldrawComponent) {
749
- return /* @__PURE__ */ jsx("div", { className: tldrawStaticContainer, children: /* @__PURE__ */ jsx("div", { className: tldrawError, children: "Failed to load tldraw" }) });
842
+ if (dataError) {
843
+ return /* @__PURE__ */ jsx("div", { className: tldrawEditorContainer, children: /* @__PURE__ */ jsx("div", { className: tldrawError, children: dataError }) });
750
844
  }
751
- return /* @__PURE__ */ jsxs(
752
- "div",
753
- {
754
- className: tldrawStaticContainer,
755
- "data-theme": theme,
756
- "data-color-scheme": theme,
757
- children: [
758
- /* @__PURE__ */ jsx(
759
- TldrawErrorBoundary,
760
- {
761
- fallback: /* @__PURE__ */ jsx("div", { className: tldrawError, children: "Failed to render tldraw" }),
762
- children: /* @__PURE__ */ jsx(TldrawComponent, { snapshot: data, hideUi: true, onMount: handleMount })
763
- }
764
- ),
765
- /* @__PURE__ */ jsxs("div", { className: tldrawActionGroup, children: [
766
- /* @__PURE__ */ jsx(
767
- "button",
768
- {
769
- type: "button",
770
- className: tldrawActionButton,
771
- title: "Zoom In",
772
- onClick: () => editorRef.current?.zoomIn(),
773
- children: /* @__PURE__ */ jsx(ZoomIn, { size: 20 })
774
- }
775
- ),
776
- /* @__PURE__ */ jsx(
777
- "button",
778
- {
779
- type: "button",
780
- className: tldrawActionButton,
781
- title: "Zoom Out",
782
- onClick: () => editorRef.current?.zoomOut(),
783
- children: /* @__PURE__ */ jsx(ZoomOut, { size: 20 })
784
- }
785
- ),
786
- /* @__PURE__ */ jsx(
787
- "button",
788
- {
789
- type: "button",
790
- className: tldrawActionButton,
791
- title: "Fit to Content",
792
- onClick: () => editorRef.current?.zoomToFit(),
793
- children: /* @__PURE__ */ jsx(ScanSearch, { size: 20 })
794
- }
795
- ),
796
- /* @__PURE__ */ jsx(
797
- "button",
798
- {
799
- type: "button",
800
- className: tldrawActionButton,
801
- title: "Expand",
802
- onClick: handleExpand,
803
- children: /* @__PURE__ */ jsx(Maximize2, { size: 20 })
804
- }
805
- )
845
+ return /* @__PURE__ */ jsxs("div", { className: tldrawEditorContainer, children: [
846
+ /* @__PURE__ */ jsx(
847
+ TldrawComponent,
848
+ {
849
+ snapshot: initialDataRef.current,
850
+ hideUi: true,
851
+ onMount: handlePreviewMount
852
+ }
853
+ ),
854
+ /* @__PURE__ */ jsx(
855
+ "button",
856
+ {
857
+ type: "button",
858
+ className: tldrawEditOverlay,
859
+ onClick: handleOpenEditor,
860
+ children: /* @__PURE__ */ jsxs("span", { className: tldrawEditLabel, children: [
861
+ /* @__PURE__ */ jsx(Pencil, { size: 16 }),
862
+ "Edit Whiteboard"
806
863
  ] })
807
- ]
808
- }
809
- );
864
+ }
865
+ )
866
+ ] });
810
867
  };
811
- class TldrawErrorBoundary extends Component {
812
- constructor() {
813
- super(...arguments);
814
- __publicField(this, "state", { hasError: false });
815
- }
816
- static getDerivedStateFromError() {
817
- return { hasError: true };
818
- }
819
- render() {
820
- return this.state.hasError ? this.props.fallback : this.props.children;
821
- }
822
- }
823
- const TldrawStaticRenderer$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
868
+ const TldrawEditRenderer$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
824
869
  __proto__: null,
825
- TldrawStaticRenderer
870
+ TldrawEditRenderer
826
871
  }, Symbol.toStringTag, { value: "Module" }));
872
+ const INSERT_TLDRAW_COMMAND = createCommand("INSERT_TLDRAW");
873
+ function TldrawPlugin() {
874
+ const [editor] = useLexicalComposerContext();
875
+ useEffect(() => {
876
+ return editor.registerCommand(
877
+ INSERT_TLDRAW_COMMAND,
878
+ (snapshot) => {
879
+ const node = $createTldrawEditNode(snapshot);
880
+ $insertNodes([node]);
881
+ return true;
882
+ },
883
+ COMMAND_PRIORITY_EDITOR
884
+ );
885
+ }, [editor]);
886
+ return null;
887
+ }
827
888
  export {
889
+ $createTldrawEditNode,
828
890
  $createTldrawNode,
891
+ $isTldrawEditNode,
829
892
  $isTldrawNode,
830
893
  INSERT_TLDRAW_COMMAND,
831
894
  TLDRAW_BLOCK_TRANSFORMER,
832
895
  TldrawConfigProvider,
896
+ TldrawDisplayRenderer,
897
+ TldrawEditNode,
833
898
  TldrawEditRenderer,
834
899
  TldrawNode,
835
900
  TldrawPlugin,
836
- TldrawStaticRenderer as TldrawRenderer,
837
- TldrawStaticRenderer,
901
+ TldrawDisplayRenderer as TldrawRenderer,
902
+ TldrawSSRRenderer,
903
+ TldrawDisplayRenderer as TldrawStaticRenderer,
838
904
  useTldrawConfig
839
905
  };
@@ -1 +1 @@
1
- @keyframes _1vqtdre3{to{transform:rotate(360deg)}}._1vqtdre0{position:relative;width:100%;aspect-ratio:16 / 10;margin:1rem 0;border-radius:.5rem;overflow:hidden}._1vqtdre1{position:relative;width:100%;aspect-ratio:16 / 10;margin:1rem 0;border-radius:.5rem;overflow:hidden;border:1px solid var(--rc-border)}._1vqtdre2{display:flex;align-items:center;justify-content:center;position:absolute;inset:0;color:var(--rc-text-secondary);font-size:var(--rc-font-size-md)}._1vqtdre2:after{content:"";display:inline-block;width:16px;height:16px;margin-left:8px;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:_1vqtdre3 .6s linear infinite}._1vqtdre4{display:flex;align-items:center;justify-content:center;position:absolute;inset:0;padding:.75rem 1rem;background-color:color-mix(in srgb,var(--rc-alert-caution) 10%,transparent);color:var(--rc-alert-caution);font-size:var(--rc-font-size-md)}._1vqtdre5{position:absolute;bottom:8px;right:8px;z-index:10;display:flex;gap:4px;border-radius:6px;padding:2px;background-color:color-mix(in srgb,currentColor 8%,transparent);backdrop-filter:blur(8px)}._1vqtdre6{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:4px;border:none;background:transparent;color:var(--rc-text-secondary);cursor:pointer;transition:background .15s,color .15s}._1vqtdre6:hover{background:color-mix(in srgb,currentColor 12%,transparent);color:var(--rc-text)}._1vqtdre6 svg{width:16px;height:16px}._1vqtdre7._1vqtdre7{position:fixed;inset:0;transform:none;width:100vw;height:100vh;max-width:100vw;max-height:100vh;margin:0;padding:0;gap:0;border-radius:0;border:none;display:flex;flex-direction:column;background:var(--rc-bg);overflow:hidden}._1vqtdre7._1vqtdre7[data-open],._1vqtdre7._1vqtdre7[data-closed]{animation:none}._1vqtdre8{display:flex;align-items:center;height:48px;flex-shrink:0;padding:0 12px 0 16px;border-bottom:1px solid var(--rc-border);gap:10px}._1vqtdre9{width:8px;height:8px;border-radius:50%;flex-shrink:0;transition:background-color .3s}._1vqtdrea{font-size:var(--rc-font-size-md);font-weight:600;color:var(--rc-text);line-height:1}._1vqtdreb{font-size:var(--rc-font-size-sm);color:var(--rc-text-secondary);line-height:1;padding-left:10px;border-left:1px solid var(--rc-border)}._1vqtdrec{margin-left:auto;display:flex;align-items:center;gap:2px}._1vqtdred{margin-left:8px;flex-shrink:0;display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:6px;border:none;background:transparent;color:var(--rc-text-secondary);cursor:pointer;transition:background .15s,color .15s}._1vqtdred:hover{background:color-mix(in srgb,currentColor 8%,transparent);color:var(--rc-text)}._1vqtdree{display:inline-flex;align-items:center;gap:4px;padding:4px 10px;border-radius:4px;border:none;background:transparent;color:var(--rc-text-secondary);cursor:pointer;font-size:var(--rc-font-size-sm);white-space:nowrap;transition:background .15s,color .15s}._1vqtdree:hover{background:color-mix(in srgb,currentColor 8%,transparent);color:var(--rc-text)}._1vqtdree:disabled{opacity:.4;pointer-events:none}._1vqtdree svg{width:14px;height:14px;flex-shrink:0}._1vqtdref{width:1px;height:16px;margin:0 4px;background:var(--rc-border);flex-shrink:0}._1vqtdreg{margin-left:auto;display:inline-flex;align-items:center;gap:6px;padding:3px 10px;border-radius:4px;background:color-mix(in srgb,currentColor 4%,transparent);color:var(--rc-text-secondary);font-size:var(--rc-font-size-xs);font-family:var(--rc-font-mono);max-width:50%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer;border:none;transition:background .15s}._1vqtdreg:hover{background:color-mix(in srgb,currentColor 8%,transparent)}._1vqtdreh{flex:1;position:relative;min-height:0}._1vqtdrei{display:flex;justify-content:flex-end;gap:8px}._1vqtdrej{padding:6px 14px;border-radius:6px;border:1px solid var(--rc-border);background:transparent;font-size:var(--rc-font-size-sm);font-weight:500;cursor:pointer;transition:background .15s;color:var(--rc-text)}._1vqtdrej:hover{background:color-mix(in srgb,currentColor 6%,transparent)}._1vqtdrek{padding:6px 14px;border-radius:6px;border:1px solid var(--rc-accent);background:var(--rc-accent);font-size:var(--rc-font-size-sm);font-weight:500;cursor:pointer;transition:opacity .15s;color:#fff}._1vqtdrek:hover{opacity:.9}._1vqtdrel{padding:6px 14px;border-radius:6px;border:1px solid var(--rc-alert-caution);background:transparent;font-size:var(--rc-font-size-sm);font-weight:500;cursor:pointer;transition:background .15s;color:var(--rc-alert-caution)}._1vqtdrel:hover{background:color-mix(in srgb,var(--rc-alert-caution) 10%,transparent)}._1vqtdrem{position:absolute;inset:0;z-index:5;display:flex;align-items:center;justify-content:center;cursor:pointer;background:transparent;border:none;transition:background .2s}._1vqtdrem:hover{background:color-mix(in srgb,currentColor 6%,transparent)}._1vqtdren{display:flex;align-items:center;gap:6px;padding:6px 14px;border-radius:6px;background:var(--rc-bg);border:1px solid var(--rc-border);color:var(--rc-text);font-size:var(--rc-font-size-sm);font-weight:500;opacity:0;transition:opacity .2s}._1vqtdrem:hover ._1vqtdren{opacity:1}
1
+ :root{--rc-text: #000;--rc-text-secondary: #18181b;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f4f4f5;--rc-border: #f4f4f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #3f3f46;--rc-code-bg: #f4f4f5;--rc-hr-border: #e4e4e7;--rc-quote-border: #2563eb;--rc-quote-bg: #eff6ff;--rc-alert-info: #006bb7;--rc-alert-warning: #cc5500;--rc-alert-tip: #11cc00;--rc-alert-caution: #cc0011;--rc-alert-important: #5500cc;--rc-max-width: 700px;--rc-space-xs: 4px;--rc-space-sm: 8px;--rc-space-md: 16px;--rc-space-lg: 24px;--rc-space-xl: 32px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 16px;--rc-font-size-small: 14px;--rc-line-height: 1.7;--rc-line-height-tight: 1.4;--rc-font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm: 4px;--rc-radius-md: 8px;--rc-radius-lg: 12px}:root.dark{--rc-text: #fafafa;--rc-text-secondary: #a1a1aa;--rc-bg: #09090b;--rc-bg-secondary: #18181b;--rc-bg-tertiary: #27272a;--rc-border: #27272a;--rc-accent: #60a5fa;--rc-accent-light: #60a5fa20;--rc-link: #60a5fa;--rc-code-text: #e4e4e7;--rc-code-bg: #27272a;--rc-hr-border: #27272a;--rc-quote-border: #60a5fa;--rc-quote-bg: #1e3a5f;--rc-alert-info: #7db9e5;--rc-alert-warning: #da864a;--rc-alert-tip: #54da48;--rc-alert-caution: #e16973;--rc-alert-important: #9966e0;--rc-max-width: 700px;--rc-space-xs: 4px;--rc-space-sm: 8px;--rc-space-md: 16px;--rc-space-lg: 24px;--rc-space-xl: 32px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 16px;--rc-font-size-small: 14px;--rc-line-height: 1.7;--rc-line-height-tight: 1.4;--rc-font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm: 4px;--rc-radius-md: 8px;--rc-radius-lg: 12px}._88yepz0{--rc-text: #000;--rc-text-secondary: #18181b;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f4f4f5;--rc-border: #f4f4f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #3f3f46;--rc-code-bg: #f4f4f5;--rc-hr-border: #e4e4e7;--rc-quote-border: #2563eb;--rc-quote-bg: #eff6ff;--rc-alert-info: #006bb7;--rc-alert-warning: #cc5500;--rc-alert-tip: #11cc00;--rc-alert-caution: #cc0011;--rc-alert-important: #5500cc;--rc-max-width: 700px;--rc-space-xs: 4px;--rc-space-sm: 8px;--rc-space-md: 16px;--rc-space-lg: 24px;--rc-space-xl: 32px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 16px;--rc-font-size-small: 14px;--rc-line-height: 1.7;--rc-line-height-tight: 1.4;--rc-font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm: 4px;--rc-radius-md: 8px;--rc-radius-lg: 12px}._88yepz1{--rc-text: #000;--rc-text-secondary: #18181b;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f4f4f5;--rc-border: #f4f4f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #3f3f46;--rc-code-bg: #f4f4f5;--rc-hr-border: #e4e4e7;--rc-quote-border: #2563eb;--rc-quote-bg: #eff6ff;--rc-alert-info: #006bb7;--rc-alert-warning: #cc5500;--rc-alert-tip: #11cc00;--rc-alert-caution: #cc0011;--rc-alert-important: #5500cc;--rc-max-width: 700px;--rc-space-xs: 4px;--rc-space-sm: 8px;--rc-space-md: 16px;--rc-space-lg: 24px;--rc-space-xl: 32px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 16px;--rc-font-size-small: 14px;--rc-line-height: 1.8;--rc-line-height-tight: 1.4;--rc-font-family: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-radius-sm: 4px;--rc-radius-md: 8px;--rc-radius-lg: 12px}._88yepz2{--rc-text: #000;--rc-text-secondary: #18181b;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f4f4f5;--rc-border: #f4f4f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #3f3f46;--rc-code-bg: #f4f4f5;--rc-hr-border: #e4e4e7;--rc-quote-border: #a1a1aa;--rc-quote-bg: #fafafa;--rc-alert-info: #006bb7;--rc-alert-warning: #cc5500;--rc-alert-tip: #11cc00;--rc-alert-caution: #cc0011;--rc-alert-important: #5500cc;--rc-max-width: none;--rc-space-xs: 2px;--rc-space-sm: 4px;--rc-space-md: 10px;--rc-space-lg: 16px;--rc-space-xl: 20px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 14px;--rc-font-size-small: 12px;--rc-line-height: 1.5;--rc-line-height-tight: 1.3;--rc-font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm: 3px;--rc-radius-md: 6px;--rc-radius-lg: 8px}.dark ._88yepz0,[data-theme=dark] ._88yepz0,.dark._88yepz0,[data-theme=dark]._88yepz0,.dark ._88yepz1,[data-theme=dark] ._88yepz1,.dark._88yepz1,[data-theme=dark]._88yepz1,.dark ._88yepz2,[data-theme=dark] ._88yepz2,.dark._88yepz2,[data-theme=dark]._88yepz2{--rc-text: #fafafa;--rc-text-secondary: #a1a1aa;--rc-bg: #09090b;--rc-bg-secondary: #18181b;--rc-bg-tertiary: #27272a;--rc-border: #27272a;--rc-accent: #60a5fa;--rc-accent-light: #60a5fa20;--rc-link: #60a5fa;--rc-code-text: #e4e4e7;--rc-code-bg: #27272a;--rc-hr-border: #27272a;--rc-quote-border: #60a5fa;--rc-quote-bg: #1e3a5f;--rc-alert-info: #7db9e5;--rc-alert-warning: #da864a;--rc-alert-tip: #54da48;--rc-alert-caution: #e16973;--rc-alert-important: #9966e0}@keyframes _1vqtdre3{to{transform:rotate(360deg)}}._1vqtdre0{position:relative;width:100%;aspect-ratio:16 / 10;margin:1rem 0;border-radius:.5rem;overflow:hidden}._1vqtdre1{position:relative;width:100%;aspect-ratio:16 / 10;margin:1rem 0;border-radius:.5rem;overflow:hidden;border:1px solid var(--rc-border)}._1vqtdre2{display:flex;align-items:center;justify-content:center;position:absolute;inset:0;color:var(--rc-text-secondary);font-size:var(--rc-font-size-md)}._1vqtdre2:after{content:"";display:inline-block;width:16px;height:16px;margin-left:8px;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:_1vqtdre3 .6s linear infinite}._1vqtdre4{display:flex;align-items:center;justify-content:center;position:absolute;inset:0;padding:.75rem 1rem;background-color:color-mix(in srgb,var(--rc-alert-caution) 10%,transparent);color:var(--rc-alert-caution);font-size:var(--rc-font-size-md)}._1vqtdre5{position:absolute;bottom:8px;right:8px;z-index:10;display:flex;gap:4px;border-radius:6px;padding:2px;background-color:color-mix(in srgb,currentColor 8%,transparent);backdrop-filter:blur(8px)}._1vqtdre6{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:4px;border:none;background:transparent;color:var(--rc-text-secondary);cursor:pointer;transition:background .15s,color .15s}._1vqtdre6:hover{background:color-mix(in srgb,currentColor 12%,transparent);color:var(--rc-text)}._1vqtdre6 svg{width:16px;height:16px}._1vqtdre7._1vqtdre7{position:fixed;inset:0;transform:none;width:100vw;height:100vh;max-width:100vw;max-height:100vh;margin:0;padding:0;gap:0;border-radius:0;border:none;display:flex;flex-direction:column;background:var(--rc-bg);overflow:hidden}._1vqtdre7._1vqtdre7[data-open],._1vqtdre7._1vqtdre7[data-closed]{animation:none}._1vqtdre8{display:flex;align-items:center;height:48px;flex-shrink:0;padding:0 12px 0 16px;border-bottom:1px solid var(--rc-border);gap:10px}._1vqtdre9{width:8px;height:8px;border-radius:50%;flex-shrink:0;transition:background-color .3s}._1vqtdrea{font-size:var(--rc-font-size-md);font-weight:600;color:var(--rc-text);line-height:1}._1vqtdreb{font-size:var(--rc-font-size-sm);color:var(--rc-text-secondary);line-height:1;padding-left:10px;border-left:1px solid var(--rc-border)}._1vqtdrec{margin-left:auto;display:flex;align-items:center;gap:2px}._1vqtdred{margin-left:8px;flex-shrink:0;display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:6px;border:none;background:transparent;color:var(--rc-text-secondary);cursor:pointer;transition:background .15s,color .15s}._1vqtdred:hover{background:color-mix(in srgb,currentColor 8%,transparent);color:var(--rc-text)}._1vqtdree{display:inline-flex;align-items:center;gap:4px;padding:4px 10px;border-radius:4px;border:none;background:transparent;color:var(--rc-text-secondary);cursor:pointer;font-size:var(--rc-font-size-sm);white-space:nowrap;transition:background .15s,color .15s}._1vqtdree:hover{background:color-mix(in srgb,currentColor 8%,transparent);color:var(--rc-text)}._1vqtdree:disabled{opacity:.4;pointer-events:none}._1vqtdree svg{width:14px;height:14px;flex-shrink:0}._1vqtdref{width:1px;height:16px;margin:0 4px;background:var(--rc-border);flex-shrink:0}._1vqtdreg{margin-left:auto;display:inline-flex;align-items:center;gap:6px;padding:3px 10px;border-radius:4px;background:color-mix(in srgb,currentColor 4%,transparent);color:var(--rc-text-secondary);font-size:var(--rc-font-size-xs);font-family:var(--rc-font-mono);max-width:50%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer;border:none;transition:background .15s}._1vqtdreg:hover{background:color-mix(in srgb,currentColor 8%,transparent)}._1vqtdreh{flex:1;position:relative;min-height:0}._1vqtdrei{display:flex;justify-content:flex-end;gap:8px}._1vqtdrej{padding:6px 14px;border-radius:6px;border:1px solid var(--rc-border);background:transparent;font-size:var(--rc-font-size-sm);font-weight:500;cursor:pointer;transition:background .15s;color:var(--rc-text)}._1vqtdrej:hover{background:color-mix(in srgb,currentColor 6%,transparent)}._1vqtdrek{padding:6px 14px;border-radius:6px;border:1px solid var(--rc-accent);background:var(--rc-accent);font-size:var(--rc-font-size-sm);font-weight:500;cursor:pointer;transition:opacity .15s;color:#fff}._1vqtdrek:hover{opacity:.9}._1vqtdrel{padding:6px 14px;border-radius:6px;border:1px solid var(--rc-alert-caution);background:transparent;font-size:var(--rc-font-size-sm);font-weight:500;cursor:pointer;transition:background .15s;color:var(--rc-alert-caution)}._1vqtdrel:hover{background:color-mix(in srgb,var(--rc-alert-caution) 10%,transparent)}._1vqtdrem{position:absolute;inset:0;z-index:5;display:flex;align-items:center;justify-content:center;cursor:pointer;background:transparent;border:none;transition:background .2s}._1vqtdrem:hover{background:color-mix(in srgb,currentColor 6%,transparent)}._1vqtdren{display:flex;align-items:center;gap:6px;padding:6px 14px;border-radius:6px;background:var(--rc-bg);border:1px solid var(--rc-border);color:var(--rc-text);font-size:var(--rc-font-size-sm);font-weight:500;opacity:0;transition:opacity .2s}._1vqtdrem:hover ._1vqtdren{opacity:1}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haklex/rich-ext-tldraw",
3
- "version": "0.0.31",
3
+ "version": "0.0.33",
4
4
  "description": "Tldraw whiteboard extension",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -17,10 +17,10 @@
17
17
  ],
18
18
  "dependencies": {
19
19
  "tldraw": "^3.15.6",
20
- "@haklex/rich-editor": "0.0.31",
21
- "@haklex/rich-editor-ui": "0.0.31",
22
- "@haklex/rich-headless": "0.0.31",
23
- "@haklex/rich-style-token": "0.0.31"
20
+ "@haklex/rich-editor": "0.0.33",
21
+ "@haklex/rich-editor-ui": "0.0.33",
22
+ "@haklex/rich-headless": "0.0.33",
23
+ "@haklex/rich-style-token": "0.0.33"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@lexical/react": "^0.40.0",
@@ -1,6 +0,0 @@
1
- import { FC } from 'react';
2
- export interface TldrawStaticRendererProps {
3
- snapshot: string;
4
- }
5
- export declare const TldrawStaticRenderer: FC<TldrawStaticRendererProps>;
6
- //# sourceMappingURL=TldrawStaticRenderer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"TldrawStaticRenderer.d.ts","sourceRoot":"","sources":["../src/TldrawStaticRenderer.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAa,KAAK,EAAE,EAAkB,MAAM,OAAO,CAAA;AAM1D,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,eAAO,MAAM,oBAAoB,EAAE,EAAE,CAAC,yBAAyB,CAsC9D,CAAA"}