@vitessce/vit-s 3.4.14 → 3.5.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.js +107 -64
- package/dist-tsc/VitS.d.ts.map +1 -1
- package/dist-tsc/VitS.js +10 -5
- package/dist-tsc/contexts.d.ts +3 -1
- package/dist-tsc/contexts.d.ts.map +1 -1
- package/dist-tsc/contexts.js +27 -2
- package/dist-tsc/hooks.d.ts +14 -5
- package/dist-tsc/hooks.d.ts.map +1 -1
- package/dist-tsc/hooks.js +22 -13
- package/dist-tsc/index.d.ts +2 -2
- package/dist-tsc/index.js +2 -2
- package/dist-tsc/state/hooks.d.ts +7 -0
- package/dist-tsc/state/hooks.d.ts.map +1 -1
- package/dist-tsc/state/hooks.js +9 -0
- package/dist-tsc/vitessce-grid-layout/VitessceGridLayout.d.ts.map +1 -1
- package/dist-tsc/vitessce-grid-layout/VitessceGridLayout.js +16 -27
- package/package.json +9 -9
- package/src/VitS.js +15 -9
- package/src/contexts.js +30 -2
- package/src/hooks.js +24 -15
- package/src/index.js +3 -1
- package/src/state/hooks.js +11 -0
- package/src/vitessce-grid-layout/VitessceGridLayout.js +26 -31
package/dist/index.js
CHANGED
|
@@ -27921,7 +27921,8 @@ const ViewType$1 = {
|
|
|
27921
27921
|
OBS_SET_FEATURE_VALUE_DISTRIBUTION: "obsSetFeatureValueDistribution",
|
|
27922
27922
|
FEATURE_VALUE_HISTOGRAM: "featureValueHistogram",
|
|
27923
27923
|
DOT_PLOT: "dotPlot",
|
|
27924
|
-
FEATURE_BAR_PLOT: "featureBarPlot"
|
|
27924
|
+
FEATURE_BAR_PLOT: "featureBarPlot",
|
|
27925
|
+
BIOMARKER_SELECT: "biomarkerSelect"
|
|
27925
27926
|
};
|
|
27926
27927
|
const DataType$1 = {
|
|
27927
27928
|
OBS_LABELS: "obsLabels",
|
|
@@ -28251,10 +28252,10 @@ const AUTO_INDEPENDENT_COORDINATION_TYPES = [
|
|
|
28251
28252
|
CoordinationType$1.EMBEDDING_OBS_OPACITY
|
|
28252
28253
|
];
|
|
28253
28254
|
const note = "This file is autogenerated by .changeset/post-changelog.mjs.";
|
|
28254
|
-
const version = "3.
|
|
28255
|
-
const date = "2024-
|
|
28255
|
+
const version = "3.5.0";
|
|
28256
|
+
const date = "2024-11-01";
|
|
28256
28257
|
const branch = "changeset-release/main";
|
|
28257
|
-
const hash = "
|
|
28258
|
+
const hash = "1eb007aa";
|
|
28258
28259
|
const META_VERSION = {
|
|
28259
28260
|
note,
|
|
28260
28261
|
version,
|
|
@@ -29282,7 +29283,7 @@ class VitessceConfigView {
|
|
|
29282
29283
|
* @param {number} w The width of the view in the layout.
|
|
29283
29284
|
* @param {number} h The height of the view in the layout.
|
|
29284
29285
|
*/
|
|
29285
|
-
constructor(component, coordinationScopes, x, y, w, h) {
|
|
29286
|
+
constructor(component, coordinationScopes, x, y, w, h, uid) {
|
|
29286
29287
|
this.view = {
|
|
29287
29288
|
component,
|
|
29288
29289
|
coordinationScopes,
|
|
@@ -29291,7 +29292,8 @@ class VitessceConfigView {
|
|
|
29291
29292
|
x,
|
|
29292
29293
|
y,
|
|
29293
29294
|
w,
|
|
29294
|
-
h
|
|
29295
|
+
h,
|
|
29296
|
+
uid
|
|
29295
29297
|
};
|
|
29296
29298
|
}
|
|
29297
29299
|
/**
|
|
@@ -29545,7 +29547,7 @@ class VitessceConfig {
|
|
|
29545
29547
|
* @returns {VitessceConfigView} A new view instance.
|
|
29546
29548
|
*/
|
|
29547
29549
|
addView(dataset, component, options) {
|
|
29548
|
-
const { x = 0, y = 0, w = 1, h = 1, mapping = null } = options || {};
|
|
29550
|
+
const { x = 0, y = 0, w = 1, h = 1, uid = void 0, mapping = null } = options || {};
|
|
29549
29551
|
const datasetMatches = this.config.coordinationSpace[CoordinationType$1.DATASET] ? Object.entries(this.config.coordinationSpace[CoordinationType$1.DATASET]).filter(([scopeName, datasetScope2]) => datasetScope2.cValue === dataset.dataset.uid).map(([scopeName]) => scopeName) : [];
|
|
29550
29552
|
let datasetScope;
|
|
29551
29553
|
if (datasetMatches.length === 1) {
|
|
@@ -29556,7 +29558,7 @@ class VitessceConfig {
|
|
|
29556
29558
|
const coordinationScopes = {
|
|
29557
29559
|
[CoordinationType$1.DATASET]: datasetScope
|
|
29558
29560
|
};
|
|
29559
|
-
const newView = new VitessceConfigView(component, coordinationScopes, x, y, w, h);
|
|
29561
|
+
const newView = new VitessceConfigView(component, coordinationScopes, x, y, w, h, uid);
|
|
29560
29562
|
if (mapping) {
|
|
29561
29563
|
const [etScope] = this.addCoordination(CoordinationType$1.EMBEDDING_TYPE);
|
|
29562
29564
|
etScope.setValue(mapping);
|
|
@@ -29574,9 +29576,20 @@ class VitessceConfig {
|
|
|
29574
29576
|
addCoordination(...args) {
|
|
29575
29577
|
const cTypes = args;
|
|
29576
29578
|
const result = [];
|
|
29577
|
-
cTypes.forEach((
|
|
29578
|
-
|
|
29579
|
-
|
|
29579
|
+
cTypes.forEach((cTypeOrObj) => {
|
|
29580
|
+
let cType;
|
|
29581
|
+
let cScope;
|
|
29582
|
+
let cValue;
|
|
29583
|
+
if (typeof cTypeOrObj === "string") {
|
|
29584
|
+
cType = cTypeOrObj;
|
|
29585
|
+
const prevScopes = this.config.coordinationSpace[cType] ? Object.keys(this.config.coordinationSpace[cType]) : [];
|
|
29586
|
+
cScope = this.getNextScope(prevScopes);
|
|
29587
|
+
} else {
|
|
29588
|
+
cType = cTypeOrObj.cType;
|
|
29589
|
+
cScope = cTypeOrObj.cScope;
|
|
29590
|
+
cValue = cTypeOrObj.cValue;
|
|
29591
|
+
}
|
|
29592
|
+
const scope = new VitessceConfigCoordinationScope(cType, cScope, cValue);
|
|
29580
29593
|
if (!this.config.coordinationSpace[scope.cType]) {
|
|
29581
29594
|
this.config.coordinationSpace[scope.cType] = {};
|
|
29582
29595
|
}
|
|
@@ -29823,7 +29836,7 @@ class VitessceConfig {
|
|
|
29823
29836
|
}
|
|
29824
29837
|
});
|
|
29825
29838
|
config2.layout.forEach((c) => {
|
|
29826
|
-
const newView = new VitessceConfigView(c.component, c.coordinationScopes, c.x, c.y, c.w, c.h);
|
|
29839
|
+
const newView = new VitessceConfigView(c.component, c.coordinationScopes, c.x, c.y, c.w, c.h, c.uid);
|
|
29827
29840
|
vc.config.layout.push(newView);
|
|
29828
29841
|
});
|
|
29829
29842
|
return vc;
|
|
@@ -30776,6 +30789,9 @@ function useSetLoaders() {
|
|
|
30776
30789
|
function useMergeCoordination() {
|
|
30777
30790
|
return useViewConfigStore((state) => state.mergeCoordination);
|
|
30778
30791
|
}
|
|
30792
|
+
function useViewConfig() {
|
|
30793
|
+
return useViewConfigStore((state) => state.viewConfig);
|
|
30794
|
+
}
|
|
30779
30795
|
function useSetViewConfig(viewConfigStoreApi) {
|
|
30780
30796
|
const setViewConfigRef = useRef(viewConfigStoreApi.getState().setViewConfig);
|
|
30781
30797
|
const setViewConfig = setViewConfigRef.current;
|
|
@@ -36713,6 +36729,36 @@ function resolveLayout(layout2) {
|
|
|
36713
36729
|
components
|
|
36714
36730
|
};
|
|
36715
36731
|
}
|
|
36732
|
+
const AsyncFunctionsContext = createContext$1({
|
|
36733
|
+
// {
|
|
36734
|
+
// asyncFunctions: { [functionType: string]: asyncFunction },
|
|
36735
|
+
// queryClient: QueryClient from react-query
|
|
36736
|
+
// }
|
|
36737
|
+
// asyncFunctions will be an object where keys are function types
|
|
36738
|
+
// (as strings) and values are the async functions.
|
|
36739
|
+
});
|
|
36740
|
+
function useAsyncFunction(functionType2) {
|
|
36741
|
+
var _a;
|
|
36742
|
+
const context = useContext(AsyncFunctionsContext);
|
|
36743
|
+
const origFunction = (_a = context == null ? void 0 : context.asyncFunctions) == null ? void 0 : _a[functionType2];
|
|
36744
|
+
const queryClient = context == null ? void 0 : context.queryClient;
|
|
36745
|
+
const partialFunction = (...args) => origFunction({ queryClient }, ...args);
|
|
36746
|
+
return partialFunction;
|
|
36747
|
+
}
|
|
36748
|
+
const PageModeViewContext = createContext$1({
|
|
36749
|
+
// Keys are view UIDs and values are
|
|
36750
|
+
// the corresponding React components.
|
|
36751
|
+
});
|
|
36752
|
+
function ensureComponent(component) {
|
|
36753
|
+
if (!component) {
|
|
36754
|
+
return () => null;
|
|
36755
|
+
}
|
|
36756
|
+
return component;
|
|
36757
|
+
}
|
|
36758
|
+
function usePageModeView(uid) {
|
|
36759
|
+
const context = useContext(PageModeViewContext);
|
|
36760
|
+
return ensureComponent(context == null ? void 0 : context[uid]);
|
|
36761
|
+
}
|
|
36716
36762
|
const ResponsiveGridLayout = reactGridLayoutWithLodashExports.WidthProvider(reactGridLayoutWithLodashExports.Responsive);
|
|
36717
36763
|
class ResponsiveHeightGridLayout extends ResponsiveGridLayout {
|
|
36718
36764
|
componentDidUpdate(prevProps) {
|
|
@@ -36812,30 +36858,23 @@ function VitessceGridLayout(props) {
|
|
|
36812
36858
|
const saveCurrentLayouts = useCallback(() => {
|
|
36813
36859
|
setLastValidGridLayouts(gridLayouts);
|
|
36814
36860
|
}, [gridLayouts]);
|
|
36815
|
-
const layoutChildren = useMemo(() => {
|
|
36861
|
+
const [layoutChildren, pageModeViews] = useMemo(() => {
|
|
36816
36862
|
const gridComponentsValues = Object.values(gridComponents);
|
|
36817
|
-
|
|
36818
|
-
|
|
36819
|
-
|
|
36820
|
-
|
|
36821
|
-
|
|
36822
|
-
|
|
36823
|
-
|
|
36824
|
-
|
|
36825
|
-
|
|
36826
|
-
|
|
36827
|
-
|
|
36828
|
-
|
|
36829
|
-
|
|
36830
|
-
|
|
36831
|
-
|
|
36832
|
-
theme,
|
|
36833
|
-
removeGridComponent: null
|
|
36834
|
-
}
|
|
36835
|
-
) }));
|
|
36836
|
-
});
|
|
36837
|
-
}
|
|
36838
|
-
return gridComponentsValues.map((v) => {
|
|
36863
|
+
const contextValue = Object.fromEntries(gridComponentsValues.map((v) => {
|
|
36864
|
+
const Component = getComponent(v.component);
|
|
36865
|
+
return [v.uid, () => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { display: "flex", flexDirection: "column", height: "100%" }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36866
|
+
Component,
|
|
36867
|
+
{
|
|
36868
|
+
...v.props,
|
|
36869
|
+
uuid: v.uid,
|
|
36870
|
+
coordinationScopes: v.coordinationScopes,
|
|
36871
|
+
coordinationScopesBy: v.coordinationScopesBy,
|
|
36872
|
+
theme,
|
|
36873
|
+
removeGridComponent: null
|
|
36874
|
+
}
|
|
36875
|
+
) }, v.uid)];
|
|
36876
|
+
}));
|
|
36877
|
+
return [gridComponentsValues.map((v) => {
|
|
36839
36878
|
const Component = getComponent(v.component);
|
|
36840
36879
|
const removeGridComponent = () => {
|
|
36841
36880
|
onRemoveComponent(v.uid);
|
|
@@ -36851,9 +36890,9 @@ function VitessceGridLayout(props) {
|
|
|
36851
36890
|
removeGridComponent
|
|
36852
36891
|
}
|
|
36853
36892
|
) }, v.uid);
|
|
36854
|
-
});
|
|
36893
|
+
}), contextValue];
|
|
36855
36894
|
}, [gridComponents, getComponent, onRemoveComponent, theme]);
|
|
36856
|
-
return pageMode ?
|
|
36895
|
+
return pageMode ? /* @__PURE__ */ jsxRuntimeExports.jsx(PageModeViewContext.Provider, { value: pageModeViews, children: children2 }) : gridLayouts && gridComponents && gridBreakpoints && gridCols && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
36857
36896
|
style,
|
|
36858
36897
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36859
36898
|
ResponsiveHeightGridLayout,
|
|
@@ -37236,18 +37275,22 @@ function useUint8ObsFeatureMatrix({ obsFeatureMatrix }) {
|
|
|
37236
37275
|
}
|
|
37237
37276
|
function useUint8FeatureSelection(expressionData) {
|
|
37238
37277
|
return useMemo(() => {
|
|
37239
|
-
if (expressionData
|
|
37240
|
-
|
|
37241
|
-
const normData = expressionData.map((arr, i) => {
|
|
37242
|
-
const [min, max] = extents[i];
|
|
37243
|
-
const ratio = 255 / (max - min);
|
|
37244
|
-
return new Uint8Array(
|
|
37245
|
-
arr.map((j) => Math.floor((j - min) * ratio))
|
|
37246
|
-
);
|
|
37247
|
-
});
|
|
37248
|
-
return [normData, extents];
|
|
37278
|
+
if ((expressionData == null ? void 0 : expressionData[0]) == null) {
|
|
37279
|
+
return { normData: null, extents: null, missing: null };
|
|
37249
37280
|
}
|
|
37250
|
-
|
|
37281
|
+
const extents = expressionData.map((arr) => extent(arr));
|
|
37282
|
+
const normData = expressionData.map((arr, i) => {
|
|
37283
|
+
const [min, max] = extents[i];
|
|
37284
|
+
const ratio = 255 / (max - min);
|
|
37285
|
+
return new Uint8Array(
|
|
37286
|
+
arr.map((j) => Math.floor((j - min) * ratio))
|
|
37287
|
+
);
|
|
37288
|
+
});
|
|
37289
|
+
const missing = expressionData.map((arr) => {
|
|
37290
|
+
const numMissing = arr.reduce((prev, curr) => Number.isNaN(curr) ? prev + 1 : prev, 0);
|
|
37291
|
+
return numMissing / arr.length;
|
|
37292
|
+
});
|
|
37293
|
+
return { normData, extents, missing };
|
|
37251
37294
|
}, [expressionData]);
|
|
37252
37295
|
}
|
|
37253
37296
|
function useExpressionValueGetter({ instanceObsIndex, matrixObsIndex, expressionData }) {
|
|
@@ -38007,14 +38050,6 @@ function createGenerateClassName(customPrefix) {
|
|
|
38007
38050
|
return `${seedPrefix}${ruleKey}`;
|
|
38008
38051
|
};
|
|
38009
38052
|
}
|
|
38010
|
-
const AsyncFunctionsContext = createContext$1({
|
|
38011
|
-
// This will be an object where keys are function types
|
|
38012
|
-
// (as strings) and values are the async functions.
|
|
38013
|
-
});
|
|
38014
|
-
function useAsyncFunction(functionType2) {
|
|
38015
|
-
const context = useContext(AsyncFunctionsContext);
|
|
38016
|
-
return context == null ? void 0 : context[functionType2];
|
|
38017
|
-
}
|
|
38018
38053
|
function VitS(props) {
|
|
38019
38054
|
const {
|
|
38020
38055
|
config: config2,
|
|
@@ -38049,14 +38084,6 @@ function VitS(props) {
|
|
|
38049
38084
|
() => coordinationTypesProp || [],
|
|
38050
38085
|
[coordinationTypesProp]
|
|
38051
38086
|
);
|
|
38052
|
-
const asyncFunctions = useMemo(
|
|
38053
|
-
() => Object.fromEntries(
|
|
38054
|
-
// Convert the array of PluginAsyncFunction instances to a mapping
|
|
38055
|
-
// from function type strings to async functions.
|
|
38056
|
-
(asyncFunctionsProp == null ? void 0 : asyncFunctionsProp.map((p) => [p.functionType, p.asyncFunction])) || []
|
|
38057
|
-
),
|
|
38058
|
-
[asyncFunctionsProp]
|
|
38059
|
-
);
|
|
38060
38087
|
const generateClassName2 = useMemo(() => createGenerateClassName(uid), [uid]);
|
|
38061
38088
|
const configVersion = config2 == null ? void 0 : config2.version;
|
|
38062
38089
|
const configKey = useMemo(() => {
|
|
@@ -38126,7 +38153,20 @@ function VitS(props) {
|
|
|
38126
38153
|
retry: 2
|
|
38127
38154
|
}
|
|
38128
38155
|
}
|
|
38156
|
+
// TODO: should the queryClient be shared? Or have an option to be shared
|
|
38157
|
+
// (e.g., based on remountOnUidChange)?
|
|
38129
38158
|
}), [configKey]);
|
|
38159
|
+
const asyncFunctions = useMemo(
|
|
38160
|
+
() => ({
|
|
38161
|
+
queryClient,
|
|
38162
|
+
asyncFunctions: Object.fromEntries(
|
|
38163
|
+
// Convert the array of PluginAsyncFunction instances to a mapping
|
|
38164
|
+
// from function type strings to async functions.
|
|
38165
|
+
(asyncFunctionsProp == null ? void 0 : asyncFunctionsProp.map((p) => [p.functionType, p.asyncFunction])) || []
|
|
38166
|
+
)
|
|
38167
|
+
}),
|
|
38168
|
+
[asyncFunctionsProp, queryClient]
|
|
38169
|
+
);
|
|
38130
38170
|
useEffect(() => {
|
|
38131
38171
|
if (success && !isEqual$1(configOrWarning, config2) && onConfigChange) {
|
|
38132
38172
|
onConfigChange(configOrWarning);
|
|
@@ -40235,6 +40275,7 @@ export {
|
|
|
40235
40275
|
useObsSegmentationsData,
|
|
40236
40276
|
useObsSetsData,
|
|
40237
40277
|
useObsSpotsData,
|
|
40278
|
+
usePageModeView,
|
|
40238
40279
|
useStyles as usePlotOptionsStyles,
|
|
40239
40280
|
usePointMultiObsLabels,
|
|
40240
40281
|
useReady,
|
|
@@ -40247,6 +40288,7 @@ export {
|
|
|
40247
40288
|
useSegmentationMultiObsSets,
|
|
40248
40289
|
useSetComponentHover,
|
|
40249
40290
|
useSetComponentViewInfo,
|
|
40291
|
+
useSetViewConfig,
|
|
40250
40292
|
useSetWarning,
|
|
40251
40293
|
useSpotMultiFeatureLabels,
|
|
40252
40294
|
useSpotMultiFeatureSelection,
|
|
@@ -40255,6 +40297,7 @@ export {
|
|
|
40255
40297
|
useUint8FeatureSelection,
|
|
40256
40298
|
useUint8ObsFeatureMatrix,
|
|
40257
40299
|
useUrls,
|
|
40300
|
+
useViewConfig,
|
|
40258
40301
|
useViewConfigStore,
|
|
40259
40302
|
useViewConfigStoreApi,
|
|
40260
40303
|
useVitessceContainer,
|
package/dist-tsc/VitS.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VitS.d.ts","sourceRoot":"","sources":["../src/VitS.js"],"names":[],"mappings":"AA+BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,4BAhCG;IAAsB,MAAM,EAApB,MAAM;IAGkB,SAAS,EAAjC,SAAS,GAAC,MAAM;IACF,MAAM,EAApB,MAAM;IACQ,KAAK,EAAnB,MAAM;IAEU,MAAM;IACN,cAAc;IAEd,cAAc;IAEf,cAAc,EAA7B,OAAO;IAIQ,sBAAsB,EAArC,OAAO;IAGY,GAAG,EAAtB,IAAI,GAAC,MAAM;IAGI,kBAAkB,EAAjC,OAAO;IAEM,SAAS,EAAtB,KAAK;IACQ,SAAS,EAAtB,KAAK;IACQ,cAAc,EAA3B,KAAK;IACQ,iBAAiB,EAA9B,KAAK;IACc,OAAO,EAA1B,IAAI,GAAC,MAAM;IACI,QAAQ,EAAvB,OAAO;CAEjB,
|
|
1
|
+
{"version":3,"file":"VitS.d.ts","sourceRoot":"","sources":["../src/VitS.js"],"names":[],"mappings":"AA+BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,4BAhCG;IAAsB,MAAM,EAApB,MAAM;IAGkB,SAAS,EAAjC,SAAS,GAAC,MAAM;IACF,MAAM,EAApB,MAAM;IACQ,KAAK,EAAnB,MAAM;IAEU,MAAM;IACN,cAAc;IAEd,cAAc;IAEf,cAAc,EAA7B,OAAO;IAIQ,sBAAsB,EAArC,OAAO;IAGY,GAAG,EAAtB,IAAI,GAAC,MAAM;IAGI,kBAAkB,EAAjC,OAAO;IAEM,SAAS,EAAtB,KAAK;IACQ,SAAS,EAAtB,KAAK;IACQ,cAAc,EAA3B,KAAK;IACQ,iBAAiB,EAA9B,KAAK;IACc,OAAO,EAA1B,IAAI,GAAC,MAAM;IACI,QAAQ,EAAvB,OAAO;CAEjB,eAqNA"}
|
package/dist-tsc/VitS.js
CHANGED
|
@@ -54,11 +54,6 @@ export function VitS(props) {
|
|
|
54
54
|
const fileTypes = useMemo(() => (fileTypesProp || []), [fileTypesProp]);
|
|
55
55
|
const jointFileTypes = useMemo(() => (jointFileTypesProp || []), [jointFileTypesProp]);
|
|
56
56
|
const coordinationTypes = useMemo(() => (coordinationTypesProp || []), [coordinationTypesProp]);
|
|
57
|
-
const asyncFunctions = useMemo(() => Object.fromEntries(
|
|
58
|
-
// Convert the array of PluginAsyncFunction instances to a mapping
|
|
59
|
-
// from function type strings to async functions.
|
|
60
|
-
asyncFunctionsProp?.map(p => ([p.functionType, p.asyncFunction]))
|
|
61
|
-
|| []), [asyncFunctionsProp]);
|
|
62
57
|
const generateClassName = useMemo(() => createGenerateClassName(uid), [uid]);
|
|
63
58
|
const configVersion = config?.version;
|
|
64
59
|
// If config.uid exists, then use it for hook dependencies to detect changes
|
|
@@ -132,7 +127,17 @@ export function VitS(props) {
|
|
|
132
127
|
retry: 2,
|
|
133
128
|
},
|
|
134
129
|
},
|
|
130
|
+
// TODO: should the queryClient be shared? Or have an option to be shared
|
|
131
|
+
// (e.g., based on remountOnUidChange)?
|
|
135
132
|
}), [configKey]);
|
|
133
|
+
const asyncFunctions = useMemo(() => ({
|
|
134
|
+
queryClient,
|
|
135
|
+
asyncFunctions: Object.fromEntries(
|
|
136
|
+
// Convert the array of PluginAsyncFunction instances to a mapping
|
|
137
|
+
// from function type strings to async functions.
|
|
138
|
+
asyncFunctionsProp?.map(p => ([p.functionType, p.asyncFunction]))
|
|
139
|
+
|| []),
|
|
140
|
+
}), [asyncFunctionsProp, queryClient]);
|
|
136
141
|
// Emit the upgraded/initialized view config
|
|
137
142
|
// to onConfigChange if necessary.
|
|
138
143
|
useEffect(() => {
|
package/dist-tsc/contexts.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export function useAsyncFunction(functionType: any): any;
|
|
1
|
+
export function useAsyncFunction(functionType: any): (...args: any[]) => any;
|
|
2
|
+
export function usePageModeView(uid: any): any;
|
|
2
3
|
export const AsyncFunctionsContext: any;
|
|
4
|
+
export const PageModeViewContext: any;
|
|
3
5
|
//# sourceMappingURL=contexts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contexts.d.ts","sourceRoot":"","sources":["../src/contexts.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"contexts.d.ts","sourceRoot":"","sources":["../src/contexts.js"],"names":[],"mappings":"AAYA,6EAQC;AAcD,+CAKC;AApCD,wCAOG;AAYH,sCAGG"}
|
package/dist-tsc/contexts.js
CHANGED
|
@@ -1,10 +1,35 @@
|
|
|
1
1
|
/* eslint-disable react-refresh/only-export-components */
|
|
2
2
|
import { createContext, useContext } from 'react';
|
|
3
3
|
export const AsyncFunctionsContext = createContext({
|
|
4
|
-
//
|
|
4
|
+
// {
|
|
5
|
+
// asyncFunctions: { [functionType: string]: asyncFunction },
|
|
6
|
+
// queryClient: QueryClient from react-query
|
|
7
|
+
// }
|
|
8
|
+
// asyncFunctions will be an object where keys are function types
|
|
5
9
|
// (as strings) and values are the async functions.
|
|
6
10
|
});
|
|
7
11
|
export function useAsyncFunction(functionType) {
|
|
8
12
|
const context = useContext(AsyncFunctionsContext);
|
|
9
|
-
|
|
13
|
+
const origFunction = context?.asyncFunctions?.[functionType];
|
|
14
|
+
const queryClient = context?.queryClient;
|
|
15
|
+
// We use partial function application here, so that the caller
|
|
16
|
+
// does not need to worry about passing in the queryClient.
|
|
17
|
+
const partialFunction = (...args) => origFunction({ queryClient }, ...args);
|
|
18
|
+
return partialFunction;
|
|
19
|
+
}
|
|
20
|
+
export const PageModeViewContext = createContext({
|
|
21
|
+
// Keys are view UIDs and values are
|
|
22
|
+
// the corresponding React components.
|
|
23
|
+
});
|
|
24
|
+
function ensureComponent(component) {
|
|
25
|
+
if (!component) {
|
|
26
|
+
return () => null;
|
|
27
|
+
}
|
|
28
|
+
return component;
|
|
29
|
+
}
|
|
30
|
+
export function usePageModeView(uid) {
|
|
31
|
+
const context = useContext(PageModeViewContext);
|
|
32
|
+
// TODO: Is there any case where we would want to
|
|
33
|
+
// throw an error instead?
|
|
34
|
+
return ensureComponent(context?.[uid]);
|
|
10
35
|
}
|
package/dist-tsc/hooks.d.ts
CHANGED
|
@@ -57,15 +57,24 @@ export function useUint8ObsFeatureMatrix({ obsFeatureMatrix }: {
|
|
|
57
57
|
/**
|
|
58
58
|
* Normalize a feature selection (data for selected
|
|
59
59
|
* columns of an obsFeatureMatrix) to a Uint8Array.
|
|
60
|
-
* @param {
|
|
60
|
+
* @param {Float32Array[] | null} expressionData The expressionData
|
|
61
61
|
* returned by the useFeatureSelection hook,
|
|
62
62
|
* where each element corresponds to an
|
|
63
63
|
* array of values for a selected feature.
|
|
64
|
-
* @returns {
|
|
65
|
-
*
|
|
66
|
-
*
|
|
64
|
+
* @returns {{
|
|
65
|
+
* normData: Uint8Array[] | null,
|
|
66
|
+
* extents: [number, number][] | null,
|
|
67
|
+
* missing: number[]
|
|
68
|
+
* }} An object tuple {normData, extents, missing} where
|
|
69
|
+
* normData is an array of Uint8Arrays (or null),
|
|
70
|
+
* extents is an array of [min, max] values for each feature (or null), and
|
|
71
|
+
* missing is an array of numbers (between 0 and 1) for each feature (or null).
|
|
67
72
|
*/
|
|
68
|
-
export function useUint8FeatureSelection(expressionData:
|
|
73
|
+
export function useUint8FeatureSelection(expressionData: Float32Array[] | null): {
|
|
74
|
+
normData: Uint8Array[] | null;
|
|
75
|
+
extents: [number, number][] | null;
|
|
76
|
+
missing: number[];
|
|
77
|
+
};
|
|
69
78
|
export function useExpressionValueGetter({ instanceObsIndex, matrixObsIndex, expressionData }: {
|
|
70
79
|
instanceObsIndex: any;
|
|
71
80
|
matrixObsIndex: any;
|
package/dist-tsc/hooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.js"],"names":[],"mappings":"AAkBA,oDAOC;AAED;;;;GAIG;AACH,uCAHa,KAAK,CAmBjB;AAED;;;;GAIG;AACH,mCAHa,KAAK,CAoCjB;AAED;;;;;GAKG;AACH,qCAJa,KAAK,CAqCjB;AAED;;;;;;GAMG;AACH,uCAHW,MAAM,EAAE,GACN,OAAO,CAOnB;AAED;;;;GAIG;AACH,8BAHW,CAAC,IAAI,GAAC,MAAM,EAAE,CAAC,EAAE,GACf,KAAK,CAYjB;AAED;;;;;;GAMG;AACH,qDAJW,GAAG,GACD,KAAK,CA0BjB;AAED;;;;;;;;;;GAUG;AACH,+DARG;IAAuB,gBAAgB,EAA/B,MAAM;CAEd,GAAU,KAAK,CAmBjB;AAED
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.js"],"names":[],"mappings":"AAkBA,oDAOC;AAED;;;;GAIG;AACH,uCAHa,KAAK,CAmBjB;AAED;;;;GAIG;AACH,mCAHa,KAAK,CAoCjB;AAED;;;;;GAKG;AACH,qCAJa,KAAK,CAqCjB;AAED;;;;;;GAMG;AACH,uCAHW,MAAM,EAAE,GACN,OAAO,CAOnB;AAED;;;;GAIG;AACH,8BAHW,CAAC,IAAI,GAAC,MAAM,EAAE,CAAC,EAAE,GACf,KAAK,CAYjB;AAED;;;;;;GAMG;AACH,qDAJW,GAAG,GACD,KAAK,CA0BjB;AAED;;;;;;;;;;GAUG;AACH,+DARG;IAAuB,gBAAgB,EAA/B,MAAM;CAEd,GAAU,KAAK,CAmBjB;AAED;;;;;;;;;;;;;;;GAeG;AACH,yDAbW,YAAY,EAAE,GAAG,IAAI,GAInB;IACZ,QAAW,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IACjC,OAAU,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,IAAI,CAAC;IACtC,OAAU,EAAE,MAAM,EAAE,CAAA;CACjB,CAwBH;AAED;;;;QA2BC;AAED,iEAOC;AAED,kHA4BC"}
|
package/dist-tsc/hooks.js
CHANGED
|
@@ -185,26 +185,35 @@ export function useUint8ObsFeatureMatrix({ obsFeatureMatrix }) {
|
|
|
185
185
|
/**
|
|
186
186
|
* Normalize a feature selection (data for selected
|
|
187
187
|
* columns of an obsFeatureMatrix) to a Uint8Array.
|
|
188
|
-
* @param {
|
|
188
|
+
* @param {Float32Array[] | null} expressionData The expressionData
|
|
189
189
|
* returned by the useFeatureSelection hook,
|
|
190
190
|
* where each element corresponds to an
|
|
191
191
|
* array of values for a selected feature.
|
|
192
|
-
* @returns {
|
|
193
|
-
*
|
|
194
|
-
*
|
|
192
|
+
* @returns {{
|
|
193
|
+
* normData: Uint8Array[] | null,
|
|
194
|
+
* extents: [number, number][] | null,
|
|
195
|
+
* missing: number[]
|
|
196
|
+
* }} An object tuple {normData, extents, missing} where
|
|
197
|
+
* normData is an array of Uint8Arrays (or null),
|
|
198
|
+
* extents is an array of [min, max] values for each feature (or null), and
|
|
199
|
+
* missing is an array of numbers (between 0 and 1) for each feature (or null).
|
|
195
200
|
*/
|
|
196
201
|
export function useUint8FeatureSelection(expressionData) {
|
|
197
202
|
return useMemo(() => {
|
|
198
|
-
if (expressionData
|
|
199
|
-
|
|
200
|
-
const normData = expressionData.map((arr, i) => {
|
|
201
|
-
const [min, max] = extents[i];
|
|
202
|
-
const ratio = 255 / (max - min);
|
|
203
|
-
return new Uint8Array(arr.map(j => Math.floor((j - min) * ratio)));
|
|
204
|
-
});
|
|
205
|
-
return [normData, extents];
|
|
203
|
+
if (expressionData?.[0] == null) {
|
|
204
|
+
return { normData: null, extents: null, missing: null };
|
|
206
205
|
}
|
|
207
|
-
|
|
206
|
+
const extents = expressionData.map(arr => extent(arr));
|
|
207
|
+
const normData = expressionData.map((arr, i) => {
|
|
208
|
+
const [min, max] = extents[i];
|
|
209
|
+
const ratio = 255 / (max - min);
|
|
210
|
+
return new Uint8Array(arr.map(j => Math.floor((j - min) * ratio)));
|
|
211
|
+
});
|
|
212
|
+
const missing = expressionData.map((arr) => {
|
|
213
|
+
const numMissing = arr.reduce((prev, curr) => (Number.isNaN(curr) ? prev + 1 : prev), 0);
|
|
214
|
+
return numMissing / arr.length;
|
|
215
|
+
});
|
|
216
|
+
return { normData, extents, missing };
|
|
208
217
|
}, [expressionData]);
|
|
209
218
|
}
|
|
210
219
|
export function useExpressionValueGetter({ instanceObsIndex, matrixObsIndex, expressionData }) {
|
package/dist-tsc/index.d.ts
CHANGED
|
@@ -3,12 +3,12 @@ export { TitleInfo } from "./TitleInfo.js";
|
|
|
3
3
|
export { PopperMenu } from "./shared-mui/components.js";
|
|
4
4
|
export { useHasLoader } from "./data-hook-utils.js";
|
|
5
5
|
export { logConfig } from "./view-config-utils.js";
|
|
6
|
-
export { useAsyncFunction } from "./contexts.js";
|
|
7
6
|
export { useReady, useUrls, useVitessceContainer, useDeckCanvasSize, useUint8ObsFeatureMatrix, useUint8FeatureSelection, useExpressionValueGetter, useGetObsMembership, useGetObsInfo, useClosestVitessceContainerSize, useWindowDimensions, useGridItemSize } from "./hooks.js";
|
|
8
|
-
export { useCoordinationScopes, useCoordinationScopesBy, useInitialCoordination, useCoordination, useComplexCoordination, useComplexCoordinationSecondary, useMultiCoordinationScopes, useMultiCoordinationScopesNonNull, useMultiCoordinationScopesSecondary, useMultiCoordinationScopesSecondaryNonNull, useMultiCoordinationValues, useMultiDatasetCoordination, useDatasetUids, useLoaders, useMergeCoordination, useMatchingLoader, useViewConfigStore, useViewConfigStoreApi, useComponentHover, useSetComponentHover, useComponentViewInfo, useSetComponentViewInfo, useWarning, useSetWarning, useAuxiliaryCoordination, useComponentLayout, useRemoveImageChannelInMetaCoordinationScopes, useAddImageChannelInMetaCoordinationScopes } from "./state/hooks.js";
|
|
7
|
+
export { useCoordinationScopes, useCoordinationScopesBy, useInitialCoordination, useCoordination, useComplexCoordination, useComplexCoordinationSecondary, useMultiCoordinationScopes, useMultiCoordinationScopesNonNull, useMultiCoordinationScopesSecondary, useMultiCoordinationScopesSecondaryNonNull, useMultiCoordinationValues, useMultiDatasetCoordination, useDatasetUids, useLoaders, useMergeCoordination, useMatchingLoader, useViewConfigStore, useViewConfigStoreApi, useViewConfig, useSetViewConfig, useComponentHover, useSetComponentHover, useComponentViewInfo, useSetComponentViewInfo, useWarning, useSetWarning, useAuxiliaryCoordination, useComponentLayout, useRemoveImageChannelInMetaCoordinationScopes, useAddImageChannelInMetaCoordinationScopes } from "./state/hooks.js";
|
|
9
8
|
export { useDescription, useImageData, useObsSetsData, useObsEmbeddingData, useFeatureSelection, useObsFeatureMatrixIndices, useSampleSetsData, useSampleEdgesData, useMultiObsLabels, useMultiObsSpots, useMultiObsPoints, useSpotMultiObsSets, useSpotMultiFeatureLabels, useMultiObsSegmentations, useMultiImages, useObsSpotsData, useObsPointsData, useObsLocationsData, useObsSegmentationsData, useNeighborhoodsData, useObsLabelsData, useObsFeatureMatrixData, useFeatureLabelsData, useGenomicProfilesData } from "./data-hooks.js";
|
|
10
9
|
export { usePointMultiObsLabels, useSpotMultiFeatureSelection, useSpotMultiObsFeatureMatrixIndices, useSegmentationMultiFeatureSelection, useSegmentationMultiObsFeatureMatrixIndices, useSegmentationMultiObsLocations, useSegmentationMultiObsSets } from "./data-hooks-multilevel.js";
|
|
11
10
|
export { AbstractLoader, AbstractTwoStepLoader, LoaderResult } from "./data/index.js";
|
|
12
11
|
export { AbstractLoaderError, DatasetNotFoundError, LoaderNotFoundError, LoaderValidationError, DataSourceFetchError } from "./errors/index.js";
|
|
13
12
|
export { CellColorEncodingOption, OptionsContainer, OptionSelect, usePlotOptionsStyles } from "./shared-plot-options/index.js";
|
|
13
|
+
export { useAsyncFunction, usePageModeView } from "./contexts.js";
|
|
14
14
|
//# sourceMappingURL=index.d.ts.map
|
package/dist-tsc/index.js
CHANGED
|
@@ -3,7 +3,7 @@ export { TitleInfo } from './TitleInfo.js';
|
|
|
3
3
|
export { PopperMenu } from './shared-mui/components.js';
|
|
4
4
|
// For plugin view types:
|
|
5
5
|
export { useReady, useUrls, useVitessceContainer, useDeckCanvasSize, useUint8ObsFeatureMatrix, useUint8FeatureSelection, useExpressionValueGetter, useGetObsMembership, useGetObsInfo, useClosestVitessceContainerSize, useWindowDimensions, useGridItemSize, } from './hooks.js';
|
|
6
|
-
export { useCoordinationScopes, useCoordinationScopesBy, useInitialCoordination, useCoordination, useComplexCoordination, useComplexCoordinationSecondary, useMultiCoordinationScopes, useMultiCoordinationScopesNonNull, useMultiCoordinationScopesSecondary, useMultiCoordinationScopesSecondaryNonNull, useMultiCoordinationValues, useMultiDatasetCoordination, useDatasetUids, useLoaders, useMergeCoordination, useMatchingLoader, useViewConfigStore, useViewConfigStoreApi, useComponentHover, useSetComponentHover, useComponentViewInfo, useSetComponentViewInfo, useWarning, useSetWarning, useAuxiliaryCoordination, useComponentLayout, useRemoveImageChannelInMetaCoordinationScopes, useAddImageChannelInMetaCoordinationScopes, } from './state/hooks.js';
|
|
6
|
+
export { useCoordinationScopes, useCoordinationScopesBy, useInitialCoordination, useCoordination, useComplexCoordination, useComplexCoordinationSecondary, useMultiCoordinationScopes, useMultiCoordinationScopesNonNull, useMultiCoordinationScopesSecondary, useMultiCoordinationScopesSecondaryNonNull, useMultiCoordinationValues, useMultiDatasetCoordination, useDatasetUids, useLoaders, useMergeCoordination, useMatchingLoader, useViewConfigStore, useViewConfigStoreApi, useViewConfig, useSetViewConfig, useComponentHover, useSetComponentHover, useComponentViewInfo, useSetComponentViewInfo, useWarning, useSetWarning, useAuxiliaryCoordination, useComponentLayout, useRemoveImageChannelInMetaCoordinationScopes, useAddImageChannelInMetaCoordinationScopes, } from './state/hooks.js';
|
|
7
7
|
export { useDescription, useImageData, useObsSetsData, useObsEmbeddingData, useFeatureSelection, useObsFeatureMatrixIndices, useSampleSetsData, useSampleEdgesData, useMultiObsLabels, useMultiObsSpots, useMultiObsPoints, useSpotMultiObsSets, useSpotMultiFeatureLabels, useMultiObsSegmentations, useMultiImages, useObsSpotsData, useObsPointsData, useObsLocationsData, useObsSegmentationsData, useNeighborhoodsData, useObsLabelsData, useObsFeatureMatrixData, useFeatureLabelsData, useGenomicProfilesData, } from './data-hooks.js';
|
|
8
8
|
export { usePointMultiObsLabels, useSpotMultiFeatureSelection, useSpotMultiObsFeatureMatrixIndices, useSegmentationMultiFeatureSelection, useSegmentationMultiObsFeatureMatrixIndices, useSegmentationMultiObsLocations, useSegmentationMultiObsSets, } from './data-hooks-multilevel.js';
|
|
9
9
|
export { useHasLoader, } from './data-hook-utils.js';
|
|
@@ -11,4 +11,4 @@ export { AbstractLoader, AbstractTwoStepLoader, LoaderResult, } from './data/ind
|
|
|
11
11
|
export { AbstractLoaderError, DatasetNotFoundError, LoaderNotFoundError, LoaderValidationError, DataSourceFetchError, } from './errors/index.js';
|
|
12
12
|
export { CellColorEncodingOption, OptionsContainer, OptionSelect, usePlotOptionsStyles, } from './shared-plot-options/index.js';
|
|
13
13
|
export { logConfig } from './view-config-utils.js';
|
|
14
|
-
export { useAsyncFunction } from './contexts.js';
|
|
14
|
+
export { useAsyncFunction, usePageModeView } from './contexts.js';
|
|
@@ -222,6 +222,13 @@ export function useSetLoaders(): Function;
|
|
|
222
222
|
* in the `useViewConfigStore` store.
|
|
223
223
|
*/
|
|
224
224
|
export function useMergeCoordination(): Function;
|
|
225
|
+
/**
|
|
226
|
+
* Obtain the current view config object from
|
|
227
|
+
* the global app state.
|
|
228
|
+
* @returns {object} The view config object
|
|
229
|
+
* in the `useViewConfigStore` store.
|
|
230
|
+
*/
|
|
231
|
+
export function useViewConfig(): object;
|
|
225
232
|
/**
|
|
226
233
|
* Obtain the view config setter function from
|
|
227
234
|
* the global app state.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/state/hooks.js"],"names":[],"mappings":"AAmCA;;;;;;GAMG;AACH,8CAJW,GAAC,mBAEC,MAAM,GAAC,SAAS,CA4B5B;AAED;;;;;;;GAOG;AACH,gDALW,GAAC,wBACD,GAAC,qBAEC,MAAM,GAAC,SAAS,CA0C5B;AAED;;;;;GAKG;AACH,6CAJW,MAAM,sBACN,GAAC,GACC,MAAM,GAAC,SAAS,CAI5B;AAED;;;;;;GAMG;AACH,+CALW,MAAM,mDACN,GAAC,wBACD,GAAC,GACC,MAAM,GAAC,SAAS,CAc5B;AA4RD;;;;;;;;;GASG;AACH,mDALW,MAAM,EAAE,sBACR,MAAM,GAEJ,MAAM,CAclB;AAED;;;;;;;;;;;;;;;GAeG;AACH,4CATW,MAAM,EAAE,sBACR,MAAM,GAEJ,KAAK,CAmCjB;AAED,yFAKC;AAED,gGAqBC;AAED,0IA4BC;AAED,iJAkEC;AAED,yFAmBC;AAED;;;;GAIG;AACH,mDAHW,MAAM,GACJ,MAAM,CAIlB;AAED;;;;;;;;;;;;;GAaG;AACH,mDAXW,MAAM,EAAE,sBACR,MAAM,wBACN,MAAM,UAEN,MAAM,GAEJ,KAAK,CA2EjB;AAED;;;;;GAKG;AACH,0DAHW,MAAM,GACJ,MAAM,CAiBlB;AAED;;;;;;GAMG;AACH,4DAJW,MAAM,wBACN,MAAM,GACJ,MAAM,CAgBlB;AAED;;;;;;;GAOG;AACH,4DANW,MAAM,EAAE,iDACR,MAAM,eACN,MAAM,iBACN,MAAM,SAuEhB;AAGD;;;;;;;;;;;GAWG;AACH,wDATW,MAAM,EAAE,sBACR,MAAM,wBACN,MAAM,GAEJ,KAAK,CAUjB;AA6BD;;;;;;;;;;;;;;;GAeG;AACH,qDATW,MAAM,EAAE,sBACR,MAAM,GAEJ,KAAK,CAgCjB;AAED;;;;;GAKG;AACH,8BAHa,MAAM,CAKlB;AAGD;;;;;;;;;;;;GAYG;AACH,2CARW,MAAM,WACN,MAAM,YACN,MAAM,0BACN,MAAM,OAoBhB;AAED;;;;;;;;;;;;GAYG;AACH,2CARW,MAAM,WACN,MAAM,YACN,MAAM,0BACN,MAAM,OAShB;AAED;;;;;GAKG;AACH,6BAHa,MAAM,EAAE,CAKpB;AAED;;;;;GAKG;AACH,+CAEC;AAED;;;;;GAKG;AACH,0EAEC;AAED;;;;;GAKG;AACH,uEAEC;AAED;;;;;GAKG;AACH,4CAEC;AAED;;;;;GAKG;AACH,0CAEC;AAED;;;;;GAKG;AACH,iDAEC;AAED;;;;;GAKG;AACH,
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/state/hooks.js"],"names":[],"mappings":"AAmCA;;;;;;GAMG;AACH,8CAJW,GAAC,mBAEC,MAAM,GAAC,SAAS,CA4B5B;AAED;;;;;;;GAOG;AACH,gDALW,GAAC,wBACD,GAAC,qBAEC,MAAM,GAAC,SAAS,CA0C5B;AAED;;;;;GAKG;AACH,6CAJW,MAAM,sBACN,GAAC,GACC,MAAM,GAAC,SAAS,CAI5B;AAED;;;;;;GAMG;AACH,+CALW,MAAM,mDACN,GAAC,wBACD,GAAC,GACC,MAAM,GAAC,SAAS,CAc5B;AA4RD;;;;;;;;;GASG;AACH,mDALW,MAAM,EAAE,sBACR,MAAM,GAEJ,MAAM,CAclB;AAED;;;;;;;;;;;;;;;GAeG;AACH,4CATW,MAAM,EAAE,sBACR,MAAM,GAEJ,KAAK,CAmCjB;AAED,yFAKC;AAED,gGAqBC;AAED,0IA4BC;AAED,iJAkEC;AAED,yFAmBC;AAED;;;;GAIG;AACH,mDAHW,MAAM,GACJ,MAAM,CAIlB;AAED;;;;;;;;;;;;;GAaG;AACH,mDAXW,MAAM,EAAE,sBACR,MAAM,wBACN,MAAM,UAEN,MAAM,GAEJ,KAAK,CA2EjB;AAED;;;;;GAKG;AACH,0DAHW,MAAM,GACJ,MAAM,CAiBlB;AAED;;;;;;GAMG;AACH,4DAJW,MAAM,wBACN,MAAM,GACJ,MAAM,CAgBlB;AAED;;;;;;;GAOG;AACH,4DANW,MAAM,EAAE,iDACR,MAAM,eACN,MAAM,iBACN,MAAM,SAuEhB;AAGD;;;;;;;;;;;GAWG;AACH,wDATW,MAAM,EAAE,sBACR,MAAM,wBACN,MAAM,GAEJ,KAAK,CAUjB;AA6BD;;;;;;;;;;;;;;;GAeG;AACH,qDATW,MAAM,EAAE,sBACR,MAAM,GAEJ,KAAK,CAgCjB;AAED;;;;;GAKG;AACH,8BAHa,MAAM,CAKlB;AAGD;;;;;;;;;;;;GAYG;AACH,2CARW,MAAM,WACN,MAAM,YACN,MAAM,0BACN,MAAM,OAoBhB;AAED;;;;;;;;;;;;GAYG;AACH,2CARW,MAAM,WACN,MAAM,YACN,MAAM,0BACN,MAAM,OAShB;AAED;;;;;GAKG;AACH,6BAHa,MAAM,EAAE,CAKpB;AAED;;;;;GAKG;AACH,+CAEC;AAED;;;;;GAKG;AACH,0EAEC;AAED;;;;;GAKG;AACH,uEAEC;AAED;;;;;GAKG;AACH,4CAEC;AAED;;;;;GAKG;AACH,0CAEC;AAED;;;;;GAKG;AACH,iDAEC;AAED;;;;;GAKG;AACH,iCAHa,MAAM,CAKlB;AAED;;;;;GAKG;AACH,oEAIC;AAGD;;;;;GAKG;AACH,qCAHa,MAAM,CAKlB;AAED;;;;;GAKG;AACH,iDAEC;AAED;;;;;GAKG;AACH,8BAHa,MAAM,CAKlB;AAED;;;;;GAKG;AACH,0CAEC;AAED;;;;;GAKG;AACH,iDAHa,MAAM,CAKlB;AAED;;;;;GAKG;AACH,6DAOC;AAED;;;;GAIG;AACH,iCAFa,MAAM,CAIlB;AAED;;;;;GAKG;AACH,8CAEC;AAvpCD;;;;aAPG,OAAO,kCAAkC,OAAO,sEAOO;AAC1D,mFAA0D;AAC1D;;;;;EAAgE;AAOhE;;;;mIAAwD;AACxD,kFAAwD;AAiIjD,yFA+KJ;AAOI,0FAFM,MAAM,CAOlB;AAcM,iDAUJ"}
|
package/dist-tsc/state/hooks.js
CHANGED
|
@@ -973,6 +973,15 @@ export function useSetLoaders() {
|
|
|
973
973
|
export function useMergeCoordination() {
|
|
974
974
|
return useViewConfigStore(state => state.mergeCoordination);
|
|
975
975
|
}
|
|
976
|
+
/**
|
|
977
|
+
* Obtain the current view config object from
|
|
978
|
+
* the global app state.
|
|
979
|
+
* @returns {object} The view config object
|
|
980
|
+
* in the `useViewConfigStore` store.
|
|
981
|
+
*/
|
|
982
|
+
export function useViewConfig() {
|
|
983
|
+
return useViewConfigStore(state => state.viewConfig);
|
|
984
|
+
}
|
|
976
985
|
/**
|
|
977
986
|
* Obtain the view config setter function from
|
|
978
987
|
* the global app state.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VitessceGridLayout.d.ts","sourceRoot":"","sources":["../../src/vitessce-grid-layout/VitessceGridLayout.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"VitessceGridLayout.d.ts","sourceRoot":"","sources":["../../src/vitessce-grid-layout/VitessceGridLayout.js"],"names":[],"mappings":"AAgBA,oDAwLC"}
|
|
@@ -3,6 +3,7 @@ import React, { useState, useMemo, useCallback } from 'react';
|
|
|
3
3
|
import { Responsive, WidthProvider } from 'react-grid-layout-with-lodash';
|
|
4
4
|
import { isEqual } from 'lodash-es';
|
|
5
5
|
import { getMaxRows, resolveLayout } from './layout-utils.js';
|
|
6
|
+
import { PageModeViewContext } from '../contexts.js';
|
|
6
7
|
const ResponsiveGridLayout = WidthProvider(Responsive);
|
|
7
8
|
class ResponsiveHeightGridLayout extends ResponsiveGridLayout {
|
|
8
9
|
componentDidUpdate(prevProps) {
|
|
@@ -97,38 +98,26 @@ export function VitessceGridLayout(props) {
|
|
|
97
98
|
const saveCurrentLayouts = useCallback(() => {
|
|
98
99
|
setLastValidGridLayouts(gridLayouts);
|
|
99
100
|
}, [gridLayouts]);
|
|
100
|
-
const layoutChildren = useMemo(() => {
|
|
101
|
+
const [layoutChildren, pageModeViews] = useMemo(() => {
|
|
101
102
|
const gridComponentsValues = Object.values(gridComponents);
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
return
|
|
105
|
-
|
|
106
|
-
const v = gridComponentsValues.find(el => el.uid === childId);
|
|
107
|
-
if (!v) {
|
|
108
|
-
// The child did not map to any view in the config, so return as-is.
|
|
109
|
-
return child;
|
|
110
|
-
}
|
|
111
|
-
// The child mapped to a view in the config,
|
|
112
|
-
// so we want to render the corresponding component as a subchild.
|
|
113
|
-
const Component = getComponent(v.component);
|
|
114
|
-
return React.cloneElement(child, { key: v.uid }, (_jsx("div", { style: { display: 'flex', flexDirection: 'column', height: '100%' }, children: _jsx(Component, { ...v.props, uuid: v.uid, coordinationScopes: v.coordinationScopes, coordinationScopesBy: v.coordinationScopesBy, theme: theme, removeGridComponent: null }) })));
|
|
115
|
-
});
|
|
116
|
-
}
|
|
103
|
+
const contextValue = Object.fromEntries(gridComponentsValues.map((v) => {
|
|
104
|
+
const Component = getComponent(v.component);
|
|
105
|
+
return [v.uid, () => (_jsx("div", { style: { display: 'flex', flexDirection: 'column', height: '100%' }, children: _jsx(Component, { ...v.props, uuid: v.uid, coordinationScopes: v.coordinationScopes, coordinationScopesBy: v.coordinationScopesBy, theme: theme, removeGridComponent: null }) }, v.uid))];
|
|
106
|
+
}));
|
|
117
107
|
// Not pageMode, so no children to render.
|
|
118
108
|
// We render the grid components based on the layout information.
|
|
119
|
-
return gridComponentsValues.map((v) => {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
109
|
+
return [gridComponentsValues.map((v) => {
|
|
110
|
+
const Component = getComponent(v.component);
|
|
111
|
+
const removeGridComponent = () => {
|
|
112
|
+
onRemoveComponent(v.uid);
|
|
113
|
+
};
|
|
114
|
+
return (_jsx("div", { children: _jsx(Component, { ...v.props, uuid: v.uid, coordinationScopes: v.coordinationScopes, coordinationScopesBy: v.coordinationScopesBy, theme: theme, removeGridComponent: removeGridComponent }) }, v.uid));
|
|
115
|
+
}), contextValue];
|
|
126
116
|
}, [gridComponents, getComponent, onRemoveComponent, theme]);
|
|
127
117
|
return (pageMode
|
|
128
|
-
?
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
/ maxRows), containerPadding: containerPadding, margin: margin, draggableHandle: draggableHandle, onLayoutChange: onLayoutChange, isBounded: isBounded, onResizeStart: saveCurrentLayouts, onDragStart: saveCurrentLayouts, onResize: onResize, onResizeStop: onResizeStop, children: layoutChildren })] }))));
|
|
118
|
+
? (_jsx(PageModeViewContext.Provider, { value: pageModeViews, children: children })) : ((gridLayouts && gridComponents && gridBreakpoints && gridCols) && (_jsxs(_Fragment, { children: [style, _jsx(ResponsiveHeightGridLayout, { className: "layout", cols: gridCols, layouts: tempGridLayouts || gridLayouts, breakpoints: gridBreakpoints, height: height, rowHeight: rowHeight
|
|
119
|
+
|| ((window.innerHeight - 2 * padding - (maxRows - 1) * margin)
|
|
120
|
+
/ maxRows), containerPadding: containerPadding, margin: margin, draggableHandle: draggableHandle, onLayoutChange: onLayoutChange, isBounded: isBounded, onResizeStart: saveCurrentLayouts, onDragStart: saveCurrentLayouts, onResize: onResize, onResizeStop: onResizeStop, children: layoutChildren })] }))));
|
|
132
121
|
}
|
|
133
122
|
VitessceGridLayout.defaultProps = {
|
|
134
123
|
padding: 10,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitessce/vit-s",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"author": "
|
|
3
|
+
"version": "3.5.0",
|
|
4
|
+
"author": "HIDIVE Lab at HMS",
|
|
5
5
|
"homepage": "http://vitessce.io",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -29,12 +29,12 @@
|
|
|
29
29
|
"uuid": "^9.0.0",
|
|
30
30
|
"zustand": "^3.5.10",
|
|
31
31
|
"react-aria": "^3.28.0",
|
|
32
|
-
"@vitessce/constants-internal": "3.
|
|
33
|
-
"@vitessce/plugins": "3.
|
|
34
|
-
"@vitessce/schemas": "3.
|
|
35
|
-
"@vitessce/utils": "3.
|
|
36
|
-
"@vitessce/sets-utils": "3.
|
|
37
|
-
"@vitessce/config": "3.
|
|
32
|
+
"@vitessce/constants-internal": "3.5.0",
|
|
33
|
+
"@vitessce/plugins": "3.5.0",
|
|
34
|
+
"@vitessce/schemas": "3.5.0",
|
|
35
|
+
"@vitessce/utils": "3.5.0",
|
|
36
|
+
"@vitessce/sets-utils": "3.5.0",
|
|
37
|
+
"@vitessce/config": "3.5.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@testing-library/jest-dom": "^5.16.4",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"react": "^18.0.0",
|
|
43
43
|
"vite": "^4.3.0",
|
|
44
44
|
"vitest": "^0.32.2",
|
|
45
|
-
"@vitessce/types": "3.
|
|
45
|
+
"@vitessce/types": "3.5.0"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
package/src/VitS.js
CHANGED
|
@@ -99,15 +99,6 @@ export function VitS(props) {
|
|
|
99
99
|
() => (coordinationTypesProp || []),
|
|
100
100
|
[coordinationTypesProp],
|
|
101
101
|
);
|
|
102
|
-
const asyncFunctions = useMemo(
|
|
103
|
-
() => Object.fromEntries(
|
|
104
|
-
// Convert the array of PluginAsyncFunction instances to a mapping
|
|
105
|
-
// from function type strings to async functions.
|
|
106
|
-
asyncFunctionsProp?.map(p => ([p.functionType, p.asyncFunction]))
|
|
107
|
-
|| [],
|
|
108
|
-
),
|
|
109
|
-
[asyncFunctionsProp],
|
|
110
|
-
);
|
|
111
102
|
|
|
112
103
|
const generateClassName = useMemo(() => createGenerateClassName(uid), [uid]);
|
|
113
104
|
|
|
@@ -196,8 +187,23 @@ export function VitS(props) {
|
|
|
196
187
|
retry: 2,
|
|
197
188
|
},
|
|
198
189
|
},
|
|
190
|
+
// TODO: should the queryClient be shared? Or have an option to be shared
|
|
191
|
+
// (e.g., based on remountOnUidChange)?
|
|
199
192
|
}), [configKey]);
|
|
200
193
|
|
|
194
|
+
const asyncFunctions = useMemo(
|
|
195
|
+
() => ({
|
|
196
|
+
queryClient,
|
|
197
|
+
asyncFunctions: Object.fromEntries(
|
|
198
|
+
// Convert the array of PluginAsyncFunction instances to a mapping
|
|
199
|
+
// from function type strings to async functions.
|
|
200
|
+
asyncFunctionsProp?.map(p => ([p.functionType, p.asyncFunction]))
|
|
201
|
+
|| [],
|
|
202
|
+
),
|
|
203
|
+
}),
|
|
204
|
+
[asyncFunctionsProp, queryClient],
|
|
205
|
+
);
|
|
206
|
+
|
|
201
207
|
// Emit the upgraded/initialized view config
|
|
202
208
|
// to onConfigChange if necessary.
|
|
203
209
|
useEffect(() => {
|
package/src/contexts.js
CHANGED
|
@@ -2,11 +2,39 @@
|
|
|
2
2
|
import { createContext, useContext } from 'react';
|
|
3
3
|
|
|
4
4
|
export const AsyncFunctionsContext = createContext({
|
|
5
|
-
//
|
|
5
|
+
// {
|
|
6
|
+
// asyncFunctions: { [functionType: string]: asyncFunction },
|
|
7
|
+
// queryClient: QueryClient from react-query
|
|
8
|
+
// }
|
|
9
|
+
// asyncFunctions will be an object where keys are function types
|
|
6
10
|
// (as strings) and values are the async functions.
|
|
7
11
|
});
|
|
8
12
|
|
|
9
13
|
export function useAsyncFunction(functionType) {
|
|
10
14
|
const context = useContext(AsyncFunctionsContext);
|
|
11
|
-
|
|
15
|
+
const origFunction = context?.asyncFunctions?.[functionType];
|
|
16
|
+
const queryClient = context?.queryClient;
|
|
17
|
+
// We use partial function application here, so that the caller
|
|
18
|
+
// does not need to worry about passing in the queryClient.
|
|
19
|
+
const partialFunction = (...args) => origFunction({ queryClient }, ...args);
|
|
20
|
+
return partialFunction;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const PageModeViewContext = createContext({
|
|
24
|
+
// Keys are view UIDs and values are
|
|
25
|
+
// the corresponding React components.
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
function ensureComponent(component) {
|
|
29
|
+
if (!component) {
|
|
30
|
+
return () => null;
|
|
31
|
+
}
|
|
32
|
+
return component;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function usePageModeView(uid) {
|
|
36
|
+
const context = useContext(PageModeViewContext);
|
|
37
|
+
// TODO: Is there any case where we would want to
|
|
38
|
+
// throw an error instead?
|
|
39
|
+
return ensureComponent(context?.[uid]);
|
|
12
40
|
}
|
package/src/hooks.js
CHANGED
|
@@ -221,28 +221,37 @@ export function useUint8ObsFeatureMatrix({ obsFeatureMatrix }) {
|
|
|
221
221
|
/**
|
|
222
222
|
* Normalize a feature selection (data for selected
|
|
223
223
|
* columns of an obsFeatureMatrix) to a Uint8Array.
|
|
224
|
-
* @param {
|
|
224
|
+
* @param {Float32Array[] | null} expressionData The expressionData
|
|
225
225
|
* returned by the useFeatureSelection hook,
|
|
226
226
|
* where each element corresponds to an
|
|
227
227
|
* array of values for a selected feature.
|
|
228
|
-
* @returns {
|
|
229
|
-
*
|
|
230
|
-
*
|
|
228
|
+
* @returns {{
|
|
229
|
+
* normData: Uint8Array[] | null,
|
|
230
|
+
* extents: [number, number][] | null,
|
|
231
|
+
* missing: number[]
|
|
232
|
+
* }} An object tuple {normData, extents, missing} where
|
|
233
|
+
* normData is an array of Uint8Arrays (or null),
|
|
234
|
+
* extents is an array of [min, max] values for each feature (or null), and
|
|
235
|
+
* missing is an array of numbers (between 0 and 1) for each feature (or null).
|
|
231
236
|
*/
|
|
232
237
|
export function useUint8FeatureSelection(expressionData) {
|
|
233
238
|
return useMemo(() => {
|
|
234
|
-
if (expressionData
|
|
235
|
-
|
|
236
|
-
const normData = expressionData.map((arr, i) => {
|
|
237
|
-
const [min, max] = extents[i];
|
|
238
|
-
const ratio = 255 / (max - min);
|
|
239
|
-
return new Uint8Array(
|
|
240
|
-
arr.map(j => Math.floor((j - min) * ratio)),
|
|
241
|
-
);
|
|
242
|
-
});
|
|
243
|
-
return [normData, extents];
|
|
239
|
+
if (expressionData?.[0] == null) {
|
|
240
|
+
return { normData: null, extents: null, missing: null };
|
|
244
241
|
}
|
|
245
|
-
|
|
242
|
+
const extents = expressionData.map(arr => extent(arr));
|
|
243
|
+
const normData = expressionData.map((arr, i) => {
|
|
244
|
+
const [min, max] = extents[i];
|
|
245
|
+
const ratio = 255 / (max - min);
|
|
246
|
+
return new Uint8Array(
|
|
247
|
+
arr.map(j => Math.floor((j - min) * ratio)),
|
|
248
|
+
);
|
|
249
|
+
});
|
|
250
|
+
const missing = expressionData.map((arr) => {
|
|
251
|
+
const numMissing = arr.reduce((prev, curr) => (Number.isNaN(curr) ? prev + 1 : prev), 0);
|
|
252
|
+
return numMissing / arr.length;
|
|
253
|
+
});
|
|
254
|
+
return { normData, extents, missing };
|
|
246
255
|
}, [expressionData]);
|
|
247
256
|
}
|
|
248
257
|
|
package/src/index.js
CHANGED
|
@@ -35,6 +35,8 @@ export {
|
|
|
35
35
|
useMatchingLoader,
|
|
36
36
|
useViewConfigStore,
|
|
37
37
|
useViewConfigStoreApi,
|
|
38
|
+
useViewConfig,
|
|
39
|
+
useSetViewConfig,
|
|
38
40
|
useComponentHover,
|
|
39
41
|
useSetComponentHover,
|
|
40
42
|
useComponentViewInfo,
|
|
@@ -105,4 +107,4 @@ export {
|
|
|
105
107
|
usePlotOptionsStyles,
|
|
106
108
|
} from './shared-plot-options/index.js';
|
|
107
109
|
export { logConfig } from './view-config-utils.js';
|
|
108
|
-
export { useAsyncFunction } from './contexts.js';
|
|
110
|
+
export { useAsyncFunction, usePageModeView } from './contexts.js';
|
package/src/state/hooks.js
CHANGED
|
@@ -1091,6 +1091,16 @@ export function useMergeCoordination() {
|
|
|
1091
1091
|
return useViewConfigStore(state => state.mergeCoordination);
|
|
1092
1092
|
}
|
|
1093
1093
|
|
|
1094
|
+
/**
|
|
1095
|
+
* Obtain the current view config object from
|
|
1096
|
+
* the global app state.
|
|
1097
|
+
* @returns {object} The view config object
|
|
1098
|
+
* in the `useViewConfigStore` store.
|
|
1099
|
+
*/
|
|
1100
|
+
export function useViewConfig() {
|
|
1101
|
+
return useViewConfigStore(state => state.viewConfig);
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1094
1104
|
/**
|
|
1095
1105
|
* Obtain the view config setter function from
|
|
1096
1106
|
* the global app state.
|
|
@@ -1103,6 +1113,7 @@ export function useSetViewConfig(viewConfigStoreApi) {
|
|
|
1103
1113
|
return setViewConfig;
|
|
1104
1114
|
}
|
|
1105
1115
|
|
|
1116
|
+
|
|
1106
1117
|
/**
|
|
1107
1118
|
* Obtain the component hover value from
|
|
1108
1119
|
* the global app state.
|
|
@@ -2,6 +2,7 @@ import React, { useState, useMemo, useCallback } from 'react';
|
|
|
2
2
|
import { Responsive, WidthProvider } from 'react-grid-layout-with-lodash';
|
|
3
3
|
import { isEqual } from 'lodash-es';
|
|
4
4
|
import { getMaxRows, resolveLayout } from './layout-utils.js';
|
|
5
|
+
import { PageModeViewContext } from '../contexts.js';
|
|
5
6
|
|
|
6
7
|
const ResponsiveGridLayout = WidthProvider(Responsive);
|
|
7
8
|
|
|
@@ -122,37 +123,28 @@ export function VitessceGridLayout(props) {
|
|
|
122
123
|
setLastValidGridLayouts(gridLayouts);
|
|
123
124
|
}, [gridLayouts]);
|
|
124
125
|
|
|
125
|
-
const layoutChildren = useMemo(() => {
|
|
126
|
+
const [layoutChildren, pageModeViews] = useMemo(() => {
|
|
126
127
|
const gridComponentsValues = Object.values(gridComponents);
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
coordinationScopes={v.coordinationScopes}
|
|
145
|
-
coordinationScopesBy={v.coordinationScopesBy}
|
|
146
|
-
theme={theme}
|
|
147
|
-
removeGridComponent={null}
|
|
148
|
-
/>
|
|
149
|
-
</div>
|
|
150
|
-
));
|
|
151
|
-
});
|
|
152
|
-
}
|
|
128
|
+
|
|
129
|
+
const contextValue = Object.fromEntries(gridComponentsValues.map((v) => {
|
|
130
|
+
const Component = getComponent(v.component);
|
|
131
|
+
return [v.uid, () => (
|
|
132
|
+
<div key={v.uid} style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
|
|
133
|
+
<Component
|
|
134
|
+
{... v.props}
|
|
135
|
+
uuid={v.uid}
|
|
136
|
+
coordinationScopes={v.coordinationScopes}
|
|
137
|
+
coordinationScopesBy={v.coordinationScopesBy}
|
|
138
|
+
theme={theme}
|
|
139
|
+
removeGridComponent={null}
|
|
140
|
+
/>
|
|
141
|
+
</div>
|
|
142
|
+
)];
|
|
143
|
+
}));
|
|
144
|
+
|
|
153
145
|
// Not pageMode, so no children to render.
|
|
154
146
|
// We render the grid components based on the layout information.
|
|
155
|
-
return gridComponentsValues.map((v) => {
|
|
147
|
+
return [gridComponentsValues.map((v) => {
|
|
156
148
|
const Component = getComponent(v.component);
|
|
157
149
|
const removeGridComponent = () => {
|
|
158
150
|
onRemoveComponent(v.uid);
|
|
@@ -169,12 +161,15 @@ export function VitessceGridLayout(props) {
|
|
|
169
161
|
/>
|
|
170
162
|
</div>
|
|
171
163
|
);
|
|
172
|
-
});
|
|
164
|
+
}), contextValue];
|
|
173
165
|
}, [gridComponents, getComponent, onRemoveComponent, theme]);
|
|
174
166
|
|
|
175
167
|
return (pageMode
|
|
176
|
-
?
|
|
177
|
-
|
|
168
|
+
? (
|
|
169
|
+
<PageModeViewContext.Provider value={pageModeViews}>
|
|
170
|
+
{children}
|
|
171
|
+
</PageModeViewContext.Provider>
|
|
172
|
+
) : ((gridLayouts && gridComponents && gridBreakpoints && gridCols) && (
|
|
178
173
|
<>
|
|
179
174
|
{style}
|
|
180
175
|
<ResponsiveHeightGridLayout
|