@bwp-web/canvas 0.8.3 → 0.9.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,17 @@
1
+ import { type RefObject } from 'react';
2
+ import type { Canvas as FabricCanvas } from 'fabric';
3
+ /**
4
+ * Shared context for the canvas ref. Provided by both
5
+ * {@link EditCanvasProvider} and {@link ViewCanvasProvider}.
6
+ *
7
+ * The value is a stable `RefObject` that never changes identity after
8
+ * mount, so consumers of this context will **not** re-render when
9
+ * canvas state (zoom, selection, etc.) changes.
10
+ */
11
+ export declare const CanvasRefContext: import("react").Context<RefObject<FabricCanvas | null> | null>;
12
+ /**
13
+ * Read `canvasRef` from the nearest {@link CanvasRefContext} provider.
14
+ * Returns `null` if no provider is present.
15
+ */
16
+ export declare function useCanvasRefContext(): RefObject<FabricCanvas | null> | null;
17
+ //# sourceMappingURL=CanvasRefContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CanvasRefContext.d.ts","sourceRoot":"","sources":["../../src/context/CanvasRefContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAClE,OAAO,KAAK,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,QAAQ,CAAC;AAErD;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,gEAC+B,CAAC;AAE7D;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,SAAS,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,IAAI,CAE3E"}
@@ -2,6 +2,10 @@ import { type ReactNode } from 'react';
2
2
  import { useEditCanvas, type UseEditCanvasOptions } from '../hooks/useEditCanvas';
3
3
  /** The full return value of {@link useEditCanvas}, exposed via context. */
4
4
  export type EditCanvasContextValue = ReturnType<typeof useEditCanvas>;
