@vitessce/vit-s 3.5.12 → 3.6.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 (68) hide show
  1. package/dist/index.js +29645 -26007
  2. package/dist-tsc/CallbackPublisher.d.ts.map +1 -1
  3. package/dist-tsc/CallbackPublisher.js +4 -4
  4. package/dist-tsc/DebugWindow.d.ts +1 -1
  5. package/dist-tsc/DebugWindow.d.ts.map +1 -1
  6. package/dist-tsc/DebugWindow.js +1 -1
  7. package/dist-tsc/LoadingIndicator.js +3 -3
  8. package/dist-tsc/TitleInfo.d.ts.map +1 -1
  9. package/dist-tsc/TitleInfo.js +8 -9
  10. package/dist-tsc/VitS.d.ts +3 -0
  11. package/dist-tsc/VitS.d.ts.map +1 -1
  12. package/dist-tsc/VitS.js +11 -6
  13. package/dist-tsc/VitessceGrid.d.ts.map +1 -1
  14. package/dist-tsc/VitessceGrid.js +5 -5
  15. package/dist-tsc/VitessceGrid.test.js +2 -6
  16. package/dist-tsc/Warning.d.ts +1 -1
  17. package/dist-tsc/Warning.d.ts.map +1 -1
  18. package/dist-tsc/Warning.js +1 -1
  19. package/dist-tsc/mui-utils.d.ts.map +1 -1
  20. package/dist-tsc/mui-utils.js +2 -0
  21. package/dist-tsc/shared-mui/components.d.ts.map +1 -1
  22. package/dist-tsc/shared-mui/components.js +5 -5
  23. package/dist-tsc/shared-mui/container.d.ts +10 -1
  24. package/dist-tsc/shared-mui/container.d.ts.map +1 -1
  25. package/dist-tsc/shared-mui/container.js +199 -190
  26. package/dist-tsc/shared-mui/styles.d.ts +3 -3
  27. package/dist-tsc/shared-mui/styles.js +9 -6
  28. package/dist-tsc/shared-plot-options/CellColorEncodingOption.js +2 -2
  29. package/dist-tsc/shared-plot-options/OptionSelect.d.ts.map +1 -1
  30. package/dist-tsc/shared-plot-options/OptionSelect.js +3 -3
  31. package/dist-tsc/shared-plot-options/OptionsContainer.js +2 -2
  32. package/dist-tsc/shared-plot-options/styles.d.ts +9 -1
  33. package/dist-tsc/shared-plot-options/styles.d.ts.map +1 -1
  34. package/dist-tsc/shared-plot-options/styles.js +4 -3
  35. package/dist-tsc/shared-warning-styles.d.ts +9 -1
  36. package/dist-tsc/shared-warning-styles.d.ts.map +1 -1
  37. package/dist-tsc/shared-warning-styles.js +2 -2
  38. package/dist-tsc/state/hooks.d.ts +8 -18
  39. package/dist-tsc/state/hooks.d.ts.map +1 -1
  40. package/dist-tsc/state/hooks.js +92 -36
  41. package/dist-tsc/title-styles.d.ts +9 -1
  42. package/dist-tsc/title-styles.d.ts.map +1 -1
  43. package/dist-tsc/title-styles.js +2 -2
  44. package/dist-tsc/vitessce-grid-layout/VitessceGridLayout.d.ts +0 -6
  45. package/dist-tsc/vitessce-grid-layout/VitessceGridLayout.js +1 -5
  46. package/dist-tsc/vitessce-grid-layout/VitessceGridLayout.test.js +2 -6
  47. package/package.json +19 -19
  48. package/src/CallbackPublisher.js +4 -3
  49. package/src/DebugWindow.js +1 -1
  50. package/src/LoadingIndicator.js +3 -3
  51. package/src/TitleInfo.js +9 -10
  52. package/src/VitS.js +19 -11
  53. package/src/VitessceGrid.js +7 -3
  54. package/src/VitessceGrid.test.jsx +3 -8
  55. package/src/Warning.js +1 -1
  56. package/src/mui-utils.js +2 -0
  57. package/src/shared-mui/components.js +11 -8
  58. package/src/shared-mui/container.js +206 -190
  59. package/src/shared-mui/styles.js +9 -7
  60. package/src/shared-plot-options/CellColorEncodingOption.js +2 -2
  61. package/src/shared-plot-options/OptionSelect.js +3 -4
  62. package/src/shared-plot-options/OptionsContainer.js +2 -2
  63. package/src/shared-plot-options/styles.js +4 -3
  64. package/src/shared-warning-styles.js +2 -2
  65. package/src/state/hooks.js +119 -43
  66. package/src/title-styles.js +2 -2
  67. package/src/vitessce-grid-layout/VitessceGridLayout.js +1 -6
  68. package/src/vitessce-grid-layout/VitessceGridLayout.test.jsx +2 -7
