@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.
- package/dist/Canvus.d.ts +46 -0
- package/dist/Canvus.d.ts.map +1 -0
- package/dist/Canvus.js +90 -0
- package/dist/Canvus.js.map +1 -0
- package/dist/context.d.ts +23 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +250 -0
- package/dist/context.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +97 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/useCanvus.d.ts +31 -0
- package/dist/useCanvus.d.ts.map +1 -0
- package/dist/useCanvus.js +46 -0
- package/dist/useCanvus.js.map +1 -0
- package/package.json +32 -0
package/dist/Canvus.d.ts
ADDED
|
@@ -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"}
|
package/dist/context.js
ADDED
|
@@ -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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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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"}
|
package/dist/types.d.ts
ADDED
|
@@ -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
|
+
}
|