@vitessce/vit-s 2.0.2 → 2.0.3

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 (172) hide show
  1. package/dist/index.mjs +84801 -0
  2. package/{dist → dist-tsc}/index.js +2 -2
  3. package/package.json +7 -7
  4. package/src/CallbackPublisher.js +81 -0
  5. package/src/LoadingIndicator.js +34 -0
  6. package/src/TitleInfo.js +240 -0
  7. package/src/VitS.js +180 -0
  8. package/src/VitessceGrid.js +110 -0
  9. package/src/VitessceGrid.test.jsx +48 -0
  10. package/src/Warning.js +62 -0
  11. package/{dist → src}/classNames.js +0 -0
  12. package/src/component-registry.js +21 -0
  13. package/src/data/AbstractLoader.js +46 -0
  14. package/{dist → src}/data/AbstractTwoStepLoader.js +5 -4
  15. package/src/data/LoaderResult.js +8 -0
  16. package/{dist → src}/data/index.js +0 -0
  17. package/src/data/loader-registry.js +19 -0
  18. package/src/data-hook-utils.js +197 -0
  19. package/src/data-hooks.js +354 -0
  20. package/src/errors/AbstractLoaderError.js +14 -0
  21. package/src/errors/DataSourceFetchError.js +15 -0
  22. package/src/errors/DatasetNotFoundError.js +23 -0
  23. package/src/errors/LoaderNotFoundError.js +24 -0
  24. package/src/errors/LoaderValidationError.js +23 -0
  25. package/src/errors/OptionsValidationError.js +25 -0
  26. package/{dist → src}/errors/index.js +0 -0
  27. package/src/file-options-schemas-legacy.js +139 -0
  28. package/src/file-options-schemas-legacy.test.js +138 -0
  29. package/src/file-options-schemas.js +327 -0
  30. package/src/file-options-schemas.test.js +26 -0
  31. package/src/hooks.js +252 -0
  32. package/src/index.js +101 -0
  33. package/src/joint-file-types-legacy.js +298 -0
  34. package/src/joint-file-types-legacy.test.js +412 -0
  35. package/src/joint-file-types.js +171 -0
  36. package/src/joint-file-types.test.js +144 -0
  37. package/{dist/schemas.js → src/json-schemas.js} +6 -1
  38. package/{dist → src}/plugins.js +102 -70
  39. package/src/plugins.test.fixtures.js +78 -0
  40. package/src/plugins.test.js +42 -0
  41. package/src/schemas/config-0.1.0.schema.json +85 -0
  42. package/src/schemas/config-1.0.0.schema.json +733 -0
  43. package/src/schemas/config-1.0.1.schema.json +909 -0
  44. package/src/schemas/config-1.0.10.schema.json +969 -0
  45. package/src/schemas/config-1.0.11.schema.json +990 -0
  46. package/src/schemas/config-1.0.12.schema.json +997 -0
  47. package/src/schemas/config-1.0.13.schema.json +1013 -0
  48. package/src/schemas/config-1.0.14.schema.json +1048 -0
  49. package/src/schemas/config-1.0.15.schema.json +1048 -0
  50. package/src/schemas/config-1.0.16.schema.json +1069 -0
  51. package/src/schemas/config-1.0.16.schema.test.js +32 -0
  52. package/src/schemas/config-1.0.2.schema.json +911 -0
  53. package/src/schemas/config-1.0.3.schema.json +911 -0
  54. package/src/schemas/config-1.0.4.schema.json +949 -0
  55. package/src/schemas/config-1.0.5.schema.json +949 -0
  56. package/src/schemas/config-1.0.6.schema.json +950 -0
  57. package/src/schemas/config-1.0.7.schema.json +950 -0
  58. package/src/schemas/config-1.0.8.schema.json +966 -0
  59. package/src/schemas/config-1.0.9.schema.json +965 -0
  60. package/src/schemas/fixtures/cellSets.good.json +16 -0
  61. package/src/schemas/fixtures/config-1.0.1.bad.json +1 -0
  62. package/src/schemas/fixtures/config-1.0.1.bad.message.json +11 -0
  63. package/src/schemas/fixtures/config-1.0.1.good.json +37 -0
  64. package/src/schemas/fixtures/config-1.0.2.bad.json +1 -0
  65. package/src/schemas/fixtures/config-1.0.2.bad.message.json +11 -0
  66. package/src/schemas/fixtures/config-1.0.2.good.json +38 -0
  67. package/src/schemas/fixtures/config-1.0.3.bad.json +1 -0
  68. package/src/schemas/fixtures/config-1.0.3.bad.message.json +11 -0
  69. package/src/schemas/fixtures/config-1.0.3.good.json +38 -0
  70. package/src/schemas/fixtures/obsSets.bad.json +1 -0
  71. package/src/schemas/fixtures/obsSets.bad.message.json +11 -0
  72. package/src/schemas/fixtures/obsSets.good.json +16 -0
  73. package/src/schemas/fixtures/obsSetsTabular.bad.json +1 -0
  74. package/src/schemas/fixtures/obsSetsTabular.bad.message.json +11 -0
  75. package/src/schemas/fixtures/obsSetsTabular.good.json +26 -0
  76. package/src/schemas/fixtures/raster.bad.json +1 -0
  77. package/src/schemas/fixtures/raster.bad.message.json +11 -0
  78. package/src/schemas/fixtures/raster.good.json +39 -0
  79. package/src/schemas/obsSets.schema.js +195 -0
  80. package/src/schemas/obsSetsTabular.schema.js +39 -0
  81. package/src/schemas/raster.schema.js +121 -0
  82. package/src/schemas/schema-schema.sh +34 -0
  83. package/{dist → src}/schemas/schema.test-old.js +0 -1
  84. package/src/shared-mui/components.js +79 -0
  85. package/src/shared-mui/container.js +212 -0
  86. package/src/shared-mui/styles.js +110 -0
  87. package/src/shared-plot-options/CellColorEncodingOption.js +43 -0
  88. package/src/shared-plot-options/OptionSelect.js +19 -0
  89. package/src/shared-plot-options/OptionsContainer.js +26 -0
  90. package/{dist → src}/shared-plot-options/index.js +0 -0
  91. package/src/shared-plot-options/styles.js +49 -0
  92. package/src/state/hooks.js +633 -0
  93. package/src/view-config-upgraders.js +628 -0
  94. package/src/view-config-utils.js +315 -0
  95. package/src/view-config-utils.test.fixtures.js +893 -0
  96. package/src/view-config-utils.test.js +95 -0
  97. package/src/view-config-versions.js +68 -0
  98. package/src/vitessce-grid-layout/VitessceGridLayout.js +158 -0
  99. package/src/vitessce-grid-layout/VitessceGridLayout.test.jsx +56 -0
  100. package/{dist → src}/vitessce-grid-layout/index.js +0 -0
  101. package/src/vitessce-grid-layout/layout-utils.js +76 -0
  102. package/src/vitessce-grid-layout/layout-utils.test.js +167 -0
  103. package/src/vitessce-grid-utils.js +160 -0
  104. package/dist/CallbackPublisher.js +0 -68
  105. package/dist/LoadingIndicator.js +0 -27
  106. package/dist/TitleInfo.js +0 -151
  107. package/dist/VitS.js +0 -112
  108. package/dist/VitessceGrid.js +0 -59
  109. package/dist/VitessceGrid.test.js +0 -36
  110. package/dist/Warning.js +0 -45
  111. package/dist/component-registry.js +0 -16
  112. package/dist/data/AbstractLoader.js +0 -35
  113. package/dist/data/LoaderResult.js +0 -7
  114. package/dist/data/loader-registry.js +0 -15
  115. package/dist/data-hook-utils.js +0 -175
  116. package/dist/data-hooks.js +0 -241
  117. package/dist/errors/AbstractLoaderError.js +0 -13
  118. package/dist/errors/DataSourceFetchError.js +0 -13
  119. package/dist/errors/DatasetNotFoundError.js +0 -17
  120. package/dist/errors/LoaderNotFoundError.js +0 -17
  121. package/dist/errors/LoaderValidationError.js +0 -15
  122. package/dist/errors/OptionsValidationError.js +0 -15
  123. package/dist/file-options-schemas-legacy.js +0 -136
  124. package/dist/file-options-schemas-legacy.test.js +0 -126
  125. package/dist/file-options-schemas.js +0 -322
  126. package/dist/file-options-schemas.test.js +0 -23
  127. package/dist/hooks.js +0 -215
  128. package/dist/joint-file-types-legacy.js +0 -278
  129. package/dist/joint-file-types-legacy.test.js +0 -400
  130. package/dist/joint-file-types.js +0 -148
  131. package/dist/joint-file-types.test.js +0 -139
  132. package/dist/plugins.test.fixtures.js +0 -76
  133. package/dist/plugins.test.js +0 -30
  134. package/dist/schemas/config-0.1.0.schema.json +0 -84
  135. package/dist/schemas/config-1.0.0.schema.json +0 -733
  136. package/dist/schemas/config-1.0.1.schema.json +0 -909
  137. package/dist/schemas/config-1.0.10.schema.json +0 -969
  138. package/dist/schemas/config-1.0.11.schema.json +0 -990
  139. package/dist/schemas/config-1.0.12.schema.json +0 -997
  140. package/dist/schemas/config-1.0.13.schema.json +0 -1013
  141. package/dist/schemas/config-1.0.14.schema.json +0 -1048
  142. package/dist/schemas/config-1.0.15.schema.json +0 -1048
  143. package/dist/schemas/config-1.0.15.schema.test.js +0 -22
  144. package/dist/schemas/config-1.0.2.schema.json +0 -910
  145. package/dist/schemas/config-1.0.3.schema.json +0 -910
  146. package/dist/schemas/config-1.0.4.schema.json +0 -949
  147. package/dist/schemas/config-1.0.5.schema.json +0 -949
  148. package/dist/schemas/config-1.0.6.schema.json +0 -949
  149. package/dist/schemas/config-1.0.7.schema.json +0 -949
  150. package/dist/schemas/config-1.0.8.schema.json +0 -965
  151. package/dist/schemas/config-1.0.9.schema.json +0 -965
  152. package/dist/schemas/obsSets.schema.js +0 -195
  153. package/dist/schemas/obsSetsTabular.schema.js +0 -38
  154. package/dist/schemas/raster.schema.js +0 -120
  155. package/dist/shared-mui/components.js +0 -35
  156. package/dist/shared-mui/container.js +0 -211
  157. package/dist/shared-mui/styles.js +0 -73
  158. package/dist/shared-plot-options/CellColorEncodingOption.js +0 -18
  159. package/dist/shared-plot-options/OptionSelect.js +0 -12
  160. package/dist/shared-plot-options/OptionsContainer.js +0 -12
  161. package/dist/shared-plot-options/styles.js +0 -48
  162. package/dist/state/hooks.js +0 -549
  163. package/dist/view-config-upgraders.js +0 -525
  164. package/dist/view-config-utils.js +0 -286
  165. package/dist/view-config-utils.test.fixtures.js +0 -765
  166. package/dist/view-config-utils.test.js +0 -66
  167. package/dist/view-config-versions.js +0 -47
  168. package/dist/vitessce-grid-layout/VitessceGridLayout.js +0 -95
  169. package/dist/vitessce-grid-layout/VitessceGridLayout.test.js +0 -40
  170. package/dist/vitessce-grid-layout/layout-utils.js +0 -60
  171. package/dist/vitessce-grid-layout/layout-utils.test.js +0 -146
  172. package/dist/vitessce-grid-utils.js +0 -140
