@imfusion/sdk-react 0.7.0-dev.31.g0ba92924

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.
Files changed (42) hide show
  1. package/README.md +51 -0
  2. package/dist/ImFusionCanvas.d.ts +26 -0
  3. package/dist/ImFusionCanvas.js +51 -0
  4. package/dist/ImFusionError.d.ts +37 -0
  5. package/dist/ImFusionError.js +41 -0
  6. package/dist/ImFusionLoading.d.ts +25 -0
  7. package/dist/ImFusionLoading.js +30 -0
  8. package/dist/ImFusionProvider.d.ts +56 -0
  9. package/dist/ImFusionProvider.js +88 -0
  10. package/dist/ImFusionReady.d.ts +25 -0
  11. package/dist/ImFusionReady.js +30 -0
  12. package/dist/context.d.ts +14 -0
  13. package/dist/context.js +3 -0
  14. package/dist/index.d.ts +17 -0
  15. package/dist/index.js +17 -0
  16. package/dist/useAnnotations.d.ts +33 -0
  17. package/dist/useAnnotations.js +67 -0
  18. package/dist/useContextMenu.d.ts +21 -0
  19. package/dist/useContextMenu.js +30 -0
  20. package/dist/useData.d.ts +26 -0
  21. package/dist/useData.js +40 -0
  22. package/dist/useDataLoader.d.ts +50 -0
  23. package/dist/useDataLoader.js +70 -0
  24. package/dist/useDisplayOptions.d.ts +59 -0
  25. package/dist/useDisplayOptions.js +87 -0
  26. package/dist/useFrameSelection.d.ts +32 -0
  27. package/dist/useFrameSelection.js +43 -0
  28. package/dist/useImFusion.d.ts +22 -0
  29. package/dist/useImFusion.js +32 -0
  30. package/dist/useImFusionError.d.ts +21 -0
  31. package/dist/useImFusionError.js +32 -0
  32. package/dist/useImFusionState.d.ts +31 -0
  33. package/dist/useImFusionState.js +32 -0
  34. package/dist/useLayoutMode.d.ts +29 -0
  35. package/dist/useLayoutMode.js +38 -0
  36. package/dist/useStableHandle.d.ts +15 -0
  37. package/dist/useStableHandle.js +12 -0
  38. package/dist/useViewVisibility.d.ts +30 -0
  39. package/dist/useViewVisibility.js +45 -0
  40. package/dist/useVisibleData.d.ts +21 -0
  41. package/dist/useVisibleData.js +32 -0
  42. package/package.json +51 -0
