@canvus/react 0.1.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.
@@ -0,0 +1,46 @@
1
+ import { type ReactNode } from "react";
2
+ import type { CanvusProps, CanvusContextValue } from "./types.js";
3
+ /**
4
+ * Imperative handle exposed via `ref` on the `<Canvus />` component.
5
+ * Provides direct access to the workspace and React node methods.
6
+ */
7
+ export type CanvusHandle = CanvusContextValue;
8
+ /**
9
+ * The primary Canvus workspace component for React applications.
10
+ *
11
+ * Renders a container `<div>`, initializes the core `Workspace`
12
+ * engine on mount, and provides React node management methods
13
+ * via the `useCanvus()` hook.
14
+ *
15
+ * Children rendered inside `<Canvus>` can access the workspace
16
+ * and React node APIs via `useCanvus()`.
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * <Canvus
21
+ * config={{ snapThreshold: 8 }}
22
+ * onSelectionChange={(ids) => setSelected(ids)}
23
+ * onReactNodeCommit={(id, snapshot) => save(id, snapshot)}
24
+ * style={{ width: "100%", height: "100vh" }}
25
+ * >
26
+ * <Toolbar />
27
+ * </Canvus>
28
+ * ```
29
+ *
30
+ * @example Imperative access via ref:
31
+ * ```tsx
32
+ * const canvusRef = useRef<CanvusHandle>(null);
33
+ *
34
+ * <Canvus ref={canvusRef}>
35
+ * <button onClick={() => {
36
+ * canvusRef.current?.addReactNode({ ... });
37
+ * }}>
38
+ * Add Node
39
+ * </button>
40
+ * </Canvus>
41
+ * ```
42
+ */
43
+ export declare const Canvus: import("react").ForwardRefExoticComponent<CanvusProps & {
44
+ children?: ReactNode;
45
+ } & import("react").RefAttributes<CanvusContextValue>>;
46
+ //# sourceMappingURL=Canvus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Canvus.d.ts","sourceRoot":"","sources":["../src/Canvus.tsx"],"names":[],"mappings":"AA4BA,OAAO,EAIL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIlE;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,kBAAkB,CAAC;AAwB9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,eAAO,MAAM,MAAM;eAAuD,SAAS;sDAsDlF,CAAC"}
package/dist/Canvus.js ADDED
@@ -0,0 +1,90 @@
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
+ // ─────────────────────────────────────────────────────────────
3
+ // @canvus/react — <Canvus /> Component
4
+ //
5
+ // The primary mount point for a Canvus workspace in React.
6
+ // Renders a container div, initializes the Workspace via
7
+ // CanvusProvider, and exposes the workspace through context.
8
+ //
9
+ // Usage:
10
+ // import { Canvus, useCanvus } from "@canvus/react";
11
+ //
12
+ // function App() {
13
+ // return (
14
+ // <Canvus
15
+ // config={{ snapThreshold: 8 }}
16
+ // onSelectionChange={(ids) => console.log(ids)}
17
+ // style={{ width: "100%", height: "100vh" }}
18
+ // >
19
+ // <ToolPanel />
20
+ // </Canvus>
21
+ // );
22
+ // }
23
+ //
24
+ // function ToolPanel() {
25
+ // const { addReactNode } = useCanvus();
26
+ // // ...
27
+ // }
28
+ // ─────────────────────────────────────────────────────────────
29
+ import { forwardRef, useImperativeHandle, useRef, } from "react";
30
+ import { CanvusProvider } from "./context.js";
31
+ import { useCanvus } from "./useCanvus.js";
32
+ // ── Internal Bridge ─────────────────────────────────────────
33
+ /**
34
+ * Bridge component that exposes the context value via
35
+ * `useImperativeHandle` to the parent's forwarded ref.
36
+ */
37
+ function CanvusBridge({ forwardedRef, children, }) {
38
+ const ctx = useCanvus();
39
+ useImperativeHandle(forwardedRef, () => ctx, [ctx]);
40
+ return _jsx(_Fragment, { children: children });
41
+ }
42
+ // ── Canvus Component ────────────────────────────────────────
43
+ /**
44
+ * The primary Canvus workspace component for React applications.
45
+ *
46
+ * Renders a container `<div>`, initializes the core `Workspace`
47
+ * engine on mount, and provides React node management methods
48
+ * via the `useCanvus()` hook.
49
+ *
50
+ * Children rendered inside `<Canvus>` can access the workspace
51
+ * and React node APIs via `useCanvus()`.
52
+ *
53
+ * @example
54
+ * ```tsx
55
+ * <Canvus
56
+ * config={{ snapThreshold: 8 }}
57
+ * onSelectionChange={(ids) => setSelected(ids)}
58
+ * onReactNodeCommit={(id, snapshot) => save(id, snapshot)}
59
+ * style={{ width: "100%", height: "100vh" }}
60
+ * >
61
+ * <Toolbar />
62
+ * </Canvus>
63
+ * ```
64
+ *
65
+ * @example Imperative access via ref:
66
+ * ```tsx
67
+ * const canvusRef = useRef<CanvusHandle>(null);
68
+ *
69
+ * <Canvus ref={canvusRef}>
70
+ * <button onClick={() => {
71
+ * canvusRef.current?.addReactNode({ ... });
72
+ * }}>
73
+ * Add Node
74
+ * </button>
75
+ * </Canvus>
76
+ * ```
77
+ */
78
+ export const Canvus = forwardRef(function Canvus({ config, style, className, children,
79
+ // Callbacks
80
+ onHTMLCommit, onReactNodeCommit, onSelectionChange, onViewportChange, onOperationsGenerated, onNodeRectChange, onInteractionChange, onBreadcrumbChange, onTextEditRequest, }, ref) {
81
+ const containerRef = useRef(null);
82
+ return (_jsx("div", { ref: containerRef, className: className, style: {
83
+ position: "relative",
84
+ overflow: "hidden",
85
+ width: "100%",
86
+ height: "100%",
87
+ ...style,
88
+ }, children: _jsx(CanvusProvider, { containerRef: containerRef, config: config, onHTMLCommit: onHTMLCommit, onReactNodeCommit: onReactNodeCommit, onSelectionChange: onSelectionChange, onViewportChange: onViewportChange, onOperationsGenerated: onOperationsGenerated, onNodeRectChange: onNodeRectChange, onInteractionChange: onInteractionChange, onBreadcrumbChange: onBreadcrumbChange, onTextEditRequest: onTextEditRequest, children: _jsx(CanvusBridge, { forwardedRef: ref, children: children }) }) }));
89
+ });
90
+ //# sourceMappingURL=Canvus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Canvus.js","sourceRoot":"","sources":["../src/Canvus.tsx"],"names":[],"mappings":";AAAA,gEAAgE;AAChE,uCAAuC;AACvC,EAAE;AACF,2DAA2D;AAC3D,yDAAyD;AACzD,6DAA6D;AAC7D,EAAE;AACF,SAAS;AACT,uDAAuD;AACvD,EAAE;AACF,qBAAqB;AACrB,eAAe;AACf,gBAAgB;AAChB,wCAAwC;AACxC,wDAAwD;AACxD,qDAAqD;AACrD,UAAU;AACV,wBAAwB;AACxB,kBAAkB;AAClB,SAAS;AACT,MAAM;AACN,EAAE;AACF,2BAA2B;AAC3B,4CAA4C;AAC5C,aAAa;AACb,MAAM;AACN,gEAAgE;AAEhE,OAAO,EACL,UAAU,EACV,mBAAmB,EACnB,MAAM,GAEP,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAW3C,+DAA+D;AAE/D;;;GAGG;AACH,SAAS,YAAY,CAAC,EACpB,YAAY,EACZ,QAAQ,GAIT;IACC,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;IAExB,mBAAmB,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAEpD,OAAO,4BAAG,QAAQ,GAAI,CAAC;AACzB,CAAC;AAED,+DAA+D;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,CAC9B,SAAS,MAAM,CACb,EACE,MAAM,EACN,KAAK,EACL,SAAS,EACT,QAAQ;AACR,YAAY;AACZ,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,GAClB,EACD,GAAG;IAEH,MAAM,YAAY,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAElD,OAAO,CACL,cACE,GAAG,EAAE,YAAY,EACjB,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE;YACL,QAAQ,EAAE,UAAU;YACpB,QAAQ,EAAE,QAAQ;YAClB,KAAK,EAAE,MAAM;YACb,MAAM,EAAE,MAAM;YACd,GAAG,KAAK;SACT,YAED,KAAC,cAAc,IACb,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,YAAY,EAC1B,iBAAiB,EAAE,iBAAiB,EACpC,iBAAiB,EAAE,iBAAiB,EACpC,gBAAgB,EAAE,gBAAgB,EAClC,qBAAqB,EAAE,qBAAqB,EAC5C,gBAAgB,EAAE,gBAAgB,EAClC,mBAAmB,EAAE,mBAAmB,EACxC,kBAAkB,EAAE,kBAAkB,EACtC,iBAAiB,EAAE,iBAAiB,YAEpC,KAAC,YAAY,IAAC,YAAY,EAAE,GAAG,YAC5B,QAAQ,GACI,GACA,GACb,CACP,CAAC;AACJ,CAAC,CACF,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { type ReactNode } from "react";
2
+ import type { CanvusContextValue, CanvusProps } from "./types.js";
3
+ /**
4
+ * React context for accessing the Canvus workspace and
5
+ * React node management methods.
6
+ *
7
+ * @internal — consumers should use `useCanvus()` instead.
8
+ */
9
+ export declare const CanvusContext: import("react").Context<CanvusContextValue | null>;
10
+ interface CanvusProviderProps extends CanvusProps {
11
+ /** The container element to mount the Workspace into. */
12
+ containerRef: React.RefObject<HTMLDivElement | null>;
13
+ children?: ReactNode;
14
+ }
15
+ /**
16
+ * Internal provider that manages the Workspace lifecycle
17
+ * and React node mounting. Wrapped by `<Canvus />`.
18
+ *
19
+ * @internal
20
+ */
21
+ export declare function CanvusProvider({ containerRef, config, onHTMLCommit, onReactNodeCommit, onSelectionChange, onViewportChange, onOperationsGenerated, onNodeRectChange, onInteractionChange, onBreadcrumbChange, onTextEditRequest, children, }: CanvusProviderProps): import("react").JSX.Element;
22
+ export {};
23
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.tsx"],"names":[],"mappings":"AAWA,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EACV,kBAAkB,EAClB,WAAW,EAGZ,MAAM,YAAY,CAAC;AAIpB;;;;;GAKG;AACH,eAAO,MAAM,aAAa,oDAAiD,CAAC;AAI5E,UAAU,mBAAoB,SAAQ,WAAW;IAC/C,yDAAyD;IACzD,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACrD,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAID;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAC7B,YAAY,EACZ,MAAM,EACN,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,QAAQ,GACT,EAAE,mBAAmB,+BAwSrB"}
@@ -0,0 +1,250 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // ─────────────────────────────────────────────────────────────
3
+ // @canvus/react — React Context & Provider
4
+ //
5
+ // Manages the Workspace lifecycle and React node mounting.
6
+ // The CanvusProvider owns:
7
+ // 1. The Workspace instance (created on mount, disposed on unmount)
8
+ // 2. A Map<string, Root> of active React roots for mounted nodes
9
+ // 3. A Map<string, ReactNodeDescriptor> tracking React node metadata
10
+ // 4. The onHTMLCommit interception logic for commit routing
11
+ // ─────────────────────────────────────────────────────────────
12
+ import { createContext, useCallback, useEffect, useMemo, useRef, useState, } from "react";
13
+ import { createRoot } from "react-dom/client";
14
+ import { Workspace } from "@canvus/core";
15
+ // ── Context ─────────────────────────────────────────────────
16
+ /**
17
+ * React context for accessing the Canvus workspace and
18
+ * React node management methods.
19
+ *
20
+ * @internal — consumers should use `useCanvus()` instead.
21
+ */
22
+ export const CanvusContext = createContext(null);
23
+ // ── Provider Component ──────────────────────────────────────
24
+ /**
25
+ * Internal provider that manages the Workspace lifecycle
26
+ * and React node mounting. Wrapped by `<Canvus />`.
27
+ *
28
+ * @internal
29
+ */
30
+ export function CanvusProvider({ containerRef, config, onHTMLCommit, onReactNodeCommit, onSelectionChange, onViewportChange, onOperationsGenerated, onNodeRectChange, onInteractionChange, onBreadcrumbChange, onTextEditRequest, children, }) {
31
+ const [workspace, setWorkspace] = useState(null);
32
+ // ── Stable refs for mutable tracking state ──────────
33
+ // These maps persist across renders without causing re-renders.
34
+ /** Active React roots indexed by node ID. */
35
+ const activeRootsRef = useRef(new Map());
36
+ /** React node metadata indexed by node ID. */
37
+ const reactNodeMetaRef = useRef(new Map());
38
+ /** Temporary store for recently deleted React node descriptors (for Undo/Redo restoration). */
39
+ const deletedReactNodesRef = useRef(new Map());
40
+ // ── Stable callback refs ────────────────────────────
41
+ // Store callbacks in refs so the Workspace doesn't need to
42
+ // be re-created when callbacks change.
43
+ const onHTMLCommitRef = useRef(onHTMLCommit);
44
+ onHTMLCommitRef.current = onHTMLCommit;
45
+ const onReactNodeCommitRef = useRef(onReactNodeCommit);
46
+ onReactNodeCommitRef.current = onReactNodeCommit;
47
+ const onSelectionChangeRef = useRef(onSelectionChange);
48
+ onSelectionChangeRef.current = onSelectionChange;
49
+ const onViewportChangeRef = useRef(onViewportChange);
50
+ onViewportChangeRef.current = onViewportChange;
51
+ const onOperationsGeneratedRef = useRef(onOperationsGenerated);
52
+ onOperationsGeneratedRef.current = onOperationsGenerated;
53
+ const onNodeRectChangeRef = useRef(onNodeRectChange);
54
+ onNodeRectChangeRef.current = onNodeRectChange;
55
+ const onInteractionChangeRef = useRef(onInteractionChange);
56
+ onInteractionChangeRef.current = onInteractionChange;
57
+ const onBreadcrumbChangeRef = useRef(onBreadcrumbChange);
58
+ onBreadcrumbChangeRef.current = onBreadcrumbChange;
59
+ const onTextEditRequestRef = useRef(onTextEditRequest);
60
+ onTextEditRequestRef.current = onTextEditRequest;
61
+ // ── Workspace Lifecycle ─────────────────────────────
62
+ // Store config in a ref — it's only consumed at workspace
63
+ // creation time and should not trigger re-creation.
64
+ const configRef = useRef(config);
65
+ configRef.current = config;
66
+ useEffect(() => {
67
+ const container = containerRef.current;
68
+ if (!container)
69
+ return;
70
+ const ws = new Workspace(container, {
71
+ onHTMLCommit: (id, html) => {
72
+ // Route commits: React nodes → onReactNodeCommit,
73
+ // vanilla HTML nodes → onHTMLCommit
74
+ const meta = reactNodeMetaRef.current.get(id);
75
+ if (meta) {
76
+ // This is a React-managed node — build snapshot
77
+ const node = ws.getNodeTree().get(id);
78
+ const snapshot = {
79
+ component: meta.component,
80
+ componentName: meta.component.displayName ||
81
+ meta.component.name ||
82
+ "Unknown",
83
+ props: meta.props,
84
+ rect: node?.currentRect ?? meta.currentRect,
85
+ };
86
+ onReactNodeCommitRef.current?.(id, snapshot);
87
+ }
88
+ else {
89
+ // Vanilla HTML node — pass through
90
+ onHTMLCommitRef.current?.(id, html);
91
+ }
92
+ },
93
+ onSelectionChange: (ids) => onSelectionChangeRef.current?.(ids),
94
+ onViewportChange: (vp) => onViewportChangeRef.current?.(vp),
95
+ onOperationsGenerated: (ops) => onOperationsGeneratedRef.current?.(ops),
96
+ onNodeRectChange: (id, rect) => onNodeRectChangeRef.current?.(id, rect),
97
+ onInteractionChange: (mode) => onInteractionChangeRef.current?.(mode),
98
+ onBreadcrumbChange: (path) => onBreadcrumbChangeRef.current?.(path),
99
+ onTextEditRequest: onTextEditRequest
100
+ ? (nodeId, element, commit) => onTextEditRequestRef.current?.(nodeId, element, commit)
101
+ : undefined,
102
+ onNodeAdded: (id) => {
103
+ const deletedMeta = deletedReactNodesRef.current.get(id);
104
+ if (deletedMeta) {
105
+ const container = ws.getContentRoot(id);
106
+ if (container) {
107
+ const root = createRoot(container);
108
+ root.render(_jsx(deletedMeta.component, { ...deletedMeta.props }));
109
+ activeRootsRef.current.set(id, root);
110
+ reactNodeMetaRef.current.set(id, deletedMeta);
111
+ deletedReactNodesRef.current.delete(id);
112
+ const node = ws.getNodeTree().get(id);
113
+ const snapshot = {
114
+ component: deletedMeta.component,
115
+ componentName: deletedMeta.component.displayName ||
116
+ deletedMeta.component.name ||
117
+ "Unknown",
118
+ props: deletedMeta.props,
119
+ rect: node?.currentRect ?? deletedMeta.currentRect,
120
+ };
121
+ onReactNodeCommitRef.current?.(id, snapshot);
122
+ }
123
+ }
124
+ },
125
+ onNodeRemoved: (id) => {
126
+ const root = activeRootsRef.current.get(id);
127
+ if (root) {
128
+ try {
129
+ root.unmount();
130
+ }
131
+ catch {
132
+ // Silently ignore
133
+ }
134
+ activeRootsRef.current.delete(id);
135
+ }
136
+ const meta = reactNodeMetaRef.current.get(id);
137
+ if (meta) {
138
+ deletedReactNodesRef.current.set(id, meta);
139
+ reactNodeMetaRef.current.delete(id);
140
+ }
141
+ },
142
+ onNodeCloned: (originalId, cloneId) => {
143
+ const meta = reactNodeMetaRef.current.get(originalId);
144
+ if (meta) {
145
+ const container = ws.getContentRoot(cloneId);
146
+ if (container) {
147
+ const root = createRoot(container);
148
+ root.render(_jsx(meta.component, { ...meta.props }));
149
+ activeRootsRef.current.set(cloneId, root);
150
+ const clonedMeta = {
151
+ id: cloneId,
152
+ component: meta.component,
153
+ props: { ...meta.props },
154
+ currentRect: ws.getNodeTree().get(cloneId)?.currentRect ?? meta.currentRect,
155
+ parentId: ws.getNodeTree().get(cloneId)?.parentId ?? null,
156
+ };
157
+ reactNodeMetaRef.current.set(cloneId, clonedMeta);
158
+ }
159
+ }
160
+ },
161
+ }, configRef.current);
162
+ setWorkspace(ws);
163
+ return () => {
164
+ // Unmount all React roots before disposing workspace
165
+ for (const root of activeRootsRef.current.values()) {
166
+ try {
167
+ root.unmount();
168
+ }
169
+ catch {
170
+ // Silently handle unmount errors during teardown
171
+ }
172
+ }
173
+ activeRootsRef.current.clear();
174
+ reactNodeMetaRef.current.clear();
175
+ ws.dispose();
176
+ setWorkspace(null);
177
+ };
178
+ // eslint-disable-next-line react-hooks/exhaustive-deps
179
+ }, [containerRef]);
180
+ // ── React Node Lifecycle Methods ────────────────────
181
+ const addReactNode = useCallback((descriptor) => {
182
+ if (!workspace) {
183
+ console.warn("[@canvus/react] addReactNode called before workspace is ready.");
184
+ return;
185
+ }
186
+ const { id, component: Component, props, currentRect, parentId } = descriptor;
187
+ // 1. Create an empty shell in the core workspace
188
+ workspace.addNode({ id, rawMarkup: '<div data-canvus-react="true"></div>', currentRect }, parentId ?? null);
189
+ // 2. Get the content root (the inner <div>)
190
+ const container = workspace.getContentRoot(id);
191
+ if (!container) {
192
+ console.warn(`[@canvus/react] Could not find content root for node "${id}".`);
193
+ return;
194
+ }
195
+ // 3. Mount React component into the container
196
+ const root = createRoot(container);
197
+ root.render(_jsx(Component, { ...props }));
198
+ // 4. Track for updates and cleanup
199
+ activeRootsRef.current.set(id, root);
200
+ reactNodeMetaRef.current.set(id, descriptor);
201
+ }, [workspace]);
202
+ const updateReactNode = useCallback((id, props) => {
203
+ const root = activeRootsRef.current.get(id);
204
+ const meta = reactNodeMetaRef.current.get(id);
205
+ if (!root || !meta) {
206
+ console.warn(`[@canvus/react] Cannot update node "${id}" — not a React-managed node.`);
207
+ return;
208
+ }
209
+ // Update stored props
210
+ const updatedMeta = {
211
+ ...meta,
212
+ props: { ...meta.props, ...props },
213
+ };
214
+ reactNodeMetaRef.current.set(id, updatedMeta);
215
+ // Re-render with merged props
216
+ const Component = updatedMeta.component;
217
+ root.render(_jsx(Component, { ...updatedMeta.props }));
218
+ }, []);
219
+ const removeReactNode = useCallback((id) => {
220
+ const meta = reactNodeMetaRef.current.get(id);
221
+ if (meta) {
222
+ deletedReactNodesRef.current.set(id, meta);
223
+ }
224
+ // Unmount the React root first
225
+ const root = activeRootsRef.current.get(id);
226
+ if (root) {
227
+ root.unmount();
228
+ activeRootsRef.current.delete(id);
229
+ }
230
+ reactNodeMetaRef.current.delete(id);
231
+ // Then remove from the core workspace
232
+ workspace?.removeNode(id);
233
+ }, [workspace]);
234
+ const addNode = useCallback((...args) => {
235
+ if (!workspace) {
236
+ throw new Error("[@canvus/react] addNode called before workspace is ready.");
237
+ }
238
+ return workspace.addNode(...args);
239
+ }, [workspace]);
240
+ // ── Context Value ───────────────────────────────────
241
+ const contextValue = useMemo(() => ({
242
+ workspace,
243
+ addReactNode,
244
+ updateReactNode,
245
+ removeReactNode,
246
+ addNode,
247
+ }), [workspace, addReactNode, updateReactNode, removeReactNode, addNode]);
248
+ return (_jsx(CanvusContext.Provider, { value: contextValue, children: children }));
249
+ }
250
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export { Canvus } from "./Canvus.js";
2
+ export type { CanvusHandle } from "./Canvus.js";
3
+ export { useCanvus } from "./useCanvus.js";
4
+ export { CanvusProvider, CanvusContext } from "./context.js";
5
+ export type { CanvusProps, CanvusContextValue, ReactNodeDescriptor, ReactNodeSnapshot, } from "./types.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIhD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAI3C,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAI7D,YAAY,EACV,WAAW,EACX,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ // ─────────────────────────────────────────────────────────────
2
+ // @canvus/react — Public API Barrel Export
3
+ // ─────────────────────────────────────────────────────────────
4
+ // ── Components ──────────────────────────────────────────────
5
+ export { Canvus } from "./Canvus.js";
6
+ // ── Hooks ───────────────────────────────────────────────────
7
+ export { useCanvus } from "./useCanvus.js";
8
+ // ── Context (for advanced usage) ────────────────────────────
9
+ export { CanvusProvider, CanvusContext } from "./context.js";
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,2CAA2C;AAC3C,gEAAgE;AAEhE,+DAA+D;AAE/D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,+DAA+D;AAE/D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,+DAA+D;AAE/D,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,97 @@
1
+ import type { Rect, WorkspaceConfig, WorkspaceCallbacks, WebHTMLNode, Workspace } from "@canvus/core";
2
+ import type { ComponentType, CSSProperties } from "react";
3
+ /**
4
+ * Descriptor for mounting a live React component as a canvas node.
5
+ *
6
+ * Instead of providing raw HTML markup, you provide a React component
7
+ * and its props. The `@canvus/react` layer will create an empty
8
+ * container in the core workspace and mount the component into it
9
+ * using React's `createRoot` API.
10
+ */
11
+ export interface ReactNodeDescriptor {
12
+ /** Unique node identifier. */
13
+ id: string;
14
+ /** The React component to render inside the canvas node. */
15
+ component: ComponentType<any>;
16
+ /** Props to pass to the component. */
17
+ props: Record<string, any>;
18
+ /** Initial position and dimensions in canvas-space. */
19
+ currentRect: Rect;
20
+ /** Optional parent node ID for nested mounting. */
21
+ parentId?: string | null;
22
+ }
23
+ /**
24
+ * Snapshot emitted when a React-managed node is committed
25
+ * after a visual gesture (drag, resize, etc.).
26
+ *
27
+ * This replaces the Flat String Bridge's HTML output for
28
+ * React nodes, giving the host application structured data
29
+ * instead of rendered HTML markup.
30
+ */
31
+ export interface ReactNodeSnapshot {
32
+ /** The React component reference. */
33
+ component: ComponentType<any>;
34
+ /** String name of the component (for serialization). */
35
+ componentName: string;
36
+ /** Current props at the time of commit. */
37
+ props: Record<string, any>;
38
+ /** Current canvas-space bounding rect after the gesture. */
39
+ rect: Rect;
40
+ }
41
+ /**
42
+ * Props for the `<Canvus />` component.
43
+ *
44
+ * Accepts workspace configuration, visual styling, and all
45
+ * workspace callbacks. React-managed node commits are routed
46
+ * to `onReactNodeCommit` instead of `onHTMLCommit`.
47
+ */
48
+ export interface CanvusProps {
49
+ /** Workspace configuration (snap threshold, overlay styles, etc.). */
50
+ config?: WorkspaceConfig;
51
+ /** CSS styles applied to the container div. */
52
+ style?: CSSProperties;
53
+ /** CSS class name for the container div. */
54
+ className?: string;
55
+ /**
56
+ * Fired for vanilla HTML node commits only.
57
+ * React-managed nodes are filtered out and routed
58
+ * to `onReactNodeCommit` instead.
59
+ */
60
+ onHTMLCommit?: WorkspaceCallbacks["onHTMLCommit"];
61
+ /**
62
+ * Fired when a React-managed node is committed after
63
+ * a visual gesture (drag, resize, spacing adjustment).
64
+ * Provides the component reference, current props, and
65
+ * updated rect for host-side state management.
66
+ */
67
+ onReactNodeCommit?: (id: string, snapshot: ReactNodeSnapshot) => void;
68
+ onSelectionChange?: WorkspaceCallbacks["onSelectionChange"];
69
+ onViewportChange?: WorkspaceCallbacks["onViewportChange"];
70
+ onOperationsGenerated?: WorkspaceCallbacks["onOperationsGenerated"];
71
+ onNodeRectChange?: WorkspaceCallbacks["onNodeRectChange"];
72
+ onInteractionChange?: WorkspaceCallbacks["onInteractionChange"];
73
+ onBreadcrumbChange?: WorkspaceCallbacks["onBreadcrumbChange"];
74
+ onTextEditRequest?: WorkspaceCallbacks["onTextEditRequest"];
75
+ }
76
+ /**
77
+ * Value returned by the `useCanvus()` hook.
78
+ *
79
+ * Provides both the raw `Workspace` instance for imperative
80
+ * access and convenience methods for React node lifecycle.
81
+ */
82
+ export interface CanvusContextValue {
83
+ /** The raw Workspace instance for imperative access, or null before mount. */
84
+ workspace: Workspace | null;
85
+ /** Mount a React component as a canvas node. */
86
+ addReactNode: (descriptor: ReactNodeDescriptor) => void;
87
+ /** Update props of a mounted React node (triggers re-render). */
88
+ updateReactNode: (id: string, props: Record<string, any>) => void;
89
+ /** Remove a React node from the canvas and unmount its React root. */
90
+ removeReactNode: (id: string) => void;
91
+ /**
92
+ * Add a vanilla HTML node (pass-through to core).
93
+ * For standard raw-markup nodes that don't use React rendering.
94
+ */
95
+ addNode: (node: Readonly<WebHTMLNode>, parentId?: string | null, index?: number) => Rect;
96
+ }
97
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,IAAI,EACJ,eAAe,EACf,kBAAkB,EAClB,WAAW,EACX,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAI1D;;;;;;;GAOG;AACH,MAAM,WAAW,mBAAmB;IAClC,8BAA8B;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,4DAA4D;IAC5D,SAAS,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;IAC9B,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,uDAAuD;IACvD,WAAW,EAAE,IAAI,CAAC;IAClB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAID;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC,qCAAqC;IACrC,SAAS,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;IAC9B,wDAAwD;IACxD,aAAa,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,4DAA4D;IAC5D,IAAI,EAAE,IAAI,CAAC;CACZ;AAID;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,sEAAsE;IACtE,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IAInB;;;;OAIG;IACH,YAAY,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;IAElD;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAItE,iBAAiB,CAAC,EAAE,kBAAkB,CAAC,mBAAmB,CAAC,CAAC;IAC5D,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,kBAAkB,CAAC,CAAC;IAC1D,qBAAqB,CAAC,EAAE,kBAAkB,CAAC,uBAAuB,CAAC,CAAC;IACpE,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,kBAAkB,CAAC,CAAC;IAC1D,mBAAmB,CAAC,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;IAChE,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,oBAAoB,CAAC,CAAC;IAC9D,iBAAiB,CAAC,EAAE,kBAAkB,CAAC,mBAAmB,CAAC,CAAC;CAC7D;AAID;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,8EAA8E;IAC9E,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAE5B,gDAAgD;IAChD,YAAY,EAAE,CAAC,UAAU,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAExD,iEAAiE;IACjE,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IAElE,sEAAsE;IACtE,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAEtC;;;OAGG;IACH,OAAO,EAAE,CACP,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,EAC3B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,EACxB,KAAK,CAAC,EAAE,MAAM,KACX,IAAI,CAAC;CACX"}
package/dist/types.js ADDED
@@ -0,0 +1,6 @@
1
+ // ─────────────────────────────────────────────────────────────
2
+ // @canvus/react — Type Definitions
3
+ // React-specific types for the Canvus React bindings package.
4
+ // ─────────────────────────────────────────────────────────────
5
+ export {};
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,mCAAmC;AACnC,8DAA8D;AAC9D,gEAAgE"}
@@ -0,0 +1,31 @@
1
+ import type { CanvusContextValue } from "./types.js";
2
+ /**
3
+ * Hook to access the Canvus workspace and React node APIs.
4
+ *
5
+ * Must be called from a component rendered inside a `<Canvus />`
6
+ * component tree.
7
+ *
8
+ * @returns The workspace instance and React node lifecycle methods.
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * function Toolbar() {
13
+ * const { workspace, addReactNode, updateReactNode, removeReactNode } = useCanvus();
14
+ *
15
+ * const handleAddCard = () => {
16
+ * addReactNode({
17
+ * id: `card-${Date.now()}`,
18
+ * component: DashboardCard,
19
+ * props: { title: "New Card" },
20
+ * currentRect: { x: 100, y: 100, width: 300, height: 200 },
21
+ * });
22
+ * };
23
+ *
24
+ * return <button onClick={handleAddCard}>Add Card</button>;
25
+ * }
26
+ * ```
27
+ *
28
+ * @throws Error if called outside of a `<Canvus />` component tree.
29
+ */
30
+ export declare function useCanvus(): CanvusContextValue;
31
+ //# sourceMappingURL=useCanvus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCanvus.d.ts","sourceRoot":"","sources":["../src/useCanvus.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,SAAS,IAAI,kBAAkB,CAW9C"}
@@ -0,0 +1,46 @@
1
+ // ─────────────────────────────────────────────────────────────
2
+ // @canvus/react — useCanvus() Hook
3
+ //
4
+ // Provides access to the Canvus workspace and React node
5
+ // management methods from any component rendered inside
6
+ // a <Canvus /> component.
7
+ // ─────────────────────────────────────────────────────────────
8
+ import { useContext } from "react";
9
+ import { CanvusContext } from "./context.js";
10
+ /**
11
+ * Hook to access the Canvus workspace and React node APIs.
12
+ *
13
+ * Must be called from a component rendered inside a `<Canvus />`
14
+ * component tree.
15
+ *
16
+ * @returns The workspace instance and React node lifecycle methods.
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * function Toolbar() {
21
+ * const { workspace, addReactNode, updateReactNode, removeReactNode } = useCanvus();
22
+ *
23
+ * const handleAddCard = () => {
24
+ * addReactNode({
25
+ * id: `card-${Date.now()}`,
26
+ * component: DashboardCard,
27
+ * props: { title: "New Card" },
28
+ * currentRect: { x: 100, y: 100, width: 300, height: 200 },
29
+ * });
30
+ * };
31
+ *
32
+ * return <button onClick={handleAddCard}>Add Card</button>;
33
+ * }
34
+ * ```
35
+ *
36
+ * @throws Error if called outside of a `<Canvus />` component tree.
37
+ */
38
+ export function useCanvus() {
39
+ const context = useContext(CanvusContext);
40
+ if (context === null) {
41
+ throw new Error("useCanvus() must be used within a <Canvus /> component. " +
42
+ "Wrap your component tree with <Canvus /> to provide the workspace context.");
43
+ }
44
+ return context;
45
+ }
46
+ //# sourceMappingURL=useCanvus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCanvus.js","sourceRoot":"","sources":["../src/useCanvus.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,mCAAmC;AACnC,EAAE;AACF,yDAAyD;AACzD,wDAAwD;AACxD,0BAA0B;AAC1B,gEAAgE;AAEhE,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG7C;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,UAAU,SAAS;IACvB,MAAM,OAAO,GAAG,UAAU,CAAC,aAAa,CAAC,CAAC;IAE1C,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,0DAA0D;YACxD,4EAA4E,CAC/E,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@canvus/react",
3
+ "version": "0.1.0",
4
+ "description": "React bindings for the Canvus visual layout SDK",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "publishConfig": {
9
+ "access": "public"
10
+ },
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "typecheck": "tsc --noEmit"
17
+ },
18
+ "peerDependencies": {
19
+ "@canvus/core": ">=0.1.0",
20
+ "react": "^18 || ^19",
21
+ "react-dom": "^18 || ^19"
22
+ },
23
+ "devDependencies": {
24
+ "@canvus/core": ">=0.1.0",
25
+ "@types/react": "^18.0.0",
26
+ "@types/react-dom": "^18.0.0",
27
+ "react": "^18.0.0",
28
+ "react-dom": "^18.0.0",
29
+ "typescript": "^5.8.3"
30
+ },
31
+ "license": "MIT"
32
+ }