@cadview/react 0.1.0 → 0.3.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/index.cjs CHANGED
@@ -11,9 +11,11 @@ var CadViewer = react.forwardRef(
11
11
  file,
12
12
  theme = "dark",
13
13
  tool = "pan",
14
+ debug,
14
15
  className,
15
16
  style,
16
17
  options,
18
+ formatConverters,
17
19
  onSelect,
18
20
  onMeasure,
19
21
  onViewChange,
@@ -26,6 +28,8 @@ var CadViewer = react.forwardRef(
26
28
  const viewer = new core.CadViewer(canvasRef.current, {
27
29
  theme,
28
30
  initialTool: tool,
31
+ debug,
32
+ formatConverters,
29
33
  ...options
30
34
  });
31
35
  viewerRef.current = viewer;
@@ -40,21 +44,37 @@ var CadViewer = react.forwardRef(
40
44
  react.useEffect(() => {
41
45
  viewerRef.current?.setTool(tool);
42
46
  }, [tool]);
47
+ react.useEffect(() => {
48
+ if (debug !== void 0) {
49
+ viewerRef.current?.setDebug(debug);
50
+ }
51
+ }, [debug]);
43
52
  react.useEffect(() => {
44
53
  const viewer = viewerRef.current;
45
54
  if (!viewer || !file) return;
46
- if (file instanceof File) {
47
- viewer.loadFile(file).then(
48
- () => onLayersLoaded?.(viewer.getLayers()),
49
- (err) => console.error("CadViewer: failed to load file", err)
50
- );
51
- } else if (file instanceof ArrayBuffer) {
52
- viewer.loadArrayBuffer(file);
53
- onLayersLoaded?.(viewer.getLayers());
54
- } else if (typeof file === "string") {
55
- viewer.loadString(file);
56
- onLayersLoaded?.(viewer.getLayers());
57
- }
55
+ let cancelled = false;
56
+ const load = async () => {
57
+ try {
58
+ if (file instanceof File) {
59
+ await viewer.loadFile(file);
60
+ } else if (file instanceof ArrayBuffer) {
61
+ await viewer.loadBuffer(file);
62
+ } else if (typeof file === "string") {
63
+ viewer.loadString(file);
64
+ }
65
+ if (!cancelled) {
66
+ onLayersLoaded?.(viewer.getLayers());
67
+ }
68
+ } catch (err) {
69
+ if (!cancelled) {
70
+ console.error("CadViewer: failed to load file", err);
71
+ }
72
+ }
73
+ };
74
+ load();
75
+ return () => {
76
+ cancelled = true;
77
+ };
58
78
  }, [file]);
59
79
  react.useEffect(() => {
60
80
  const viewer = viewerRef.current;
@@ -128,6 +148,17 @@ function useCadViewer(canvasRef, options) {
128
148
  setError(err instanceof Error ? err : new Error(String(err)));
129
149
  }
130
150
  }, []);
151
+ const loadBuffer = react.useCallback(async (buffer) => {
152
+ if (!viewerRef.current) return;
153
+ setError(null);
154
+ try {
155
+ await viewerRef.current.loadBuffer(buffer);
156
+ setLayers(viewerRef.current.getLayers());
157
+ setIsLoaded(true);
158
+ } catch (err) {
159
+ setError(err instanceof Error ? err : new Error(String(err)));
160
+ }
161
+ }, []);
131
162
  const loadString = react.useCallback((dxf) => {
132
163
  if (!viewerRef.current) return;
133
164
  setError(null);
@@ -145,6 +176,7 @@ function useCadViewer(canvasRef, options) {
145
176
  isLoaded,
146
177
  error,
147
178
  loadFile,
179
+ loadBuffer,
148
180
  loadString,
149
181
  fitToView: () => viewerRef.current?.fitToView(),
150
182
  setLayerVisible: (name, visible) => viewerRef.current?.setLayerVisible(name, visible),
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/CadViewer.tsx","../src/useCadViewer.ts"],"names":["forwardRef","CadViewer","useRef","useEffect","CoreCadViewer","useImperativeHandle","jsx","useState","useCallback"],"mappings":"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","file":"index.cjs","sourcesContent":["import {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n type CSSProperties,\n} from 'react';\nimport {\n CadViewer as CoreCadViewer,\n type CadViewerOptions,\n type DxfLayer,\n type SelectEvent,\n type MeasureEvent,\n type ViewTransform,\n type Tool,\n type Theme,\n} from '@cadview/core';\n\nexport interface CadViewerProps {\n file?: File | ArrayBuffer | string | null;\n theme?: Theme;\n tool?: Tool;\n className?: string;\n style?: CSSProperties;\n options?: Omit<CadViewerOptions, 'theme' | 'initialTool'>;\n onSelect?: (event: SelectEvent) => void;\n onMeasure?: (event: MeasureEvent) => void;\n onViewChange?: (transform: ViewTransform) => void;\n onLayersLoaded?: (layers: DxfLayer[]) => void;\n}\n\nexport interface CadViewerRef {\n getViewer(): CoreCadViewer | null;\n fitToView(): void;\n getLayers(): DxfLayer[];\n setLayerVisible(name: string, visible: boolean): void;\n}\n\nexport const CadViewer = forwardRef<CadViewerRef, CadViewerProps>(\n function CadViewer(props, ref) {\n const {\n file,\n theme = 'dark',\n tool = 'pan',\n className,\n style,\n options,\n onSelect,\n onMeasure,\n onViewChange,\n onLayersLoaded,\n } = props;\n\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const viewerRef = useRef<CoreCadViewer | null>(null);\n\n useEffect(() => {\n if (!canvasRef.current) return;\n\n const viewer = new CoreCadViewer(canvasRef.current, {\n theme,\n initialTool: tool,\n ...options,\n });\n viewerRef.current = viewer;\n\n return () => {\n viewer.destroy();\n viewerRef.current = null;\n };\n }, []);\n\n useEffect(() => {\n viewerRef.current?.setTheme(theme);\n }, [theme]);\n\n useEffect(() => {\n viewerRef.current?.setTool(tool);\n }, [tool]);\n\n useEffect(() => {\n const viewer = viewerRef.current;\n if (!viewer || !file) return;\n\n if (file instanceof File) {\n viewer.loadFile(file).then(\n () => onLayersLoaded?.(viewer.getLayers()),\n (err) => console.error('CadViewer: failed to load file', err),\n );\n } else if (file instanceof ArrayBuffer) {\n viewer.loadArrayBuffer(file);\n onLayersLoaded?.(viewer.getLayers());\n } else if (typeof file === 'string') {\n viewer.loadString(file);\n onLayersLoaded?.(viewer.getLayers());\n }\n }, [file]);\n\n useEffect(() => {\n const viewer = viewerRef.current;\n if (!viewer) return;\n\n const handlers: Array<() => void> = [];\n\n if (onSelect) {\n viewer.on('select', onSelect);\n handlers.push(() => viewer.off('select', onSelect));\n }\n if (onMeasure) {\n viewer.on('measure', onMeasure);\n handlers.push(() => viewer.off('measure', onMeasure));\n }\n if (onViewChange) {\n viewer.on('viewchange', onViewChange);\n handlers.push(() => viewer.off('viewchange', onViewChange));\n }\n\n return () => { handlers.forEach((h) => { h(); }); };\n }, [onSelect, onMeasure, onViewChange]);\n\n useImperativeHandle(ref, () => ({\n getViewer: () => viewerRef.current,\n fitToView: () => viewerRef.current?.fitToView(),\n getLayers: () => viewerRef.current?.getLayers() ?? [],\n setLayerVisible: (name: string, visible: boolean) =>\n viewerRef.current?.setLayerVisible(name, visible),\n }));\n\n return (\n <div\n className={className}\n style={{ position: 'relative', overflow: 'hidden', ...style }}\n >\n <canvas\n ref={canvasRef}\n style={{ display: 'block', width: '100%', height: '100%' }}\n />\n </div>\n );\n },\n);\n","import { useEffect, useRef, useState, useCallback } from 'react';\nimport {\n CadViewer,\n type CadViewerOptions,\n type DxfLayer,\n} from '@cadview/core';\n\nexport function useCadViewer(\n canvasRef: React.RefObject<HTMLCanvasElement | null>,\n options?: CadViewerOptions,\n) {\n const viewerRef = useRef<CadViewer | null>(null);\n const [viewer, setViewer] = useState<CadViewer | null>(null);\n const [layers, setLayers] = useState<DxfLayer[]>([]);\n const [isLoaded, setIsLoaded] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n if (!canvasRef.current) return;\n const v = new CadViewer(canvasRef.current, options);\n viewerRef.current = v;\n setViewer(v);\n return () => {\n v.destroy();\n viewerRef.current = null;\n setViewer(null);\n };\n }, []);\n\n const loadFile = useCallback(async (file: File) => {\n if (!viewerRef.current) return;\n setError(null);\n try {\n await viewerRef.current.loadFile(file);\n setLayers(viewerRef.current.getLayers());\n setIsLoaded(true);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n }\n }, []);\n\n const loadString = useCallback((dxf: string) => {\n if (!viewerRef.current) return;\n setError(null);\n try {\n viewerRef.current.loadString(dxf);\n setLayers(viewerRef.current.getLayers());\n setIsLoaded(true);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n }\n }, []);\n\n return {\n viewer,\n layers,\n isLoaded,\n error,\n loadFile,\n loadString,\n fitToView: () => viewerRef.current?.fitToView(),\n setLayerVisible: (name: string, visible: boolean) =>\n viewerRef.current?.setLayerVisible(name, visible),\n setTheme: (theme: 'dark' | 'light') =>\n viewerRef.current?.setTheme(theme),\n setTool: (tool: 'pan' | 'select' | 'measure') =>\n viewerRef.current?.setTool(tool),\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/CadViewer.tsx","../src/useCadViewer.ts"],"names":["forwardRef","CadViewer","useRef","useEffect","CoreCadViewer","useImperativeHandle","jsx","useState","useCallback"],"mappings":"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","file":"index.cjs","sourcesContent":["import {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n type CSSProperties,\n} from 'react';\nimport {\n CadViewer as CoreCadViewer,\n type CadViewerOptions,\n type FormatConverter,\n type DebugOptions,\n type DxfLayer,\n type SelectEvent,\n type MeasureEvent,\n type ViewTransform,\n type Tool,\n type Theme,\n} from '@cadview/core';\n\nexport interface CadViewerProps {\n file?: File | ArrayBuffer | string | null;\n theme?: Theme;\n tool?: Tool;\n /** Enable debug overlay. Pass `true` for defaults, or a `DebugOptions` object. */\n debug?: boolean | DebugOptions;\n className?: string;\n style?: CSSProperties;\n options?: Omit<CadViewerOptions, 'theme' | 'initialTool' | 'debug'>;\n /** Format converters for non-DXF file formats (e.g. DWG via @cadview/dwg). */\n formatConverters?: FormatConverter[];\n onSelect?: (event: SelectEvent) => void;\n onMeasure?: (event: MeasureEvent) => void;\n onViewChange?: (transform: ViewTransform) => void;\n onLayersLoaded?: (layers: DxfLayer[]) => void;\n}\n\nexport interface CadViewerRef {\n getViewer(): CoreCadViewer | null;\n fitToView(): void;\n getLayers(): DxfLayer[];\n setLayerVisible(name: string, visible: boolean): void;\n}\n\nexport const CadViewer = forwardRef<CadViewerRef, CadViewerProps>(\n function CadViewer(props, ref) {\n const {\n file,\n theme = 'dark',\n tool = 'pan',\n debug,\n className,\n style,\n options,\n formatConverters,\n onSelect,\n onMeasure,\n onViewChange,\n onLayersLoaded,\n } = props;\n\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const viewerRef = useRef<CoreCadViewer | null>(null);\n\n useEffect(() => {\n if (!canvasRef.current) return;\n\n const viewer = new CoreCadViewer(canvasRef.current, {\n theme,\n initialTool: tool,\n debug,\n formatConverters,\n ...options,\n });\n viewerRef.current = viewer;\n\n return () => {\n viewer.destroy();\n viewerRef.current = null;\n };\n }, []);\n\n useEffect(() => {\n viewerRef.current?.setTheme(theme);\n }, [theme]);\n\n useEffect(() => {\n viewerRef.current?.setTool(tool);\n }, [tool]);\n\n useEffect(() => {\n if (debug !== undefined) {\n viewerRef.current?.setDebug(debug);\n }\n }, [debug]);\n\n useEffect(() => {\n const viewer = viewerRef.current;\n if (!viewer || !file) return;\n let cancelled = false;\n\n const load = async () => {\n try {\n if (file instanceof File) {\n await viewer.loadFile(file);\n } else if (file instanceof ArrayBuffer) {\n await viewer.loadBuffer(file);\n } else if (typeof file === 'string') {\n viewer.loadString(file);\n }\n if (!cancelled) {\n onLayersLoaded?.(viewer.getLayers());\n }\n } catch (err) {\n if (!cancelled) {\n console.error('CadViewer: failed to load file', err);\n }\n }\n };\n\n load();\n\n return () => {\n cancelled = true;\n };\n }, [file]);\n\n useEffect(() => {\n const viewer = viewerRef.current;\n if (!viewer) return;\n\n const handlers: Array<() => void> = [];\n\n if (onSelect) {\n viewer.on('select', onSelect);\n handlers.push(() => viewer.off('select', onSelect));\n }\n if (onMeasure) {\n viewer.on('measure', onMeasure);\n handlers.push(() => viewer.off('measure', onMeasure));\n }\n if (onViewChange) {\n viewer.on('viewchange', onViewChange);\n handlers.push(() => viewer.off('viewchange', onViewChange));\n }\n\n return () => { handlers.forEach((h) => { h(); }); };\n }, [onSelect, onMeasure, onViewChange]);\n\n useImperativeHandle(ref, () => ({\n getViewer: () => viewerRef.current,\n fitToView: () => viewerRef.current?.fitToView(),\n getLayers: () => viewerRef.current?.getLayers() ?? [],\n setLayerVisible: (name: string, visible: boolean) =>\n viewerRef.current?.setLayerVisible(name, visible),\n }));\n\n return (\n <div\n className={className}\n style={{ position: 'relative', overflow: 'hidden', ...style }}\n >\n <canvas\n ref={canvasRef}\n style={{ display: 'block', width: '100%', height: '100%' }}\n />\n </div>\n );\n },\n);\n","import { useEffect, useRef, useState, useCallback } from 'react';\nimport {\n CadViewer,\n type CadViewerOptions,\n type DxfLayer,\n} from '@cadview/core';\n\nexport function useCadViewer(\n canvasRef: React.RefObject<HTMLCanvasElement | null>,\n options?: CadViewerOptions,\n) {\n const viewerRef = useRef<CadViewer | null>(null);\n const [viewer, setViewer] = useState<CadViewer | null>(null);\n const [layers, setLayers] = useState<DxfLayer[]>([]);\n const [isLoaded, setIsLoaded] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n if (!canvasRef.current) return;\n const v = new CadViewer(canvasRef.current, options);\n viewerRef.current = v;\n setViewer(v);\n return () => {\n v.destroy();\n viewerRef.current = null;\n setViewer(null);\n };\n }, []);\n\n const loadFile = useCallback(async (file: File) => {\n if (!viewerRef.current) return;\n setError(null);\n try {\n await viewerRef.current.loadFile(file);\n setLayers(viewerRef.current.getLayers());\n setIsLoaded(true);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n }\n }, []);\n\n const loadBuffer = useCallback(async (buffer: ArrayBuffer) => {\n if (!viewerRef.current) return;\n setError(null);\n try {\n await viewerRef.current.loadBuffer(buffer);\n setLayers(viewerRef.current.getLayers());\n setIsLoaded(true);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n }\n }, []);\n\n const loadString = useCallback((dxf: string) => {\n if (!viewerRef.current) return;\n setError(null);\n try {\n viewerRef.current.loadString(dxf);\n setLayers(viewerRef.current.getLayers());\n setIsLoaded(true);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n }\n }, []);\n\n return {\n viewer,\n layers,\n isLoaded,\n error,\n loadFile,\n loadBuffer,\n loadString,\n fitToView: () => viewerRef.current?.fitToView(),\n setLayerVisible: (name: string, visible: boolean) =>\n viewerRef.current?.setLayerVisible(name, visible),\n setTheme: (theme: 'dark' | 'light') =>\n viewerRef.current?.setTheme(theme),\n setTool: (tool: 'pan' | 'select' | 'measure') =>\n viewerRef.current?.setTool(tool),\n };\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -1,15 +1,19 @@
1
1
  import * as react from 'react';
2
2
  import { CSSProperties } from 'react';
3
- import { Theme, Tool, CadViewerOptions, SelectEvent, MeasureEvent, ViewTransform, DxfLayer, CadViewer as CadViewer$1 } from '@cadview/core';
4
- export { DxfDocument, DxfEntity, DxfLayer, MeasureEvent, SelectEvent, Theme, Tool, ViewTransform } from '@cadview/core';
3
+ import { Theme, Tool, DebugOptions, CadViewerOptions, FormatConverter, SelectEvent, MeasureEvent, ViewTransform, DxfLayer, CadViewer as CadViewer$1 } from '@cadview/core';
4
+ export { DxfDocument, DxfEntity, DxfLayer, FormatConverter, MeasureEvent, SelectEvent, Theme, Tool, ViewTransform } from '@cadview/core';
5
5
 
6
6
  interface CadViewerProps {
7
7
  file?: File | ArrayBuffer | string | null;
8
8
  theme?: Theme;
9
9
  tool?: Tool;
10
+ /** Enable debug overlay. Pass `true` for defaults, or a `DebugOptions` object. */
11
+ debug?: boolean | DebugOptions;
10
12
  className?: string;
11
13
  style?: CSSProperties;
12
- options?: Omit<CadViewerOptions, 'theme' | 'initialTool'>;
14
+ options?: Omit<CadViewerOptions, 'theme' | 'initialTool' | 'debug'>;
15
+ /** Format converters for non-DXF file formats (e.g. DWG via @cadview/dwg). */
16
+ formatConverters?: FormatConverter[];
13
17
  onSelect?: (event: SelectEvent) => void;
14
18
  onMeasure?: (event: MeasureEvent) => void;
15
19
  onViewChange?: (transform: ViewTransform) => void;
@@ -29,6 +33,7 @@ declare function useCadViewer(canvasRef: React.RefObject<HTMLCanvasElement | nul
29
33
  isLoaded: boolean;
30
34
  error: Error | null;
31
35
  loadFile: (file: File) => Promise<void>;
36
+ loadBuffer: (buffer: ArrayBuffer) => Promise<void>;
32
37
  loadString: (dxf: string) => void;
33
38
  fitToView: () => void | undefined;
34
39
  setLayerVisible: (name: string, visible: boolean) => void | undefined;
package/dist/index.d.ts CHANGED
@@ -1,15 +1,19 @@
1
1
  import * as react from 'react';
2
2
  import { CSSProperties } from 'react';
3
- import { Theme, Tool, CadViewerOptions, SelectEvent, MeasureEvent, ViewTransform, DxfLayer, CadViewer as CadViewer$1 } from '@cadview/core';
4
- export { DxfDocument, DxfEntity, DxfLayer, MeasureEvent, SelectEvent, Theme, Tool, ViewTransform } from '@cadview/core';
3
+ import { Theme, Tool, DebugOptions, CadViewerOptions, FormatConverter, SelectEvent, MeasureEvent, ViewTransform, DxfLayer, CadViewer as CadViewer$1 } from '@cadview/core';
4
+ export { DxfDocument, DxfEntity, DxfLayer, FormatConverter, MeasureEvent, SelectEvent, Theme, Tool, ViewTransform } from '@cadview/core';
5
5
 
6
6
  interface CadViewerProps {
7
7
  file?: File | ArrayBuffer | string | null;
8
8
  theme?: Theme;
9
9
  tool?: Tool;
10
+ /** Enable debug overlay. Pass `true` for defaults, or a `DebugOptions` object. */
11
+ debug?: boolean | DebugOptions;
10
12
  className?: string;
11
13
  style?: CSSProperties;
12
- options?: Omit<CadViewerOptions, 'theme' | 'initialTool'>;
14
+ options?: Omit<CadViewerOptions, 'theme' | 'initialTool' | 'debug'>;
15
+ /** Format converters for non-DXF file formats (e.g. DWG via @cadview/dwg). */
16
+ formatConverters?: FormatConverter[];
13
17
  onSelect?: (event: SelectEvent) => void;
14
18
  onMeasure?: (event: MeasureEvent) => void;
15
19
  onViewChange?: (transform: ViewTransform) => void;
@@ -29,6 +33,7 @@ declare function useCadViewer(canvasRef: React.RefObject<HTMLCanvasElement | nul
29
33
  isLoaded: boolean;
30
34
  error: Error | null;
31
35
  loadFile: (file: File) => Promise<void>;
36
+ loadBuffer: (buffer: ArrayBuffer) => Promise<void>;
32
37
  loadString: (dxf: string) => void;
33
38
  fitToView: () => void | undefined;
34
39
  setLayerVisible: (name: string, visible: boolean) => void | undefined;
package/dist/index.js CHANGED
@@ -9,9 +9,11 @@ var CadViewer = forwardRef(
9
9
  file,
10
10
  theme = "dark",
11
11
  tool = "pan",
12
+ debug,
12
13
  className,
13
14
  style,
14
15
  options,
16
+ formatConverters,
15
17
  onSelect,
16
18
  onMeasure,
17
19
  onViewChange,
@@ -24,6 +26,8 @@ var CadViewer = forwardRef(
24
26
  const viewer = new CadViewer$1(canvasRef.current, {
25
27
  theme,
26
28
  initialTool: tool,
29
+ debug,
30
+ formatConverters,
27
31
  ...options
28
32
  });
29
33
  viewerRef.current = viewer;
@@ -38,21 +42,37 @@ var CadViewer = forwardRef(
38
42
  useEffect(() => {
39
43
  viewerRef.current?.setTool(tool);
40
44
  }, [tool]);
45
+ useEffect(() => {
46
+ if (debug !== void 0) {
47
+ viewerRef.current?.setDebug(debug);
48
+ }
49
+ }, [debug]);
41
50
  useEffect(() => {
42
51
  const viewer = viewerRef.current;
43
52
  if (!viewer || !file) return;
44
- if (file instanceof File) {
45
- viewer.loadFile(file).then(
46
- () => onLayersLoaded?.(viewer.getLayers()),
47
- (err) => console.error("CadViewer: failed to load file", err)
48
- );
49
- } else if (file instanceof ArrayBuffer) {
50
- viewer.loadArrayBuffer(file);
51
- onLayersLoaded?.(viewer.getLayers());
52
- } else if (typeof file === "string") {
53
- viewer.loadString(file);
54
- onLayersLoaded?.(viewer.getLayers());
55
- }
53
+ let cancelled = false;
54
+ const load = async () => {
55
+ try {
56
+ if (file instanceof File) {
57
+ await viewer.loadFile(file);
58
+ } else if (file instanceof ArrayBuffer) {
59
+ await viewer.loadBuffer(file);
60
+ } else if (typeof file === "string") {
61
+ viewer.loadString(file);
62
+ }
63
+ if (!cancelled) {
64
+ onLayersLoaded?.(viewer.getLayers());
65
+ }
66
+ } catch (err) {
67
+ if (!cancelled) {
68
+ console.error("CadViewer: failed to load file", err);
69
+ }
70
+ }
71
+ };
72
+ load();
73
+ return () => {
74
+ cancelled = true;
75
+ };
56
76
  }, [file]);
57
77
  useEffect(() => {
58
78
  const viewer = viewerRef.current;
@@ -126,6 +146,17 @@ function useCadViewer(canvasRef, options) {
126
146
  setError(err instanceof Error ? err : new Error(String(err)));
127
147
  }
128
148
  }, []);
149
+ const loadBuffer = useCallback(async (buffer) => {
150
+ if (!viewerRef.current) return;
151
+ setError(null);
152
+ try {
153
+ await viewerRef.current.loadBuffer(buffer);
154
+ setLayers(viewerRef.current.getLayers());
155
+ setIsLoaded(true);
156
+ } catch (err) {
157
+ setError(err instanceof Error ? err : new Error(String(err)));
158
+ }
159
+ }, []);
129
160
  const loadString = useCallback((dxf) => {
130
161
  if (!viewerRef.current) return;
131
162
  setError(null);
@@ -143,6 +174,7 @@ function useCadViewer(canvasRef, options) {
143
174
  isLoaded,
144
175
  error,
145
176
  loadFile,
177
+ loadBuffer,
146
178
  loadString,
147
179
  fitToView: () => viewerRef.current?.fitToView(),
148
180
  setLayerVisible: (name, visible) => viewerRef.current?.setLayerVisible(name, visible),
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/CadViewer.tsx","../src/useCadViewer.ts"],"names":["CadViewer","CoreCadViewer","useRef","useEffect"],"mappings":";;;;;AAsCO,IAAM,SAAA,GAAY,UAAA;AAAA,EACvB,SAASA,UAAAA,CAAU,KAAA,EAAO,GAAA,EAAK;AAC7B,IAAA,MAAM;AAAA,MACJ,IAAA;AAAA,MACA,KAAA,GAAQ,MAAA;AAAA,MACR,IAAA,GAAO,KAAA;AAAA,MACP,SAAA;AAAA,MACA,KAAA;AAAA,MACA,OAAA;AAAA,MACA,QAAA;AAAA,MACA,SAAA;AAAA,MACA,YAAA;AAAA,MACA;AAAA,KACF,GAAI,KAAA;AAEJ,IAAA,MAAM,SAAA,GAAY,OAA0B,IAAI,CAAA;AAChD,IAAA,MAAM,SAAA,GAAY,OAA6B,IAAI,CAAA;AAEnD,IAAA,SAAA,CAAU,MAAM;AACd,MAAA,IAAI,CAAC,UAAU,OAAA,EAAS;AAExB,MAAA,MAAM,MAAA,GAAS,IAAIC,WAAA,CAAc,SAAA,CAAU,OAAA,EAAS;AAAA,QAClD,KAAA;AAAA,QACA,WAAA,EAAa,IAAA;AAAA,QACb,GAAG;AAAA,OACJ,CAAA;AACD,MAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AAEpB,MAAA,OAAO,MAAM;AACX,QAAA,MAAA,CAAO,OAAA,EAAQ;AACf,QAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AAAA,MACtB,CAAA;AAAA,IACF,CAAA,EAAG,EAAE,CAAA;AAEL,IAAA,SAAA,CAAU,MAAM;AACd,MAAA,SAAA,CAAU,OAAA,EAAS,SAAS,KAAK,CAAA;AAAA,IACnC,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEV,IAAA,SAAA,CAAU,MAAM;AACd,MAAA,SAAA,CAAU,OAAA,EAAS,QAAQ,IAAI,CAAA;AAAA,IACjC,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,IAAA,SAAA,CAAU,MAAM;AACd,MAAA,MAAM,SAAS,SAAA,CAAU,OAAA;AACzB,MAAA,IAAI,CAAC,MAAA,IAAU,CAAC,IAAA,EAAM;AAEtB,MAAA,IAAI,gBAAgB,IAAA,EAAM;AACxB,QAAA,MAAA,CAAO,QAAA,CAAS,IAAI,CAAA,CAAE,IAAA;AAAA,UACpB,MAAM,cAAA,GAAiB,MAAA,CAAO,SAAA,EAAW,CAAA;AAAA,UACzC,CAAC,GAAA,KAAQ,OAAA,CAAQ,KAAA,CAAM,kCAAkC,GAAG;AAAA,SAC9D;AAAA,MACF,CAAA,MAAA,IAAW,gBAAgB,WAAA,EAAa;AACtC,QAAA,MAAA,CAAO,gBAAgB,IAAI,CAAA;AAC3B,QAAA,cAAA,GAAiB,MAAA,CAAO,WAAW,CAAA;AAAA,MACrC,CAAA,MAAA,IAAW,OAAO,IAAA,KAAS,QAAA,EAAU;AACnC,QAAA,MAAA,CAAO,WAAW,IAAI,CAAA;AACtB,QAAA,cAAA,GAAiB,MAAA,CAAO,WAAW,CAAA;AAAA,MACrC;AAAA,IACF,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,IAAA,SAAA,CAAU,MAAM;AACd,MAAA,MAAM,SAAS,SAAA,CAAU,OAAA;AACzB,MAAA,IAAI,CAAC,MAAA,EAAQ;AAEb,MAAA,MAAM,WAA8B,EAAC;AAErC,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,MAAA,CAAO,EAAA,CAAG,UAAU,QAAQ,CAAA;AAC5B,QAAA,QAAA,CAAS,KAAK,MAAM,MAAA,CAAO,GAAA,CAAI,QAAA,EAAU,QAAQ,CAAC,CAAA;AAAA,MACpD;AACA,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,MAAA,CAAO,EAAA,CAAG,WAAW,SAAS,CAAA;AAC9B,QAAA,QAAA,CAAS,KAAK,MAAM,MAAA,CAAO,GAAA,CAAI,SAAA,EAAW,SAAS,CAAC,CAAA;AAAA,MACtD;AACA,MAAA,IAAI,YAAA,EAAc;AAChB,QAAA,MAAA,CAAO,EAAA,CAAG,cAAc,YAAY,CAAA;AACpC,QAAA,QAAA,CAAS,KAAK,MAAM,MAAA,CAAO,GAAA,CAAI,YAAA,EAAc,YAAY,CAAC,CAAA;AAAA,MAC5D;AAEA,MAAA,OAAO,MAAM;AAAE,QAAA,QAAA,CAAS,OAAA,CAAQ,CAAC,CAAA,KAAM;AAAE,UAAA,CAAA,EAAE;AAAA,QAAG,CAAC,CAAA;AAAA,MAAG,CAAA;AAAA,IACpD,CAAA,EAAG,CAAC,QAAA,EAAU,SAAA,EAAW,YAAY,CAAC,CAAA;AAEtC,IAAA,mBAAA,CAAoB,KAAK,OAAO;AAAA,MAC9B,SAAA,EAAW,MAAM,SAAA,CAAU,OAAA;AAAA,MAC3B,SAAA,EAAW,MAAM,SAAA,CAAU,OAAA,EAAS,SAAA,EAAU;AAAA,MAC9C,WAAW,MAAM,SAAA,CAAU,OAAA,EAAS,SAAA,MAAe,EAAC;AAAA,MACpD,eAAA,EAAiB,CAAC,IAAA,EAAc,OAAA,KAC9B,UAAU,OAAA,EAAS,eAAA,CAAgB,MAAM,OAAO;AAAA,KACpD,CAAE,CAAA;AAEF,IAAA,uBACE,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAA;AAAA,QACA,OAAO,EAAE,QAAA,EAAU,YAAY,QAAA,EAAU,QAAA,EAAU,GAAG,KAAA,EAAM;AAAA,QAE5D,QAAA,kBAAA,GAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,GAAA,EAAK,SAAA;AAAA,YACL,OAAO,EAAE,OAAA,EAAS,SAAS,KAAA,EAAO,MAAA,EAAQ,QAAQ,MAAA;AAAO;AAAA;AAC3D;AAAA,KACF;AAAA,EAEJ;AACF;ACrIO,SAAS,YAAA,CACd,WACA,OAAA,EACA;AACA,EAAA,MAAM,SAAA,GAAYC,OAAyB,IAAI,CAAA;AAC/C,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAA2B,IAAI,CAAA;AAC3D,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,QAAA,CAAqB,EAAE,CAAA;AACnD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAS,KAAK,CAAA;AAC9C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAuB,IAAI,CAAA;AAErD,EAAAC,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,UAAU,OAAA,EAAS;AACxB,IAAA,MAAM,CAAA,GAAI,IAAIH,WAAAA,CAAU,SAAA,CAAU,SAAS,OAAO,CAAA;AAClD,IAAA,SAAA,CAAU,OAAA,GAAU,CAAA;AACpB,IAAA,SAAA,CAAU,CAAC,CAAA;AACX,IAAA,OAAO,MAAM;AACX,MAAA,CAAA,CAAE,OAAA,EAAQ;AACV,MAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AACpB,MAAA,SAAA,CAAU,IAAI,CAAA;AAAA,IAChB,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,QAAA,GAAW,WAAA,CAAY,OAAO,IAAA,KAAe;AACjD,IAAA,IAAI,CAAC,UAAU,OAAA,EAAS;AACxB,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,IAAI;AACF,MAAA,MAAM,SAAA,CAAU,OAAA,CAAQ,QAAA,CAAS,IAAI,CAAA;AACrC,MAAA,SAAA,CAAU,SAAA,CAAU,OAAA,CAAQ,SAAA,EAAW,CAAA;AACvC,MAAA,WAAA,CAAY,IAAI,CAAA;AAAA,IAClB,SAAS,GAAA,EAAK;AACZ,MAAA,QAAA,CAAS,GAAA,YAAe,QAAQ,GAAA,GAAM,IAAI,MAAM,MAAA,CAAO,GAAG,CAAC,CAAC,CAAA;AAAA,IAC9D;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,UAAA,GAAa,WAAA,CAAY,CAAC,GAAA,KAAgB;AAC9C,IAAA,IAAI,CAAC,UAAU,OAAA,EAAS;AACxB,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,IAAI;AACF,MAAA,SAAA,CAAU,OAAA,CAAQ,WAAW,GAAG,CAAA;AAChC,MAAA,SAAA,CAAU,SAAA,CAAU,OAAA,CAAQ,SAAA,EAAW,CAAA;AACvC,MAAA,WAAA,CAAY,IAAI,CAAA;AAAA,IAClB,SAAS,GAAA,EAAK;AACZ,MAAA,QAAA,CAAS,GAAA,YAAe,QAAQ,GAAA,GAAM,IAAI,MAAM,MAAA,CAAO,GAAG,CAAC,CAAC,CAAA;AAAA,IAC9D;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,MAAA;AAAA,IACA,QAAA;AAAA,IACA,KAAA;AAAA,IACA,QAAA;AAAA,IACA,UAAA;AAAA,IACA,SAAA,EAAW,MAAM,SAAA,CAAU,OAAA,EAAS,SAAA,EAAU;AAAA,IAC9C,eAAA,EAAiB,CAAC,IAAA,EAAc,OAAA,KAC9B,UAAU,OAAA,EAAS,eAAA,CAAgB,MAAM,OAAO,CAAA;AAAA,IAClD,UAAU,CAAC,KAAA,KACT,SAAA,CAAU,OAAA,EAAS,SAAS,KAAK,CAAA;AAAA,IACnC,SAAS,CAAC,IAAA,KACR,SAAA,CAAU,OAAA,EAAS,QAAQ,IAAI;AAAA,GACnC;AACF","file":"index.js","sourcesContent":["import {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n type CSSProperties,\n} from 'react';\nimport {\n CadViewer as CoreCadViewer,\n type CadViewerOptions,\n type DxfLayer,\n type SelectEvent,\n type MeasureEvent,\n type ViewTransform,\n type Tool,\n type Theme,\n} from '@cadview/core';\n\nexport interface CadViewerProps {\n file?: File | ArrayBuffer | string | null;\n theme?: Theme;\n tool?: Tool;\n className?: string;\n style?: CSSProperties;\n options?: Omit<CadViewerOptions, 'theme' | 'initialTool'>;\n onSelect?: (event: SelectEvent) => void;\n onMeasure?: (event: MeasureEvent) => void;\n onViewChange?: (transform: ViewTransform) => void;\n onLayersLoaded?: (layers: DxfLayer[]) => void;\n}\n\nexport interface CadViewerRef {\n getViewer(): CoreCadViewer | null;\n fitToView(): void;\n getLayers(): DxfLayer[];\n setLayerVisible(name: string, visible: boolean): void;\n}\n\nexport const CadViewer = forwardRef<CadViewerRef, CadViewerProps>(\n function CadViewer(props, ref) {\n const {\n file,\n theme = 'dark',\n tool = 'pan',\n className,\n style,\n options,\n onSelect,\n onMeasure,\n onViewChange,\n onLayersLoaded,\n } = props;\n\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const viewerRef = useRef<CoreCadViewer | null>(null);\n\n useEffect(() => {\n if (!canvasRef.current) return;\n\n const viewer = new CoreCadViewer(canvasRef.current, {\n theme,\n initialTool: tool,\n ...options,\n });\n viewerRef.current = viewer;\n\n return () => {\n viewer.destroy();\n viewerRef.current = null;\n };\n }, []);\n\n useEffect(() => {\n viewerRef.current?.setTheme(theme);\n }, [theme]);\n\n useEffect(() => {\n viewerRef.current?.setTool(tool);\n }, [tool]);\n\n useEffect(() => {\n const viewer = viewerRef.current;\n if (!viewer || !file) return;\n\n if (file instanceof File) {\n viewer.loadFile(file).then(\n () => onLayersLoaded?.(viewer.getLayers()),\n (err) => console.error('CadViewer: failed to load file', err),\n );\n } else if (file instanceof ArrayBuffer) {\n viewer.loadArrayBuffer(file);\n onLayersLoaded?.(viewer.getLayers());\n } else if (typeof file === 'string') {\n viewer.loadString(file);\n onLayersLoaded?.(viewer.getLayers());\n }\n }, [file]);\n\n useEffect(() => {\n const viewer = viewerRef.current;\n if (!viewer) return;\n\n const handlers: Array<() => void> = [];\n\n if (onSelect) {\n viewer.on('select', onSelect);\n handlers.push(() => viewer.off('select', onSelect));\n }\n if (onMeasure) {\n viewer.on('measure', onMeasure);\n handlers.push(() => viewer.off('measure', onMeasure));\n }\n if (onViewChange) {\n viewer.on('viewchange', onViewChange);\n handlers.push(() => viewer.off('viewchange', onViewChange));\n }\n\n return () => { handlers.forEach((h) => { h(); }); };\n }, [onSelect, onMeasure, onViewChange]);\n\n useImperativeHandle(ref, () => ({\n getViewer: () => viewerRef.current,\n fitToView: () => viewerRef.current?.fitToView(),\n getLayers: () => viewerRef.current?.getLayers() ?? [],\n setLayerVisible: (name: string, visible: boolean) =>\n viewerRef.current?.setLayerVisible(name, visible),\n }));\n\n return (\n <div\n className={className}\n style={{ position: 'relative', overflow: 'hidden', ...style }}\n >\n <canvas\n ref={canvasRef}\n style={{ display: 'block', width: '100%', height: '100%' }}\n />\n </div>\n );\n },\n);\n","import { useEffect, useRef, useState, useCallback } from 'react';\nimport {\n CadViewer,\n type CadViewerOptions,\n type DxfLayer,\n} from '@cadview/core';\n\nexport function useCadViewer(\n canvasRef: React.RefObject<HTMLCanvasElement | null>,\n options?: CadViewerOptions,\n) {\n const viewerRef = useRef<CadViewer | null>(null);\n const [viewer, setViewer] = useState<CadViewer | null>(null);\n const [layers, setLayers] = useState<DxfLayer[]>([]);\n const [isLoaded, setIsLoaded] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n if (!canvasRef.current) return;\n const v = new CadViewer(canvasRef.current, options);\n viewerRef.current = v;\n setViewer(v);\n return () => {\n v.destroy();\n viewerRef.current = null;\n setViewer(null);\n };\n }, []);\n\n const loadFile = useCallback(async (file: File) => {\n if (!viewerRef.current) return;\n setError(null);\n try {\n await viewerRef.current.loadFile(file);\n setLayers(viewerRef.current.getLayers());\n setIsLoaded(true);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n }\n }, []);\n\n const loadString = useCallback((dxf: string) => {\n if (!viewerRef.current) return;\n setError(null);\n try {\n viewerRef.current.loadString(dxf);\n setLayers(viewerRef.current.getLayers());\n setIsLoaded(true);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n }\n }, []);\n\n return {\n viewer,\n layers,\n isLoaded,\n error,\n loadFile,\n loadString,\n fitToView: () => viewerRef.current?.fitToView(),\n setLayerVisible: (name: string, visible: boolean) =>\n viewerRef.current?.setLayerVisible(name, visible),\n setTheme: (theme: 'dark' | 'light') =>\n viewerRef.current?.setTheme(theme),\n setTool: (tool: 'pan' | 'select' | 'measure') =>\n viewerRef.current?.setTool(tool),\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/CadViewer.tsx","../src/useCadViewer.ts"],"names":["CadViewer","CoreCadViewer","useRef","useEffect"],"mappings":"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","file":"index.js","sourcesContent":["import {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n type CSSProperties,\n} from 'react';\nimport {\n CadViewer as CoreCadViewer,\n type CadViewerOptions,\n type FormatConverter,\n type DebugOptions,\n type DxfLayer,\n type SelectEvent,\n type MeasureEvent,\n type ViewTransform,\n type Tool,\n type Theme,\n} from '@cadview/core';\n\nexport interface CadViewerProps {\n file?: File | ArrayBuffer | string | null;\n theme?: Theme;\n tool?: Tool;\n /** Enable debug overlay. Pass `true` for defaults, or a `DebugOptions` object. */\n debug?: boolean | DebugOptions;\n className?: string;\n style?: CSSProperties;\n options?: Omit<CadViewerOptions, 'theme' | 'initialTool' | 'debug'>;\n /** Format converters for non-DXF file formats (e.g. DWG via @cadview/dwg). */\n formatConverters?: FormatConverter[];\n onSelect?: (event: SelectEvent) => void;\n onMeasure?: (event: MeasureEvent) => void;\n onViewChange?: (transform: ViewTransform) => void;\n onLayersLoaded?: (layers: DxfLayer[]) => void;\n}\n\nexport interface CadViewerRef {\n getViewer(): CoreCadViewer | null;\n fitToView(): void;\n getLayers(): DxfLayer[];\n setLayerVisible(name: string, visible: boolean): void;\n}\n\nexport const CadViewer = forwardRef<CadViewerRef, CadViewerProps>(\n function CadViewer(props, ref) {\n const {\n file,\n theme = 'dark',\n tool = 'pan',\n debug,\n className,\n style,\n options,\n formatConverters,\n onSelect,\n onMeasure,\n onViewChange,\n onLayersLoaded,\n } = props;\n\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const viewerRef = useRef<CoreCadViewer | null>(null);\n\n useEffect(() => {\n if (!canvasRef.current) return;\n\n const viewer = new CoreCadViewer(canvasRef.current, {\n theme,\n initialTool: tool,\n debug,\n formatConverters,\n ...options,\n });\n viewerRef.current = viewer;\n\n return () => {\n viewer.destroy();\n viewerRef.current = null;\n };\n }, []);\n\n useEffect(() => {\n viewerRef.current?.setTheme(theme);\n }, [theme]);\n\n useEffect(() => {\n viewerRef.current?.setTool(tool);\n }, [tool]);\n\n useEffect(() => {\n if (debug !== undefined) {\n viewerRef.current?.setDebug(debug);\n }\n }, [debug]);\n\n useEffect(() => {\n const viewer = viewerRef.current;\n if (!viewer || !file) return;\n let cancelled = false;\n\n const load = async () => {\n try {\n if (file instanceof File) {\n await viewer.loadFile(file);\n } else if (file instanceof ArrayBuffer) {\n await viewer.loadBuffer(file);\n } else if (typeof file === 'string') {\n viewer.loadString(file);\n }\n if (!cancelled) {\n onLayersLoaded?.(viewer.getLayers());\n }\n } catch (err) {\n if (!cancelled) {\n console.error('CadViewer: failed to load file', err);\n }\n }\n };\n\n load();\n\n return () => {\n cancelled = true;\n };\n }, [file]);\n\n useEffect(() => {\n const viewer = viewerRef.current;\n if (!viewer) return;\n\n const handlers: Array<() => void> = [];\n\n if (onSelect) {\n viewer.on('select', onSelect);\n handlers.push(() => viewer.off('select', onSelect));\n }\n if (onMeasure) {\n viewer.on('measure', onMeasure);\n handlers.push(() => viewer.off('measure', onMeasure));\n }\n if (onViewChange) {\n viewer.on('viewchange', onViewChange);\n handlers.push(() => viewer.off('viewchange', onViewChange));\n }\n\n return () => { handlers.forEach((h) => { h(); }); };\n }, [onSelect, onMeasure, onViewChange]);\n\n useImperativeHandle(ref, () => ({\n getViewer: () => viewerRef.current,\n fitToView: () => viewerRef.current?.fitToView(),\n getLayers: () => viewerRef.current?.getLayers() ?? [],\n setLayerVisible: (name: string, visible: boolean) =>\n viewerRef.current?.setLayerVisible(name, visible),\n }));\n\n return (\n <div\n className={className}\n style={{ position: 'relative', overflow: 'hidden', ...style }}\n >\n <canvas\n ref={canvasRef}\n style={{ display: 'block', width: '100%', height: '100%' }}\n />\n </div>\n );\n },\n);\n","import { useEffect, useRef, useState, useCallback } from 'react';\nimport {\n CadViewer,\n type CadViewerOptions,\n type DxfLayer,\n} from '@cadview/core';\n\nexport function useCadViewer(\n canvasRef: React.RefObject<HTMLCanvasElement | null>,\n options?: CadViewerOptions,\n) {\n const viewerRef = useRef<CadViewer | null>(null);\n const [viewer, setViewer] = useState<CadViewer | null>(null);\n const [layers, setLayers] = useState<DxfLayer[]>([]);\n const [isLoaded, setIsLoaded] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n if (!canvasRef.current) return;\n const v = new CadViewer(canvasRef.current, options);\n viewerRef.current = v;\n setViewer(v);\n return () => {\n v.destroy();\n viewerRef.current = null;\n setViewer(null);\n };\n }, []);\n\n const loadFile = useCallback(async (file: File) => {\n if (!viewerRef.current) return;\n setError(null);\n try {\n await viewerRef.current.loadFile(file);\n setLayers(viewerRef.current.getLayers());\n setIsLoaded(true);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n }\n }, []);\n\n const loadBuffer = useCallback(async (buffer: ArrayBuffer) => {\n if (!viewerRef.current) return;\n setError(null);\n try {\n await viewerRef.current.loadBuffer(buffer);\n setLayers(viewerRef.current.getLayers());\n setIsLoaded(true);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n }\n }, []);\n\n const loadString = useCallback((dxf: string) => {\n if (!viewerRef.current) return;\n setError(null);\n try {\n viewerRef.current.loadString(dxf);\n setLayers(viewerRef.current.getLayers());\n setIsLoaded(true);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n }\n }, []);\n\n return {\n viewer,\n layers,\n isLoaded,\n error,\n loadFile,\n loadBuffer,\n loadString,\n fitToView: () => viewerRef.current?.fitToView(),\n setLayerVisible: (name: string, visible: boolean) =>\n viewerRef.current?.setLayerVisible(name, visible),\n setTheme: (theme: 'dark' | 'light') =>\n viewerRef.current?.setTheme(theme),\n setTool: (tool: 'pan' | 'select' | 'measure') =>\n viewerRef.current?.setTool(tool),\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cadview/react",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "React wrapper for @cadview/core — CAD/DXF file viewer component",
@@ -48,7 +48,7 @@
48
48
  "peerDependencies": {
49
49
  "react": "^18.0.0 || ^19.0.0",
50
50
  "react-dom": "^18.0.0 || ^19.0.0",
51
- "@cadview/core": "0.1.0"
51
+ "@cadview/core": "0.3.0"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@types/react": "^19.0.0",
@@ -57,7 +57,7 @@
57
57
  "react-dom": "^19.0.0",
58
58
  "tsup": "^8.0.0",
59
59
  "typescript": "^5.7.0",
60
- "@cadview/core": "0.1.0"
60
+ "@cadview/core": "0.3.0"
61
61
  },
62
62
  "sideEffects": false,
63
63
  "scripts": {