@@ -0,0 +1,38 @@
1
+ import { useState, useEffect, useCallback } from 'react';
2
+ import { useImFusion } from './useImFusion.js';
3
+ /**
4
+ * Returns the reactive display layout mode.
5
+ *
6
+ * Subscribes to {@link @imfusion/sdk!DisplayAutoLayouter.onModeChanged | DisplayAutoLayouter.onModeChanged}.
7
+ *
8
+ * @returns The current mode and a function to change it
9
+ * @throws If called outside of an {@link ImFusionProvider}
10
+ * @throws If called before the SDK has finished initializing
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * function LayoutPicker() {
15
+ * const { mode, setMode } = useLayoutMode();
16
+ * return (
17
+ * <select value={mode} onChange={e => setMode(e.target.value as DisplayLayoutMode)}>
18
+ * <option value="Auto">Auto</option>
19
+ * <option value="Rows">Rows</option>
20
+ * <option value="FocusPlusStack">Focus + Stack</option>
21
+ * <option value="FocusPlusRows">Focus + Rows</option>
22
+ * </select>
23
+ * );
24
+ * }
25
+ * ```
26
+ */
27
+ export function useLayoutMode() {
28
+ const imf = useImFusion();
29
+ const [mode, setModeState] = useState(() => imf.display.layouter().currentMode());
30
+ useEffect(() => {
31
+ const layouter = imf.display.layouter();
32
+ setModeState(layouter.currentMode());
33
+ const off = layouter.onModeChanged(setModeState);
34
+ return off;
35
+ }, [imf]);
36
+ const setMode = useCallback((newMode) => imf.display.layouter().setLayoutMode(newMode), [imf]);
37
+ return { mode, setMode };
38
+ }
@@ -0,0 +1,15 @@
1
+ import type { ClassHandle } from '@imfusion/sdk';
2
+ /**
3
+ * Returns a stable reference for a WASM handle, using
4
+ * {@link @imfusion/sdk!ClassHandle.isAliasOf | isAliasOf} instead of `===` to detect
5
+ * identity changes.
6
+ *
7
+ * Different JS wrapper objects can alias the same underlying C++ object.
8
+ * This hook ensures that the returned reference only changes when the
9
+ * underlying C++ object actually changes, making it safe to use in
10
+ * `useEffect` dependency arrays and other identity-sensitive contexts.
11
+ *
12
+ * @internal
13
+ */
14
+ export declare function useStableHandle<T extends ClassHandle>(handle: T): T;
15
+ export declare function useStableHandle<T extends ClassHandle>(handle: T | undefined): T | undefined;
@@ -0,0 +1,12 @@
1
+ import { useState } from 'react';
2
+ export function useStableHandle(handle) {
3
+ const [stable, setStable] = useState(handle);
4
+ if (handle !== undefined && stable !== undefined) {
5
+ if (!handle.isAliasOf(stable))
6
+ setStable(handle);
7
+ }
8
+ else if (handle !== stable) {
9
+ setStable(handle);
10
+ }
11
+ return stable;
12
+ }
@@ -0,0 +1,30 @@
1
+ import type { View } from '@imfusion/sdk';
2
+ /**
3
+ * Returns the reactive 'hidden' state of a view.
4
+ *
5
+ * Subscribes to {@link @imfusion/sdk!DisplayAutoLayouter.onViewHiddenChanged | DisplayAutoLayouter.onViewHiddenChanged}
6
+ *
7
+ * @param view - The view to observe
8
+ * @returns The current 'hidden' state and a function to change it
9
+ * @throws If called outside of an {@link ImFusionProvider}
10
+ * @throws If called before the SDK has finished initializing
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * function ViewToggle({ view }: { view: View }) {
15
+ * const { hidden, setHidden } = useViewVisibility(view);
16
+ * return (
17
+ * <label>
18
+ * <input type="checkbox" checked={!hidden} onChange={e => setHidden(!e.target.checked)} />
19
+ * Show view
20
+ * </label>
21
+ * );
22
+ * }
23
+ * ```
24
+ *
25
+ * @see {@link useLayoutMode}
26
+ */
27
+ export declare function useViewVisibility(view: View): {
28
+ hidden: boolean;
29
+ setHidden: (hidden: boolean) => void;
30
+ };
@@ -0,0 +1,45 @@
1
+ import { useState, useEffect, useCallback } from 'react';
2
+ import { useImFusion } from './useImFusion.js';
3
+ import { useStableHandle } from './useStableHandle.js';
4
+ /**
5
+ * Returns the reactive 'hidden' state of a view.
6
+ *
7
+ * Subscribes to {@link @imfusion/sdk!DisplayAutoLayouter.onViewHiddenChanged | DisplayAutoLayouter.onViewHiddenChanged}
8
+ *
9
+ * @param view - The view to observe
10
+ * @returns The current 'hidden' state and a function to change it
11
+ * @throws If called outside of an {@link ImFusionProvider}
12
+ * @throws If called before the SDK has finished initializing
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * function ViewToggle({ view }: { view: View }) {
17
+ * const { hidden, setHidden } = useViewVisibility(view);
18
+ * return (
19
+ * <label>
20
+ * <input type="checkbox" checked={!hidden} onChange={e => setHidden(!e.target.checked)} />
21
+ * Show view
22
+ * </label>
23
+ * );
24
+ * }
25
+ * ```
26
+ *
27
+ * @see {@link useLayoutMode}
28
+ */
29
+ export function useViewVisibility(view) {
30
+ const imf = useImFusion();
31
+ const stableView = useStableHandle(view);
32
+ const [hidden, setHiddenState] = useState(() => imf.display.layouter().isViewHidden(stableView));
33
+ useEffect(() => {
34
+ const layouter = imf.display.layouter();
35
+ setHiddenState(layouter.isViewHidden(stableView));
36
+ const off = layouter.onViewHiddenChanged((changedView, isHidden) => {
37
+ if (changedView.isAliasOf(stableView)) {
38
+ setHiddenState(isHidden);
39
+ }
40
+ });
41
+ return off;
42
+ }, [imf, stableView]);
43
+ const setHidden = useCallback((value) => imf.display.layouter().setViewHidden(stableView, value), [imf, stableView]);
44
+ return { hidden, setHidden };
45
+ }
@@ -0,0 +1,21 @@
1
+ import type { Data, HandleArray } from '@imfusion/sdk';
2
+ /**
3
+ * Returns the reactive list of currently visible datasets.
4
+ *
5
+ * Subscribes to {@link @imfusion/sdk!RadiologyViewGroup.onVisibleDataChanged | RadiologyViewGroup.onVisibleDataChanged}.
6
+ *
7
+ * @returns A {@link @imfusion/sdk!HandleArray | HandleArray} of visible datasets
8
+ * @throws If called outside of an {@link ImFusionProvider}
9
+ * @throws If called before the SDK has finished initializing
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * function VisibleDataInfo() {
14
+ * const visibleData = useVisibleData();
15
+ * return <p>Visible: {visibleData.map(d => d.name).join(', ')}</p>;
16
+ * }
17
+ * ```
18
+ *
19
+ * @see {@link useData}
20
+ */
21
+ export declare function useVisibleData(): HandleArray<Data>;
@@ -0,0 +1,32 @@
1
+ import { useState, useEffect } from 'react';
2
+ import { useImFusion } from './useImFusion.js';
3
+ /**
4
+ * Returns the reactive list of currently visible datasets.
5
+ *
6
+ * Subscribes to {@link @imfusion/sdk!RadiologyViewGroup.onVisibleDataChanged | RadiologyViewGroup.onVisibleDataChanged}.
7
+ *
8
+ * @returns A {@link @imfusion/sdk!HandleArray | HandleArray} of visible datasets
9
+ * @throws If called outside of an {@link ImFusionProvider}
10
+ * @throws If called before the SDK has finished initializing
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * function VisibleDataInfo() {
15
+ * const visibleData = useVisibleData();
16
+ * return <p>Visible: {visibleData.map(d => d.name).join(', ')}</p>;
17
+ * }
18
+ * ```
19
+ *
20
+ * @see {@link useData}
21
+ */
22
+ export function useVisibleData() {
23
+ const imf = useImFusion();
24
+ const [visibleData, setVisibleData] = useState(() => imf.display.viewGroup().visibleData());
25
+ useEffect(() => {
26
+ const off = imf.display.viewGroup().onVisibleDataChanged((_before, after) => {
27
+ setVisibleData(after);
28
+ });
29
+ return off;
30
+ }, [imf]);
31
+ return visibleData;
32
+ }
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@imfusion/sdk-react",
3
+ "version": "0.7.0-dev.31.g0ba92924",
4
+ "description": "React bindings for ImFusion WebSDK",
5
+ "author": "ImFusion GmbH",
6
+ "license": "SEE LICENSE IN License.rtf",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/ImFusionGmbH/websdk-demo.git"
10
+ },
11
+ "publishConfig": {
12
+ "registry": "https://registry.npmjs.org",
13
+ "access": "restricted"
14
+ },
15
+ "type": "module",
16
+ "main": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "import": "./dist/index.js",
21
+ "types": "./dist/index.d.ts"
22
+ }
23
+ },
24
+ "scripts": {
25
+ "build": "tsc -p tsconfig.build.json",
26
+ "prepack": "npm run build",
27
+ "test": "vitest",
28
+ "test:ci": "vitest run --coverage --reporter=default --reporter=junit --outputFile=reports/vitest.junit.xml",
29
+ "posttest:ci": "tsx -- ../coverage/parse-coverage.ts"
30
+ },
31
+ "files": [
32
+ "dist/**",
33
+ "License.rtf"
34
+ ],
35
+ "peerDependencies": {
36
+ "@imfusion/sdk": "0.7.0-dev.31.g0ba92924",
37
+ "react": ">=18"
38
+ },
39
+ "devDependencies": {
40
+ "@imfusion/sdk": "*",
41
+ "@testing-library/react": "^16.0.0",
42
+ "@types/react": "^19.0.0",
43
+ "@types/react-dom": "^19.0.0",
44
+ "@vitest/browser-playwright": "4.0.1",
45
+ "playwright": "1.55.1",
46
+ "react": "^19.0.0",
47
+ "react-dom": "^19.0.0",
48
+ "serve-static": "^2.2.0",
49
+ "typescript": "^5.7.2"
50
+ }
51
+ }