@@ -1,23 +1,79 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
1
2
  /* eslint-disable max-len */
2
3
  /* eslint-disable react-refresh/only-export-components */
3
- import { useRef, useCallback, useMemo } from 'react';
4
- import create from 'zustand';
5
- import createContext from 'zustand/context';
6
- import shallow from 'zustand/shallow';
4
+ import React, { useCallback, useRef, useMemo, createContext, useContext, } from 'react';
5
+ import { create, useStore } from 'zustand';
6
+ import { useShallow } from 'zustand/shallow';
7
+ import { subscribeWithSelector } from 'zustand/middleware';
7
8
  import { isMatch, cloneDeep } from 'lodash-es';
8
9
  import { CoordinationType } from '@vitessce/constants-internal';
9
10
  import { capitalize } from '@vitessce/utils';
10
11
  import { getCoordinationSpaceAndScopes } from '@vitessce/config';
11
12
  import { removeImageChannelInMetaCoordinationScopesHelper, addImageChannelInMetaCoordinationScopesHelper, } from './spatial-reducers.js';
12
- // Reference: https://github.com/pmndrs/zustand#react-context
13
- // Reference: https://github.com/pmndrs/zustand/blob/e47ea03/tests/context.test.tsx#L60
14
- const { Provider: ViewConfigProviderLocal, useStore: useViewConfigStoreLocal, useStoreApi: useViewConfigStoreApiLocal, } = createContext();
15
- export const ViewConfigProvider = ViewConfigProviderLocal;
16
- export const useViewConfigStore = useViewConfigStoreLocal;
17
- export const useViewConfigStoreApi = useViewConfigStoreApiLocal;
18
- const { Provider: AuxiliaryProviderLocal, useStore: useAuxiliaryStoreLocal, } = createContext();
19
- export const AuxiliaryProvider = AuxiliaryProviderLocal;
20
- export const useAuxiliaryStore = useAuxiliaryStoreLocal;
13
+ // References for Zustand v3:
14
+ // - https://github.com/pmndrs/zustand#react-context
15
+ // - https://github.com/pmndrs/zustand/blob/e47ea03/tests/context.test.tsx#L60
16
+ // References for Zustand v4:
17
+ // - https://github.com/pmndrs/zustand/discussions/1180#discussioncomment-3354713
18
+ // - https://zustand.docs.pmnd.rs/previous-versions/zustand-v3-create-context#migration
19
+ const ViewConfigStoreContext = createContext(null);
20
+ const AuxiliaryStoreContext = createContext(null);
21
+ export function ViewConfigProvider(props) {
22
+ const { createStore, children, } = props;
23
+ // Reference: https://github.com/pmndrs/zustand/discussions/1180
24
+ const storeRef = useRef();
25
+ if (!storeRef.current) {
26
+ storeRef.current = createStore();
27
+ }
28
+ return (_jsx(ViewConfigStoreContext.Provider, { value: storeRef.current, children: children }));
29
+ }
30
+ export function useViewConfigStoreApi() {
31
+ const store = useContext(ViewConfigStoreContext);
32
+ if (!store) {
33
+ throw new Error('Missing StoreProvider');
34
+ }
35
+ return store;
36
+ }
37
+ export function useViewConfigStore(selector) {
38
+ const store = useViewConfigStoreApi();
39
+ if (!store) {
40
+ throw new Error('Missing StoreProvider');
41
+ }
42
+ const slice = useStore(store, selector);
43
+ return slice;
44
+ }
45
+ export function useViewConfigStoreShallow(selector) {
46
+ return useViewConfigStore(useShallow(selector));
47
+ }
48
+ /* Begin auxiliary store things */
49
+ export function AuxiliaryProvider(props) {
50
+ const { createStore, children, } = props;
51
+ // Reference: https://github.com/pmndrs/zustand/discussions/1180
52
+ const storeRef = useRef();
53
+ if (!storeRef.current) {
54
+ storeRef.current = createStore();
55
+ }
56
+ return (_jsx(AuxiliaryStoreContext.Provider, { value: storeRef.current, children: children }));
57
+ }
58
+ export function useAuxiliaryStoreApi() {
59
+ const store = useContext(AuxiliaryStoreContext);
60
+ if (!store) {
61
+ throw new Error('Missing StoreProvider');
62
+ }
63
+ return store;
64
+ }
65
+ export function useAuxiliaryStore(selector) {
66
+ const store = useAuxiliaryStoreApi();
67
+ if (!store) {
68
+ throw new Error('Missing StoreProvider');
69
+ }
70
+ const slice = useStore(store, selector);
71
+ return slice;
72
+ }
73
+ export function useAuxiliaryStoreShallow(selector) {
74
+ return useAuxiliaryStore(useShallow(selector));
75
+ }
76
+ /* end auxiliary store things */
21
77
  /**
22
78
  * Get the "computed" coordinationScopes after accounting for
23
79
  * meta-coordination.
@@ -137,7 +193,7 @@ export function getParameterScopeBy(parameter, byType, typeScope, coordinationSc
137
193
  * - https://github.com/pmndrs/zustand#using-subscribe-with-selector
138
194
  * @returns {function} The useStore hook.
139
195
  */