5
+ /** Viewport slice — changes on every zoom/scroll. */
6
+ export type EditCanvasViewportValue = Pick<EditCanvasContextValue, 'zoom' | 'viewport'>;
7
+ /** State slice — everything except canvasRef and viewport. */
8
+ export type EditCanvasStateValue = Omit<EditCanvasContextValue, 'canvasRef' | 'zoom' | 'viewport'>;
5
9
  export interface EditCanvasProviderProps {
6
10
  /** Options forwarded to the underlying {@link useEditCanvas} hook. */
7
11
  options?: UseEditCanvasOptions;
@@ -11,10 +15,14 @@ export interface EditCanvasProviderProps {
11
15
  * Calls {@link useEditCanvas} internally and provides the full canvas API
12
16
  * to all descendants via React context.
13
17
  *
14
- * Use {@link useEditCanvasContext} in any descendant to access `canvasRef`,
15
- * `isDirty`, `objects`, `isLoading`, `lockLightMode`, `viewport`,
16
- * `setMode`, `setBackground`, and every other value that `useEditCanvas`
17
- * returns — without prop drilling or bridge contexts.
18
+ * Internally splits state into three contexts (ref, viewport, state) so
19
+ * that helper hooks like {@link useCanvasRef} and components like
20
+ * {@link ObjectOverlay} do not re-render on unrelated state changes.
21
+ *
22
+ * Use {@link useEditCanvasContext} in any descendant to access the full
23
+ * combined value, or use the fine-grained hooks
24
+ * {@link useEditCanvasViewport} / {@link useEditCanvasState} for better
25
+ * performance.
18
26
  *
19
27
  * Descendant components can also use {@link ObjectOverlay},
20
28
  * {@link useCanvasEvents}, {@link useCanvasTooltip}, and
@@ -40,7 +48,7 @@ export interface EditCanvasProviderProps {
40
48
  * }
41
49
  *
42
50
  * function MySidebar() {
43
- * const { isDirty, resetDirty } = useEditCanvasContext();
51
+ * const { isDirty, resetDirty } = useEditCanvasState();
44
52
  * return <SaveButton disabled={!isDirty} onClick={() => { save(); resetDirty(); }} />;
45
53
  * }
46
54
  * ```
@@ -50,6 +58,10 @@ export declare function EditCanvasProvider({ options, children, }: EditCanvasPro
50
58
  * Access the full {@link useEditCanvas} API from any descendant of
51
59
  * {@link EditCanvasProvider}.
52
60
  *
61
+ * This subscribes to all three internal contexts, so the component will
62
+ * re-render on any state change. For better performance, prefer
63
+ * {@link useEditCanvasViewport} or {@link useEditCanvasState}.
64
+ *
53
65
  * Throws if called outside of a provider.
54
66
  */
55
67
  export declare function useEditCanvasContext(): EditCanvasContextValue;
@@ -58,4 +70,24 @@ export declare function useEditCanvasContext(): EditCanvasContextValue;
58
70
  * when called outside of an {@link EditCanvasProvider}.
59
71
  */
60
72
  export declare function useEditCanvasContextSafe(): EditCanvasContextValue | null;
73
+ /**
74
+ * Access only the viewport slice (zoom level and viewport controls) from
75
+ * the nearest {@link EditCanvasProvider}.
76
+ *
77
+ * This subscribes only to viewport changes — the component will **not**
78
+ * re-render when selection, dirty state, or other non-viewport state changes.
79
+ *
80
+ * Throws if called outside of a provider.
81
+ */
82
+ export declare function useEditCanvasViewport(): EditCanvasViewportValue;
83
+ /**
84
+ * Access only the non-viewport state slice from the nearest
85
+ * {@link EditCanvasProvider}.
86
+ *
87
+ * This subscribes only to state changes (selection, dirty, history, etc.) —
88
+ * the component will **not** re-render on zoom/scroll changes.
89
+ *
90
+ * Throws if called outside of a provider.
91
+ */
92
+ export declare function useEditCanvasState(): EditCanvasStateValue;
61
93
  //# sourceMappingURL=EditCanvasContext.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EditCanvasContext.d.ts","sourceRoot":"","sources":["../../src/context/EditCanvasContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAClE,OAAO,EACL,aAAa,EACb,KAAK,oBAAoB,EAC1B,MAAM,wBAAwB,CAAC;AAEhC,2EAA2E;AAC3E,MAAM,MAAM,sBAAsB,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AAItE,MAAM,WAAW,uBAAuB;IACtC,sEAAsE;IACtE,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACP,QAAQ,GACT,EAAE,uBAAuB,2CAOzB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,sBAAsB,CAQ7D;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,sBAAsB,GAAG,IAAI,CAExE"}
1
+ {"version":3,"file":"EditCanvasContext.d.ts","sourceRoot":"","sources":["../../src/context/EditCanvasContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC3E,OAAO,EACL,aAAa,EACb,KAAK,oBAAoB,EAC1B,MAAM,wBAAwB,CAAC;AAGhC,2EAA2E;AAC3E,MAAM,MAAM,sBAAsB,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AAEtE,qDAAqD;AACrD,MAAM,MAAM,uBAAuB,GAAG,IAAI,CACxC,sBAAsB,EACtB,MAAM,GAAG,UAAU,CACpB,CAAC;AAEF,8DAA8D;AAC9D,MAAM,MAAM,oBAAoB,GAAG,IAAI,CACrC,sBAAsB,EACtB,WAAW,GAAG,MAAM,GAAG,UAAU,CAClC,CAAC;AAOF,MAAM,WAAW,uBAAuB;IACtC,sEAAsE;IACtE,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACP,QAAQ,GACT,EAAE,uBAAuB,2CAkDzB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,IAAI,sBAAsB,CAe7D;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,sBAAsB,GAAG,IAAI,CAcxE;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,IAAI,uBAAuB,CAQ/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,IAAI,oBAAoB,CAQzD"}
@@ -2,6 +2,10 @@ import { type ReactNode } from 'react';
2
2
  import { useViewCanvas, type UseViewCanvasOptions } from '../hooks/useViewCanvas';
3
3
  /** The full return value of {@link useViewCanvas}, exposed via context. */
4
4
  export type ViewCanvasContextValue = ReturnType<typeof useViewCanvas>;
5
+ /** Viewport slice — changes on every zoom/scroll. */
6
+ export type ViewCanvasViewportValue = Pick<ViewCanvasContextValue, 'zoom' | 'viewport'>;
7
+ /** State slice — everything except canvasRef and viewport. */
8
+ export type ViewCanvasStateValue = Omit<ViewCanvasContextValue, 'canvasRef' | 'zoom' | 'viewport'>;
5
9
  export interface ViewCanvasProviderProps {
6
10
  /** Options forwarded to the underlying {@link useViewCanvas} hook. */
7
11
  options?: UseViewCanvasOptions;
@@ -11,10 +15,14 @@ export interface ViewCanvasProviderProps {
11
15
  * Calls {@link useViewCanvas} internally and provides the full canvas API
12
16
  * to all descendants via React context.
13
17
  *
14
- * Use {@link useViewCanvasContext} in any descendant to access `canvasRef`,
15
- * `viewport`, `objects`, `isLoading`, `setObjectStyle`, and every other
16
- * value that `useViewCanvas` returns without prop drilling or bridge
17
- * contexts.
18
+ * Internally splits state into three contexts (ref, viewport, state) so
19
+ * that helper hooks like {@link useCanvasRef} and components like
20
+ * {@link ObjectOverlay} do not re-render on unrelated state changes.
21
+ *
22
+ * Use {@link useViewCanvasContext} in any descendant to access the full
23
+ * combined value, or use the fine-grained hooks
24
+ * {@link useViewCanvasViewport} / {@link useViewCanvasState} for better
25
+ * performance.
18
26
  *
19
27
  * Descendant components can also use {@link ObjectOverlay},
20
28
  * {@link useCanvasEvents}, {@link useCanvasTooltip}, and
@@ -38,7 +46,7 @@ export interface ViewCanvasProviderProps {
38
46
  * }
39
47
  *
40
48
  * function MyToolbar() {
41
- * const { viewport } = useViewCanvasContext();
49
+ * const { viewport } = useViewCanvasViewport();
42
50
  * return <ZoomControls onZoomIn={viewport.zoomIn} onZoomOut={viewport.zoomOut} />;
43
51
  * }
44
52
  * ```
@@ -48,6 +56,10 @@ export declare function ViewCanvasProvider({ options, children, }: ViewCanvasPro
48
56
  * Access the full {@link useViewCanvas} API from any descendant of
49
57
  * {@link ViewCanvasProvider}.
50
58
  *
59
+ * This subscribes to all three internal contexts, so the component will
60
+ * re-render on any state change. For better performance, prefer
61
+ * {@link useViewCanvasViewport} or {@link useViewCanvasState}.
62
+ *
51
63
  * Throws if called outside of a provider.
52
64
  */
53
65
  export declare function useViewCanvasContext(): ViewCanvasContextValue;
@@ -56,4 +68,24 @@ export declare function useViewCanvasContext(): ViewCanvasContextValue;
56
68
  * when called outside of a {@link ViewCanvasProvider}.
57
69
  */
58
70
  export declare function useViewCanvasContextSafe(): ViewCanvasContextValue | null;
71
+ /**
72
+ * Access only the viewport slice (zoom level and viewport controls) from
73
+ * the nearest {@link ViewCanvasProvider}.
74
+ *
75
+ * This subscribes only to viewport changes — the component will **not**
76
+ * re-render when objects or loading state changes.
77
+ *
78
+ * Throws if called outside of a provider.
79
+ */
80
+ export declare function useViewCanvasViewport(): ViewCanvasViewportValue;
81
+ /**
82
+ * Access only the non-viewport state slice from the nearest
83
+ * {@link ViewCanvasProvider}.
84
+ *
85
+ * This subscribes only to state changes (objects, loading, etc.) —
86
+ * the component will **not** re-render on zoom/scroll changes.
87
+ *
88
+ * Throws if called outside of a provider.
89
+ */
90
+ export declare function useViewCanvasState(): ViewCanvasStateValue;
59
91
  //# sourceMappingURL=ViewCanvasContext.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ViewCanvasContext.d.ts","sourceRoot":"","sources":["../../src/context/ViewCanvasContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAClE,OAAO,EACL,aAAa,EACb,KAAK,oBAAoB,EAC1B,MAAM,wBAAwB,CAAC;AAEhC,2EAA2E;AAC3E,MAAM,MAAM,sBAAsB,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AAItE,MAAM,WAAW,uBAAuB;IACtC,sEAAsE;IACtE,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACP,QAAQ,GACT,EAAE,uBAAuB,2CAOzB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,sBAAsB,CAQ7D;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,sBAAsB,GAAG,IAAI,CAExE"}
1
+ {"version":3,"file":"ViewCanvasContext.d.ts","sourceRoot":"","sources":["../../src/context/ViewCanvasContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC3E,OAAO,EACL,aAAa,EACb,KAAK,oBAAoB,EAC1B,MAAM,wBAAwB,CAAC;AAGhC,2EAA2E;AAC3E,MAAM,MAAM,sBAAsB,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AAEtE,qDAAqD;AACrD,MAAM,MAAM,uBAAuB,GAAG,IAAI,CACxC,sBAAsB,EACtB,MAAM,GAAG,UAAU,CACpB,CAAC;AAEF,8DAA8D;AAC9D,MAAM,MAAM,oBAAoB,GAAG,IAAI,CACrC,sBAAsB,EACtB,WAAW,GAAG,MAAM,GAAG,UAAU,CAClC,CAAC;AAOF,MAAM,WAAW,uBAAuB;IACtC,sEAAsE;IACtE,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACP,QAAQ,GACT,EAAE,uBAAuB,2CA+BzB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,IAAI,sBAAsB,CAe7D;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,sBAAsB,GAAG,IAAI,CAcxE;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,IAAI,uBAAuB,CAQ/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,IAAI,oBAAoB,CAQzD"}
@@ -1,6 +1,6 @@
1
- export { EditCanvasProvider, useEditCanvasContext } from './EditCanvasContext';
2
- export type { EditCanvasProviderProps, EditCanvasContextValue, } from './EditCanvasContext';
3
- export { ViewCanvasProvider, useViewCanvasContext } from './ViewCanvasContext';
4
- export type { ViewCanvasProviderProps, ViewCanvasContextValue, } from './ViewCanvasContext';
1
+ export { EditCanvasProvider, useEditCanvasContext, useEditCanvasContextSafe, useEditCanvasViewport, useEditCanvasState, } from './EditCanvasContext';
2
+ export type { EditCanvasProviderProps, EditCanvasContextValue, EditCanvasViewportValue, EditCanvasStateValue, } from './EditCanvasContext';
3
+ export { ViewCanvasProvider, useViewCanvasContext, useViewCanvasContextSafe, useViewCanvasViewport, useViewCanvasState, } from './ViewCanvasContext';
4
+ export type { ViewCanvasProviderProps, ViewCanvasContextValue, ViewCanvasViewportValue, ViewCanvasStateValue, } from './ViewCanvasContext';
5
5
  export { useCanvasRef } from './useCanvasRef';
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/context/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,YAAY,EACV,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,YAAY,EACV,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/context/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
@@ -6,8 +6,10 @@ import type { Canvas as FabricCanvas } from 'fabric';
6
6
  *
7
7
  * Returns `null` if neither provider is present in the tree.
8
8
  *
9
- * Both context hooks are called unconditionally (Rules-of-Hooks compliant).
10
- * In practice only one provider will be active at a time.
9
+ * This hook reads from the shared {@link CanvasRefContext}, which holds a
10
+ * stable `RefObject` that never changes identity. Consumers of this hook
11
+ * will **not** re-render when canvas state (zoom, selection, etc.) changes
12
+ * — only when the provider mounts/unmounts.
11
13
  */
12
14
  export declare function useCanvasRef(): RefObject<FabricCanvas | null> | null;
13
15
  //# sourceMappingURL=useCanvasRef.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useCanvasRef.d.ts","sourceRoot":"","sources":["../../src/context/useCanvasRef.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,QAAQ,CAAC;AAIrD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,IAAI,SAAS,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,IAAI,CAIpE"}
1
+ {"version":3,"file":"useCanvasRef.d.ts","sourceRoot":"","sources":["../../src/context/useCanvasRef.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,QAAQ,CAAC;AAGrD;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,IAAI,SAAS,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,IAAI,CAEpE"}
package/dist/index.cjs CHANGED
@@ -83,8 +83,12 @@ __export(index_exports, {
83
83
  useCanvasTooltip: () => useCanvasTooltip,
84
84
  useEditCanvas: () => useEditCanvas,
85
85
  useEditCanvasContext: () => useEditCanvasContext,
86
+ useEditCanvasState: () => useEditCanvasState,
87
+ useEditCanvasViewport: () => useEditCanvasViewport,
86
88
  useViewCanvas: () => useViewCanvas,
87
89
  useViewCanvasContext: () => useViewCanvasContext,
90
+ useViewCanvasState: () => useViewCanvasState,
91
+ useViewCanvasViewport: () => useViewCanvasViewport,
88
92
  util: () => import_fabric19.util
89
93
  });
90
94
  module.exports = __toCommonJS(index_exports);
@@ -3052,61 +3056,18 @@ function useViewCanvas(options) {
3052
3056
  }
3053
3057
 
3054
3058
  // src/hooks/useCanvasEvents.ts
3055
- var import_react7 = require("react");
3059
+ var import_react6 = require("react");
3056
3060
 
3057
- // src/context/ViewCanvasContext.tsx
3061
+ // src/context/CanvasRefContext.ts
3058
3062
  var import_react5 = require("react");
3059
- var import_jsx_runtime2 = require("react/jsx-runtime");
3060
- var ViewCanvasContext = (0, import_react5.createContext)(null);
3061
- function ViewCanvasProvider({
3062
- options,
3063
- children
3064
- }) {
3065
- const canvas = useViewCanvas(options);
3066
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ViewCanvasContext.Provider, { value: canvas, children });
3067
- }
3068
- function useViewCanvasContext() {
3069
- const ctx = (0, import_react5.useContext)(ViewCanvasContext);
3070
- if (ctx === null) {
3071
- throw new Error(
3072
- "useViewCanvasContext must be used within a <ViewCanvasProvider>"
3073
- );
3074
- }
3075
- return ctx;
3076
- }
3077
- function useViewCanvasContextSafe() {
3078
- return (0, import_react5.useContext)(ViewCanvasContext);
3079
- }
3080
-
3081
- // src/context/EditCanvasContext.tsx
3082
- var import_react6 = require("react");
3083
- var import_jsx_runtime3 = require("react/jsx-runtime");
3084
- var EditCanvasContext = (0, import_react6.createContext)(null);
3085
- function EditCanvasProvider({
3086
- options,
3087
- children
3088
- }) {
3089
- const canvas = useEditCanvas(options);
3090
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(EditCanvasContext.Provider, { value: canvas, children });
3091
- }
3092
- function useEditCanvasContext() {
3093
- const ctx = (0, import_react6.useContext)(EditCanvasContext);
3094
- if (ctx === null) {
3095
- throw new Error(
3096
- "useEditCanvasContext must be used within an <EditCanvasProvider>"
3097
- );
3098
- }
3099
- return ctx;
3100
- }
3101
- function useEditCanvasContextSafe() {
3102
- return (0, import_react6.useContext)(EditCanvasContext);
3063
+ var CanvasRefContext = (0, import_react5.createContext)(null);
3064
+ function useCanvasRefContext() {
3065
+ return (0, import_react5.useContext)(CanvasRefContext);
3103
3066
  }
3104
3067
 
3105
3068
  // src/context/useCanvasRef.ts
3106
3069
  function useCanvasRef() {
3107
- const viewCtx = useViewCanvasContextSafe();
3108
- const editCtx = useEditCanvasContextSafe();
3109
- return viewCtx?.canvasRef ?? editCtx?.canvasRef ?? null;
3070
+ return useCanvasRefContext();
3110
3071
  }
3111
3072
 
3112
3073
  // src/hooks/useCanvasEvents.ts
@@ -3115,9 +3076,9 @@ function useCanvasEvents(canvasRefOrEvents, maybeEvents) {
3115
3076
  const contextCanvasRef = useCanvasRef();
3116
3077
  const resolvedCanvasRef = isContextOverload ? contextCanvasRef : canvasRefOrEvents;
3117
3078
  const events = isContextOverload ? canvasRefOrEvents : maybeEvents;
3118
- const eventsRef = (0, import_react7.useRef)(events);
3079
+ const eventsRef = (0, import_react6.useRef)(events);
3119
3080
  eventsRef.current = events;
3120
- (0, import_react7.useEffect)(() => {
3081
+ (0, import_react6.useEffect)(() => {
3121
3082
  const canvas = resolvedCanvasRef?.current;
3122
3083
  if (!canvas) return;
3123
3084
  const wrappers = /* @__PURE__ */ new Map();
@@ -3138,21 +3099,21 @@ function useCanvasEvents(canvasRefOrEvents, maybeEvents) {
3138
3099
  }
3139
3100
 
3140
3101
  // src/hooks/useCanvasTooltip.ts
3141
- var import_react8 = require("react");
3102
+ var import_react7 = require("react");
3142
3103
  function useCanvasTooltip(canvasRefOrOptions, maybeOptions) {
3143
3104
  const isContextOverload = maybeOptions === void 0;
3144
3105
  const contextCanvasRef = useCanvasRef();
3145
3106
  const resolvedCanvasRef = isContextOverload ? contextCanvasRef : canvasRefOrOptions;
3146
3107
  const options = isContextOverload ? canvasRefOrOptions : maybeOptions;
3147
- const [state, setState] = (0, import_react8.useState)({
3108
+ const [state, setState] = (0, import_react7.useState)({
3148
3109
  visible: false,
3149
3110
  content: null,
3150
3111
  position: { x: 0, y: 0 }
3151
3112
  });
3152
- const hoveredObjectRef = (0, import_react8.useRef)(null);
3153
- const optionsRef = (0, import_react8.useRef)(options);
3113
+ const hoveredObjectRef = (0, import_react7.useRef)(null);
3114
+ const optionsRef = (0, import_react7.useRef)(options);
3154
3115
  optionsRef.current = options;
3155
- (0, import_react8.useEffect)(() => {
3116
+ (0, import_react7.useEffect)(() => {
3156
3117
  const canvas = resolvedCanvasRef?.current;
3157
3118
  if (!canvas) return;
3158
3119
  function calculatePosition(target) {
@@ -3206,18 +3167,18 @@ function useCanvasTooltip(canvasRefOrOptions, maybeOptions) {
3206
3167
  }
3207
3168
 
3208
3169
  // src/hooks/useCanvasClick.ts
3209
- var import_react9 = require("react");
3170
+ var import_react8 = require("react");
3210
3171
  function useCanvasClick(canvasRefOrOnClick, onClickOrOptions, maybeOptions) {
3211
3172
  const isContextOverload = typeof canvasRefOrOnClick === "function";
3212
3173
  const contextCanvasRef = useCanvasRef();
3213
3174
  const resolvedCanvasRef = isContextOverload ? contextCanvasRef : canvasRefOrOnClick;
3214
3175
  const onClick = isContextOverload ? canvasRefOrOnClick : onClickOrOptions;
3215
3176
  const options = isContextOverload ? onClickOrOptions : maybeOptions;
3216
- const onClickRef = (0, import_react9.useRef)(onClick);
3177
+ const onClickRef = (0, import_react8.useRef)(onClick);
3217
3178
  onClickRef.current = onClick;
3218
- const optionsRef = (0, import_react9.useRef)(options);
3179
+ const optionsRef = (0, import_react8.useRef)(options);
3219
3180
  optionsRef.current = options;
3220
- (0, import_react9.useEffect)(() => {
3181
+ (0, import_react8.useEffect)(() => {
3221
3182
  const canvas = resolvedCanvasRef?.current;
3222
3183
  if (!canvas) return;
3223
3184
  let mouseDown = null;
@@ -3261,8 +3222,151 @@ function useCanvasClick(canvasRefOrOnClick, onClickOrOptions, maybeOptions) {
3261
3222
  }, [resolvedCanvasRef]);
3262
3223
  }
3263
3224
 
3264
- // src/overlay/ObjectOverlay.tsx
3225
+ // src/context/EditCanvasContext.tsx
3226
+ var import_react9 = require("react");
3227
+ var import_jsx_runtime2 = require("react/jsx-runtime");
3228
+ var EditViewportContext = (0, import_react9.createContext)(null);
3229
+ var EditStateContext = (0, import_react9.createContext)(null);
3230
+ function EditCanvasProvider({
3231
+ options,
3232
+ children
3233
+ }) {
3234
+ const canvas = useEditCanvas(options);
3235
+ const viewportValue = (0, import_react9.useMemo)(
3236
+ () => ({ zoom: canvas.zoom, viewport: canvas.viewport }),
3237
+ [canvas.zoom, canvas.viewport]
3238
+ );
3239
+ const stateValue = (0, import_react9.useMemo)(
3240
+ () => ({
3241
+ onReady: canvas.onReady,
3242
+ objects: canvas.objects,
3243
+ isLoading: canvas.isLoading,
3244
+ selected: canvas.selected,
3245
+ isEditingVertices: canvas.isEditingVertices,
3246
+ setMode: canvas.setMode,
3247
+ setBackground: canvas.setBackground,
3248
+ isDirty: canvas.isDirty,
3249
+ resetDirty: canvas.resetDirty,
3250
+ markDirty: canvas.markDirty,
3251
+ undo: canvas.undo,
3252
+ redo: canvas.redo,
3253
+ canUndo: canvas.canUndo,
3254
+ canRedo: canvas.canRedo,
3255
+ lockLightMode: canvas.lockLightMode,
3256
+ setLockLightMode: canvas.setLockLightMode
3257
+ }),
3258
+ // Only reactive state — stable callbacks omitted
3259
+ // eslint-disable-next-line react-hooks/exhaustive-deps
3260
+ [
3261
+ canvas.objects,
3262
+ canvas.isLoading,
3263
+ canvas.selected,
3264
+ canvas.isEditingVertices,
3265
+ canvas.isDirty,
3266
+ canvas.canUndo,
3267
+ canvas.canRedo,
3268
+ canvas.lockLightMode
3269
+ ]
3270
+ );
3271
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CanvasRefContext.Provider, { value: canvas.canvasRef, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EditViewportContext.Provider, { value: viewportValue, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EditStateContext.Provider, { value: stateValue, children }) }) });
3272
+ }
3273
+ function useEditCanvasContext() {
3274
+ const canvasRef = (0, import_react9.useContext)(CanvasRefContext);
3275
+ const viewport = (0, import_react9.useContext)(EditViewportContext);
3276
+ const state = (0, import_react9.useContext)(EditStateContext);
3277
+ if (canvasRef === null || viewport === null || state === null) {
3278
+ throw new Error(
3279
+ "useEditCanvasContext must be used within an <EditCanvasProvider>"
3280
+ );
3281
+ }
3282
+ return (0, import_react9.useMemo)(
3283
+ () => ({ canvasRef, ...viewport, ...state }),
3284
+ [canvasRef, viewport, state]
3285
+ );
3286
+ }
3287
+ function useEditCanvasViewport() {
3288
+ const ctx = (0, import_react9.useContext)(EditViewportContext);
3289
+ if (ctx === null) {
3290
+ throw new Error(
3291
+ "useEditCanvasViewport must be used within an <EditCanvasProvider>"
3292
+ );
3293
+ }
3294
+ return ctx;
3295
+ }
3296
+ function useEditCanvasState() {
3297
+ const ctx = (0, import_react9.useContext)(EditStateContext);
3298
+ if (ctx === null) {
3299
+ throw new Error(
3300
+ "useEditCanvasState must be used within an <EditCanvasProvider>"
3301
+ );
3302
+ }
3303
+ return ctx;
3304
+ }
3305
+
3306
+ // src/context/ViewCanvasContext.tsx
3265
3307
  var import_react10 = require("react");
3308
+ var import_jsx_runtime3 = require("react/jsx-runtime");
3309
+ var ViewViewportContext = (0, import_react10.createContext)(null);
3310
+ var ViewStateContext = (0, import_react10.createContext)(null);
3311
+ function ViewCanvasProvider({
3312
+ options,
3313
+ children
3314
+ }) {
3315
+ const canvas = useViewCanvas(options);
3316
+ const viewportValue = (0, import_react10.useMemo)(
3317
+ () => ({ zoom: canvas.zoom, viewport: canvas.viewport }),
3318
+ [canvas.zoom, canvas.viewport]
3319
+ );
3320
+ const stateValue = (0, import_react10.useMemo)(
3321
+ () => ({
3322
+ onReady: canvas.onReady,
3323
+ objects: canvas.objects,
3324
+ isLoading: canvas.isLoading,
3325
+ setObjectStyle: canvas.setObjectStyle,
3326
+ setObjectStyles: canvas.setObjectStyles,
3327
+ setObjectStyleByType: canvas.setObjectStyleByType
3328
+ }),
3329
+ // Only reactive state — stable callbacks omitted
3330
+ // eslint-disable-next-line react-hooks/exhaustive-deps
3331
+ [canvas.objects, canvas.isLoading]
3332
+ );
3333
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CanvasRefContext.Provider, { value: canvas.canvasRef, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ViewViewportContext.Provider, { value: viewportValue, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ViewStateContext.Provider, { value: stateValue, children }) }) });
3334
+ }
3335
+ function useViewCanvasContext() {
3336
+ const canvasRef = (0, import_react10.useContext)(CanvasRefContext);
3337
+ const viewport = (0, import_react10.useContext)(ViewViewportContext);
3338
+ const state = (0, import_react10.useContext)(ViewStateContext);
3339
+ if (canvasRef === null || viewport === null || state === null) {
3340
+ throw new Error(
3341
+ "useViewCanvasContext must be used within a <ViewCanvasProvider>"
3342
+ );
3343
+ }
3344
+ return (0, import_react10.useMemo)(
3345
+ () => ({ canvasRef, ...viewport, ...state }),
3346
+ [canvasRef, viewport, state]
3347
+ );
3348
+ }
3349
+ function useViewCanvasViewport() {
3350
+ const ctx = (0, import_react10.useContext)(ViewViewportContext);
3351
+ if (ctx === null) {
3352
+ throw new Error(
3353
+ "useViewCanvasViewport must be used within a <ViewCanvasProvider>"
3354
+ );
3355
+ }
3356
+ return ctx;
3357
+ }
3358
+ function useViewCanvasState() {
3359
+ const ctx = (0, import_react10.useContext)(ViewStateContext);
3360
+ if (ctx === null) {
3361
+ throw new Error(
3362
+ "useViewCanvasState must be used within a <ViewCanvasProvider>"
3363
+ );
3364
+ }
3365
+ return ctx;
3366
+ }
3367
+
3368
+ // src/overlay/ObjectOverlay.tsx
3369
+ var import_react11 = require("react");
3266
3370
  var import_material = require("@mui/material");
3267
3371
  var import_fabric18 = require("fabric");
3268
3372
  var import_jsx_runtime4 = require("react/jsx-runtime");
@@ -3275,8 +3379,8 @@ function ObjectOverlay({
3275
3379
  }) {
3276
3380
  const contextCanvasRef = useCanvasRef();
3277
3381
  const canvasRef = canvasRefProp ?? contextCanvasRef;
3278
- const stackRef = (0, import_react10.useRef)(null);
3279
- (0, import_react10.useEffect)(() => {
3382
+ const stackRef = (0, import_react11.useRef)(null);
3383
+ (0, import_react11.useEffect)(() => {
3280
3384
  const canvas = canvasRef?.current;
3281
3385
  if (!canvas || !object) return;
3282
3386
  function update() {
@@ -3331,7 +3435,7 @@ function ObjectOverlay({
3331
3435
 
3332
3436
  // src/overlay/OverlayContent.tsx
3333
3437
  var import_material2 = require("@mui/material");
3334
- var import_react11 = require("react");
3438
+ var import_react12 = require("react");
3335
3439
  var import_jsx_runtime5 = require("react/jsx-runtime");
3336
3440
  function OverlayContent({
3337
3441
  children,
@@ -3340,9 +3444,9 @@ function OverlayContent({
3340
3444
  sx,
3341
3445
  ...rest
3342
3446
  }) {
3343
- const outerRef = (0, import_react11.useRef)(null);
3344
- const innerRef = (0, import_react11.useRef)(null);
3345
- (0, import_react11.useEffect)(() => {
3447
+ const outerRef = (0, import_react12.useRef)(null);
3448
+ const innerRef = (0, import_react12.useRef)(null);
3449
+ (0, import_react12.useEffect)(() => {
3346
3450
  const outer = outerRef.current;
3347
3451
  const inner = innerRef.current;
3348
3452
  if (!outer || !inner) return;
@@ -3403,7 +3507,7 @@ function OverlayContent({
3403
3507
 
3404
3508
  // src/overlay/FixedSizeContent.tsx
3405
3509
  var import_material3 = require("@mui/material");
3406
- var import_react12 = require("react");
3510
+ var import_react13 = require("react");
3407
3511
  var import_jsx_runtime6 = require("react/jsx-runtime");
3408
3512
  function FixedSizeContent({
3409
3513
  children,
@@ -3412,9 +3516,9 @@ function FixedSizeContent({
3412
3516
  sx,
3413
3517
  ...rest
3414
3518
  }) {
3415
- const ref = (0, import_react12.useRef)(null);
3416
- const totalContentHeightRef = (0, import_react12.useRef)(0);
3417
- (0, import_react12.useEffect)(() => {
3519
+ const ref = (0, import_react13.useRef)(null);
3520
+ const totalContentHeightRef = (0, import_react13.useRef)(0);
3521
+ (0, import_react13.useEffect)(() => {
3418
3522
  const el = ref.current;
3419
3523
  if (!el) return;
3420
3524
  let clipAncestor = el.parentElement;
@@ -3477,7 +3581,7 @@ function FixedSizeContent({
3477
3581
 
3478
3582
  // src/overlay/OverlayBadge.tsx
3479
3583
  var import_material4 = require("@mui/material");
3480
- var import_react13 = require("react");
3584
+ var import_react14 = require("react");
3481
3585
  var import_jsx_runtime7 = require("react/jsx-runtime");
3482
3586
  function toPx(v) {
3483
3587
  if (v === void 0) return void 0;
@@ -3520,9 +3624,9 @@ function OverlayBadge({
3520
3624
  sx,
3521
3625
  ...rest
3522
3626
  }) {
3523
- const ref = (0, import_react13.useRef)(null);
3524
- const baseSize = (0, import_react13.useRef)(null);
3525
- (0, import_react13.useEffect)(() => {
3627
+ const ref = (0, import_react14.useRef)(null);
3628
+ const baseSize = (0, import_react14.useRef)(null);
3629
+ (0, import_react14.useEffect)(() => {
3526
3630
  const el = ref.current;
3527
3631
  if (!el) return;
3528
3632
  const ancestor = el.parentElement;
@@ -3661,8 +3765,12 @@ var import_fabric19 = require("fabric");
3661
3765
  useCanvasTooltip,
3662
3766
  useEditCanvas,
3663
3767
  useEditCanvasContext,
3768
+ useEditCanvasState,
3769
+ useEditCanvasViewport,
3664
3770
  useViewCanvas,
3665
3771
  useViewCanvasContext,
3772
+ useViewCanvasState,
3773
+ useViewCanvasViewport,
3666
3774
  util
3667
3775
  });
3668
3776
  //# sourceMappingURL=index.cjs.map