@niivue/nv-web-component 1.0.0-rc.10

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/README.md ADDED
@@ -0,0 +1,226 @@
1
+ # @niivue/nv-web-component
2
+
3
+ Lit-based Web Components for NiiVue. The package registers standard custom elements that work with plain HTML, Vite, Lit, React, Vue, Svelte, or any other browser environment that supports Web Components.
4
+
5
+ The API is DOM-first: configure elements with properties, call methods on the element instance, and listen for `CustomEvent`s.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ bun add @niivue/nv-web-component @niivue/niivue lit
11
+ ```
12
+
13
+ ## Getting started: single viewer
14
+
15
+ Importing the package registers `<niivue-viewer>` automatically.
16
+
17
+ ```html
18
+ <niivue-viewer id="viewer" style="height: 600px"></niivue-viewer>
19
+
20
+ <script type="module">
21
+ import '@niivue/nv-web-component'
22
+
23
+ await customElements.whenDefined('niivue-viewer')
24
+
25
+ const viewer = document.querySelector('#viewer')
26
+
27
+ viewer.volumes = [
28
+ {
29
+ url: '/volumes/mni152.nii.gz',
30
+ name: 'MNI152',
31
+ colormap: 'gray',
32
+ },
33
+ ]
34
+
35
+ viewer.addEventListener('image-loaded', (event) => {
36
+ console.log('loaded volume', event.detail)
37
+ })
38
+
39
+ viewer.addEventListener('location-change', (event) => {
40
+ console.log('location', event.detail)
41
+ })
42
+
43
+ viewer.addEventListener('niivue-error', (event) => {
44
+ console.error('NiiVue error', event.detail)
45
+ })
46
+ </script>
47
+ ```
48
+
49
+ ### Updating viewer settings
50
+
51
+ Use element methods for common NiiVue operations. The standalone viewer methods target its own NiiVue instance.
52
+
53
+ ```js
54
+ const viewer = document.querySelector('niivue-viewer')
55
+
56
+ await viewer.setColormap(0, 'hot')
57
+ await viewer.setOpacity(0, 0.8)
58
+ await viewer.setCalMinMax(0, 10, 200)
59
+
60
+ viewer.setColorbarVisible(true)
61
+ viewer.setCrosshairVisible(false)
62
+ viewer.setPrimaryDragMode(DRAG_MODE.pan)
63
+ ```
64
+
65
+ With imports:
66
+
67
+ ```js
68
+ import { DRAG_MODE } from '@niivue/nv-web-component'
69
+ ```
70
+
71
+ ## Getting started: scene of viewers
72
+
73
+ Use `<niivue-scene>` when you want multiple independent NiiVue viewers managed as one scene. The `layout` property controls how many viewer slots exist.
74
+
75
+ ```html
76
+ <niivue-scene id="scene" layout="2x2" style="height: 600px"></niivue-scene>
77
+
78
+ <script type="module">
79
+ import '@niivue/nv-web-component'
80
+
81
+ await customElements.whenDefined('niivue-scene')
82
+
83
+ const scene = document.querySelector('#scene')
84
+ await scene.updateComplete
85
+
86
+ const volume = {
87
+ url: '/volumes/mni152.nii.gz',
88
+ name: 'MNI152',
89
+ colormap: 'gray',
90
+ }
91
+
92
+ // The 2x2 layout creates four viewer slots. Load the same image into each
93
+ // viewer as separate NiiVue volume instances.
94
+ await Promise.all(
95
+ Array.from({ length: scene.snapshot.viewerCount }, (_value, index) =>
96
+ scene.loadVolume(index, volume),
97
+ ),
98
+ )
99
+
100
+ scene.addEventListener('scene-change', (event) => {
101
+ console.log('scene snapshot', event.detail)
102
+ })
103
+ </script>
104
+ ```
105
+
106
+ `customElements.whenDefined()` waits for element registration. Wait for Lit's
107
+ `scene.updateComplete`, or for the first `scene-change` event, before reading
108
+ `scene.snapshot.viewerCount` or loading volumes into scene viewers.
109
+
110
+ ### Updating all scene viewers
111
+
112
+ Scene methods that target volumes take both a viewer index and a volume index. Batch operations across viewers with `Promise.all`.
113
+
114
+ ```js
115
+ const scene = document.querySelector('niivue-scene')
116
+
117
+ await Promise.all(
118
+ Array.from({ length: scene.snapshot.viewerCount }, (_value, index) =>
119
+ scene.setColormap(index, 0, 'hot'),
120
+ ),
121
+ )
122
+ ```
123
+
124
+ Viewer-wide scene settings accept an optional `viewerIndex`. If omitted, they apply to every viewer in the scene.
125
+
126
+ ```js
127
+ import { DRAG_MODE } from '@niivue/nv-web-component'
128
+
129
+ scene.setColorbarVisible(true)
130
+ scene.setCrosshairVisible(false)
131
+ scene.setPrimaryDragMode(DRAG_MODE.pan)
132
+
133
+ // Apply only to viewer 0.
134
+ scene.setCrosshairVisible(true, 0)
135
+ ```
136
+
137
+ ### Changing layouts and broadcasting
138
+
139
+ ```js
140
+ scene.layout = '1x2'
141
+ scene.broadcasting = true
142
+
143
+ scene.addEventListener('location-change', (event) => {
144
+ const { viewerIndex, data } = event.detail
145
+ console.log(`viewer ${viewerIndex}`, data)
146
+ })
147
+ ```
148
+
149
+ ## API reference
150
+
151
+ ### `<niivue-viewer>`
152
+
153
+ Properties:
154
+
155
+ - `volumes: ImageFromUrlOptions[]` - declarative volume list, diffed automatically.
156
+ - `options: Partial<NiiVueOptions>` - NiiVue construction options.
157
+ - `sliceType: number` / `slice-type` attribute - active slice type.
158
+ - `nv: NiiVue | null` - raw NiiVue instance after initialization.
159
+
160
+ Methods:
161
+
162
+ - `setColormap(volumeIndex, colormap)`
163
+ - `setOpacity(volumeIndex, opacity)`
164
+ - `setCalMinMax(volumeIndex, calMin, calMax)`
165
+ - `setColorbarVisible(visible)`
166
+ - `setCrosshairVisible(visible)`
167
+ - `setPrimaryDragMode(mode)`
168
+ - `setSecondaryDragMode(mode)`
169
+
170
+ Events:
171
+
172
+ - `location-change`
173
+ - `image-loaded`
174
+ - `niivue-error`
175
+
176
+ ### `<niivue-scene>`
177
+
178
+ Properties:
179
+
180
+ - `layout: string` - one of the exported `defaultLayouts` keys (`1x1`, `1x2`, `2x1`, `1x3`, `3x1`, `2x2`, `3x3`).
181
+ - `broadcasting: boolean` - synchronizes crosshair/camera interactions across viewers.
182
+ - `snapshot: NvSceneControllerSnapshot` - current scene state.
183
+ - `scene: NvSceneController` - controller for advanced usage.
184
+
185
+ Methods:
186
+
187
+ - `addViewer(options?)`
188
+ - `removeViewer(index)`
189
+ - `canAddViewer()`
190
+ - `setViewerSliceLayout(index, layout)`
191
+ - `loadVolume(index, opts)`
192
+ - `loadVolumes(index, optsArray)`
193
+ - `removeVolume(index, url)`
194
+ - `setColormap(viewerIndex, volumeIndex, colormap)`
195
+ - `setOpacity(viewerIndex, volumeIndex, opacity)`
196
+ - `setCalMinMax(viewerIndex, volumeIndex, calMin, calMax)`
197
+ - `setColorbarVisible(visible, viewerIndex?)`
198
+ - `setCrosshairVisible(visible, viewerIndex?)`
199
+ - `setPrimaryDragMode(mode, viewerIndex?)`
200
+ - `setSecondaryDragMode(mode, viewerIndex?)`
201
+
202
+ Events:
203
+
204
+ - `scene-change`
205
+ - `viewer-created`
206
+ - `viewer-removed`
207
+ - `location-change`
208
+ - `image-loaded`
209
+ - `niivue-error`
210
+ - `volume-added`
211
+ - `volume-removed`
212
+
213
+ ## Manual registration
214
+
215
+ ```ts
216
+ import { defineNiivueWebComponents } from '@niivue/nv-web-component'
217
+
218
+ defineNiivueWebComponents({
219
+ elementName: 'my-niivue-viewer',
220
+ sceneElementName: 'my-niivue-scene',
221
+ })
222
+ ```
223
+
224
+ ## Exports
225
+
226
+ The package exports `NiivueViewerElement`, `NiivueSceneElement`, `NvSceneController`, `defaultLayouts`, `defaultSliceLayouts`, `defaultViewerOptions`, `DRAG_MODE`, `SLICE_TYPE`, and NiiVue types.
@@ -0,0 +1,20 @@
1
+ export interface CanvasPosition {
2
+ top: string;
3
+ left: string;
4
+ width: string;
5
+ height: string;
6
+ }
7
+ export type LayoutFunction = (containerElement: HTMLElement, index: number, total: number) => CanvasPosition;
8
+ export interface LayoutConfig {
9
+ slots: number;
10
+ label: string;
11
+ layoutFunction: LayoutFunction;
12
+ }
13
+ export declare const layout1x1: LayoutFunction;
14
+ export declare const layout2x2: LayoutFunction;
15
+ export declare const layout1x2: LayoutFunction;
16
+ export declare const layout2x1: LayoutFunction;
17
+ export declare const layout1x3: LayoutFunction;
18
+ export declare const layout3x1: LayoutFunction;
19
+ export declare const layout3x3: LayoutFunction;
20
+ export declare const defaultLayouts: Record<string, LayoutConfig>;
@@ -0,0 +1,107 @@
1
+ import { NiiVueOptions, NVImage, default as NiiVue, DRAG_MODE, SLICE_TYPE } from '@niivue/niivue';
2
+ import { LitElement, PropertyValues } from 'lit';
3
+ import { defaultLayouts } from './layouts';
4
+ import { defaultSliceLayouts, defaultViewerOptions, NvSceneController, NvSceneControllerSnapshot, SliceLayoutTile } from './nvscene-controller';
5
+ import { ImageFromUrlOptions } from './types';
6
+ export declare const defaultElementName = "niivue-viewer";
7
+ export declare const defaultSceneElementName = "niivue-scene";
8
+ export type NiivueWebComponentOptions = {
9
+ elementName?: string;
10
+ sceneElementName?: string;
11
+ };
12
+ type VolumeVisualProps = {
13
+ colormap?: string;
14
+ calMin?: number;
15
+ calMax?: number;
16
+ opacity?: number;
17
+ };
18
+ export declare const volumeKey: (opts: ImageFromUrlOptions) => string;
19
+ export declare const volumeIdentity: (volume: Pick<NVImage, "url" | "name">) => string;
20
+ export declare const extractVisualProps: (opts: ImageFromUrlOptions) => VolumeVisualProps;
21
+ export declare const volumeVisualUpdates: (next: VolumeVisualProps, prev: VolumeVisualProps) => Partial<VolumeVisualProps>;
22
+ export declare const volumeIndexByKey: (volumes: Pick<NVImage, "url" | "name">[], key: string) => number;
23
+ export declare class NiivueViewerElement extends LitElement {
24
+ static properties: {
25
+ volumes: {
26
+ attribute: boolean;
27
+ };
28
+ options: {
29
+ attribute: boolean;
30
+ };
31
+ sliceType: {
32
+ type: NumberConstructor;
33
+ attribute: string;
34
+ };
35
+ };
36
+ static styles: import('lit').CSSResult;
37
+ volumes: ImageFromUrlOptions[];
38
+ options: Partial<NiiVueOptions>;
39
+ sliceType: 0;
40
+ private niivue;
41
+ private resizeObserver;
42
+ private loadedVolumes;
43
+ private attachmentReady;
44
+ private attachmentGeneration;
45
+ get nv(): NiiVue | null;
46
+ render(): import('lit-html').TemplateResult<1>;
47
+ firstUpdated(): void;
48
+ updated(changed: PropertyValues<this>): void;
49
+ disconnectedCallback(): void;
50
+ private emitError;
51
+ private ownsAttachment;
52
+ private getAttachedNiivue;
53
+ setColormap(volumeIndex: number, colormap: string): Promise<void>;
54
+ setOpacity(volumeIndex: number, opacity: number): Promise<void>;
55
+ setCalMinMax(volumeIndex: number, calMin: number, calMax: number): Promise<void>;
56
+ setColorbarVisible(visible: boolean): void;
57
+ setCrosshairVisible(visible: boolean): void;
58
+ setPrimaryDragMode(mode: number): void;
59
+ setSecondaryDragMode(mode: number): void;
60
+ private syncVolumes;
61
+ private reconcileVolumeOrder;
62
+ }
63
+ export declare class NiivueSceneElement extends LitElement {
64
+ static properties: {
65
+ layout: {
66
+ type: StringConstructor;
67
+ };
68
+ broadcasting: {
69
+ type: BooleanConstructor;
70
+ reflect: boolean;
71
+ };
72
+ snapshot: {
73
+ attribute: boolean;
74
+ };
75
+ };
76
+ static styles: import('lit').CSSResult;
77
+ layout: string;
78
+ broadcasting: boolean;
79
+ snapshot: NvSceneControllerSnapshot;
80
+ readonly scene: NvSceneController;
81
+ private unsubscribe;
82
+ private resizeObserver;
83
+ constructor();
84
+ render(): import('lit-html').TemplateResult<1>;
85
+ firstUpdated(): void;
86
+ updated(changed: PropertyValues<this>): void;
87
+ disconnectedCallback(): void;
88
+ addViewer(options?: Partial<NiiVueOptions>): Promise<import('./nvscene-controller').ViewerSlot>;
89
+ removeViewer(index: number): void;
90
+ canAddViewer(): boolean;
91
+ setViewerSliceLayout(index: number, layout: SliceLayoutTile[] | null): void;
92
+ loadVolume(index: number, opts: ImageFromUrlOptions): Promise<NVImage>;
93
+ loadVolumes(index: number, opts: ImageFromUrlOptions[]): Promise<NVImage[]>;
94
+ removeVolume(index: number, url: string): Promise<void>;
95
+ setColormap(viewerIndex: number, volumeIndex: number, colormap: string): Promise<void>;
96
+ setOpacity(viewerIndex: number, volumeIndex: number, opacity: number): Promise<void>;
97
+ setCalMinMax(viewerIndex: number, volumeIndex: number, calMin: number, calMax: number): Promise<void>;
98
+ setColorbarVisible(visible: boolean, viewerIndex?: number): void;
99
+ setCrosshairVisible(visible: boolean, viewerIndex?: number): void;
100
+ setPrimaryDragMode(mode: number, viewerIndex?: number): void;
101
+ setSecondaryDragMode(mode: number, viewerIndex?: number): void;
102
+ private forEachTargetViewer;
103
+ private forwardSceneEvents;
104
+ }
105
+ export declare function defineNiivueWebComponents(options?: NiivueWebComponentOptions): void;
106
+ export type { ImageFromUrlOptions, NiiVueOptions, NVImage };
107
+ export { DRAG_MODE, defaultLayouts, defaultSliceLayouts, defaultViewerOptions, NvSceneController, SLICE_TYPE, };