@@ -1,66 +0,0 @@
1
- /* eslint-disable camelcase */
2
- import { getExistingScopesForCoordinationType, initialize, } from './view-config-utils';
3
- import { upgradeFrom0_1_0, upgradeFrom1_0_0, } from './view-config-upgraders';
4
- import { legacyViewConfig0_1_0, upgradedLegacyViewConfig0_1_0, legacyViewConfig1_0_0, upgradedLegacyViewConfig1_0_0, initializedViewConfig, viewConfig1_0_10, missingViewUids, } from './view-config-utils.test.fixtures';
5
- describe('src/app/view-config-utils.js', () => {
6
- describe('getExistingScopesForCoordinationType', () => {
7
- it('gets all scope names for a particular coordination type', () => {
8
- const config = {
9
- coordinationSpace: {
10
- dataset: {
11
- A: 'my-dataset-1',
12
- B: 'my-dataset-2',
13
- },
14
- },
15
- layout: [
16
- {
17
- coordinationScopes: {
18
- dataset: 'A',
19
- },
20
- },
21
- {
22
- coordinationScopes: {
23
- dataset: 'C',
24
- },
25
- },
26
- ],
27
- };
28
- expect(getExistingScopesForCoordinationType(config, 'dataset')).toEqual(['A', 'B', 'C']);
29
- });
30
- });
31
- describe('upgrade', () => {
32
- it('upgrade view config from v0.1.0 to v1.0.0', () => {
33
- expect(upgradeFrom0_1_0(legacyViewConfig0_1_0, 'A')).toEqual(upgradedLegacyViewConfig0_1_0);
34
- });
35
- it('upgrade view config from v1.0.0 to v1.0.1', () => {
36
- expect(upgradeFrom1_0_0(legacyViewConfig1_0_0)).toEqual(upgradedLegacyViewConfig1_0_0);
37
- });
38
- });
39
- describe('initialize', () => {
40
- it('initializes coordination space and component coordination scopes when initStrategy is auto', () => {
41
- expect(initialize(viewConfig1_0_10)).toEqual(initializedViewConfig);
42
- });
43
- it('does not change the result when initialized twice when initStrategy is auto', () => {
44
- const firstResult = initialize(viewConfig1_0_10);
45
- expect(firstResult).toEqual(initializedViewConfig);
46
- const secondResult = initialize(firstResult);
47
- expect(secondResult).toEqual(initializedViewConfig);
48
- });
49
- it('generates unique ids for the view uid property when missing', () => {
50
- const withUids = initialize(missingViewUids);
51
- expect(withUids.layout[0].uid).toEqual('A');
52
- // Should not overwrite uid when present:
53
- expect(withUids.layout[1].uid).toEqual('some-umap');
54
- expect(withUids.layout[2].uid).toEqual('B');
55
- expect(withUids.layout[3].uid).toEqual('C');
56
- });
57
- it('does not initialize when initStrategy is none', () => {
58
- const noneInitViewConfig = {
59
- ...upgradedLegacyViewConfig0_1_0,
60
- initStrategy: 'none',
61
- };
62
- expect(initialize(noneInitViewConfig).coordinationSpace)
63
- .toEqual(noneInitViewConfig.coordinationSpace);
64
- });
65
- });
66
- });
@@ -1,47 +0,0 @@
1
- /* eslint-disable camelcase */
2
- import Ajv from 'ajv';
3
- import configSchema0_1_0 from './schemas/config-0.1.0.schema.json';
4
- import configSchema1_0_0 from './schemas/config-1.0.0.schema.json';
5
- import configSchema1_0_1 from './schemas/config-1.0.1.schema.json';
6
- import configSchema1_0_2 from './schemas/config-1.0.2.schema.json';
7
- import configSchema1_0_3 from './schemas/config-1.0.3.schema.json';
8
- import configSchema1_0_4 from './schemas/config-1.0.4.schema.json';
9
- import configSchema1_0_5 from './schemas/config-1.0.5.schema.json';
10
- import configSchema1_0_6 from './schemas/config-1.0.6.schema.json';
11
- import configSchema1_0_7 from './schemas/config-1.0.7.schema.json';
12
- import configSchema1_0_8 from './schemas/config-1.0.8.schema.json';
13
- import configSchema1_0_9 from './schemas/config-1.0.9.schema.json';
14
- import configSchema1_0_10 from './schemas/config-1.0.10.schema.json';
15
- import configSchema1_0_11 from './schemas/config-1.0.11.schema.json';
16
- import configSchema1_0_12 from './schemas/config-1.0.12.schema.json';
17
- import configSchema1_0_13 from './schemas/config-1.0.13.schema.json';
18
- import configSchema1_0_14 from './schemas/config-1.0.14.schema.json';
19
- import configSchema1_0_15 from './schemas/config-1.0.15.schema.json';
20
- import obsSetsSchema from './schemas/obsSets.schema';
21
- import rasterSchema from './schemas/raster.schema';
22
- import { upgradeFrom0_1_0, upgradeFrom1_0_0, upgradeFrom1_0_1, upgradeFrom1_0_2, upgradeFrom1_0_3, upgradeFrom1_0_4, upgradeFrom1_0_5, upgradeFrom1_0_6, upgradeFrom1_0_7, upgradeFrom1_0_8, upgradeFrom1_0_9, upgradeFrom1_0_10, upgradeFrom1_0_11, upgradeFrom1_0_12, upgradeFrom1_0_13, upgradeFrom1_0_14, } from './view-config-upgraders';
23
- /**
24
- * Mapping from view config versions to view config schemas and upgrade functions.
25
- * Add a new schema and upgrade function here when bumping the view config version.
26
- * The latest view config version should always have a null value instead of an upgrade function.
27
- */
28
- export const LATEST_VERSION = '1.0.15';
29
- export const SCHEMA_HANDLERS = {
30
- '0.1.0': [new Ajv().compile(configSchema0_1_0), upgradeFrom0_1_0],
31
- '1.0.0': [new Ajv().addSchema(obsSetsSchema).addSchema(rasterSchema).compile(configSchema1_0_0), upgradeFrom1_0_0],
32
- '1.0.1': [new Ajv().addSchema(obsSetsSchema).addSchema(rasterSchema).compile(configSchema1_0_1), upgradeFrom1_0_1],
33
- '1.0.2': [new Ajv().addSchema(obsSetsSchema).addSchema(rasterSchema).compile(configSchema1_0_2), upgradeFrom1_0_2],
34
- '1.0.3': [new Ajv().addSchema(obsSetsSchema).addSchema(rasterSchema).compile(configSchema1_0_3), upgradeFrom1_0_3],
35
- '1.0.4': [new Ajv().addSchema(obsSetsSchema).addSchema(rasterSchema).compile(configSchema1_0_4), upgradeFrom1_0_4],
36
- '1.0.5': [new Ajv().addSchema(obsSetsSchema).addSchema(rasterSchema).compile(configSchema1_0_5), upgradeFrom1_0_5],
37
- '1.0.6': [new Ajv().addSchema(obsSetsSchema).addSchema(rasterSchema).compile(configSchema1_0_6), upgradeFrom1_0_6],
38
- '1.0.7': [new Ajv().addSchema(obsSetsSchema).addSchema(rasterSchema).compile(configSchema1_0_7), upgradeFrom1_0_7],
39
- '1.0.8': [new Ajv().addSchema(obsSetsSchema).addSchema(rasterSchema).compile(configSchema1_0_8), upgradeFrom1_0_8],
40
- '1.0.9': [new Ajv().addSchema(obsSetsSchema).addSchema(rasterSchema).compile(configSchema1_0_9), upgradeFrom1_0_9],
41
- '1.0.10': [new Ajv().addSchema(obsSetsSchema).addSchema(rasterSchema).compile(configSchema1_0_10), upgradeFrom1_0_10],
42
- '1.0.11': [new Ajv().addSchema(obsSetsSchema).addSchema(rasterSchema).compile(configSchema1_0_11), upgradeFrom1_0_11],
43
- '1.0.12': [new Ajv().addSchema(obsSetsSchema).addSchema(rasterSchema).compile(configSchema1_0_12), upgradeFrom1_0_12],
44
- '1.0.13': [new Ajv().addSchema(obsSetsSchema).addSchema(rasterSchema).compile(configSchema1_0_13), upgradeFrom1_0_13],
45
- '1.0.14': [new Ajv().addSchema(obsSetsSchema).addSchema(rasterSchema).compile(configSchema1_0_14), upgradeFrom1_0_14],
46
- '1.0.15': [new Ajv().addSchema(obsSetsSchema).addSchema(rasterSchema).compile(configSchema1_0_15), null],
47
- };
@@ -1,95 +0,0 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import React, { useState } from 'react';
3
- import { Responsive, WidthProvider } from 'react-grid-layout-with-lodash';
4
- import isEqual from 'lodash/isEqual';
5
- import { getMaxRows, resolveLayout } from './layout-utils';
6
- const ResponsiveGridLayout = WidthProvider(Responsive);
7
- class ResponsiveHeightGridLayout extends ResponsiveGridLayout {
8
- componentDidUpdate(prevProps) {
9
- if (this.props.height !== prevProps.height) {
10
- this.onWindowResize();
11
- }
12
- }
13
- }
14
- export function VitessceGridLayout(props) {
15
- const { layout, getComponent, padding, margin, draggableHandle: draggableHandleClass, onResize, onResizeStop, rowHeight, theme, height, onRemoveComponent, onLayoutChange: onLayoutChangeProp, isBounded, } = props;
16
- const draggableHandle = `.${draggableHandleClass}`;
17
- // If layout changes, update grid components.
18
- const { cols: gridCols, layouts: gridLayouts, breakpoints: gridBreakpoints, components: gridComponents, } = resolveLayout(layout);
19
- const maxRows = getMaxRows(gridLayouts);
20
- // Inline CSS is generally avoided, but this saves the end-user a little work,
21
- // and prevents class names from getting out of sync.
22
- const style = (_jsx("style", { children: `
23
- ${draggableHandle} {
24
- cursor: grab;
25
- }
26
- ${draggableHandle}:active {
27
- cursor: grabbing;
28
- }
29
- ` }));
30
- // A bit of hacky feeling stuff to prevent users from stacking elements and forcing the
31
- // grid boundary to change even when isBounded is set to true. It seems like react-grid-layout
32
- // should support this through isBounded and maxRows, but neither of these actually works for the
33
- // edge case where a user drags one element above another and forces the first element downwards.
34
- //
35
- // Additionally, react-grid-layout doesn't revert if you don't save a new/changed layouts. If you
36
- // wish to do this, first you have to save the new layouts and render the grid with it, and then
37
- // you can revert to the original layouts. Thus, we need one state for the current grid layouts,
38
- // which gets called on every onLayoutChange. If the grid height is still valid, we then call
39
- // onValidLayoutChange, otherwise we reset currentGridLayouts to lastValidGridLayouts.
40
- //
41
- // See the following GitHub issue for more information.
42
- // https://github.com/react-grid-layout/react-grid-layout/issues/1104#issuecomment-827785217
43
- const [currentGridLayouts, setCurrentGridLayouts] = useState(gridLayouts);
44
- const [lastValidGridLayouts, setLastValidGridLayouts] = useState(gridLayouts);
45
- const onValidLayoutChange = (newLayout) => {
46
- if (newLayout.length === Object.entries(gridComponents).length) {
47
- const newComponentProps = {};
48
- newLayout.forEach((nextC) => {
49
- const id = nextC.i;
50
- const prevC = gridComponents[id];
51
- if (prevC) {
52
- const nextProps = {
53
- x: nextC.x, y: nextC.y, w: nextC.w, h: nextC.h,
54
- };
55
- const prevProps = {
56
- x: prevC.x, y: prevC.y, w: prevC.w, h: prevC.h,
57
- };
58
- if (!isEqual(nextProps, prevProps)) {
59
- newComponentProps[id] = nextProps;
60
- }
61
- }
62
- });
63
- if (Object.keys(newComponentProps).length > 0) {
64
- onLayoutChangeProp(newComponentProps);
65
- }
66
- }
67
- };
68
- const onLayoutChange = (newLayout, allLayouts) => {
69
- setCurrentGridLayouts(allLayouts);
70
- if (!isBounded || getMaxRows({ ID: newLayout }) <= maxRows) {
71
- onValidLayoutChange(newLayout);
72
- setLastValidGridLayouts(allLayouts);
73
- }
74
- else {
75
- setCurrentGridLayouts(lastValidGridLayouts);
76
- }
77
- };
78
- const saveCurrentLayouts = () => {
79
- setLastValidGridLayouts(currentGridLayouts);
80
- };
81
- const layoutChildren = Object.values(gridComponents).map((v) => {
82
- const Component = getComponent(v.component);
83
- const removeGridComponent = () => {
84
- onRemoveComponent(v.uid);
85
- };
86
- return (_jsx("div", { children: _jsx(Component, { ...v.props, uuid: v.uid, coordinationScopes: v.coordinationScopes, theme: theme, removeGridComponent: removeGridComponent }) }, v.uid));
87
- });
88
- return (currentGridLayouts && gridComponents && gridBreakpoints && gridCols) && (_jsxs(_Fragment, { children: [style, _jsx(ResponsiveHeightGridLayout, { className: "layout", cols: gridCols, layouts: currentGridLayouts, breakpoints: gridBreakpoints, height: height, rowHeight: rowHeight
89
- || ((window.innerHeight - 2 * padding - (maxRows - 1) * margin)
90
- / maxRows), containerPadding: [padding, padding], margin: [margin, margin], draggableHandle: draggableHandle, onLayoutChange: onLayoutChange, isBounded: isBounded, onResizeStart: saveCurrentLayouts, onDragStart: saveCurrentLayouts, onResize: onResize, onResizeStop: onResizeStop, children: layoutChildren })] }));
91
- }
92
- VitessceGridLayout.defaultProps = {
93
- padding: 10,
94
- margin: 10,
95
- };
@@ -1,40 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import '@testing-library/jest-dom';
3
- import { cleanup, render, screen } from '@testing-library/react';
4
- import { afterEach } from 'vitest';
5
- import { VitessceGridLayout } from './VitessceGridLayout';
6
- afterEach(() => {
7
- cleanup();
8
- });
9
- function FakeComponent(props) {
10
- const { text } = props;
11
- return _jsx("span", { children: text });
12
- }
13
- const layoutJson = {
14
- columns: {
15
- 600: [0, 2, 4, 8],
16
- },
17
- components: [
18
- { component: 'FakeComponent',
19
- uid: 'fake',
20
- props: { text: 'Hello World' },
21
- x: 0, y: 0, w: 2 },
22
- ],
23
- };
24
- describe('VitessceGridLayout.js', () => {
25
- describe('<VitessceGridLayout />', () => {
26
- it('mount() works', async () => {
27
- const { container } = render(_jsx(VitessceGridLayout, { layout: layoutJson, getComponent: () => FakeComponent, draggableHandle: ".my-handle" }));
28
- expect(await screen.findByText('Hello World'));
29
- expect(container.querySelectorAll('.react-grid-item span:not(.react-resizable-handle)').length).toEqual(1);
30
- const style = container.querySelectorAll('style');
31
- expect(style.length).toEqual(1);
32
- expect(style[0].textContent).toContain('.my-handle {');
33
- expect(style[0].textContent).toContain('.my-handle:active {');
34
- });
35
- it('rowHeight works', () => {
36
- const { container } = render(_jsx(VitessceGridLayout, { layout: layoutJson, getComponent: () => FakeComponent, draggableHandle: ".my-handle", rowHeight: 123 }));
37
- expect(container.querySelector('.react-grid-item').style.height).toEqual('123px');
38
- });
39
- });
40
- });
@@ -1,60 +0,0 @@
1
- import range from 'lodash/range';
2
- function sum(a) {
3
- return a.reduce((x, y) => x + y, 0);
4
- }
5
- export function makeGridLayout(colXs, colLayout) {
6
- const colWs = [];
7
- for (let i = 0; i < colXs.length; i++) { // eslint-disable-line no-plusplus
8
- colWs.push(colXs[i + 1] - colXs[i]);
9
- }
10
- return Object.entries(colLayout).map(([id, spec]) => ({
11
- i: id,
12
- y: spec.y,
13
- h: spec.h || 1,
14
- x: colXs[spec.x],
15
- w: sum(colWs.slice(spec.x, spec.x + (spec.w || 1))),
16
- }));
17
- }
18
- export function getMaxRows(layouts) {
19
- return Math.max(...Object.values(layouts).map(layout => Math.max(...layout.map(xywh => xywh.y + xywh.h))));
20
- }
21
- export function resolveLayout(layout) {
22
- const cols = {};
23
- const layouts = {};
24
- const breakpoints = {};
25
- const components = {};
26
- const positions = {};
27
- (('components' in layout) ? layout.components : layout).forEach((def) => {
28
- const id = def.uid;
29
- components[id] = {
30
- uid: def.uid,
31
- component: def.component,
32
- props: def.props || {},
33
- coordinationScopes: def.coordinationScopes || {},
34
- };
35
- positions[id] = {
36
- id, x: def.x, y: def.y, w: def.w, h: def.h,
37
- };
38
- });
39
- if ('components' in layout) {
40
- Object.entries(layout.columns).forEach(([width, columnXs]) => {
41
- cols[width] = columnXs[columnXs.length - 1];
42
- layouts[width] = makeGridLayout(columnXs, positions);
43
- breakpoints[width] = width;
44
- });
45
- }
46
- else {
47
- // static layout
48
- const id = 'ID';
49
- const columnCount = 12;
50
- cols[id] = columnCount;
51
- layouts[id] = makeGridLayout(range(columnCount + 1), positions);
52
- breakpoints[id] = 1000;
53
- // Default has different numbers of columns at different widths,
54
- // so we do need to override that to ensure the same number of columns,
55
- // regardless of window width.
56
- }
57
- return {
58
- cols, layouts, breakpoints, components,
59
- };
60
- }
@@ -1,146 +0,0 @@
1
- import { makeGridLayout, getMaxRows, resolveLayout, } from './layout-utils';
2
- describe('layout-utils.js', () => {
3
- describe('makeGridLayout', () => {
4
- it('applies columnXs and makes list from object', () => {
5
- const columnXs = [0, 4, 8, 12];
6
- const layout = {
7
- bigLeft: { x: 0, y: 0, w: 2 },
8
- smallRight: { x: 2, y: 0 },
9
- smallLeft: { x: 0, y: 1 },
10
- bigRight: { x: 1, y: 1, w: 2 },
11
- wholeRow: { x: 0, y: 2, w: 3 },
12
- };
13
- const gridLayout = makeGridLayout(columnXs, layout);
14
- expect(gridLayout).toEqual(
15
- /* Disable eslint so it's easier to copy-and-paste from test results. */
16
- /* eslint-disable quote-props */
17
- /* eslint-disable quotes */
18
- [
19
- {
20
- "h": 1,
21
- "i": "bigLeft",
22
- "w": 8,
23
- "x": 0,
24
- "y": 0,
25
- },
26
- {
27
- "h": 1,
28
- "i": "smallRight",
29
- "w": 4,
30
- "x": 8,
31
- "y": 0,
32
- },
33
- {
34
- "h": 1,
35
- "i": "smallLeft",
36
- "w": 4,
37
- "x": 0,
38
- "y": 1,
39
- },
40
- {
41
- "h": 1,
42
- "i": "bigRight",
43
- "w": 8,
44
- "x": 4,
45
- "y": 1,
46
- },
47
- {
48
- "h": 1,
49
- "i": "wholeRow",
50
- "w": 12,
51
- "x": 0,
52
- "y": 2,
53
- },
54
- ]);
55
- });
56
- });
57
- describe('getMaxRows', () => {
58
- it('works', () => {
59
- const columnXs = [0, 4, 8, 12];
60
- const layout = {
61
- bigLeft: { x: 0, y: 0, w: 2 },
62
- smallRight: { x: 2, y: 0 },
63
- smallLeft: { x: 0, y: 1 },
64
- bigRight: { x: 1, y: 1, w: 2 },
65
- wholeRow: { x: 0, y: 2, w: 3 },
66
- };
67
- const gridLayout = makeGridLayout(columnXs, layout);
68
- expect(getMaxRows([gridLayout])).toEqual(3);
69
- });
70
- });
71
- describe('resolveLayout', () => {
72
- const componentsSpec = [
73
- {
74
- uid: 'i0', component: 'NoProps', x: 0, y: 0,
75
- },
76
- {
77
- uid: 'i1', component: 'HasProps', props: { foo: 'bar' }, x: 1, y: 1, w: 1, h: 1,
78
- },
79
- ];
80
- const expectedComponents = {
81
- i0: {
82
- uid: 'i0',
83
- component: 'NoProps',
84
- coordinationScopes: {},
85
- props: {},
86
- },
87
- i1: {
88
- uid: 'i1',
89
- component: 'HasProps',
90
- coordinationScopes: {},
91
- props: {
92
- foo: 'bar',
93
- },
94
- },
95
- };
96
- it('handles responsive', () => {
97
- const { cols, layouts, breakpoints, components, } = resolveLayout({
98
- columns: {
99
- 1000: [0, 3, 9, 12],
100
- 800: [0, 4, 8, 12],
101
- },
102
- components: componentsSpec,
103
- });
104
- expect(cols).toEqual({ 800: 12, 1000: 12 });
105
- expect(layouts).toEqual({
106
- 800: [
107
- {
108
- h: 1, i: 'i0', w: 4, x: 0, y: 0,
109
- },
110
- {
111
- h: 1, i: 'i1', w: 4, x: 4, y: 1,
112
- },
113
- ],
114
- 1000: [
115
- {
116
- h: 1, i: 'i0', w: 3, x: 0, y: 0,
117
- },
118
- {
119
- h: 1, i: 'i1', w: 6, x: 3, y: 1,
120
- },
121
- ],
122
- });
123
- expect(breakpoints).toEqual({
124
- 800: '800',
125
- 1000: '1000',
126
- });
127
- expect(components).toEqual(expectedComponents);
128
- });
129
- it('handles static', () => {
130
- const { cols, layouts, breakpoints, components, } = resolveLayout(componentsSpec);
131
- expect(cols).toEqual({ ID: 12 });
132
- expect(layouts).toEqual({
133
- ID: [
134
- {
135
- h: 1, i: 'i0', w: 1, x: 0, y: 0,
136
- },
137
- {
138
- h: 1, i: 'i1', w: 1, x: 1, y: 1,
139
- },
140
- ],
141
- });
142
- expect(breakpoints).toEqual({ ID: 1000 });
143
- expect(components).toEqual(expectedComponents);
144
- });
145
- });
146
- });
@@ -1,140 +0,0 @@
1
- import { useState, useEffect, useRef, } from 'react';
2
- import { InternMap } from 'internmap';
3
- import isEqual from 'lodash/isEqual';
4
- import pick from 'lodash/pick';
5
- import { DEFAULT_COORDINATION_VALUES, DATA_TYPE_COORDINATION_VALUE_USAGE } from '@vitessce/constants-internal';
6
- import { getSourceAndLoaderFromFileType } from './data/loader-registry';
7
- import { getFileTypeDataTypeMapping } from './plugins';
8
- /**
9
- * Return the bottom coordinate of the layout.
10
- * https://github.com/STRML/react-grid-layout/blob/20dac73f91274526034c00968b5bedb9c2ed36b9/lib/utils.js#L82
11
- * @param {array} layout react-grid-layout layout array.
12
- * @returns {number} Bottom coordinate.
13
- */
14
- function getNumRows(layout) {
15
- let max = 0;
16
- let bottomY;
17
- // eslint-disable-next-line no-plusplus
18
- for (let i = 0, len = layout.length; i < len; i++) {
19
- bottomY = layout[i].y + layout[i].h;
20
- if (bottomY > max)
21
- max = bottomY;
22
- }
23
- return max;
24
- }
25
- /**
26
- * Compute the row height based on the container height, number of rows,
27
- * and margin/padding. Basically the reverse of the react-grid-layout's
28
- * `.containerHeight()` function.
29
- * https://github.com/STRML/react-grid-layout/blob/83251e5e682abfa3252ff89d4bacf47fdc1f4270/lib/ReactGridLayout.jsx#L223
30
- * @param {number} containerHeight The height of the .vitessce-container element.
31
- * @param {number} numRows The number of rows in the layout.
32
- * @param {number} margin The margin value that will be passed to VitessceGrid.
33
- * @param {number} padding The padding value that will be passed to VitessceGrid.
34
- * @returns {number} The new row height value.
35
- */
36
- function getRowHeight(containerHeight, numRows, margin, padding) {
37
- const effectiveContainerHeight = containerHeight - 2 * padding - (numRows - 1) * margin;
38
- return effectiveContainerHeight / numRows;
39
- }
40
- export function useRowHeight(config, initialRowHeight, height, margin, padding) {
41
- const [containerHeight, setContainerHeight] = useState(height);
42
- const [rowHeight, setRowHeight] = useState(initialRowHeight);
43
- const containerRef = useRef();
44
- // Detect when the `config` or `containerHeight` variables
45
- // have changed, and update `rowHeight` in response.
46
- useEffect(() => {
47
- const numRows = getNumRows(config.layout);
48
- const newRowHeight = getRowHeight(containerHeight, numRows, margin, padding);
49
- setRowHeight(newRowHeight);
50
- }, [containerHeight, config, margin, padding]);
51
- // Update the `containerHeight` state when the `height` prop has changed.
52
- useEffect(() => {
53
- if (height !== null && height !== undefined) {
54
- setContainerHeight(height);
55
- }
56
- }, [height]);
57
- // If no height prop has been provided, set the `containerHeight`
58
- // using height of the `.vitessce-container` element.
59
- // Check the container element height whenever the window has been
60
- // resized, as it may change if `.vitessce-container` should be
61
- // sized relative to its parent (and by extension, potentially the window).
62
- useEffect(() => {
63
- if (height !== null && height !== undefined) {
64
- // eslint will complain if the return value is inconsistent,
65
- // so return a no-op function.
66
- return () => { };
67
- }
68
- function onWindowResize() {
69
- if (!containerRef.current)
70
- return;
71
- const containerRect = containerRef.current.getBoundingClientRect();
72
- setContainerHeight(containerRect.height);
73
- }
74
- window.addEventListener('resize', onWindowResize);
75
- onWindowResize();
76
- return () => {
77
- window.removeEventListener('resize', onWindowResize);
78
- };
79
- }, [containerRef, height]);
80
- return [rowHeight, containerRef];
81
- }
82
- function withDefaults(coordinationValues, dataType, fileType, datasetUid) {
83
- const defaultKeys = DATA_TYPE_COORDINATION_VALUE_USAGE[dataType]
84
- .filter(k => (Object.keys(DEFAULT_COORDINATION_VALUES).includes(k)
85
- && DEFAULT_COORDINATION_VALUES[k]
86
- && !Object.keys(coordinationValues).includes(k)));
87
- const defaultValues = pick(DEFAULT_COORDINATION_VALUES, defaultKeys);
88
- const coordinationValuesWithDefaults = {
89
- ...defaultValues,
90
- // The user-provided values should take precedence.
91
- ...coordinationValues,
92
- };
93
- if (!isEqual(coordinationValues, coordinationValuesWithDefaults)) {
94
- // eslint-disable-next-line max-len
95
- console.warn(`Using coordination value defaults for file type ${fileType} in dataset ${datasetUid}\nBefore: ${JSON.stringify(coordinationValues)}\nAfter: ${JSON.stringify(coordinationValuesWithDefaults)}`);
96
- }
97
- return coordinationValuesWithDefaults;
98
- }
99
- /**
100
- * Create a mapping from dataset ID to loader objects by data type.
101
- * @param {object[]} datasets The datasets array from the view config.
102
- * @param {string} configDescription The top-level description in the
103
- * view config.
104
- * @returns {object} Mapping from dataset ID to data type to loader
105
- * instance.
106
- */
107
- export function createLoaders(datasets, configDescription) {
108
- const result = {};
109
- const dataSources = {};
110
- const fileTypeDataTypeMapping = getFileTypeDataTypeMapping();
111
- datasets.forEach((dataset) => {
112
- const datasetLoaders = {
113
- name: dataset.name,
114
- description: dataset.description || configDescription,
115
- loaders: {},
116
- };
117
- dataset.files.forEach((file) => {
118
- const { url, options, requestInit, fileType, coordinationValues = {}, } = file;
119
- const dataType = fileTypeDataTypeMapping[fileType];
120
- const coordinationValuesWithDefaults = withDefaults(coordinationValues, dataType, fileType, dataset.uid);
121
- const [DataSourceClass, LoaderClass] = getSourceAndLoaderFromFileType(fileType);
122
- // Create _one_ DataSourceClass instance per URL. Derived loaders share this object.
123
- const fileId = url || JSON.stringify(options);
124
- if (!(fileId in dataSources)) {
125
- dataSources[fileId] = new DataSourceClass({ url, requestInit });
126
- }
127
- const loader = new LoaderClass(dataSources[fileId], file);
128
- if (datasetLoaders.loaders[dataType]) {
129
- datasetLoaders.loaders[dataType].set(coordinationValuesWithDefaults, loader);
130
- }
131
- else {
132
- datasetLoaders.loaders[dataType] = new InternMap([
133
- [coordinationValuesWithDefaults, loader],
134
- ], JSON.stringify);
135
- }
136
- });
137
- result[dataset.uid] = datasetLoaders;
138
- });
139
- return result;
140
- }