140
- export const createViewConfigStore = (initialLoaders, initialConfig) => create(set => ({
196
+ export const createViewConfigStore = (initialLoaders, initialConfig) => create()(subscribeWithSelector(set => ({
141
197
  // State:
142
198
  // The viewConfig is an object which must conform to the schema
143
199
  // found in src/schemas/config.schema.json.
@@ -309,13 +365,13 @@ export const createViewConfigStore = (initialLoaders, initialConfig) => create(s
309
365
  mostRecentConfigSource: 'internal',
310
366
  };
311
367
  }),
312
- }));
368
+ })));
313
369
  /**
314
370
  * Hook for getting components' layout from the view config based on
315
371
  * matching all coordination scopes.
316
372
  * @returns {Object} The components' layout.
317
373
  */
318
- export const useComponentLayout = (component, scopes, coordinationScopes) => useViewConfigStore(state => state.viewConfig.layout.filter(l => l.component === component).filter(l => scopes.every(scope => l.coordinationScopes[scope]
374
+ export const useComponentLayout = (component, scopes, coordinationScopes) => useViewConfigStoreShallow(state => state.viewConfig.layout.filter(l => l.component === component).filter(l => scopes.every(scope => l.coordinationScopes[scope]
319
375
  === coordinationScopes[scope])));
320
376
  /**
321
377
  * The useAuxiliaryStore hook is initialized via the zustand
@@ -405,7 +461,7 @@ const useGridSizeStore = create(set => ({
405
461
  * @returns {object} Object containing all coordination values.
406
462
  */
407
463
  export function useInitialCoordination(parameters, coordinationScopes) {
408
- const values = useViewConfigStore((state) => {
464
+ const values = useViewConfigStoreShallow((state) => {
409
465
  const { coordinationSpace } = state.initialViewConfig;
410
466
  return Object.fromEntries(parameters.map((parameter) => {
411
467
  if (coordinationSpace && coordinationSpace[parameter]) {
@@ -414,7 +470,7 @@ export function useInitialCoordination(parameters, coordinationScopes) {
414
470
  }
415
471
  return [parameter, undefined];
416
472
  }));
417
- }, shallow);
473
+ });
418
474
  return values;
419
475
  }
420
476
  /**
@@ -435,7 +491,7 @@ export function useInitialCoordination(parameters, coordinationScopes) {
435
491
  */
436
492
  export function useCoordination(parameters, coordinationScopes) {
437
493
  const setCoordinationValue = useViewConfigStore(state => state.setCoordinationValue);
438
- const values = useViewConfigStore((state) => {
494
+ const values = useViewConfigStoreShallow((state) => {
439
495
  const { coordinationSpace } = state.viewConfig;
440
496
  return Object.fromEntries(parameters.map((parameter) => {
441
497
  if (coordinationSpace) {
@@ -447,7 +503,7 @@ export function useCoordination(parameters, coordinationScopes) {
447
503
  }
448
504
  return [parameter, undefined];
449
505
  }));
450
- }, shallow);
506
+ });
451
507
  const setters = useMemo(() => Object.fromEntries(parameters.map((parameter) => {
452
508
  const setterName = `set${capitalize(parameter)}`;
453
509
  const setterFunc = value => setCoordinationValue({
@@ -470,10 +526,10 @@ export function useMultiCoordinationScopesNonNull(parameter, coordinationScopes)
470
526
  const scopes = getParameterScope(parameter, coordinationScopes);
471
527
  // Return array of coordination scopes,
472
528
  // but filter out any whose value is null / falsey.
473
- const parameterSpace = useViewConfigStore((state) => {
529
+ const parameterSpace = useViewConfigStoreShallow((state) => {
474
530
  const { coordinationSpace } = state.viewConfig;
475
531
  return coordinationSpace?.[parameter];
476
- }, shallow);
532
+ });
477
533
  const nonNullScopes = useMemo(() => {
478
534
  // Convert a single scope to an array of scopes to be consistent.
479
535
  const scopesArr = Array.isArray(scopes) ? scopes : [scopes];
@@ -516,14 +572,14 @@ export function useMultiCoordinationScopesSecondary(parameter, byType, coordinat
516
572
  }
517
573
  export function useMultiCoordinationScopesSecondaryNonNull(parameter, byType, coordinationScopes, coordinationScopesBy) {
518
574
  const scopes = getParameterScope(byType, coordinationScopes);
519
- const parameterSpace = useViewConfigStore((state) => {
575
+ const parameterSpace = useViewConfigStoreShallow((state) => {
520
576
  const { coordinationSpace } = state.viewConfig;
521
577
  return coordinationSpace?.[parameter];
522
- }, shallow);
523
- const byTypeSpace = useViewConfigStore((state) => {
578
+ });
579
+ const byTypeSpace = useViewConfigStoreShallow((state) => {
524
580
  const { coordinationSpace } = state.viewConfig;
525
581
  return coordinationSpace?.[byType];
526
- }, shallow);
582
+ });
527
583
  return useMemo(() => {
528
584
  if (scopes && coordinationScopesBy?.[byType]?.[parameter]) {
529
585
  const scopesArr = Array.isArray(scopes) ? scopes : [scopes];
@@ -580,7 +636,7 @@ export function useMultiCoordinationScopesSecondaryNonNull(parameter, byType, co
580
636
  export function useMultiCoordinationValues(parameter, coordinationScopes) {
581
637
  const scopes = getParameterScope(parameter, coordinationScopes);
582
638
  // Mapping from dataset coordination scope name to dataset uid
583
- const vals = useViewConfigStore((state) => {
639
+ const vals = useViewConfigStoreShallow((state) => {
584
640
  const { coordinationSpace } = state.viewConfig;
585
641
  // Convert a single scope to an array of scopes to be consistent.
586
642
  const scopesArr = Array.isArray(scopes) ? scopes : [scopes];
@@ -592,7 +648,7 @@ export function useMultiCoordinationValues(parameter, coordinationScopes) {
592
648
  return [scope, undefined];
593
649
  // eslint-disable-next-line no-unused-vars
594
650
  }).filter(([k, v]) => v !== undefined));
595
- }, shallow);
651
+ });
596
652
  return vals;
597
653
  }
598
654
  /**
@@ -619,10 +675,10 @@ export function useDatasetUids(coordinationScopes) {
619
675
  */
620
676
  export function useComplexCoordination(parameters, coordinationScopes, coordinationScopesBy, byType) {
621
677
  const setCoordinationValue = useViewConfigStore(state => state.setCoordinationValue);
622
- const parameterSpaces = useViewConfigStore((state) => {
678
+ const parameterSpaces = useViewConfigStoreShallow((state) => {
623
679
  const { coordinationSpace } = state.viewConfig;
624
680
  return parameters.map(parameter => coordinationSpace[parameter]);
625
- }, shallow);
681
+ });
626
682
  const values = useMemo(() => {
627
683
  const typeScopes = getParameterScope(byType, coordinationScopes);
628
684
  if (typeScopes) {
@@ -683,10 +739,10 @@ export function useComplexCoordination(parameters, coordinationScopes, coordinat
683
739
  * @returns {object} The coordinationScopes after filling in with meta-coordinationScopes.
684
740
  */
685
741
  export function useCoordinationScopes(coordinationScopes) {
686
- const metaSpace = useViewConfigStore((state) => {
742
+ const metaSpace = useViewConfigStoreShallow((state) => {
687
743
  const { coordinationSpace } = state.viewConfig;
688
744
  return coordinationSpace?.[CoordinationType.META_COORDINATION_SCOPES];
689
- }, shallow);
745
+ });
690
746
  const vals = useMemo(() => {
691
747
  const scopes = getScopes(coordinationScopes, metaSpace);
692
748
  // Prevent infinite loop, delete metaCoordinationScopes now that they are computed.
@@ -703,10 +759,10 @@ export function useCoordinationScopes(coordinationScopes) {
703
759
  * @returns {object} The coordinationScopesBy after filling in with meta-coordinationScopesBy.
704
760
  */
705
761
  export function useCoordinationScopesBy(coordinationScopes, coordinationScopesBy) {
706
- const metaSpaceBy = useViewConfigStore((state) => {
762
+ const metaSpaceBy = useViewConfigStoreShallow((state) => {
707
763
  const { coordinationSpace } = state.viewConfig;
708
764
  return coordinationSpace?.[CoordinationType.META_COORDINATION_SCOPES_BY];
709
- }, shallow);
765
+ });
710
766
  const vals = useMemo(() => {
711
767
  const scopesBy = getScopesBy(coordinationScopes, coordinationScopesBy, metaSpaceBy);
712
768
  return scopesBy;
@@ -846,7 +902,7 @@ export function useAuxiliaryCoordination(parameters, coordinationScopes) {
846
902
  const setCoordinationValue = useAuxiliaryStore(state => state.setCoordinationValue);
847
903
  const mappedCoordinationScopes = mapCoordinationScopes(coordinationScopes);
848
904
  const mappedParameters = mapParameters(parameters);
849
- const values = useAuxiliaryStore((state) => {
905
+ const values = useAuxiliaryStoreShallow((state) => {
850
906
  const { auxiliaryStore } = state;
851
907
  return Object.fromEntries(mappedParameters.map((parameter) => {
852
908
  if (auxiliaryStore && auxiliaryStore[parameter]) {
@@ -855,7 +911,7 @@ export function useAuxiliaryCoordination(parameters, coordinationScopes) {
855
911
  }
856
912
  return [parameter, undefined];
857
913
  }));
858
- }, shallow);
914
+ });
859
915
  const setters = useMemo(() => Object.fromEntries(mappedParameters.map((parameter) => {
860
916
  const setterName = `set${capitalize(parameter)}`;
861
917
  const setterFunc = value => setCoordinationValue({
@@ -1,2 +1,10 @@
1
- export const useTitleStyles: (props?: any) => import("@material-ui/core/styles/withStyles").ClassNameMap<never>;
1
+ export const useTitleStyles: (params: void, muiStyleOverridesParams?: {
2
+ props: Record<string, unknown>;
3
+ ownerState?: Record<string, unknown> | undefined;
4
+ } | undefined) => {
5
+ classes: Record<never, string>;
6
+ theme: import("@mui/material").Theme;
7
+ css: import("tss-react").Css;
8
+ cx: import("tss-react").Cx;
9
+ };
2
10
  //# sourceMappingURL=title-styles.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"title-styles.d.ts","sourceRoot":"","sources":["../src/title-styles.js"],"names":[],"mappings":"AAEA,gHA2EI"}
1
+ {"version":3,"file":"title-styles.d.ts","sourceRoot":"","sources":["../src/title-styles.js"],"names":[],"mappings":"AAEA;;cA6BI,CAAF;;;kBAKE,eAGD;gBAAyB,WAAU;eAAsB,WAAU;EAsClE"}
@@ -1,5 +1,5 @@
1
- import { makeStyles } from '@material-ui/core';
2
- export const useTitleStyles = makeStyles(theme => ({
1
+ import { makeStyles } from '@vitessce/styles';
2
+ export const useTitleStyles = makeStyles()(theme => ({
3
3
  title: {
4
4
  color: theme.palette.primaryForeground,
5
5
  overflowX: 'hidden',
@@ -1,8 +1,2 @@
1
1
  export function VitessceGridLayout(props: any): any;
2
- export namespace VitessceGridLayout {
3
- namespace defaultProps {
4
- let padding: number;
5
- let margin: number;
6
- }
7
- }
8
2
  //# sourceMappingURL=VitessceGridLayout.d.ts.map
@@ -15,7 +15,7 @@ class ResponsiveHeightGridLayout extends ResponsiveGridLayout {
15
15
  }
16
16
  }
17
17
  export function VitessceGridLayout(props) {
18
- const { layout, viewTypes, coordinationTypes, fileTypes, stores, padding, margin: marginProp, draggableHandle: draggableHandleClass, onResize, onResizeStop, rowHeight, theme, height, onRemoveComponent, onLayoutChange: onLayoutChangeProp, isBounded, pageMode, children, } = props;
18
+ const { layout, viewTypes, coordinationTypes, fileTypes, stores, padding = 10, margin: marginProp = 10, draggableHandle: draggableHandleClass, onResize, onResizeStop, rowHeight, theme, height, onRemoveComponent, onLayoutChange: onLayoutChangeProp, isBounded, pageMode, children, } = props;
19
19
  const getComponent = useCallback((viewType) => {
20
20
  if (Array.isArray(viewTypes)) {
21
21
  const matchingViewType = viewTypes.find(v => v.name === viewType);
@@ -125,7 +125,3 @@ export function VitessceGridLayout(props) {
125
125
  || ((window.innerHeight - 2 * padding - (maxRows - 1) * margin)
126
126
  / maxRows), containerPadding: containerPadding, margin: margin, draggableHandle: draggableHandle, onLayoutChange: onLayoutChange, isBounded: isBounded, onResizeStart: saveCurrentLayouts, onDragStart: saveCurrentLayouts, onResize: onResize, onResizeStop: onResizeStop, children: layoutChildren })] }))));
127
127
  }
128
- VitessceGridLayout.defaultProps = {
129
- padding: 10,
130
- margin: 10,
131
- };
@@ -1,13 +1,9 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { describe, it, expect, afterEach } from 'vitest';
3
- import '@testing-library/jest-dom';
4
- import { cleanup, render, screen } from '@testing-library/react';
2
+ import { describe, it, expect } from 'vitest';
3
+ import { render, screen } from '@testing-library/react';
5
4
  import React from 'react';
6
5
  import { PluginViewType } from '@vitessce/plugins';
7
6
  import { VitessceGridLayout } from './VitessceGridLayout.js';
8
- afterEach(() => {
9
- cleanup();
10
- });
11
7
  function FakeComponent(props) {
12
8
  const { text } = props;
13
9
  return _jsx("span", { children: text });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitessce/vit-s",
3
- "version": "3.5.12",
3
+ "version": "3.6.1",
4
4
  "author": "HIDIVE Lab at HMS",
5
5
  "homepage": "http://vitessce.io",
6
6
  "repository": {
@@ -16,9 +16,7 @@
16
16
  "dist-tsc"
17
17
  ],
18
18
  "dependencies": {
19
- "@material-ui/core": "~4.12.3",
20
- "@material-ui/icons": "~4.11.2",
21
- "@tanstack/react-query": "^4.29.12",
19
+ "@tanstack/react-query": "^5.80.2",
22
20
  "clsx": "^1.1.1",
23
21
  "d3-array": "^2.4.0",
24
22
  "fast-deep-equal": "^3.1.3",
@@ -27,28 +25,30 @@
27
25
  "lodash-es": "^4.17.21",
28
26
  "react-grid-layout-with-lodash": "^1.3.5",
29
27
  "uuid": "^9.0.0",
30
- "zustand": "^3.5.10",
28
+ "zustand": "^5.0.4",
31
29
  "react-aria": "^3.28.0",
32
30
  "react-error-boundary": "^5.0.0",
33
- "@vitessce/abstract": "3.5.12",
34
- "@vitessce/constants-internal": "3.5.12",
35
- "@vitessce/plugins": "3.5.12",
36
- "@vitessce/schemas": "3.5.12",
37
- "@vitessce/utils": "3.5.12",
38
- "@vitessce/sets-utils": "3.5.12",
39
- "@vitessce/config": "3.5.12",
40
- "@vitessce/globals": "3.5.12"
31
+ "@vitessce/styles": "3.6.1",
32
+ "@vitessce/abstract": "3.6.1",
33
+ "@vitessce/constants-internal": "3.6.1",
34
+ "@vitessce/plugins": "3.6.1",
35
+ "@vitessce/schemas": "3.6.1",
36
+ "@vitessce/utils": "3.6.1",
37
+ "@vitessce/sets-utils": "3.6.1",
38
+ "@vitessce/config": "3.6.1",
39
+ "@vitessce/globals": "3.6.1"
41
40
  },
42
41
  "devDependencies": {
43
- "@testing-library/jest-dom": "^5.16.4",
44
- "@testing-library/react": "^13.3.0",
42
+ "@testing-library/jest-dom": "^6.6.3",
43
+ "@testing-library/react": "^16.3.0",
45
44
  "react": "^18.0.0",
46
- "vite": "^4.3.0",
47
- "vitest": "^0.32.2",
48
- "@vitessce/types": "3.5.12"
45
+ "react-dom": "^18.0.0",
46
+ "vite": "^6.3.5",
47
+ "vitest": "^3.1.4",
48
+ "@vitessce/types": "3.6.1"
49
49
  },
50
50
  "peerDependencies": {
51
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
51
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
52
52
  },
53
53
  "scripts": {
54
54
  "bundle": "pnpm exec vite build -c ../../scripts/vite.config.js",
@@ -44,6 +44,9 @@ export default function CallbackPublisher(props) {
44
44
  // to subscribe to view config changes.
45
45
  // Reference: https://github.com/react-spring/zustand#transient-updates-for-often-occuring-state-changes
46
46
  useEffect(() => viewConfigStoreApi.subscribe(
47
+ // The function to specify which part of the store
48
+ // we want to subscribe to.
49
+ state => state.viewConfig,
47
50
  // The function to run on each publish.
48
51
  (viewConfig) => {
49
52
  if (validateOnConfigChange && viewConfig) {
@@ -53,9 +56,7 @@ export default function CallbackPublisher(props) {
53
56
  onConfigChange(viewConfig);
54
57
  }
55
58
  },
56
- // The function to specify which part of the store
57
- // we want to subscribe to.
58
- state => state.viewConfig,
59
+ // TODO: here, should we specify the "shallow" equality function?
59
60
  ), [onConfigChange, validateOnConfigChange, viewConfigStoreApi, pluginSpecificConfigSchema]);
60
61
 
61
62
  // Emit updates to the warning message.
@@ -3,7 +3,7 @@ import { useStyles } from './shared-warning-styles.js';
3
3
  import { VITESSCE_CONTAINER } from './classNames.js';
4
4
 
5
5
  export function DebugWindow({ debugErrors }) {
6
- const classes = useStyles();
6
+ const { classes } = useStyles();
7
7
  return (
8
8
  <div className={VITESSCE_CONTAINER}>
9
9
  <div className={clsx(classes.warningLayout, classes.containerFluid)}>
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
- import { makeStyles, CircularProgress } from '@material-ui/core';
2
+ import { makeStyles, CircularProgress } from '@vitessce/styles';
3
3
 
4
- const useStyles = makeStyles(() => ({
4
+ const useStyles = makeStyles()(() => ({
5
5
  loadingIndicatorBackdrop: {
6
6
  position: 'absolute',
7
7
  top: '0',
@@ -30,7 +30,7 @@ const useStyles = makeStyles(() => ({
30
30
  }));
31
31
 
32
32
  export default function LoadingIndicator() {
33
- const classes = useStyles();
33
+ const { classes } = useStyles();
34
34
  return (
35
35
  <div className={classes.loadingIndicatorBackdrop}>
36
36
  <div className={classes.loadingIndicatorContainer} role="status" aria-live="polite">
package/src/TitleInfo.js CHANGED
@@ -1,21 +1,20 @@
1
1
  import React, { useState, useMemo } from 'react';
2
2
  import clsx from 'clsx';
3
- import { makeStyles, MenuItem, IconButton, Link } from '@material-ui/core';
4
- import {
3
+ import { makeStyles, MenuItem, IconButton, Link,
5
4
  CloudDownload as CloudDownloadIcon,
6
5
  ArrowDropDown as ArrowDropDownIcon,
7
6
  ArrowDropUp as ArrowDropUpIcon,
8
7
  Settings as SettingsIcon,
9
8
  Close as CloseIcon,
10
9
  Help as HelpIcon,
11
- } from '@material-ui/icons';
10
+ } from '@vitessce/styles';
12
11
 
13
12
  import { TOOLTIP_ANCESTOR } from './classNames.js';
14
13
  import LoadingIndicator from './LoadingIndicator.js';
15
14
  import { PopperMenu } from './shared-mui/components.js';
16
15
  import { useTitleStyles } from './title-styles.js';
17
16
 
18
- const useStyles = makeStyles(theme => ({
17
+ const useStyles = makeStyles()(theme => ({
19
18
  iconButton: {
20
19
  border: 'none',
21
20
  marginLeft: 0,
@@ -27,7 +26,7 @@ const useStyles = makeStyles(theme => ({
27
26
  '&:hover': {
28
27
  backgroundColor: theme.palette.primaryBackgroundLight,
29
28
  },
30
- '&:first-child': {
29
+ '&:first-of-type': {
31
30
  marginLeft: '0.25em',
32
31
  },
33
32
  '&:last-child': {
@@ -69,7 +68,7 @@ function SettingsIconWithArrow({ open }) {
69
68
  function PlotOptions(props) {
70
69
  const { options } = props;
71
70
  const [open, setOpen] = useState(false);
72
- const classes = useStyles();
71
+ const { classes } = useStyles();
73
72
 
74
73
  const buttonIcon = useMemo(() => (<SettingsIconWithArrow open={open} />), [open]);
75
74
  return (options ? (
@@ -98,7 +97,7 @@ function CloudDownloadIconWithArrow({ open }) {
98
97
  function DownloadOptions(props) {
99
98
  const { urls } = props;
100
99
  const [open, setOpen] = useState(false);
101
- const classes = useStyles();
100
+ const { classes } = useStyles();
102
101
  const buttonIcon = useMemo(() => (<CloudDownloadIconWithArrow open={open} />), [open]);
103
102
  return (urls && urls.length ? (
104
103
  <PopperMenu
@@ -123,7 +122,7 @@ function DownloadOptions(props) {
123
122
  function HelpButton(props) {
124
123
  const { helpText } = props;
125
124
  const [open, setOpen] = useState(false);
126
- const classes = useStyles();
125
+ const { classes } = useStyles();
127
126
  return (
128
127
  <PopperMenu
129
128
  open={open}
@@ -142,7 +141,7 @@ function HelpButton(props) {
142
141
 
143
142
  function ClosePaneButton(props) {
144
143
  const { removeGridComponent } = props;
145
- const classes = useStyles();
144
+ const { classes } = useStyles();
146
145
  return (
147
146
  <IconButton
148
147
  onClick={removeGridComponent}
@@ -163,7 +162,7 @@ export function TitleInfo(props) {
163
162
  helpText, withPadding = true,
164
163
  } = props;
165
164
 
166
- const classes = useTitleStyles();
165
+ const { classes } = useTitleStyles();
167
166
 
168
167
  return (
169
168
  // d-flex without wrapping div is not always full height; I don't understand the root cause.
package/src/VitS.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import React, { useState, useEffect, useMemo, useCallback, useLayoutEffect } from 'react';
2
2
  import {
3
3
  ThemeProvider,
4
- StylesProvider,
5
- } from '@material-ui/core';
4
+ CacheProvider,
5
+ createCache,
6
+ } from '@vitessce/styles';
6
7
  import {
7
8
  QueryClient,
8
9
  QueryClientProvider,
@@ -30,7 +31,6 @@ import {
30
31
  logConfig,
31
32
  } from './view-config-utils.js';
32
33
  import { createLoaders } from './vitessce-grid-utils.js';
33
- import { createGenerateClassName } from './mui-utils.js';
34
34
  import { AsyncFunctionsContext } from './contexts.js';
35
35
 
36
36
 
@@ -59,6 +59,8 @@ import { AsyncFunctionsContext } from './contexts.js';
59
59
  * @param {null|string} props.uid A unique identifier for this Vitessce instance,
60
60
  * for the purpose of avoiding CSS autogenerated class name conflicts. Must be valid as part
61
61
  * of a CSS class name string.
62
+ * @param {undefined|Node} props.styleContainer The DOM node for insertion of styles,
63
+ * passed to Emotion's createCache.container. Useful when Vitessce is in the Shadow DOM.
62
64
  * @param {boolean} props.remountOnUidChange Whether to remount the coordination provider
63
65
  * upon changes to config.uid. By default, true.
64
66
  * @param {array} props.viewTypes Plugin view types.
@@ -85,6 +87,7 @@ export function VitS(props) {
85
87
  validateOnConfigChange = false,
86
88
  isBounded = false,
87
89
  uid = null,
90
+ styleContainer,
88
91
  remountOnUidChange = true,
89
92
  viewTypes: viewTypesProp,
90
93
  fileTypes: fileTypesProp,
@@ -110,7 +113,6 @@ export function VitS(props) {
110
113
  () => (coordinationTypesProp || []),
111
114
  [coordinationTypesProp],
112
115
  );
113
- const generateClassName = useMemo(() => createGenerateClassName(uid), [uid]);
114
116
 
115
117
  // Set error handling-related globals.
116
118
  useLayoutEffect(() => {
@@ -221,6 +223,12 @@ export function VitS(props) {
221
223
  [asyncFunctionsProp, queryClient],
222
224
  );
223
225
 
226
+ const muiCache = useMemo(() => createCache({
227
+ key: uid || 'vit',
228
+ prepend: true,
229
+ container: styleContainer,
230
+ }), [uid, styleContainer]);
231
+
224
232
  // Emit the upgraded/initialized view config
225
233
  // to onConfigChange if necessary.
226
234
  useEffect(() => {
@@ -252,20 +260,20 @@ export function VitS(props) {
252
260
  // so that when the child throws errors the parent can catch.
253
261
  if (debugMode && debugErrors.length > 0) {
254
262
  return (
255
- <StylesProvider generateClassName={generateClassName}>
263
+ <CacheProvider value={muiCache}>
256
264
  <ThemeProvider theme={muiTheme[theme]}>
257
265
  <DebugWindow debugErrors={debugErrors} />
258
266
  </ThemeProvider>
259
- </StylesProvider>
267
+ </CacheProvider>
260
268
  );
261
269
  }
262
270
  return success ? (
263
- <StylesProvider generateClassName={generateClassName}>
271
+ <CacheProvider value={muiCache}>
264
272
  <ThemeProvider theme={muiTheme[theme]}>
265
273
  <QueryClientProvider client={queryClient}>
266
274
  <ViewConfigProvider
267
275
  createStore={createViewConfigStoreClosure}
268
- {...(remountOnUidChange ? ({ key: configKey }) : {})}
276
+ key={(remountOnUidChange ? configKey : undefined)}
269
277
  >
270
278
  <AuxiliaryProvider createStore={createAuxiliaryStore}>
271
279
  <AsyncFunctionsContext.Provider value={asyncFunctions}>
@@ -297,12 +305,12 @@ export function VitS(props) {
297
305
  </ViewConfigProvider>
298
306
  </QueryClientProvider>
299
307
  </ThemeProvider>
300
- </StylesProvider>
308
+ </CacheProvider>
301
309
  ) : (
302
- <StylesProvider generateClassName={generateClassName}>
310
+ <CacheProvider value={muiCache}>
303
311
  <ThemeProvider theme={muiTheme[theme]}>
304
312
  <Warning {...configOrWarning} />
305
313
  </ThemeProvider>
306
- </StylesProvider>
314
+ </CacheProvider>
307
315
  );
308
316
  }
@@ -19,7 +19,10 @@ import {
19
19
  import {
20
20
  useClosestVitessceContainerSize,
21
21
  } from './hooks.js';
22
- import { useVitessceContainerStyles } from './shared-mui/container.js';
22
+ import {
23
+ useVitessceContainerStyles,
24
+ GridLayoutGlobalStyles,
25
+ } from './shared-mui/container.js';
23
26
  import { useTitleStyles } from './title-styles.js';
24
27
  import { getAltText } from './generate-alt-text.js';
25
28
 
@@ -61,8 +64,8 @@ export default function VitessceGrid(props) {
61
64
 
62
65
  const [componentWidth] = useClosestVitessceContainerSize(containerRef);
63
66
 
64
- const classes = useVitessceContainerStyles();
65
- const titleClasses = useTitleStyles();
67
+ const { classes } = useVitessceContainerStyles();
68
+ const { classes: titleClasses } = useTitleStyles();
66
69
 
67
70
  const altText = useMemo(() => getAltText(config), [configKey]);
68
71
 
@@ -113,6 +116,7 @@ export default function VitessceGrid(props) {
113
116
  role="group"
114
117
  aria-label={altText}
115
118
  >
119
+ <GridLayoutGlobalStyles classes={classes} />
116
120
  {layout ? (
117
121
  <VitessceGridLayout
118
122
  pageMode={pageMode}