@vitessce/vit-s 2.0.3 → 3.0.1

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 (215) hide show
  1. package/dist/index.js +44072 -0
  2. package/dist-tsc/CallbackPublisher.d.ts +18 -0
  3. package/dist-tsc/CallbackPublisher.d.ts.map +1 -0
  4. package/dist-tsc/CallbackPublisher.js +62 -0
  5. package/dist-tsc/LoadingIndicator.d.ts +2 -0
  6. package/dist-tsc/LoadingIndicator.d.ts.map +1 -0
  7. package/dist-tsc/LoadingIndicator.js +26 -0
  8. package/dist-tsc/TitleInfo.d.ts +2 -0
  9. package/dist-tsc/TitleInfo.d.ts.map +1 -0
  10. package/dist-tsc/TitleInfo.js +74 -0
  11. package/dist-tsc/VitS.d.ts +50 -0
  12. package/dist-tsc/VitS.d.ts.map +1 -0
  13. package/dist-tsc/VitS.js +139 -0
  14. package/dist-tsc/VitessceGrid.d.ts +23 -0
  15. package/dist-tsc/VitessceGrid.d.ts.map +1 -0
  16. package/dist-tsc/VitessceGrid.js +63 -0
  17. package/dist-tsc/VitessceGrid.test.d.ts +2 -0
  18. package/dist-tsc/VitessceGrid.test.d.ts.map +1 -0
  19. package/dist-tsc/VitessceGrid.test.js +43 -0
  20. package/dist-tsc/Warning.d.ts +2 -0
  21. package/dist-tsc/Warning.d.ts.map +1 -0
  22. package/dist-tsc/Warning.js +45 -0
  23. package/dist-tsc/classNames.d.ts +8 -0
  24. package/dist-tsc/classNames.d.ts.map +1 -0
  25. package/dist-tsc/classNames.js +8 -0
  26. package/dist-tsc/data/AbstractLoader.d.ts +22 -0
  27. package/dist-tsc/data/AbstractLoader.d.ts.map +1 -0
  28. package/dist-tsc/data/AbstractLoader.js +18 -0
  29. package/dist-tsc/data/AbstractTwoStepLoader.d.ts +6 -0
  30. package/dist-tsc/data/AbstractTwoStepLoader.d.ts.map +1 -0
  31. package/dist-tsc/data/AbstractTwoStepLoader.js +7 -0
  32. package/dist-tsc/data/LoaderResult.d.ts +12 -0
  33. package/dist-tsc/data/LoaderResult.d.ts.map +1 -0
  34. package/dist-tsc/data/LoaderResult.js +12 -0
  35. package/dist-tsc/data/index.d.ts +4 -0
  36. package/dist-tsc/data/index.d.ts.map +1 -0
  37. package/dist-tsc/data/index.js +3 -0
  38. package/dist-tsc/data/loader-registry.d.ts +9 -0
  39. package/dist-tsc/data/loader-registry.d.ts.map +1 -0
  40. package/dist-tsc/data/loader-registry.js +27 -0
  41. package/dist-tsc/data-hook-utils.d.ts +65 -0
  42. package/dist-tsc/data-hook-utils.d.ts.map +1 -0
  43. package/dist-tsc/data-hook-utils.js +191 -0
  44. package/dist-tsc/data-hooks.d.ts +73 -0
  45. package/dist-tsc/data-hooks.d.ts.map +1 -0
  46. package/dist-tsc/data-hooks.js +254 -0
  47. package/dist-tsc/errors/AbstractLoaderError.d.ts +10 -0
  48. package/dist-tsc/errors/AbstractLoaderError.d.ts.map +1 -0
  49. package/dist-tsc/errors/AbstractLoaderError.js +13 -0
  50. package/dist-tsc/errors/DataSourceFetchError.d.ts +8 -0
  51. package/dist-tsc/errors/DataSourceFetchError.d.ts.map +1 -0
  52. package/dist-tsc/errors/DataSourceFetchError.js +13 -0
  53. package/dist-tsc/errors/DatasetNotFoundError.d.ts +6 -0
  54. package/dist-tsc/errors/DatasetNotFoundError.d.ts.map +1 -0
  55. package/dist-tsc/errors/DatasetNotFoundError.js +17 -0
  56. package/dist-tsc/errors/LoaderNotFoundError.d.ts +10 -0
  57. package/dist-tsc/errors/LoaderNotFoundError.d.ts.map +1 -0
  58. package/dist-tsc/errors/LoaderNotFoundError.js +17 -0
  59. package/dist-tsc/errors/LoaderValidationError.d.ts +10 -0
  60. package/dist-tsc/errors/LoaderValidationError.d.ts.map +1 -0
  61. package/dist-tsc/errors/LoaderValidationError.js +15 -0
  62. package/dist-tsc/errors/index.d.ts +6 -0
  63. package/dist-tsc/errors/index.d.ts.map +1 -0
  64. package/dist-tsc/errors/index.js +5 -0
  65. package/dist-tsc/hooks.d.ts +76 -0
  66. package/dist-tsc/hooks.d.ts.map +1 -0
  67. package/dist-tsc/hooks.js +262 -0
  68. package/dist-tsc/index.d.ts +12 -0
  69. package/dist-tsc/index.d.ts.map +1 -0
  70. package/dist-tsc/index.js +11 -17
  71. package/dist-tsc/mui-utils.d.ts +2 -0
  72. package/dist-tsc/mui-utils.d.ts.map +1 -0
  73. package/dist-tsc/mui-utils.js +44 -0
  74. package/dist-tsc/plugins.test.fixtures.d.ts +61 -0
  75. package/dist-tsc/plugins.test.fixtures.d.ts.map +1 -0
  76. package/dist-tsc/plugins.test.fixtures.js +76 -0
  77. package/dist-tsc/shared-mui/components.d.ts +2 -0
  78. package/dist-tsc/shared-mui/components.d.ts.map +1 -0
  79. package/dist-tsc/shared-mui/components.js +29 -0
  80. package/dist-tsc/shared-mui/container.d.ts +2 -0
  81. package/dist-tsc/shared-mui/container.d.ts.map +1 -0
  82. package/dist-tsc/shared-mui/container.js +211 -0
  83. package/dist-tsc/shared-mui/styles.d.ts +5 -0
  84. package/dist-tsc/shared-mui/styles.d.ts.map +1 -0
  85. package/dist-tsc/shared-mui/styles.js +109 -0
  86. package/dist-tsc/shared-plot-options/CellColorEncodingOption.d.ts +2 -0
  87. package/dist-tsc/shared-plot-options/CellColorEncodingOption.d.ts.map +1 -0
  88. package/dist-tsc/shared-plot-options/CellColorEncodingOption.js +17 -0
  89. package/dist-tsc/shared-plot-options/OptionSelect.d.ts +2 -0
  90. package/dist-tsc/shared-plot-options/OptionSelect.d.ts.map +1 -0
  91. package/dist-tsc/shared-plot-options/OptionSelect.js +12 -0
  92. package/dist-tsc/shared-plot-options/OptionsContainer.d.ts +2 -0
  93. package/dist-tsc/shared-plot-options/OptionsContainer.d.ts.map +1 -0
  94. package/dist-tsc/shared-plot-options/OptionsContainer.js +9 -0
  95. package/dist-tsc/shared-plot-options/index.d.ts +5 -0
  96. package/dist-tsc/shared-plot-options/index.d.ts.map +1 -0
  97. package/dist-tsc/shared-plot-options/index.js +4 -0
  98. package/dist-tsc/shared-plot-options/styles.d.ts +2 -0
  99. package/dist-tsc/shared-plot-options/styles.d.ts.map +1 -0
  100. package/dist-tsc/shared-plot-options/styles.js +48 -0
  101. package/dist-tsc/state/hooks.d.ts +242 -0
  102. package/dist-tsc/state/hooks.d.ts.map +1 -0
  103. package/dist-tsc/state/hooks.js +615 -0
  104. package/dist-tsc/title-styles.d.ts +2 -0
  105. package/dist-tsc/title-styles.d.ts.map +1 -0
  106. package/dist-tsc/title-styles.js +72 -0
  107. package/dist-tsc/view-config-utils.d.ts +31 -0
  108. package/dist-tsc/view-config-utils.d.ts.map +1 -0
  109. package/dist-tsc/view-config-utils.js +240 -0
  110. package/dist-tsc/view-config-utils.test.d.ts +2 -0
  111. package/dist-tsc/view-config-utils.test.d.ts.map +1 -0
  112. package/dist-tsc/view-config-utils.test.fixtures.d.ts +1049 -0
  113. package/dist-tsc/view-config-utils.test.fixtures.d.ts.map +1 -0
  114. package/dist-tsc/view-config-utils.test.fixtures.js +883 -0
  115. package/dist-tsc/view-config-utils.test.js +210 -0
  116. package/dist-tsc/vitessce-grid-layout/VitessceGridLayout.d.ts +8 -0
  117. package/dist-tsc/vitessce-grid-layout/VitessceGridLayout.d.ts.map +1 -0
  118. package/dist-tsc/vitessce-grid-layout/VitessceGridLayout.js +114 -0
  119. package/dist-tsc/vitessce-grid-layout/VitessceGridLayout.test.d.ts +2 -0
  120. package/dist-tsc/vitessce-grid-layout/VitessceGridLayout.test.d.ts.map +1 -0
  121. package/dist-tsc/vitessce-grid-layout/VitessceGridLayout.test.js +48 -0
  122. package/dist-tsc/vitessce-grid-layout/index.d.ts +2 -0
  123. package/dist-tsc/vitessce-grid-layout/index.d.ts.map +1 -0
  124. package/dist-tsc/vitessce-grid-layout/index.js +1 -0
  125. package/dist-tsc/vitessce-grid-layout/layout-utils.d.ts +15 -0
  126. package/dist-tsc/vitessce-grid-layout/layout-utils.d.ts.map +1 -0
  127. package/dist-tsc/vitessce-grid-layout/layout-utils.js +61 -0
  128. package/dist-tsc/vitessce-grid-layout/layout-utils.test.d.ts +2 -0
  129. package/dist-tsc/vitessce-grid-layout/layout-utils.test.d.ts.map +1 -0
  130. package/dist-tsc/vitessce-grid-layout/layout-utils.test.js +149 -0
  131. package/dist-tsc/vitessce-grid-utils.d.ts +13 -0
  132. package/dist-tsc/vitessce-grid-utils.d.ts.map +1 -0
  133. package/dist-tsc/vitessce-grid-utils.js +141 -0
  134. package/package.json +25 -11
  135. package/src/CallbackPublisher.js +7 -11
  136. package/src/LoadingIndicator.js +1 -2
  137. package/src/TitleInfo.js +12 -85
  138. package/src/VitS.js +143 -85
  139. package/src/VitessceGrid.js +35 -21
  140. package/src/VitessceGrid.test.jsx +23 -8
  141. package/src/Warning.js +4 -4
  142. package/src/data/AbstractLoader.js +2 -25
  143. package/src/data/AbstractTwoStepLoader.js +1 -1
  144. package/src/data/LoaderResult.js +5 -0
  145. package/src/data/index.js +3 -3
  146. package/src/data/loader-registry.js +22 -13
  147. package/src/data-hook-utils.js +119 -86
  148. package/src/data-hooks.js +150 -131
  149. package/src/errors/DataSourceFetchError.js +2 -2
  150. package/src/errors/DatasetNotFoundError.js +1 -1
  151. package/src/errors/LoaderNotFoundError.js +1 -1
  152. package/src/errors/LoaderValidationError.js +1 -1
  153. package/src/errors/index.js +5 -6
  154. package/src/hooks.js +81 -26
  155. package/src/index.js +23 -46
  156. package/src/mui-utils.js +52 -0
  157. package/src/shared-mui/components.js +10 -8
  158. package/src/shared-mui/container.js +1 -1
  159. package/src/shared-mui/styles.js +5 -2
  160. package/src/shared-plot-options/CellColorEncodingOption.js +3 -4
  161. package/src/shared-plot-options/OptionSelect.js +3 -3
  162. package/src/shared-plot-options/OptionsContainer.js +2 -5
  163. package/src/shared-plot-options/index.js +4 -4
  164. package/src/shared-plot-options/styles.js +2 -2
  165. package/src/state/hooks.js +75 -23
  166. package/src/title-styles.js +73 -0
  167. package/src/view-config-utils.js +54 -98
  168. package/src/view-config-utils.test.jsx +223 -0
  169. package/src/vitessce-grid-layout/VitessceGridLayout.js +51 -30
  170. package/src/vitessce-grid-layout/VitessceGridLayout.test.jsx +17 -9
  171. package/src/vitessce-grid-layout/index.js +1 -1
  172. package/src/vitessce-grid-layout/layout-utils.js +1 -1
  173. package/src/vitessce-grid-layout/layout-utils.test.js +2 -1
  174. package/src/vitessce-grid-utils.js +27 -15
  175. package/dist/index.mjs +0 -84801
  176. package/src/component-registry.js +0 -21
  177. package/src/errors/OptionsValidationError.js +0 -25
  178. package/src/file-options-schemas-legacy.js +0 -139
  179. package/src/file-options-schemas-legacy.test.js +0 -138
  180. package/src/file-options-schemas.js +0 -327
  181. package/src/file-options-schemas.test.js +0 -26
  182. package/src/joint-file-types-legacy.js +0 -298
  183. package/src/joint-file-types-legacy.test.js +0 -412
  184. package/src/joint-file-types.js +0 -171
  185. package/src/joint-file-types.test.js +0 -144
  186. package/src/json-schemas.js +0 -9
  187. package/src/plugins.js +0 -186
  188. package/src/plugins.test.js +0 -42
  189. package/src/schemas/config-0.1.0.schema.json +0 -85
  190. package/src/schemas/config-1.0.0.schema.json +0 -733
  191. package/src/schemas/config-1.0.1.schema.json +0 -909
  192. package/src/schemas/config-1.0.10.schema.json +0 -969
  193. package/src/schemas/config-1.0.11.schema.json +0 -990
  194. package/src/schemas/config-1.0.12.schema.json +0 -997
  195. package/src/schemas/config-1.0.13.schema.json +0 -1013
  196. package/src/schemas/config-1.0.14.schema.json +0 -1048
  197. package/src/schemas/config-1.0.15.schema.json +0 -1048
  198. package/src/schemas/config-1.0.16.schema.json +0 -1069
  199. package/src/schemas/config-1.0.16.schema.test.js +0 -32
  200. package/src/schemas/config-1.0.2.schema.json +0 -911
  201. package/src/schemas/config-1.0.3.schema.json +0 -911
  202. package/src/schemas/config-1.0.4.schema.json +0 -949
  203. package/src/schemas/config-1.0.5.schema.json +0 -949
  204. package/src/schemas/config-1.0.6.schema.json +0 -950
  205. package/src/schemas/config-1.0.7.schema.json +0 -950
  206. package/src/schemas/config-1.0.8.schema.json +0 -966
  207. package/src/schemas/config-1.0.9.schema.json +0 -965
  208. package/src/schemas/obsSets.schema.js +0 -195
  209. package/src/schemas/obsSetsTabular.schema.js +0 -39
  210. package/src/schemas/raster.schema.js +0 -121
  211. package/src/schemas/schema-schema.sh +0 -34
  212. package/src/schemas/schema.test-old.js +0 -49
  213. package/src/view-config-upgraders.js +0 -628
  214. package/src/view-config-utils.test.js +0 -95
  215. package/src/view-config-versions.js +0 -68
