@vitessce/vit-s 3.8.4 → 3.8.6
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/blosc-B8fjEpk7.js +888 -0
- package/dist/chunk-INHXZS53-DHVJiuU3.js +19 -0
- package/dist/index.js +3856 -1115
- package/dist/lz4-C9lm_i9S.js +805 -0
- package/dist/zstd-y75FARxZ.js +775 -0
- package/dist-tsc/Sidebar.d.ts +2 -0
- package/dist-tsc/Sidebar.d.ts.map +1 -0
- package/dist-tsc/Sidebar.js +32 -0
- package/dist-tsc/VitS.d.ts.map +1 -1
- package/dist-tsc/VitS.js +8 -0
- package/dist-tsc/VitessceGrid.js +1 -1
- package/dist-tsc/hooks.d.ts +1 -1
- package/dist-tsc/hooks.d.ts.map +1 -1
- package/dist-tsc/hooks.js +2 -2
- package/dist-tsc/index.d.ts +1 -0
- package/dist-tsc/index.js +1 -0
- package/dist-tsc/on-drop.d.ts +16 -0
- package/dist-tsc/on-drop.d.ts.map +1 -0
- package/dist-tsc/on-drop.js +180 -0
- package/package.json +14 -12
- package/src/Sidebar.js +80 -0
- package/src/VitS.js +9 -0
- package/src/VitessceGrid.js +1 -1
- package/src/hooks.js +2 -2
- package/src/index.js +1 -0
- package/src/on-drop.js +197 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Sidebar.d.ts","sourceRoot":"","sources":["../src/Sidebar.js"],"names":[],"mappings":"AAgCA,iDA+CC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React, { useCallback } from 'react';
|
|
3
|
+
import { makeStyles, IconButton, Code as CodeIcon, InvertColors as InvertColorsIcon, } from '@vitessce/styles';
|
|
4
|
+
const useStyles = makeStyles()(() => ({
|
|
5
|
+
sidebarContainer: {
|
|
6
|
+
backgroundColor: 'silver',
|
|
7
|
+
width: '30px',
|
|
8
|
+
height: '100%',
|
|
9
|
+
},
|
|
10
|
+
sidebarUl: {
|
|
11
|
+
listStyleType: 'none',
|
|
12
|
+
margin: 0,
|
|
13
|
+
padding: 0,
|
|
14
|
+
},
|
|
15
|
+
sidebarLi: {},
|
|
16
|
+
sidebarIconButton: {
|
|
17
|
+
padding: '3px',
|
|
18
|
+
},
|
|
19
|
+
sidebarIcon: {
|
|
20
|
+
color: 'black',
|
|
21
|
+
width: '24px',
|
|
22
|
+
height: '24px',
|
|
23
|
+
},
|
|
24
|
+
}));
|
|
25
|
+
export function Sidebar(props) {
|
|
26
|
+
const { theme, setTheme, configEditable, themeEditable, } = props;
|
|
27
|
+
const { classes } = useStyles();
|
|
28
|
+
const onToggleTheme = useCallback(() => {
|
|
29
|
+
setTheme(theme === 'dark' ? 'light2' : 'dark');
|
|
30
|
+
}, [theme]);
|
|
31
|
+
return (_jsx("div", { className: classes.sidebarContainer, children: _jsxs("ul", { className: classes.sidebarUl, children: [themeEditable ? (_jsx("li", { className: classes.sidebarLi, children: _jsx(IconButton, { alt: "Change theme", onClick: onToggleTheme, "aria-label": "Change theme", className: classes.sidebarIconButton, children: _jsx(InvertColorsIcon, { className: classes.sidebarIcon }) }) })) : null, configEditable ? (_jsx("li", { className: classes.sidebarLi, children: _jsx(IconButton, { alt: "Edit configuration", onClick: () => { }, "aria-label": "Edit configuration", className: classes.sidebarIconButton, children: _jsx(CodeIcon, { className: classes.sidebarIcon }) }) })) : null] }) }));
|
|
32
|
+
}
|
package/dist-tsc/VitS.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VitS.d.ts","sourceRoot":"","sources":["../src/VitS.js"],"names":[],"mappings":"AAqCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,4BApCG;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;IAGW,cAAc,EAApC,SAAS,GAAC,IAAI;IAEC,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;IACQ,SAAS,EAAxB,OAAO;IACY,QAAQ,EAA3B,IAAI,GAAC,MAAM;CAErB,
|
|
1
|
+
{"version":3,"file":"VitS.d.ts","sourceRoot":"","sources":["../src/VitS.js"],"names":[],"mappings":"AAqCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,4BApCG;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;IAGW,cAAc,EAApC,SAAS,GAAC,IAAI;IAEC,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;IACQ,SAAS,EAAxB,OAAO;IACY,QAAQ,EAA3B,IAAI,GAAC,MAAM;CAErB,eAmQA"}
|
package/dist-tsc/VitS.js
CHANGED
|
@@ -55,6 +55,14 @@ import { AsyncFunctionsContext } from './contexts.js';
|
|
|
55
55
|
*/
|
|
56
56
|
export function VitS(props) {
|
|
57
57
|
const { config, stores, rowHeight, height, theme, onWarn, onConfigChange, onLoaderChange, validateConfig = true, validateOnConfigChange = false, isBounded = false, uid = null, styleContainer, remountOnUidChange = true, viewTypes: viewTypesProp, fileTypes: fileTypesProp, jointFileTypes: jointFileTypesProp, coordinationTypes: coordinationTypesProp, asyncFunctions: asyncFunctionsProp, warning, pageMode = false, children, debugMode = DEFAULT_DEBUG_MODE, logLevel = DEFAULT_LOG_LEVEL, } = props;
|
|
58
|
+
/*
|
|
59
|
+
const prefersDark = (
|
|
60
|
+
window.matchMedia
|
|
61
|
+
&& window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
62
|
+
);
|
|
63
|
+
const defaultTheme = prefersDark ? 'dark' : 'light';
|
|
64
|
+
const [theme, setTheme] = useState(themeProp ?? defaultTheme);
|
|
65
|
+
*/
|
|
58
66
|
// eslint-disable-next-line no-unused-vars
|
|
59
67
|
const [debugErrors, setDebugErrors] = useState([]);
|
|
60
68
|
const viewTypes = useMemo(() => (viewTypesProp || []), [viewTypesProp]);
|
package/dist-tsc/VitessceGrid.js
CHANGED
|
@@ -28,7 +28,7 @@ export default function VitessceGrid(props) {
|
|
|
28
28
|
const { success, configKey, rowHeight: initialRowHeight, config, theme, height, isBounded, viewTypes, fileTypes, coordinationTypes, stores, pageMode, children, } = props;
|
|
29
29
|
const [rowHeight, containerRef] = useRowHeight(config, initialRowHeight, height, margin, padding);
|
|
30
30
|
const onResize = useEmitGridResize();
|
|
31
|
-
const [componentWidth] = useClosestVitessceContainerSize(containerRef);
|
|
31
|
+
const [componentWidth] = useClosestVitessceContainerSize(containerRef, 0);
|
|
32
32
|
const { classes } = useVitessceContainerStyles();
|
|
33
33
|
const { classes: titleClasses } = useTitleStyles();
|
|
34
34
|
const altText = useMemo(() => getAltText(config), [configKey]);
|
package/dist-tsc/hooks.d.ts
CHANGED
|
@@ -39,7 +39,7 @@ export function useUrls(urls: (null | object[])[]): array;
|
|
|
39
39
|
* @returns {array} `[width, height]` where width and height
|
|
40
40
|
* are numbers.
|
|
41
41
|
*/
|
|
42
|
-
export function useClosestVitessceContainerSize(ref: Ref): array;
|
|
42
|
+
export function useClosestVitessceContainerSize(ref: Ref, sidebarWidth: any): array;
|
|
43
43
|
/**
|
|
44
44
|
* Normalize an obsFeatureMatrix to a Uint8Array.
|
|
45
45
|
* @param {object} params
|
package/dist-tsc/hooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.js"],"names":[],"mappings":"AAqBA,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,
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.js"],"names":[],"mappings":"AAqBA,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,sBACD,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;AAED;;;;;;;;;;GAUG;AACH,yDALW,MAAM,oBACN,gBAAI,IAAI,iBAEN;IAAE,kBAAkB,EAAE,OAAO,CAAA;CAAE,GAAC,IAAI,CAkChD;AAED;;;;;;;GAOG;AACH,6CALW,GAAC,YACD,CAAC,OAAO,CAAC,GAEP,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA8BlC"}
|
package/dist-tsc/hooks.js
CHANGED
|
@@ -141,14 +141,14 @@ export function useUrls(urls) {
|
|
|
141
141
|
* @returns {array} `[width, height]` where width and height
|
|
142
142
|
* are numbers.
|
|
143
143
|
*/
|
|
144
|
-
export function useClosestVitessceContainerSize(ref) {
|
|
144
|
+
export function useClosestVitessceContainerSize(ref, sidebarWidth) {
|
|
145
145
|
const [height, setHeight] = useState();
|
|
146
146
|
const [width, setWidth] = useState();
|
|
147
147
|
useEffect(() => {
|
|
148
148
|
function onWindowResize() {
|
|
149
149
|
if (ref.current) {
|
|
150
150
|
const { clientHeight: componentHeight, clientWidth: componentWidth, } = ref.current.closest(`.${VITESSCE_CONTAINER}`);
|
|
151
|
-
setWidth(componentWidth);
|
|
151
|
+
setWidth(componentWidth - sidebarWidth);
|
|
152
152
|
setHeight(componentHeight);
|
|
153
153
|
}
|
|
154
154
|
}
|
package/dist-tsc/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export { PopperMenu } from "./shared-mui/components.js";
|
|
|
5
5
|
export { useHasLoader } from "./data-hook-utils.js";
|
|
6
6
|
export { logConfig } from "./view-config-utils.js";
|
|
7
7
|
export { createLoaders } from "./vitessce-grid-utils.js";
|
|
8
|
+
export { createOnDrop } from "./on-drop.js";
|
|
8
9
|
export { useReady, useUrls, useVitessceContainer, useDeckCanvasSize, useUint8ObsFeatureMatrix, useUint8FeatureSelection, useExpressionValueGetter, useGetObsMembership, useGetObsInfo, useClosestVitessceContainerSize, useWindowDimensions, useGridItemSize, useExpandedFeatureLabelsMap, useColumnNameMapping } from "./hooks.js";
|
|
9
10
|
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";
|
|
10
11
|
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, useComparisonMetadata, useFeatureStatsData, useFeatureSetStatsData, useObsSetStatsData } from "./data-hooks.js";
|
package/dist-tsc/index.js
CHANGED
|
@@ -12,3 +12,4 @@ export { CellColorEncodingOption, OptionsContainer, OptionSelect, usePlotOptions
|
|
|
12
12
|
export { logConfig } from './view-config-utils.js';
|
|
13
13
|
export { useAsyncFunction, usePageModeView } from './contexts.js';
|
|
14
14
|
export { createLoaders } from './vitessce-grid-utils.js';
|
|
15
|
+
export { createOnDrop } from './on-drop.js';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create an event handler for either dropzone or input type="file" elements.
|
|
3
|
+
* @param {object} setters - The parameters for the drop event handler.
|
|
4
|
+
* @param {function} setters.setViewConfig - A function to set the view config.
|
|
5
|
+
* @param {function} setters.setStores - A function to set the stores.
|
|
6
|
+
* @param {boolean} isFileInput - Whether the drop zone is for file input.
|
|
7
|
+
* By default, false.
|
|
8
|
+
* @param {boolean} isConfigInput - Whether the drop zone is for config input.
|
|
9
|
+
* By default, false.
|
|
10
|
+
* @returns A drop event handler async function.
|
|
11
|
+
*/
|
|
12
|
+
export function createOnDrop(setters: {
|
|
13
|
+
setViewConfig: Function;
|
|
14
|
+
setStores: Function;
|
|
15
|
+
}, isFileInput?: boolean, isConfigInput?: boolean): (e: any) => Promise<void>;
|
|
16
|
+
//# sourceMappingURL=on-drop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"on-drop.d.ts","sourceRoot":"","sources":["../src/on-drop.js"],"names":[],"mappings":"AAoEA;;;;;;;;;;GAUG;AACH,sCARG;IAA0B,aAAa;IACb,SAAS;CACnC,gBAAQ,OAAO,kBAEP,OAAO,6BAyHjB"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { getFilesFromDataTransferItems } from '@placemarkio/flat-drop-files';
|
|
2
|
+
import { generateConfigAlt as generateConfig, parseUrlsFromString } from '@vitessce/config';
|
|
3
|
+
// Stores
|
|
4
|
+
// This "flat" store can be slow to initialize when the Zarr store contains many files.
|
|
5
|
+
class FlatFileSystemStore {
|
|
6
|
+
constructor(files) {
|
|
7
|
+
this.files = files;
|
|
8
|
+
}
|
|
9
|
+
async get(key) {
|
|
10
|
+
// The list of files does not prefix its paths with slashes.
|
|
11
|
+
const file = this.files.find(f => `/${f.relpath}` === key);
|
|
12
|
+
if (!file)
|
|
13
|
+
return undefined;
|
|
14
|
+
const buffer = await file.arrayBuffer();
|
|
15
|
+
return new Uint8Array(buffer);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/*
|
|
19
|
+
// Get a file handle to a file in a directory.
|
|
20
|
+
async function resolveFileHandleForPath(
|
|
21
|
+
root, // A root directory from the Web File System API.
|
|
22
|
+
path, // A key to a file in the root directory.
|
|
23
|
+
) {
|
|
24
|
+
const dirs = path.split('/');
|
|
25
|
+
const fname = dirs.pop();
|
|
26
|
+
if (!fname) {
|
|
27
|
+
throw new Error('Invalid path');
|
|
28
|
+
}
|
|
29
|
+
for (const dir of dirs) {
|
|
30
|
+
root = await root.getDirectoryHandle(dir);
|
|
31
|
+
}
|
|
32
|
+
// Returns a file handle to the file.
|
|
33
|
+
return root.getFileHandle(fname);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// TODO: use this hierarchical store to avoid the issues with flattening the file tree up-front,
|
|
37
|
+
// as this store only traverses/accesses the parts of the tree that are needed.
|
|
38
|
+
class HierarchicalFileSystemStore {
|
|
39
|
+
constructor(root) {
|
|
40
|
+
// root is a FileSystemDirectoryHandle
|
|
41
|
+
this.root = root;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async get(key) {
|
|
45
|
+
// TODO: better error handling
|
|
46
|
+
// I believe a missing file will trigger an error here, which we should explicitly
|
|
47
|
+
// catch and return `undefined`
|
|
48
|
+
const fh = await resolveFileHandleForPath(this.root, key.slice(1)).catch(
|
|
49
|
+
() => undefined,
|
|
50
|
+
);
|
|
51
|
+
if (!fh) {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const file = await fh.getFile();
|
|
56
|
+
return file.arrayBuffer();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// TODO: implement getRange
|
|
60
|
+
}
|
|
61
|
+
*/
|
|
62
|
+
/**
|
|
63
|
+
* Create an event handler for either dropzone or input type="file" elements.
|
|
64
|
+
* @param {object} setters - The parameters for the drop event handler.
|
|
65
|
+
* @param {function} setters.setViewConfig - A function to set the view config.
|
|
66
|
+
* @param {function} setters.setStores - A function to set the stores.
|
|
67
|
+
* @param {boolean} isFileInput - Whether the drop zone is for file input.
|
|
68
|
+
* By default, false.
|
|
69
|
+
* @param {boolean} isConfigInput - Whether the drop zone is for config input.
|
|
70
|
+
* By default, false.
|
|
71
|
+
* @returns A drop event handler async function.
|
|
72
|
+
*/
|
|
73
|
+
export function createOnDrop(setters, isFileInput = false, isConfigInput = false) {
|
|
74
|
+
return async (e) => {
|
|
75
|
+
const { setViewConfig, setStores } = setters;
|
|
76
|
+
let topLevelEntries;
|
|
77
|
+
let files;
|
|
78
|
+
if (isFileInput) {
|
|
79
|
+
// Reference: https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/File_drag_and_drop
|
|
80
|
+
// Note: e.target.files is a FileList, not an array.
|
|
81
|
+
// If we use the spread operator, the methods like file.arrayBuffer() get lost.
|
|
82
|
+
files = Array.from(e.target.files);
|
|
83
|
+
// Here, we use files.forEach rather than files = files.map
|
|
84
|
+
// so that we can modify the original array in place.
|
|
85
|
+
files.forEach((f, i) => {
|
|
86
|
+
if (!f.path) {
|
|
87
|
+
// eslint-disable-next-line no-param-reassign
|
|
88
|
+
files[i].path = files[i].webkitRelativePath;
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
// When a user selects a directory via a file picker dialog,
|
|
92
|
+
// we get only a flat list of files.
|
|
93
|
+
// In order to match e.dataTransfer.items behavior,
|
|
94
|
+
// we create fake top-level entries for each unique directory/file name.
|
|
95
|
+
const dirNames = new Set();
|
|
96
|
+
topLevelEntries = [];
|
|
97
|
+
Array.from(files).forEach((file) => {
|
|
98
|
+
const dirName = file.path.split('/')[0];
|
|
99
|
+
if (dirName) {
|
|
100
|
+
dirNames.add(dirName);
|
|
101
|
+
}
|
|
102
|
+
// If the file is at the top level (no directory),
|
|
103
|
+
// we need to add a top-level entry for it.
|
|
104
|
+
if (dirName === file.name) {
|
|
105
|
+
topLevelEntries.push({
|
|
106
|
+
isDirectory: false,
|
|
107
|
+
name: file.name,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
topLevelEntries = topLevelEntries.concat(Array.from(dirNames).map(name => ({
|
|
112
|
+
isDirectory: true,
|
|
113
|
+
name,
|
|
114
|
+
})));
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
topLevelEntries = Object.values(e.dataTransfer.items)
|
|
118
|
+
.map(item => item.webkitGetAsEntry());
|
|
119
|
+
files = await getFilesFromDataTransferItems(e.dataTransfer.items);
|
|
120
|
+
}
|
|
121
|
+
if (isConfigInput) {
|
|
122
|
+
// We expect a single file which contains the config JSON.
|
|
123
|
+
if (files.length === 1) {
|
|
124
|
+
const file = files[0];
|
|
125
|
+
if (file.name.endsWith('.json')) {
|
|
126
|
+
const content = await file.arrayBuffer();
|
|
127
|
+
// Alternatively, use the FileReader API.
|
|
128
|
+
const json = JSON.parse(new TextDecoder().decode(content));
|
|
129
|
+
setViewConfig(json);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// TODO: implement an alternative approach that does not first flatten the file tree,
|
|
135
|
+
// since it can be very large.
|
|
136
|
+
// See https://github.com/manzt/zarrita.js/pull/161/files
|
|
137
|
+
const stores = topLevelEntries.map((entry) => {
|
|
138
|
+
if (entry.isDirectory) {
|
|
139
|
+
// TODO: optimize by using a single loop for filter+map,
|
|
140
|
+
// and by using .substring (rather than split+slice+join).
|
|
141
|
+
const dirFiles = files
|
|
142
|
+
.filter(f => f.path.split('/')?.[0] === entry.name)
|
|
143
|
+
.map((f) => {
|
|
144
|
+
// eslint-disable-next-line no-param-reassign
|
|
145
|
+
f.relpath = f.path.split('/')?.slice(1).join('/');
|
|
146
|
+
return f;
|
|
147
|
+
});
|
|
148
|
+
// Create a store for each top-level item of e.dataTransfer.items.
|
|
149
|
+
const store = new FlatFileSystemStore(dirFiles);
|
|
150
|
+
return [entry.name, store];
|
|
151
|
+
}
|
|
152
|
+
// This is a single file. Check extension to determine how to create a store.
|
|
153
|
+
if (entry.name.endsWith('.zip')) {
|
|
154
|
+
// Create a zip store.
|
|
155
|
+
// TODO
|
|
156
|
+
}
|
|
157
|
+
else if (entry.name.endsWith('.tif') || entry.name.endsWith('.tiff')) {
|
|
158
|
+
// Create an OME-TIFF-as-NGFF store?
|
|
159
|
+
// TODO
|
|
160
|
+
}
|
|
161
|
+
else if (entry.name.endsWith('.csv')) {
|
|
162
|
+
// Create a CSV store?
|
|
163
|
+
// TODO
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
// Throw?
|
|
167
|
+
// TODO
|
|
168
|
+
}
|
|
169
|
+
return [entry.name, null];
|
|
170
|
+
});
|
|
171
|
+
const parsedUrls = stores.map(([name, store]) => ({
|
|
172
|
+
...parseUrlsFromString(name)[0],
|
|
173
|
+
store,
|
|
174
|
+
}));
|
|
175
|
+
const { config, stores: storesForConfig } = await generateConfig(parsedUrls);
|
|
176
|
+
const newConfig = config.toJSON();
|
|
177
|
+
setViewConfig(newConfig);
|
|
178
|
+
setStores(storesForConfig);
|
|
179
|
+
};
|
|
180
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitessce/vit-s",
|
|
3
|
-
"version": "3.8.
|
|
3
|
+
"version": "3.8.6",
|
|
4
4
|
"author": "HIDIVE Lab at HMS",
|
|
5
5
|
"homepage": "http://vitessce.io",
|
|
6
6
|
"repository": {
|
|
@@ -28,16 +28,18 @@
|
|
|
28
28
|
"zustand": "^5.0.4",
|
|
29
29
|
"react-aria": "^3.28.0",
|
|
30
30
|
"react-error-boundary": "^5.0.0",
|
|
31
|
-
"@
|
|
32
|
-
"
|
|
33
|
-
"@vitessce/
|
|
34
|
-
"@vitessce/
|
|
35
|
-
"@vitessce/
|
|
36
|
-
"@vitessce/
|
|
37
|
-
"@vitessce/
|
|
38
|
-
"@vitessce/
|
|
39
|
-
"@vitessce/
|
|
40
|
-
"@vitessce/
|
|
31
|
+
"@placemarkio/flat-drop-files": "^1.0.2",
|
|
32
|
+
"zarrita": "0.5.4",
|
|
33
|
+
"@vitessce/styles": "3.8.6",
|
|
34
|
+
"@vitessce/abstract": "3.8.6",
|
|
35
|
+
"@vitessce/error": "3.8.6",
|
|
36
|
+
"@vitessce/constants-internal": "3.8.6",
|
|
37
|
+
"@vitessce/plugins": "3.8.6",
|
|
38
|
+
"@vitessce/schemas": "3.8.6",
|
|
39
|
+
"@vitessce/sets-utils": "3.8.6",
|
|
40
|
+
"@vitessce/utils": "3.8.6",
|
|
41
|
+
"@vitessce/config": "3.8.6",
|
|
42
|
+
"@vitessce/globals": "3.8.6"
|
|
41
43
|
},
|
|
42
44
|
"devDependencies": {
|
|
43
45
|
"@testing-library/jest-dom": "^6.6.3",
|
|
@@ -46,7 +48,7 @@
|
|
|
46
48
|
"react-dom": "18.3.1",
|
|
47
49
|
"vite": "^7.0.0",
|
|
48
50
|
"vitest": "^3.1.4",
|
|
49
|
-
"@vitessce/types": "3.8.
|
|
51
|
+
"@vitessce/types": "3.8.6"
|
|
50
52
|
},
|
|
51
53
|
"peerDependencies": {
|
|
52
54
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
package/src/Sidebar.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
makeStyles,
|
|
4
|
+
IconButton,
|
|
5
|
+
Code as CodeIcon,
|
|
6
|
+
InvertColors as InvertColorsIcon,
|
|
7
|
+
} from '@vitessce/styles';
|
|
8
|
+
|
|
9
|
+
const useStyles = makeStyles()(() => ({
|
|
10
|
+
sidebarContainer: {
|
|
11
|
+
backgroundColor: 'silver',
|
|
12
|
+
width: '30px',
|
|
13
|
+
height: '100%',
|
|
14
|
+
},
|
|
15
|
+
sidebarUl: {
|
|
16
|
+
listStyleType: 'none',
|
|
17
|
+
margin: 0,
|
|
18
|
+
padding: 0,
|
|
19
|
+
},
|
|
20
|
+
sidebarLi: {
|
|
21
|
+
|
|
22
|
+
},
|
|
23
|
+
sidebarIconButton: {
|
|
24
|
+
padding: '3px',
|
|
25
|
+
},
|
|
26
|
+
sidebarIcon: {
|
|
27
|
+
color: 'black',
|
|
28
|
+
width: '24px',
|
|
29
|
+
height: '24px',
|
|
30
|
+
},
|
|
31
|
+
}));
|
|
32
|
+
|
|
33
|
+
export function Sidebar(props) {
|
|
34
|
+
const {
|
|
35
|
+
theme,
|
|
36
|
+
setTheme,
|
|
37
|
+
configEditable,
|
|
38
|
+
themeEditable,
|
|
39
|
+
} = props;
|
|
40
|
+
const { classes } = useStyles();
|
|
41
|
+
|
|
42
|
+
const onToggleTheme = useCallback(() => {
|
|
43
|
+
setTheme(theme === 'dark' ? 'light2' : 'dark');
|
|
44
|
+
}, [theme]);
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<div className={classes.sidebarContainer}>
|
|
48
|
+
<ul className={classes.sidebarUl}>
|
|
49
|
+
{themeEditable ? (
|
|
50
|
+
<li className={classes.sidebarLi}>
|
|
51
|
+
<IconButton
|
|
52
|
+
alt="Change theme"
|
|
53
|
+
onClick={onToggleTheme}
|
|
54
|
+
aria-label="Change theme"
|
|
55
|
+
className={classes.sidebarIconButton}
|
|
56
|
+
>
|
|
57
|
+
<InvertColorsIcon
|
|
58
|
+
className={classes.sidebarIcon}
|
|
59
|
+
/>
|
|
60
|
+
</IconButton>
|
|
61
|
+
</li>
|
|
62
|
+
) : null}
|
|
63
|
+
{configEditable ? (
|
|
64
|
+
<li className={classes.sidebarLi}>
|
|
65
|
+
<IconButton
|
|
66
|
+
alt="Edit configuration"
|
|
67
|
+
onClick={() => {}}
|
|
68
|
+
aria-label="Edit configuration"
|
|
69
|
+
className={classes.sidebarIconButton}
|
|
70
|
+
>
|
|
71
|
+
<CodeIcon
|
|
72
|
+
className={classes.sidebarIcon}
|
|
73
|
+
/>
|
|
74
|
+
</IconButton>
|
|
75
|
+
</li>
|
|
76
|
+
) : null}
|
|
77
|
+
</ul>
|
|
78
|
+
</div>
|
|
79
|
+
);
|
|
80
|
+
}
|
package/src/VitS.js
CHANGED
|
@@ -102,6 +102,15 @@ export function VitS(props) {
|
|
|
102
102
|
logLevel = DEFAULT_LOG_LEVEL,
|
|
103
103
|
} = props;
|
|
104
104
|
|
|
105
|
+
/*
|
|
106
|
+
const prefersDark = (
|
|
107
|
+
window.matchMedia
|
|
108
|
+
&& window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
109
|
+
);
|
|
110
|
+
const defaultTheme = prefersDark ? 'dark' : 'light';
|
|
111
|
+
const [theme, setTheme] = useState(themeProp ?? defaultTheme);
|
|
112
|
+
*/
|
|
113
|
+
|
|
105
114
|
// eslint-disable-next-line no-unused-vars
|
|
106
115
|
const [debugErrors, setDebugErrors] = useState([]);
|
|
107
116
|
const viewTypes = useMemo(() => (viewTypesProp || []), [viewTypesProp]);
|
package/src/VitessceGrid.js
CHANGED
|
@@ -62,7 +62,7 @@ export default function VitessceGrid(props) {
|
|
|
62
62
|
const [rowHeight, containerRef] = useRowHeight(config, initialRowHeight, height, margin, padding);
|
|
63
63
|
const onResize = useEmitGridResize();
|
|
64
64
|
|
|
65
|
-
const [componentWidth] = useClosestVitessceContainerSize(containerRef);
|
|
65
|
+
const [componentWidth] = useClosestVitessceContainerSize(containerRef, 0);
|
|
66
66
|
|
|
67
67
|
const { classes } = useVitessceContainerStyles();
|
|
68
68
|
const { classes: titleClasses } = useTitleStyles();
|
package/src/hooks.js
CHANGED
|
@@ -170,7 +170,7 @@ export function useUrls(urls) {
|
|
|
170
170
|
* @returns {array} `[width, height]` where width and height
|
|
171
171
|
* are numbers.
|
|
172
172
|
*/
|
|
173
|
-
export function useClosestVitessceContainerSize(ref) {
|
|
173
|
+
export function useClosestVitessceContainerSize(ref, sidebarWidth) {
|
|
174
174
|
const [height, setHeight] = useState();
|
|
175
175
|
const [width, setWidth] = useState();
|
|
176
176
|
|
|
@@ -180,7 +180,7 @@ export function useClosestVitessceContainerSize(ref) {
|
|
|
180
180
|
const {
|
|
181
181
|
clientHeight: componentHeight, clientWidth: componentWidth,
|
|
182
182
|
} = ref.current.closest(`.${VITESSCE_CONTAINER}`);
|
|
183
|
-
setWidth(componentWidth);
|
|
183
|
+
setWidth(componentWidth - sidebarWidth);
|
|
184
184
|
setHeight(componentHeight);
|
|
185
185
|
}
|
|
186
186
|
}
|
package/src/index.js
CHANGED