@@ -0,0 +1,615 @@
1
+ /* eslint-disable react-refresh/only-export-components */
2
+ import { useRef, useCallback, useMemo } from 'react';
3
+ import create from 'zustand';
4
+ import createContext from 'zustand/context';
5
+ import shallow from 'zustand/shallow';
6
+ import { isMatch, cloneDeep } from 'lodash-es';
7
+ import { CoordinationType } from '@vitessce/constants-internal';
8
+ import { fromEntries, capitalize } from '@vitessce/utils';
9
+ // Reference: https://github.com/pmndrs/zustand#react-context
10
+ // Reference: https://github.com/pmndrs/zustand/blob/e47ea03/tests/context.test.tsx#L60
11
+ const { Provider: ViewConfigProviderLocal, useStore: useViewConfigStoreLocal, useStoreApi: useViewConfigStoreApiLocal, } = createContext();
12
+ export const ViewConfigProvider = ViewConfigProviderLocal;
13
+ export const useViewConfigStore = useViewConfigStoreLocal;
14
+ export const useViewConfigStoreApi = useViewConfigStoreApiLocal;
15
+ const { Provider: AuxiliaryProviderLocal, useStore: useAuxiliaryStoreLocal, } = createContext();
16
+ export const AuxiliaryProvider = AuxiliaryProviderLocal;
17
+ export const useAuxiliaryStore = useAuxiliaryStoreLocal;
18
+ /**
19
+ * The useViewConfigStore hook is initialized via the zustand
20
+ * create() function, which sets up both the state variables
21
+ * and the reducer-type functions.
22
+ * References:
23
+ * - https://github.com/react-spring/zustand
24
+ * - https://github.com/pmndrs/zustand/releases/tag/v3.6.0
25
+ * - https://github.com/pmndrs/zustand#using-subscribe-with-selector
26
+ * @returns {function} The useStore hook.
27
+ */
28
+ export const createViewConfigStore = (initialLoaders, initialConfig) => create(set => ({
29
+ // State:
30
+ // The viewConfig is an object which must conform to the schema
31
+ // found in src/schemas/config.schema.json.
32
+ viewConfig: initialConfig,
33
+ // Store the initial config so that its values can be used for resetting.
34
+ initialViewConfig: cloneDeep(initialConfig),
35
+ // The loaders object is a mapping from dataset ID to
36
+ // data type to loader object instance.
37
+ loaders: initialLoaders,
38
+ // Reducer functions which update the state
39
+ // (although technically also part of state):
40
+ setViewConfig: viewConfig => set({ viewConfig, initialViewConfig: viewConfig }),
41
+ setLoaders: loaders => set({ loaders }),
42
+ setCoordinationValue: ({ parameter, scope, value }) => set(state => ({
43
+ viewConfig: {
44
+ ...state.viewConfig,
45
+ coordinationSpace: {
46
+ ...state.viewConfig.coordinationSpace,
47
+ [parameter]: {
48
+ ...state.viewConfig.coordinationSpace[parameter],
49
+ [scope]: value,
50
+ },
51
+ },
52
+ },
53
+ })),
54
+ removeComponent: uid => set((state) => {
55
+ const newLayout = state.viewConfig.layout.filter(c => c.uid !== uid);
56
+ return {
57
+ viewConfig: {
58
+ ...state.viewConfig,
59
+ layout: newLayout,
60
+ },
61
+ };
62
+ }),
63
+ changeLayout: newComponentProps => set((state) => {
64
+ const newLayout = state.viewConfig.layout
65
+ .slice()
66
+ .map(componentProps => ({
67
+ ...componentProps,
68
+ ...newComponentProps[componentProps.uid],
69
+ }));
70
+ return {
71
+ viewConfig: {
72
+ ...state.viewConfig,
73
+ layout: newLayout,
74
+ },
75
+ };
76
+ }),
77
+ }));
78
+ /**
79
+ * Hook for getting components' layout from the view config based on
80
+ * matching all coordination scopes.
81
+ * @returns {Object} The components' layout.
82
+ */
83
+ export const useComponentLayout = (component, scopes, coordinationScopes) => useViewConfigStore(state => state.viewConfig.layout.filter(l => l.component === component).filter(l => scopes.every(scope => l.coordinationScopes[scope]
84
+ === coordinationScopes[scope])));
85
+ /**
86
+ * The useAuxiliaryStore hook is initialized via the zustand
87
+ * create() function, which sets up both the state variables
88
+ * and the reducer-type functions.
89
+ * Reference: https://github.com/react-spring/zustand
90
+ * It is meant to be used for non-viewconfig-based coordination between components.
91
+ * For example, as currently happens, the layer controller can coordinate
92
+ * on-load callbacks with spatial view based on whether or not they are
93
+ * coordinated via `spatialImageLayer` - the callbacks are not part of the view config
94
+ * though so they live here.
95
+ * @returns {function} The useStore hook.
96
+ */
97
+ export const createAuxiliaryStore = () => create(set => ({
98
+ auxiliaryStore: null,
99
+ setCoordinationValue: ({ parameter, scope, value }) => set(state => ({
100
+ auxiliaryStore: {
101
+ ...state.auxiliaryStore,
102
+ [parameter]: {
103
+ [scope]: value,
104
+ },
105
+ },
106
+ })),
107
+ }));
108
+ /**
109
+ * The hover store can be used to store global state
110
+ * related to which component is currently hovered,
111
+ * which is required for tooltip / crossover elements.
112
+ * @returns {function} The useStore hook.
113
+ */
114
+ const useHoverStore = create(set => ({
115
+ // Components may need to know if they are the "hover source"
116
+ // for tooltip interactions. This value should be a unique
117
+ // component ID, such as its index in the view config layout.
118
+ componentHover: null,
119
+ setComponentHover: componentHover => set({ componentHover }),
120
+ }));
121
+ /**
122
+ * The warning store can be used to store global state
123
+ * related to app warning messages.
124
+ * @returns {function} The useStore hook.
125
+ */
126
+ const useWarnStore = create(set => ({
127
+ // Want a global state to collect warning messages
128
+ // that occur anywhere in the app.
129
+ warning: null,
130
+ setWarning: warning => set({ warning }),
131
+ }));
132
+ /**
133
+ * The view info store can be used to store component-level
134
+ * viewInfo objects,
135
+ * which are required for tooltip / crossover elements.
136
+ * @returns {function} The useStore hook.
137
+ */
138
+ const useViewInfoStore = create(set => ({
139
+ // The viewInfo object is a mapping from
140
+ // component IDs to component view info objects.
141
+ // Each view info object must have a project() function.
142
+ viewInfo: {},
143
+ setComponentViewInfo: (uuid, viewInfo) => set(state => ({
144
+ viewInfo: {
145
+ ...state.viewInfo,
146
+ [uuid]: viewInfo,
147
+ },
148
+ })),
149
+ }));
150
+ /**
151
+ * The grid size store can be used to store a
152
+ * counter which updates on each window or react-grid-layout
153
+ * resize event.
154
+ * @returns {function} The useStore hook.
155
+ */
156
+ const useGridSizeStore = create(set => ({
157
+ resizeCount: {},
158
+ incrementResizeCount: () => set(state => ({
159
+ resizeCount: state.resizeCount + 1,
160
+ })),
161
+ }));
162
+ /**
163
+ * This hook uses the same logic as for the `values` part of
164
+ * the useCoordination hook, with the difference that it
165
+ * gets its values from the _initial_ view config rather
166
+ * than the current view config.
167
+ * @param {string[]} parameters Array of coordination types.
168
+ * @param {object} coordinationScopes Mapping of coordination types
169
+ * to scope names.
170
+ * @returns {object} Object containing all coordination values.
171
+ */
172
+ export function useInitialCoordination(parameters, coordinationScopes) {
173
+ const values = useViewConfigStore((state) => {
174
+ const { coordinationSpace } = state.initialViewConfig;
175
+ return fromEntries(parameters.map((parameter) => {
176
+ if (coordinationSpace && coordinationSpace[parameter]) {
177
+ const value = coordinationSpace[parameter][coordinationScopes[parameter]];
178
+ return [parameter, value];
179
+ }
180
+ return [parameter, undefined];
181
+ }));
182
+ }, shallow);
183
+ return values;
184
+ }
185
+ /**
186
+ * The useCoordination hook returns both the
187
+ * values and setter functions for the coordination objects
188
+ * in a particular coordination scope mapping.
189
+ * This hook is intended to be used within the ___Subscriber
190
+ * components to allow them to "hook into" only those coordination
191
+ * objects and setter functions of relevance.
192
+ * @param {string[]} parameters Array of coordination types.
193
+ * @param {object} coordinationScopes Mapping of coordination types
194
+ * to scope names.
195
+ * @returns {array} Returns a tuple [values, setters]
196
+ * where values is an object containing all coordination values,
197
+ * and setters is an object containing all coordination setter
198
+ * functions for the values in `values`, named with a "set"
199
+ * prefix.
200
+ */
201
+ export function useCoordination(parameters, coordinationScopes) {
202
+ const setCoordinationValue = useViewConfigStore(state => state.setCoordinationValue);
203
+ const values = useViewConfigStore((state) => {
204
+ const { coordinationSpace } = state.viewConfig;
205
+ return fromEntries(parameters.map((parameter) => {
206
+ if (coordinationSpace && coordinationSpace[parameter]) {
207
+ const value = coordinationSpace[parameter][coordinationScopes[parameter]];
208
+ return [parameter, value];
209
+ }
210
+ return [parameter, undefined];
211
+ }));
212
+ }, shallow);
213
+ const setters = useMemo(() => fromEntries(parameters.map((parameter) => {
214
+ const setterName = `set${capitalize(parameter)}`;
215
+ const setterFunc = value => setCoordinationValue({
216
+ parameter,
217
+ scope: coordinationScopes[parameter],
218
+ value,
219
+ });
220
+ return [setterName, setterFunc];
221
+ // eslint-disable-next-line react-hooks/exhaustive-deps
222
+ })), [parameters, coordinationScopes]);
223
+ return [values, setters];
224
+ }
225
+ export function useMultiCoordinationValues(parameter, coordinationScopes) {
226
+ const scopes = coordinationScopes[parameter];
227
+ // Mapping from dataset coordination scope name to dataset uid
228
+ const vals = useViewConfigStore((state) => {
229
+ const { coordinationSpace } = state.viewConfig;
230
+ // Convert a single scope to an array of scopes to be consistent.
231
+ const scopesArr = Array.isArray(scopes) ? scopes : [scopes];
232
+ return fromEntries(scopesArr.map((scope) => {
233
+ if (coordinationSpace && coordinationSpace[parameter]) {
234
+ const value = coordinationSpace[parameter][scope];
235
+ return [scope, value];
236
+ }
237
+ return [scope, undefined];
238
+ // eslint-disable-next-line no-unused-vars
239
+ }).filter(([k, v]) => v !== undefined));
240
+ }, shallow);
241
+ return vals;
242
+ }
243
+ /**
244
+ * Get a mapping from dataset coordination scopes to dataset UIDs.
245
+ * @param {object} coordinationScopes The coordination scope mapping object for a view.
246
+ * @returns {object} Mapping from dataset coordination scope names to dataset UIDs.
247
+ */
248
+ export function useDatasetUids(coordinationScopes) {
249
+ return useMultiCoordinationValues(CoordinationType.DATASET, coordinationScopes);
250
+ }
251
+ /**
252
+ * Use coordination values and coordination setter functions corresponding to
253
+ * {coordinationType}-specific coordination scopes for each coordination type.
254
+ * @param {string[]} parameters An array of coordination types supported by a view.
255
+ * @param {object} coordinationScopes The coordination scope mapping object for a view.
256
+ * @param {object} coordinationScopesBy The per-coordinationType coordination scope
257
+ * mapping object for a view.
258
+ * @param {string} byType The {coordinationType} to use for per-{coordinationType} coordination
259
+ * scope mappings.
260
+ * @returns {array} [cValues, cSetters] where
261
+ * cValues is a mapping from coordination scope name to { coordinationType: coordinationValue },
262
+ * and cSetters is a mapping from coordination scope name to { setCoordinationType }
263
+ * setter functions.
264
+ */
265
+ export function useComplexCoordination(parameters, coordinationScopes, coordinationScopesBy, byType) {
266
+ const setCoordinationValue = useViewConfigStore(state => state.setCoordinationValue);
267
+ const typeScopes = coordinationScopes[byType];
268
+ const byTypeScopes = coordinationScopesBy[byType];
269
+ // Convert a single scope to an array of scopes to be consistent.
270
+ const typeScopesArr = Array.isArray(typeScopes) ? typeScopes : [typeScopes];
271
+ const values = useViewConfigStore((state) => {
272
+ const { coordinationSpace } = state.viewConfig;
273
+ return fromEntries(typeScopesArr.map((datasetScope) => {
274
+ const datasetValues = fromEntries(parameters.map((parameter) => {
275
+ if (coordinationSpace && coordinationSpace[parameter]) {
276
+ let value;
277
+ const parameterSpace = coordinationSpace[parameter];
278
+ const parameterScopeGlobal = coordinationScopes[parameter];
279
+ const parameterScopeByDataset = byTypeScopes?.[parameter];
280
+ if (parameterScopeByDataset && parameterScopeByDataset[datasetScope]) {
281
+ value = parameterSpace[parameterScopeByDataset[datasetScope]];
282
+ }
283
+ else if (parameterScopeGlobal) {
284
+ value = parameterSpace[parameterScopeGlobal];
285
+ }
286
+ else {
287
+ console.error(`coordination scope for ${parameter} was not found.`);
288
+ }
289
+ return [parameter, value];
290
+ }
291
+ return [parameter, undefined];
292
+ }));
293
+ return [datasetScope, datasetValues];
294
+ }));
295
+ }, shallow);
296
+ const setters = useMemo(() => fromEntries(typeScopesArr.map((datasetScope) => {
297
+ const datasetSetters = fromEntries(parameters.map((parameter) => {
298
+ const setterName = `set${capitalize(parameter)}`;
299
+ let setterFunc;
300
+ const parameterScopeGlobal = coordinationScopes[parameter];
301
+ const parameterScopeByDataset = byTypeScopes?.[parameter];
302
+ if (parameterScopeByDataset && parameterScopeByDataset[datasetScope]) {
303
+ setterFunc = value => setCoordinationValue({
304
+ parameter,
305
+ scope: parameterScopeByDataset[datasetScope],
306
+ value,
307
+ });
308
+ }
309
+ else if (parameterScopeGlobal) {
310
+ setterFunc = value => setCoordinationValue({
311
+ parameter,
312
+ scope: parameterScopeGlobal,
313
+ value,
314
+ });
315
+ }
316
+ else {
317
+ console.error(`coordination scope for ${parameter} was not found.`);
318
+ }
319
+ return [setterName, setterFunc];
320
+ }));
321
+ return [datasetScope, datasetSetters];
322
+ // eslint-disable-next-line react-hooks/exhaustive-deps
323
+ })), [parameters, coordinationScopes]);
324
+ return [values, setters];
325
+ }
326
+ /**
327
+ * Use coordination values and coordination setter functions corresponding to
328
+ * dataset-specific coordination scopes for each coordination type.
329
+ * @param {string[]} parameters An array of coordination types supported by a view.
330
+ * @param {object} coordinationScopes The coordination scope mapping object for a view.
331
+ * @param {object} coordinationScopesBy The per-coordinationType coordination scope
332
+ * mapping object for a view.
333
+ * @returns {array} [cValues, cSetters] where
334
+ * cValues is a mapping from coordination scope name to { coordinationType: coordinationValue },
335
+ * and cSetters is a mapping from coordination scope name to { setCoordinationType }
336
+ * setter functions.
337
+ */
338
+ export function useMultiDatasetCoordination(parameters, coordinationScopes, coordinationScopesBy) {
339
+ return useComplexCoordination(parameters, coordinationScopes, coordinationScopesBy, CoordinationType.DATASET);
340
+ }
341
+ const AUXILIARY_COORDINATION_TYPES_MAP = {
342
+ spatialImageLayer: ['imageLayerCallbacks', 'areLoadingImageChannels'],
343
+ spatialSegmentationLayer: ['segmentationLayerCallbacks', 'areLoadingSegmentationChannels'],
344
+ };
345
+ /**
346
+ * The maps the coordination types of incoming scopes to new types
347
+ * for the auxiliary store.
348
+ * @param {object} coordinationScopes Mapping of coordination types
349
+ * to scope names.
350
+ * @returns {object} Mapping of coordination types
351
+ * to new scope names for the auxiliary store.
352
+ */
353
+ const mapCoordinationScopes = (coordinationScopes) => {
354
+ const newCoordinationScopes = {};
355
+ Object.keys(coordinationScopes).forEach((key) => {
356
+ const newCoordinationTypes = AUXILIARY_COORDINATION_TYPES_MAP[key] || [];
357
+ newCoordinationTypes.forEach((coordinationType) => {
358
+ newCoordinationScopes[coordinationType || key] = coordinationScopes[key];
359
+ });
360
+ });
361
+ return newCoordinationScopes;
362
+ };
363
+ const mapParameters = parameters => parameters
364
+ .map(parameter => AUXILIARY_COORDINATION_TYPES_MAP[parameter]).filter(Boolean).flat();
365
+ /**
366
+ * The useAuxiliaryCoordination hook returns both the
367
+ * values and setter functions for the auxiliary coordination objects
368
+ * in a particular coordination scope mapping.
369
+ * This hook is intended to be used within the ___Subscriber
370
+ * components to allow them to "hook into" only those auxiliary coordination
371
+ * objects and setter functions of relevance, for example "on load" callbacks.
372
+ * @param {string[]} parameters Array of coordination types.
373
+ * @param {object} coordinationScopes Mapping of coordination types
374
+ * to scope names.
375
+ * @returns {array} Returns a tuple [values, setters]
376
+ * where values is an object containing all coordination values,
377
+ * and setters is an object containing all coordination setter
378
+ * functions for the values in `values`, named with a "set"
379
+ * prefix.
380
+ */
381
+ export function useAuxiliaryCoordination(parameters, coordinationScopes) {
382
+ const setCoordinationValue = useAuxiliaryStore(state => state.setCoordinationValue);
383
+ const mappedCoordinationScopes = mapCoordinationScopes(coordinationScopes);
384
+ const mappedParameters = mapParameters(parameters);
385
+ const values = useAuxiliaryStore((state) => {
386
+ const { auxiliaryStore } = state;
387
+ return fromEntries(mappedParameters.map((parameter) => {
388
+ if (auxiliaryStore && auxiliaryStore[parameter]) {
389
+ const value = auxiliaryStore[parameter][mappedCoordinationScopes[parameter]];
390
+ return [parameter, value];
391
+ }
392
+ return [parameter, undefined];
393
+ }));
394
+ }, shallow);
395
+ const setters = useMemo(() => fromEntries(mappedParameters.map((parameter) => {
396
+ const setterName = `set${capitalize(parameter)}`;
397
+ const setterFunc = value => setCoordinationValue({
398
+ parameter,
399
+ scope: mappedCoordinationScopes[parameter],
400
+ value,
401
+ });
402
+ return [setterName, setterFunc];
403
+ // eslint-disable-next-line react-hooks/exhaustive-deps
404
+ })), [parameters, coordinationScopes]);
405
+ return [values, setters];
406
+ }
407
+ /**
408
+ * Obtain the loaders object from
409
+ * the global app state.
410
+ * @returns {object} The loaders object
411
+ * in the `useViewConfigStore` store.
412
+ */
413
+ export function useLoaders() {
414
+ return useViewConfigStore(state => state.loaders);
415
+ }
416
+ /**
417
+ * Find a specific loader instance for a particular dataset, data type, and view
418
+ * coordination values (mapping from coordination types to coordination values).
419
+ * Uses lodash/isMatch to perform matching against the file definition's
420
+ * coordination value mapping.
421
+ * @param {object} loaders The value returned by useLoaders.
422
+ * @param {string} dataset The dataset UID.
423
+ * @param {string} dataType The data type for the matching file.
424
+ * @param {object} viewCoordinationValues Current coordination values
425
+ * from the view. Match these against a subset of file definition coordination
426
+ * values.
427
+ * @returns The matching loader instance or `null`.
428
+ */
429
+ export function getMatchingLoader(loaders, dataset, dataType, viewCoordinationValues) {
430
+ if (!loaders[dataset]) {
431
+ return null;
432
+ }
433
+ const loaderInternMap = loaders[dataset].loaders[dataType];
434
+ if (!loaderInternMap) {
435
+ return null;
436
+ }
437
+ const loaderKeys = Array.from(loaderInternMap.keys());
438
+ const matchingKey = loaderKeys
439
+ .find(fileCoordinationValues => isMatch(fileCoordinationValues, viewCoordinationValues));
440
+ if (!matchingKey) {
441
+ return null;
442
+ }
443
+ return loaderInternMap.get(matchingKey);
444
+ }
445
+ /**
446
+ * Find a specific loader instance for a particular dataset, data type, and view
447
+ * coordination values (mapping from coordination types to coordination values).
448
+ * Uses lodash/isMatch to perform matching against the file definition's
449
+ * coordination value mapping.
450
+ * @param {object} loaders The value returned by useLoaders.
451
+ * @param {string} dataset The dataset UID.
452
+ * @param {string} dataType The data type for the matching file.
453
+ * @param {object} viewCoordinationValues Current coordination values
454
+ * from the view. Match these against a subset of file definition coordination
455
+ * values.
456
+ * @returns The matching loader instance or `null`.
457
+ */
458
+ export function useMatchingLoader(loaders, dataset, dataType, viewCoordinationValues) {
459
+ return useMemo(() => getMatchingLoader(loaders, dataset, dataType, viewCoordinationValues), [loaders, dataset, dataType, viewCoordinationValues]);
460
+ }
461
+ /**
462
+ * Find a specific loader instance for a particular dataset, data type, and view
463
+ * coordination values (mapping from coordination types to coordination values).
464
+ * Uses lodash/isMatch to perform matching against the file definition's
465
+ * coordination value mapping.
466
+ * TODO: can this function be removed?
467
+ * @param {object} loaders The value returned by useLoaders.
468
+ * @param {string} dataset The dataset UID.
469
+ * @param {string} dataType The data type for the matching file.
470
+ * @param {object} viewCoordinationValues Current coordination values
471
+ * from the view. Match these against a subset of file definition coordination
472
+ * values.
473
+ * @returns The matching loader instance or `null`.
474
+ */
475
+ export function useMatchingLoaders(loaders, dataset, dataType, viewCoordinationValuesObj) {
476
+ return useMemo(() => {
477
+ if (!loaders[dataset]) {
478
+ return null;
479
+ }
480
+ const loaderInternMap = loaders[dataset].loaders[dataType];
481
+ if (!loaderInternMap) {
482
+ return null;
483
+ }
484
+ const loaderKeys = Array.from(loaderInternMap.keys());
485
+ function getLoader(viewCoordinationValues) {
486
+ const matchingKey = loaderKeys
487
+ .find(fileCoordinationValues => isMatch(fileCoordinationValues, viewCoordinationValues));
488
+ return loaderInternMap.get(matchingKey);
489
+ }
490
+ return fromEntries(Object.entries(viewCoordinationValuesObj).map(([key, viewCoordinationValues]) => ([
491
+ key,
492
+ getLoader(viewCoordinationValues),
493
+ ])));
494
+ }, [loaders, dataset, dataType, viewCoordinationValuesObj]);
495
+ }
496
+ /**
497
+ * Obtain the view config layout array from
498
+ * the global app state.
499
+ * @returns {object[]} The layout array
500
+ * in the `useViewConfigStore` store.
501
+ */
502
+ export function useLayout() {
503
+ return useViewConfigStore(state => state.viewConfig?.layout);
504
+ }
505
+ /**
506
+ * Obtain the component removal function from
507
+ * the global app state.
508
+ * @returns {function} The remove component function
509
+ * in the `useViewInfoStore` store.
510
+ */
511
+ export function useRemoveComponent() {
512
+ return useViewConfigStore(state => state.removeComponent);
513
+ }
514
+ /**
515
+ * Obtain the component prop setter function from
516
+ * the global app state.
517
+ * @returns {function} The set component props function
518
+ * in the `useViewInfoStore` store.
519
+ */
520
+ export function useChangeLayout() {
521
+ return useViewConfigStore(state => state.changeLayout);
522
+ }
523
+ /**
524
+ * Obtain the loaders setter function from
525
+ * the global app state.
526
+ * @returns {function} The loaders setter function
527
+ * in the `useViewConfigStore` store.
528
+ */
529
+ export function useSetLoaders() {
530
+ return useViewConfigStore(state => state.setLoaders);
531
+ }
532
+ /**
533
+ * Obtain the view config setter function from
534
+ * the global app state.
535
+ * @returns {function} The view config setter function
536
+ * in the `useViewConfigStore` store.
537
+ */
538
+ export function useSetViewConfig(viewConfigStoreApi) {
539
+ const setViewConfigRef = useRef(viewConfigStoreApi.getState().setViewConfig);
540
+ const setViewConfig = setViewConfigRef.current;
541
+ return setViewConfig;
542
+ }
543
+ /**
544
+ * Obtain the component hover value from
545
+ * the global app state.
546
+ * @returns {number} The hovered component ID
547
+ * in the `useHoverStore` store.
548
+ */
549
+ export function useComponentHover() {
550
+ return useHoverStore(state => state.componentHover);
551
+ }
552
+ /**
553
+ * Obtain the component hover setter function from
554
+ * the global app state.
555
+ * @returns {function} The component hover setter function
556
+ * in the `useHoverStore` store.
557
+ */
558
+ export function useSetComponentHover() {
559
+ return useHoverStore(state => state.setComponentHover);
560
+ }
561
+ /**
562
+ * Obtain the warning message from
563
+ * the global app state.
564
+ * @returns {string} The warning message
565
+ * in the `useWarnStore` store.
566
+ */
567
+ export function useWarning() {
568
+ return useWarnStore(state => state.warning);
569
+ }
570
+ /**
571
+ * Obtain the warning setter function from
572
+ * the global app state.
573
+ * @returns {function} The warning setter function
574
+ * in the `useWarnStore` store.
575
+ */
576
+ export function useSetWarning() {
577
+ return useWarnStore(state => state.setWarning);
578
+ }
579
+ /**
580
+ * Obtain the component view info value from
581
+ * the global app state.
582
+ * @returns {object} The view info object for the component
583
+ * in the `useViewInfoStore` store.
584
+ */
585
+ export function useComponentViewInfo(uuid) {
586
+ return useViewInfoStore(useCallback(state => state.viewInfo[uuid], [uuid]));
587
+ }
588
+ /**
589
+ * Obtain the component view info setter function from
590
+ * the global app state.
591
+ * @returns {function} The component view info setter function
592
+ * in the `useViewInfoStore` store.
593
+ */
594
+ export function useSetComponentViewInfo(uuid) {
595
+ const setViewInfoRef = useRef(useViewInfoStore.getState().setComponentViewInfo);
596
+ const setComponentViewInfo = useCallback(viewInfo => setViewInfoRef.current(uuid, viewInfo), [uuid]);
597
+ return setComponentViewInfo;
598
+ }
599
+ /**
600
+ * Obtain the grid resize count value
601
+ * from the global app state.
602
+ * @returns {number} The grid resize increment value.
603
+ */
604
+ export function useGridResize() {
605
+ return useGridSizeStore(state => state.resizeCount);
606
+ }
607
+ /**
608
+ * Obtain the grid resize count increment function
609
+ * from the global app state.
610
+ * @returns {function} The grid resize count increment
611
+ * function.
612
+ */
613
+ export function useEmitGridResize() {
614
+ return useGridSizeStore(state => state.incrementResizeCount);
615
+ }
@@ -0,0 +1,2 @@
1
+ export const useTitleStyles: (props?: any) => import("@material-ui/core/styles/withStyles").ClassNameMap<never>;
2
+ //# sourceMappingURL=title-styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"title-styles.d.ts","sourceRoot":"","sources":["../src/title-styles.js"],"names":[],"mappings":"AAEA,gHAsEI"}
@@ -0,0 +1,72 @@
1
+ import { makeStyles } from '@material-ui/core';
2
+ export const useTitleStyles = makeStyles(theme => ({
3
+ title: {
4
+ color: theme.palette.primaryForeground,
5
+ overflowX: 'hidden',
6
+ display: 'flex',
7
+ flexDirection: 'row',
8
+ flexShrink: '0',
9
+ },
10
+ titleLeft: {
11
+ flexShrink: '1',
12
+ textOverflow: 'ellipsis',
13
+ whiteSpace: 'nowrap',
14
+ },
15
+ titleInfo: {
16
+ width: '100%',
17
+ textOverflow: 'ellipsis',
18
+ whiteSpace: 'nowrap',
19
+ overflow: 'hidden',
20
+ fontSize: '80% !important',
21
+ opacity: '.8',
22
+ padding: '0 4px',
23
+ justifyContent: 'center',
24
+ lineHeight: '25px !important',
25
+ flexShrink: '1',
26
+ textAlign: 'right !important',
27
+ },
28
+ titleButtons: {
29
+ display: 'flex',
30
+ flexDirection: 'row',
31
+ flexGrow: '1',
32
+ flexShrink: '0',
33
+ justifyContent: 'right',
34
+ '& div': {
35
+ display: 'inline-block',
36
+ },
37
+ },
38
+ card: {
39
+ border: `1px solid ${theme.palette.cardBorder}`,
40
+ flex: '1 1 auto',
41
+ minHeight: '1px',
42
+ padding: '12px',
43
+ marginTop: '8px',
44
+ marginBottom: '8px',
45
+ position: 'relative',
46
+ display: 'flex',
47
+ flexDirection: 'column',
48
+ minWidth: '0',
49
+ wordWrap: 'break-word',
50
+ backgroundClip: 'border-box',
51
+ borderRadius: '4px',
52
+ },
53
+ noScrollCard: {
54
+ backgroundColor: theme.palette.secondaryBackground,
55
+ color: theme.palette.secondaryForeground,
56
+ },
57
+ scrollCard: {
58
+ backgroundColor: theme.palette.primaryBackground,
59
+ color: theme.palette.primaryForeground,
60
+ '& a': {
61
+ color: theme.palette.primaryForegroundActive,
62
+ },
63
+ overflowY: 'auto',
64
+ },
65
+ spatialCard: {
66
+ backgroundColor: theme.palette.black,
67
+ color: theme.palette.white,
68
+ '& a': {
69
+ color: theme.palette.white,
70
+ },
71
+ },
72
+ }));