@genspectrum/dashboard-components 0.13.6 → 0.14.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 (73) hide show
  1. package/custom-elements.json +41 -79
  2. package/dist/{LineageFilterChangedEvent-GedKNGFI.js → LineageFilterChangedEvent-C9dXOxt6.js} +11 -3
  3. package/dist/LineageFilterChangedEvent-C9dXOxt6.js.map +1 -0
  4. package/dist/components.d.ts +63 -71
  5. package/dist/components.js +440 -312
  6. package/dist/components.js.map +1 -1
  7. package/dist/style.css +20 -5
  8. package/dist/util.d.ts +61 -51
  9. package/dist/util.js +1 -1
  10. package/package.json +1 -1
  11. package/src/preact/LapisUrlContext.ts +14 -1
  12. package/src/preact/aggregatedData/aggregate.stories.tsx +3 -3
  13. package/src/preact/aggregatedData/aggregate.tsx +3 -4
  14. package/src/preact/components/tabs.tsx +3 -5
  15. package/src/preact/dateRangeSelector/computeInitialValues.spec.ts +34 -20
  16. package/src/preact/dateRangeSelector/computeInitialValues.ts +25 -21
  17. package/src/preact/dateRangeSelector/date-range-selector.stories.tsx +104 -40
  18. package/src/preact/dateRangeSelector/date-range-selector.tsx +29 -20
  19. package/src/preact/dateRangeSelector/dateRangeOption.ts +11 -1
  20. package/src/preact/lineageFilter/lineage-filter.stories.tsx +3 -3
  21. package/src/preact/lineageFilter/lineage-filter.tsx +3 -4
  22. package/src/preact/locationFilter/location-filter.stories.tsx +3 -3
  23. package/src/preact/locationFilter/location-filter.tsx +4 -4
  24. package/src/preact/map/sequences-by-location.stories.tsx +3 -3
  25. package/src/preact/map/sequences-by-location.tsx +3 -4
  26. package/src/preact/mutationComparison/mutation-comparison.stories.tsx +3 -3
  27. package/src/preact/mutationComparison/mutation-comparison.tsx +4 -4
  28. package/src/preact/mutationFilter/ExampleMutation.tsx +68 -0
  29. package/src/preact/mutationFilter/mutation-filter-info.tsx +179 -112
  30. package/src/preact/mutationFilter/mutation-filter.stories.tsx +5 -5
  31. package/src/preact/mutationFilter/mutation-filter.tsx +10 -5
  32. package/src/preact/mutations/mutations.stories.tsx +3 -3
  33. package/src/preact/mutations/mutations.tsx +4 -4
  34. package/src/preact/mutationsOverTime/mutations-over-time-grid.tsx +26 -4
  35. package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +3 -3
  36. package/src/preact/mutationsOverTime/mutations-over-time.tsx +4 -4
  37. package/src/preact/numberSequencesOverTime/number-sequences-over-time.stories.tsx +3 -3
  38. package/src/preact/numberSequencesOverTime/number-sequences-over-time.tsx +4 -4
  39. package/src/preact/prevalenceOverTime/prevalence-over-time.stories.tsx +3 -3
  40. package/src/preact/prevalenceOverTime/prevalence-over-time.tsx +4 -4
  41. package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.stories.tsx +3 -3
  42. package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.tsx +4 -4
  43. package/src/preact/statistic/statistics.stories.tsx +3 -3
  44. package/src/preact/statistic/statistics.tsx +2 -3
  45. package/src/preact/textInput/text-input.stories.tsx +3 -3
  46. package/src/preact/textInput/text-input.tsx +3 -4
  47. package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.stories.tsx +5 -9
  48. package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.tsx +5 -5
  49. package/src/web-components/PreactLitAdapter.tsx +3 -3
  50. package/src/web-components/{app.stories.ts → gs-app.stories.ts} +1 -1
  51. package/src/web-components/{app.ts → gs-app.ts} +5 -3
  52. package/src/web-components/index.ts +1 -1
  53. package/src/web-components/input/gs-date-range-selector.stories.ts +6 -13
  54. package/src/web-components/input/gs-date-range-selector.tsx +15 -38
  55. package/src/web-components/input/gs-lineage-filter.stories.ts +1 -1
  56. package/src/web-components/input/gs-location-filter.stories.ts +1 -1
  57. package/src/web-components/input/gs-mutation-filter.stories.ts +2 -2
  58. package/src/web-components/input/gs-text-input.stories.ts +1 -1
  59. package/src/web-components/visualization/gs-aggregate.stories.ts +1 -1
  60. package/src/web-components/visualization/gs-mutation-comparison.stories.ts +1 -1
  61. package/src/web-components/visualization/gs-mutations-over-time.stories.ts +1 -1
  62. package/src/web-components/visualization/gs-mutations.stories.ts +1 -1
  63. package/src/web-components/visualization/gs-number-sequences-over-time.stories.ts +1 -1
  64. package/src/web-components/visualization/gs-prevalence-over-time.stories.ts +1 -1
  65. package/src/web-components/visualization/gs-relative-growth-advantage.stories.ts +1 -1
  66. package/src/web-components/visualization/gs-sequences-by-location.stories.ts +1 -1
  67. package/src/web-components/visualization/gs-statistics.stories.ts +1 -1
  68. package/src/web-components/wastewaterVisualization/gs-wastewater-mutations-over-time.stories.ts +4 -1
  69. package/src/web-components/wastewaterVisualization/gs-wastewater-mutations-over-time.tsx +6 -2
  70. package/standalone-bundle/dashboard-components.js +7016 -6951
  71. package/standalone-bundle/dashboard-components.js.map +1 -1
  72. package/standalone-bundle/style.css +1 -1
  73. package/dist/LineageFilterChangedEvent-GedKNGFI.js.map +0 -1
@@ -4,7 +4,7 @@ import { expect, userEvent, waitFor } from '@storybook/test';
4
4
  import { MutationsOverTime, type MutationsOverTimeProps } from './mutations-over-time';
5
5
  import { LAPIS_URL } from '../../constants';
6
6
  import referenceGenome from '../../lapisApi/__mockData__/referenceGenome.json';
7
- import { LapisUrlContext } from '../LapisUrlContext';
7
+ import { LapisUrlContextProvider } from '../LapisUrlContext';
8
8
  import { ReferenceGenomeContext } from '../ReferenceGenomeContext';
9
9
  import { expectInvalidAttributesErrorMessage } from '../shared/stories/expectErrorMessage';
10
10
 
@@ -38,7 +38,7 @@ export default meta;
38
38
 
39
39
  const Template = {
40
40
  render: (args: MutationsOverTimeProps) => (
41
- <LapisUrlContext.Provider value={LAPIS_URL}>
41
+ <LapisUrlContextProvider value={LAPIS_URL}>
42
42
  <ReferenceGenomeContext.Provider value={referenceGenome}>
43
43
  <MutationsOverTime
44
44
  lapisFilter={args.lapisFilter}
@@ -50,7 +50,7 @@ const Template = {
50
50
  lapisDateField={args.lapisDateField}
51
51
  />
52
52
  </ReferenceGenomeContext.Provider>
53
- </LapisUrlContext.Provider>
53
+ </LapisUrlContextProvider>
54
54
  ),
55
55
  };
56
56
 
@@ -1,5 +1,5 @@
1
1
  import { type FunctionComponent } from 'preact';
2
- import { type Dispatch, type StateUpdater, useContext, useMemo, useState } from 'preact/hooks';
2
+ import { type Dispatch, type StateUpdater, useMemo, useState } from 'preact/hooks';
3
3
  import z from 'zod';
4
4
 
5
5
  // @ts-expect-error -- uses subpath imports and vite worker import
@@ -18,7 +18,7 @@ import {
18
18
  } from '../../types';
19
19
  import { type Deletion, type Substitution } from '../../utils/mutations';
20
20
  import { toTemporalClass } from '../../utils/temporalClass';
21
- import { LapisUrlContext } from '../LapisUrlContext';
21
+ import { useLapisUrl } from '../LapisUrlContext';
22
22
  import { type ColorScale } from '../components/color-scale-selector';
23
23
  import { ColorScaleSelectorDropdown } from '../components/color-scale-selector-dropdown';
24
24
  import { CsvDownloadButton } from '../components/csv-download-button';
@@ -63,7 +63,7 @@ export const MutationsOverTime: FunctionComponent<MutationsOverTimeProps> = (com
63
63
  };
64
64
 
65
65
  export const MutationsOverTimeInner: FunctionComponent<MutationsOverTimeProps> = (componentProps) => {
66
- const lapis = useContext(LapisUrlContext);
66
+ const lapis = useLapisUrl();
67
67
  const { lapisFilter, sequenceType, granularity, lapisDateField } = componentProps;
68
68
 
69
69
  const messageToWorker = useMemo(() => {
@@ -230,7 +230,7 @@ type MutationsOverTimeInfoProps = {
230
230
  };
231
231
 
232
232
  const MutationsOverTimeInfo: FunctionComponent<MutationsOverTimeInfoProps> = ({ originalComponentProps }) => {
233
- const lapis = useContext(LapisUrlContext);
233
+ const lapis = useLapisUrl();
234
234
  return (
235
235
  <Info>
236
236
  <InfoHeadline1>Mutations over time</InfoHeadline1>
@@ -5,7 +5,7 @@ import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
5
5
  import oneVariantEG from '../../preact/numberSequencesOverTime/__mockData__/oneVariantEG.json';
6
6
  import twoVariantsEG from '../../preact/numberSequencesOverTime/__mockData__/twoVariantsEG.json';
7
7
  import twoVariantsJN1 from '../../preact/numberSequencesOverTime/__mockData__/twoVariantsJN1.json';
8
- import { LapisUrlContext } from '../LapisUrlContext';
8
+ import { LapisUrlContextProvider } from '../LapisUrlContext';
9
9
  import { expectInvalidAttributesErrorMessage } from '../shared/stories/expectErrorMessage';
10
10
 
11
11
  export default {
@@ -29,9 +29,9 @@ export default {
29
29
 
30
30
  const Template: StoryObj<NumberSequencesOverTimeProps> = {
31
31
  render: (args) => (
32
- <LapisUrlContext.Provider value={LAPIS_URL}>
32
+ <LapisUrlContextProvider value={LAPIS_URL}>
33
33
  <NumberSequencesOverTime {...args} />
34
- </LapisUrlContext.Provider>
34
+ </LapisUrlContextProvider>
35
35
  ),
36
36
  args: {
37
37
  views: ['bar', 'line', 'table'],
@@ -1,5 +1,5 @@
1
1
  import { type FunctionComponent } from 'preact';
2
- import { useContext, useState } from 'preact/hooks';
2
+ import { useState } from 'preact/hooks';
3
3
  import z from 'zod';
4
4
 
5
5
  import { getNumberOfSequencesOverTimeTableData } from './getNumberOfSequencesOverTimeTableData';
@@ -11,7 +11,7 @@ import {
11
11
  queryNumberOfSequencesOverTime,
12
12
  } from '../../query/queryNumberOfSequencesOverTime';
13
13
  import { namedLapisFilterSchema, temporalGranularitySchema, views } from '../../types';
14
- import { LapisUrlContext } from '../LapisUrlContext';
14
+ import { useLapisUrl } from '../LapisUrlContext';
15
15
  import { CsvDownloadButton } from '../components/csv-download-button';
16
16
  import { ErrorBoundary } from '../components/error-boundary';
17
17
  import { Fullscreen } from '../components/fullscreen';
@@ -59,7 +59,7 @@ export const NumberSequencesOverTime = (componentProps: NumberSequencesOverTimeP
59
59
 
60
60
  const NumberSequencesOverTimeInner = (componentProps: NumberSequencesOverTimeProps) => {
61
61
  const { lapisFilters, lapisDateField, granularity, smoothingWindow } = componentProps;
62
- const lapis = useContext(LapisUrlContext);
62
+ const lapis = useLapisUrl();
63
63
 
64
64
  const { data, error, isLoading } = useQuery(
65
65
  () => queryNumberOfSequencesOverTime(lapis, lapisFilters, lapisDateField, granularity, smoothingWindow),
@@ -169,7 +169,7 @@ type NumberSequencesOverTimeInfoProps = {
169
169
  const NumberSequencesOverTimeInfo: FunctionComponent<NumberSequencesOverTimeInfoProps> = ({
170
170
  originalComponentProps,
171
171
  }) => {
172
- const lapis = useContext(LapisUrlContext);
172
+ const lapis = useLapisUrl();
173
173
 
174
174
  return (
175
175
  <Info>
@@ -1,7 +1,7 @@
1
1
  import type { StoryObj } from '@storybook/preact';
2
2
  import { expect, waitFor } from '@storybook/test';
3
3
 
4
- import { LapisUrlContext } from '../LapisUrlContext';
4
+ import { LapisUrlContextProvider } from '../LapisUrlContext';
5
5
  import denominatorFilter from './__mockData__/denominatorFilter.json';
6
6
  import denominatorOneDataset from './__mockData__/denominatorFilterOneDataset.json';
7
7
  import numeratorFilterEG from './__mockData__/numeratorFilterEG.json';
@@ -42,9 +42,9 @@ export default {
42
42
 
43
43
  const Template = {
44
44
  render: (args: PrevalenceOverTimeProps) => (
45
- <LapisUrlContext.Provider value={LAPIS_URL}>
45
+ <LapisUrlContextProvider value={LAPIS_URL}>
46
46
  <PrevalenceOverTime {...args} />
47
- </LapisUrlContext.Provider>
47
+ </LapisUrlContextProvider>
48
48
  ),
49
49
  };
50
50
 
@@ -1,5 +1,5 @@
1
1
  import { type FunctionComponent } from 'preact';
2
- import { useContext, useEffect, useState } from 'preact/hooks';
2
+ import { useEffect, useState } from 'preact/hooks';
3
3
  import z from 'zod';
4
4
 
5
5
  import { getPrevalenceOverTimeTableData } from './getPrevalenceOverTimeTableData';
@@ -9,7 +9,7 @@ import PrevalenceOverTimeLineChart from './prevalence-over-time-line-chart';
9
9
  import PrevalenceOverTimeTable from './prevalence-over-time-table';
10
10
  import { type PrevalenceOverTimeData, queryPrevalenceOverTime } from '../../query/queryPrevalenceOverTime';
11
11
  import { lapisFilterSchema, namedLapisFilterSchema, temporalGranularitySchema, views } from '../../types';
12
- import { LapisUrlContext } from '../LapisUrlContext';
12
+ import { useLapisUrl } from '../LapisUrlContext';
13
13
  import { ConfidenceIntervalSelector } from '../components/confidence-interval-selector';
14
14
  import { CsvDownloadButton } from '../components/csv-download-button';
15
15
  import { ErrorBoundary } from '../components/error-boundary';
@@ -65,7 +65,7 @@ export const PrevalenceOverTime: FunctionComponent<PrevalenceOverTimeProps> = (c
65
65
 
66
66
  export const PrevalenceOverTimeInner: FunctionComponent<PrevalenceOverTimeProps> = (componentProps) => {
67
67
  const { numeratorFilters, denominatorFilter, granularity, smoothingWindow, lapisDateField } = componentProps;
68
- const lapis = useContext(LapisUrlContext);
68
+ const lapis = useLapisUrl();
69
69
 
70
70
  const { data, error, isLoading } = useQuery(
71
71
  () =>
@@ -226,7 +226,7 @@ const Toolbar: FunctionComponent<ToolbarProps> = ({
226
226
 
227
227
  const PrevalenceOverTimeInfo: FunctionComponent<PrevalenceOverTimeProps> = (componentProps) => {
228
228
  const { granularity, smoothingWindow, views } = componentProps;
229
- const lapis = useContext(LapisUrlContext);
229
+ const lapis = useLapisUrl();
230
230
  return (
231
231
  <Info>
232
232
  <InfoHeadline1>Prevalence over time</InfoHeadline1>
@@ -5,7 +5,7 @@ import denominator from './__mockData__/denominatorFilter.json';
5
5
  import numerator from './__mockData__/numeratorFilter.json';
6
6
  import { RelativeGrowthAdvantage, type RelativeGrowthAdvantageProps } from './relative-growth-advantage';
7
7
  import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
8
- import { LapisUrlContext } from '../LapisUrlContext';
8
+ import { LapisUrlContextProvider } from '../LapisUrlContext';
9
9
  import { expectInvalidAttributesErrorMessage } from '../shared/stories/expectErrorMessage';
10
10
 
11
11
  export default {
@@ -30,9 +30,9 @@ export default {
30
30
 
31
31
  export const Primary: StoryObj<RelativeGrowthAdvantageProps> = {
32
32
  render: (args: RelativeGrowthAdvantageProps) => (
33
- <LapisUrlContext.Provider value={LAPIS_URL}>
33
+ <LapisUrlContextProvider value={LAPIS_URL}>
34
34
  <RelativeGrowthAdvantage {...args} />
35
- </LapisUrlContext.Provider>
35
+ </LapisUrlContextProvider>
36
36
  ),
37
37
  args: {
38
38
  numeratorFilter: {
@@ -1,5 +1,5 @@
1
1
  import { type FunctionComponent } from 'preact';
2
- import { useContext, useState } from 'preact/hooks';
2
+ import { useState } from 'preact/hooks';
3
3
  import z from 'zod';
4
4
 
5
5
  import RelativeGrowthAdvantageChart from './relative-growth-advantage-chart';
@@ -9,7 +9,7 @@ import {
9
9
  type RelativeGrowthAdvantageData,
10
10
  } from '../../query/queryRelativeGrowthAdvantage';
11
11
  import { lapisFilterSchema, views } from '../../types';
12
- import { LapisUrlContext } from '../LapisUrlContext';
12
+ import { useLapisUrl } from '../LapisUrlContext';
13
13
  import { ErrorBoundary } from '../components/error-boundary';
14
14
  import { Fullscreen } from '../components/fullscreen';
15
15
  import Info, { InfoComponentCode, InfoHeadline1, InfoHeadline2, InfoLink, InfoParagraph } from '../components/info';
@@ -52,7 +52,7 @@ export const RelativeGrowthAdvantage: FunctionComponent<RelativeGrowthAdvantageP
52
52
  };
53
53
 
54
54
  export const RelativeGrowthAdvantageInner: FunctionComponent<RelativeGrowthAdvantageProps> = (componentProps) => {
55
- const lapis = useContext(LapisUrlContext);
55
+ const lapis = useLapisUrl();
56
56
  const { numeratorFilter, denominatorFilter, generationTime, lapisDateField } = componentProps;
57
57
 
58
58
  const [yAxisScaleType, setYAxisScaleType] = useState<ScaleType>('linear');
@@ -160,7 +160,7 @@ const RelativeGrowthAdvantageToolbar: FunctionComponent<RelativeGrowthAdvantageT
160
160
  const RelativeGrowthAdvantageInfo: FunctionComponent<{ originalComponentProps: RelativeGrowthAdvantageProps }> = ({
161
161
  originalComponentProps,
162
162
  }) => {
163
- const lapis = useContext(LapisUrlContext);
163
+ const lapis = useLapisUrl();
164
164
  const generationTime = originalComponentProps.generationTime;
165
165
 
166
166
  return (
@@ -2,7 +2,7 @@ import { type Meta, type StoryObj } from '@storybook/preact';
2
2
  import { expect, waitFor, within } from '@storybook/test';
3
3
 
4
4
  import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
5
- import { LapisUrlContext } from '../LapisUrlContext';
5
+ import { LapisUrlContextProvider } from '../LapisUrlContext';
6
6
  import denominatorData from './__mockData__/denominator.json';
7
7
  import numeratorData from './__mockData__/numerator.json';
8
8
  import { Statistics, type StatisticsProps } from './statistics';
@@ -55,9 +55,9 @@ export default meta;
55
55
 
56
56
  export const Default: StoryObj<StatisticsProps> = {
57
57
  render: (args) => (
58
- <LapisUrlContext.Provider value={LAPIS_URL}>
58
+ <LapisUrlContextProvider value={LAPIS_URL}>
59
59
  <Statistics {...args} />
60
- </LapisUrlContext.Provider>
60
+ </LapisUrlContextProvider>
61
61
  ),
62
62
  args: {
63
63
  numeratorFilter: {
@@ -1,10 +1,9 @@
1
1
  import { type FunctionComponent } from 'preact';
2
- import { useContext } from 'preact/hooks';
3
2
  import z from 'zod';
4
3
 
5
4
  import { queryGeneralStatistics } from '../../query/queryGeneralStatistics';
6
5
  import { lapisFilterSchema } from '../../types';
7
- import { LapisUrlContext } from '../LapisUrlContext';
6
+ import { useLapisUrl } from '../LapisUrlContext';
8
7
  import { ErrorBoundary } from '../components/error-boundary';
9
8
  import { LoadingDisplay } from '../components/loading-display';
10
9
  import { NoDataDisplay } from '../components/no-data-display';
@@ -35,7 +34,7 @@ export const Statistics: FunctionComponent<StatisticsProps> = (componentProps) =
35
34
 
36
35
  export const StatisticsInner: FunctionComponent<StatisticsProps> = (componentProps) => {
37
36
  const { numeratorFilter, denominatorFilter } = componentProps;
38
- const lapis = useContext(LapisUrlContext);
37
+ const lapis = useLapisUrl();
39
38
 
40
39
  const { data, error, isLoading } = useQuery(async () => {
41
40
  return queryGeneralStatistics(numeratorFilter, denominatorFilter, lapis);
@@ -5,7 +5,7 @@ import data from './__mockData__/aggregated_hosts.json';
5
5
  import { TextInput, type TextInputProps } from './text-input';
6
6
  import { previewHandles } from '../../../.storybook/preview';
7
7
  import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
8
- import { LapisUrlContext } from '../LapisUrlContext';
8
+ import { LapisUrlContextProvider } from '../LapisUrlContext';
9
9
  import { expectInvalidAttributesErrorMessage } from '../shared/stories/expectErrorMessage';
10
10
 
11
11
  const meta: Meta<TextInputProps> = {
@@ -67,9 +67,9 @@ export default meta;
67
67
 
68
68
  export const Default: StoryObj<TextInputProps> = {
69
69
  render: (args) => (
70
- <LapisUrlContext.Provider value={LAPIS_URL}>
70
+ <LapisUrlContextProvider value={LAPIS_URL}>
71
71
  <TextInput {...args} />
72
- </LapisUrlContext.Provider>
72
+ </LapisUrlContextProvider>
73
73
  ),
74
74
  args: {
75
75
  lapisField: 'host',
@@ -1,10 +1,9 @@
1
1
  import { type FunctionComponent } from 'preact';
2
- import { useContext } from 'preact/hooks';
3
2
  import z from 'zod';
4
3
 
5
- import { fetchStringAutocompleteList } from './fetchStringAutocompleteList';
6
- import { LapisUrlContext } from '../LapisUrlContext';
4
+ import { useLapisUrl } from '../LapisUrlContext';
7
5
  import { TextInputChangedEvent } from './TextInputChangedEvent';
6
+ import { fetchStringAutocompleteList } from './fetchStringAutocompleteList';
8
7
  import { lapisFilterSchema } from '../../types';
9
8
  import { DownshiftCombobox } from '../components/downshift-combobox';
10
9
  import { ErrorBoundary } from '../components/error-boundary';
@@ -46,7 +45,7 @@ const TextInputInner: FunctionComponent<TextInputInnerProps> = ({
46
45
  placeholderText,
47
46
  lapisFilter,
48
47
  }) => {
49
- const lapis = useContext(LapisUrlContext);
48
+ const lapis = useLapisUrl();
50
49
 
51
50
  const { data, error, isLoading } = useQuery(
52
51
  () => fetchStringAutocompleteList({ lapis, field: lapisField, lapisFilter }),
@@ -3,7 +3,7 @@ import { type Meta, type StoryObj } from '@storybook/preact';
3
3
  import { WastewaterMutationsOverTime, type WastewaterMutationsOverTimeProps } from './wastewater-mutations-over-time';
4
4
  import { WISE_DETAILS_ENDPOINT, WISE_LAPIS_URL } from '../../../constants';
5
5
  import referenceGenome from '../../../lapisApi/__mockData__/referenceGenome.json';
6
- import { LapisUrlContext } from '../../LapisUrlContext';
6
+ import { LapisUrlContextProvider } from '../../LapisUrlContext';
7
7
  import { ReferenceGenomeContext } from '../../ReferenceGenomeContext';
8
8
  import details from './__mockData__/details.json';
9
9
 
@@ -28,16 +28,11 @@ export default meta;
28
28
 
29
29
  const Template = {
30
30
  render: (args: WastewaterMutationsOverTimeProps) => (
31
- <LapisUrlContext.Provider value={WISE_LAPIS_URL}>
31
+ <LapisUrlContextProvider value={WISE_LAPIS_URL}>
32
32
  <ReferenceGenomeContext.Provider value={referenceGenome}>
33
- <WastewaterMutationsOverTime
34
- width={args.width}
35
- height={args.height}
36
- lapisFilter={args.lapisFilter}
37
- sequenceType={args.sequenceType}
38
- />
33
+ <WastewaterMutationsOverTime {...args} />
39
34
  </ReferenceGenomeContext.Provider>
40
- </LapisUrlContext.Provider>
35
+ </LapisUrlContextProvider>
41
36
  ),
42
37
  };
43
38
 
@@ -48,6 +43,7 @@ export const Default: StoryObj<WastewaterMutationsOverTimeProps> = {
48
43
  height: '700px',
49
44
  lapisFilter: {},
50
45
  sequenceType: 'nucleotide',
46
+ maxNumberOfGridRows: 100,
51
47
  },
52
48
  parameters: {
53
49
  fetchMock: {
@@ -1,10 +1,10 @@
1
1
  import { type FunctionComponent } from 'preact';
2
- import { type Dispatch, type StateUpdater, useContext, useState } from 'preact/hooks';
2
+ import { type Dispatch, type StateUpdater, useState } from 'preact/hooks';
3
3
  import z from 'zod';
4
4
 
5
5
  import { computeWastewaterMutationsOverTimeDataPerLocation } from './computeWastewaterMutationsOverTimeDataPerLocation';
6
6
  import { lapisFilterSchema, sequenceTypeSchema } from '../../../types';
7
- import { LapisUrlContext } from '../../LapisUrlContext';
7
+ import { useLapisUrl } from '../../LapisUrlContext';
8
8
  import { type ColorScale } from '../../components/color-scale-selector';
9
9
  import { ColorScaleSelectorDropdown } from '../../components/color-scale-selector-dropdown';
10
10
  import { ErrorBoundary } from '../../components/error-boundary';
@@ -23,7 +23,7 @@ const wastewaterMutationOverTimeSchema = z.object({
23
23
  sequenceType: sequenceTypeSchema,
24
24
  width: z.string(),
25
25
  height: z.string(),
26
- maxNumberOfGridRows: z.number().optional(),
26
+ maxNumberOfGridRows: z.number(),
27
27
  });
28
28
 
29
29
  export type WastewaterMutationsOverTimeProps = z.infer<typeof wastewaterMutationOverTimeSchema>;
@@ -44,7 +44,7 @@ export const WastewaterMutationsOverTime: FunctionComponent<WastewaterMutationsO
44
44
  export const WastewaterMutationsOverTimeInner: FunctionComponent<WastewaterMutationsOverTimeProps> = (
45
45
  componentProps,
46
46
  ) => {
47
- const lapis = useContext(LapisUrlContext);
47
+ const lapis = useLapisUrl();
48
48
 
49
49
  const {
50
50
  data: mutationOverTimeDataPerLocation,
@@ -142,7 +142,7 @@ type WastewaterMutationsOverTimeInfoProps = {
142
142
  const WastewaterMutationsOverTimeInfo: FunctionComponent<WastewaterMutationsOverTimeInfoProps> = ({
143
143
  originalComponentProps,
144
144
  }) => {
145
- const lapis = useContext(LapisUrlContext);
145
+ const lapis = useLapisUrl();
146
146
  return (
147
147
  <Info>
148
148
  <InfoHeadline1>Info for mutations over time</InfoHeadline1>
@@ -7,7 +7,7 @@ import { type JSXInternal } from 'preact/src/jsx';
7
7
  import { lapisContext } from './lapis-context';
8
8
  import { referenceGenomeContext } from './reference-genome-context';
9
9
  import { type ReferenceGenome } from '../lapisApi/ReferenceGenome';
10
- import { LapisUrlContext } from '../preact/LapisUrlContext';
10
+ import { LapisUrlContextProvider } from '../preact/LapisUrlContext';
11
11
  import { ReferenceGenomeContext } from '../preact/ReferenceGenomeContext';
12
12
  import minMaxPercentSliderCss from '../preact/components/min-max-percent-slider.css?inline';
13
13
  import tailwindStyle from '../styles/tailwind.css?inline';
@@ -47,11 +47,11 @@ export abstract class PreactLitAdapter extends ReactiveElement {
47
47
 
48
48
  override update(changedProperties: PropertyValues) {
49
49
  const vdom = (
50
- <LapisUrlContext.Provider value={this.lapis}>
50
+ <LapisUrlContextProvider value={this.lapis}>
51
51
  <ReferenceGenomeContext.Provider value={this.referenceGenome}>
52
52
  {this.render()}
53
53
  </ReferenceGenomeContext.Provider>
54
- </LapisUrlContext.Provider>
54
+ </LapisUrlContextProvider>
55
55
  );
56
56
  super.update(changedProperties);
57
57
  render(vdom, this.renderRoot);
@@ -4,7 +4,7 @@ import type { Meta, StoryObj } from '@storybook/web-components';
4
4
  import { html, LitElement } from 'lit';
5
5
  import { customElement } from 'lit/decorators.js';
6
6
 
7
- import './app';
7
+ import './gs-app';
8
8
 
9
9
  import { lapisContext } from './lapis-context';
10
10
  import { referenceGenomeContext } from './reference-genome-context';
@@ -29,7 +29,7 @@ const lapisUrlSchema = z.string().url();
29
29
  * This component does __not__ use a shadow DOM. Children of this component will be rendered directly in the light DOM.
30
30
  */
31
31
  @customElement('gs-app')
32
- export class App extends LitElement {
32
+ export class AppComponent extends LitElement {
33
33
  /**
34
34
  * Required.
35
35
  *
@@ -55,7 +55,9 @@ export class App extends LitElement {
55
55
  task: async () => {
56
56
  const lapisUrl = lapisUrlSchema.parse(this.lapis);
57
57
 
58
- this.referenceGenome = await fetchReferenceGenome(lapisUrl);
58
+ this.referenceGenome = await fetchReferenceGenome(
59
+ lapisUrl.endsWith('/') ? lapisUrl.slice(0, -1) : lapisUrl,
60
+ );
59
61
  },
60
62
  args: () => [this.lapis],
61
63
  });
@@ -84,7 +86,7 @@ function GsAppError(error: string) {
84
86
 
85
87
  declare global {
86
88
  interface HTMLElementTagNameMap {
87
- 'gs-app': App;
89
+ 'gs-app': AppComponent;
88
90
  }
89
91
  }
90
92
 
@@ -1,4 +1,4 @@
1
- export { App } from './app.js';
1
+ export { AppComponent } from './gs-app';
2
2
  export * from './visualization';
3
3
  export * from './wastewaterVisualization';
4
4
  export * from './input';
@@ -7,7 +7,7 @@ import { previewHandles } from '../../../.storybook/preview';
7
7
  import { LAPIS_URL } from '../../constants';
8
8
  import { type DateRangeSelectorProps } from '../../preact/dateRangeSelector/date-range-selector';
9
9
  import './gs-date-range-selector';
10
- import '../app';
10
+ import '../gs-app';
11
11
  import { toYYYYMMDD } from '../../preact/dateRangeSelector/dateConversion';
12
12
  import { dateRangeOptionPresets } from '../../preact/dateRangeSelector/dateRangeOption';
13
13
  import { withinShadowRoot } from '../withinShadowRoot.story';
@@ -16,9 +16,7 @@ const codeExample = String.raw`
16
16
  <gs-date-range-selector
17
17
  dateRangeOptions='[{ "label": "Year 2021", "dateFrom": "2021-01-01", "dateTo": "2021-12-31" }]'
18
18
  earliestDate="1970-01-01"
19
- initialValue="Year 2021"
20
- initialDateFrom="2020-01-01"
21
- initialDateTo="2021-01-01"
19
+ valule="Year 2021"
22
20
  width="100%"
23
21
  lapisDateField="myDateColumn"
24
22
  ></gs-date-range-selector>`;
@@ -40,11 +38,10 @@ const meta: Meta<Required<DateRangeSelectorProps>> = {
40
38
  },
41
39
  }),
42
40
  argTypes: {
43
- initialValue: {
41
+ value: {
44
42
  control: {
45
- type: 'select',
43
+ type: 'object',
46
44
  },
47
- options: [dateRangeOptionPresets.lastMonth.label, dateRangeOptionPresets.allTimes.label, 'CustomDateRange'],
48
45
  },
49
46
  lapisDateField: { control: { type: 'text' } },
50
47
  dateRangeOptions: {
@@ -71,11 +68,9 @@ const meta: Meta<Required<DateRangeSelectorProps>> = {
71
68
  customDateRange,
72
69
  ],
73
70
  earliestDate: '1970-01-01',
74
- initialValue: dateRangeOptionPresets.lastMonth.label,
71
+ value: dateRangeOptionPresets.lastMonth.label,
75
72
  lapisDateField: 'aDateColumn',
76
73
  width: '100%',
77
- initialDateFrom: undefined,
78
- initialDateTo: undefined,
79
74
  },
80
75
  tags: ['autodocs'],
81
76
  };
@@ -89,9 +84,7 @@ export const Default: StoryObj<Required<DateRangeSelectorProps>> = {
89
84
  <gs-date-range-selector
90
85
  .dateRangeOptions=${args.dateRangeOptions}
91
86
  .earliestDate=${args.earliestDate}
92
- .initialValue=${args.initialValue}
93
- .initialDateFrom=${args.initialDateFrom}
94
- .initialDateTo=${args.initialDateTo}
87
+ .value=${args.value}
95
88
  .width=${args.width}
96
89
  .lapisDateField=${args.lapisDateField}
97
90
  ></gs-date-range-selector>
@@ -46,15 +46,18 @@ import { PreactLitAdapter } from '../PreactLitAdapter';
46
46
  * Contains the selected dateRangeOption or when users select custom values it contains the selected dates.
47
47
  *
48
48
  * Use this event, when you want to control this component in your JS application.
49
+ * You can supply the `detail` of this event to the `value` attribute of this component.
49
50
  */
50
51
  @customElement('gs-date-range-selector')
51
52
  export class DateRangeSelectorComponent extends PreactLitAdapter {
52
53
  /**
53
54
  * An array of date range options that the select field should provide.
54
- * The `label` will be shown to the user, and it will be available as `initialValue`.
55
+ * The `label` will be shown to the user, and it will be available as `value`.
55
56
  * The dates must be in the format `YYYY-MM-DD`.
56
57
  *
57
58
  * If dateFrom or dateTo is not set, the component will default to the `earliestDate` or the current date.
59
+ *
60
+ * We provide some options in `dateRangeOptionPresets` for convenience.
58
61
  */
59
62
  @property({ type: Array })
60
63
  dateRangeOptions: { label: string; dateFrom?: string; dateTo?: string }[] = [];
@@ -66,33 +69,17 @@ export class DateRangeSelectorComponent extends PreactLitAdapter {
66
69
  earliestDate: string = '1900-01-01';
67
70
 
68
71
  /**
69
- * The initial value to use for this date range selector.
70
- * Must be a valid label from the `dateRangeOptions`.
71
- *
72
- * If the value is not set, the component will default to the range `earliestDate` until today.
73
- *
74
- * It will be overwritten if `initialDateFrom` or `initialDateTo` is set.
72
+ * The value to use for this date range selector.
73
+ * - If it is a string, then it must be a valid label from the `dateRangeOptions`.
74
+ * - If it is an object, then it accepts dates in the format `YYYY-MM-DD` for the keys `dateFrom` and `dateTo`.
75
+ * Keys that are not set will default to the `earliestDate` or the current date respectively.
76
+ * - If the attribute is not set, the component will default to the range `earliestDate` until today.
75
77
  *
76
- * We provide some options in `dateRangeOptionPresets` for convenience.
77
- */
78
- @property()
79
- initialValue: string | undefined = undefined;
80
-
81
- /**
82
- * A date string in the format `YYYY-MM-DD`.
83
- * If set, the date range selector will be initialized with the given date (overwriting `initialValue` to `custom`).
84
- * If `initialDateTo` is set, but this is unset, it will default to `earliestDate`.
85
- */
86
- @property()
87
- initialDateFrom: string | undefined = undefined;
88
-
89
- /**
90
- * A date string in the format `YYYY-MM-DD`.
91
- * If set, the date range selector will be initialized with the given date (overwriting `initialValue` to `custom`).
92
- * If `initialDateFrom` is set, but this is unset, it will default to the current date.
78
+ * The `detail` of the `gs-date-range-option-changed` event can be used for this attribute,
79
+ * if you want to control this component in your JS application.
93
80
  */
94
- @property()
95
- initialDateTo: string | undefined = undefined;
81
+ @property({ type: Object })
82
+ value: string | { dateFrom?: string; dateTo?: string } | undefined = undefined;
96
83
 
97
84
  /**
98
85
  * The width of the component.
@@ -113,9 +100,7 @@ export class DateRangeSelectorComponent extends PreactLitAdapter {
113
100
  <DateRangeSelector
114
101
  dateRangeOptions={this.dateRangeOptions}
115
102
  earliestDate={this.earliestDate}
116
- initialValue={this.initialValue}
117
- initialDateFrom={this.initialDateFrom}
118
- initialDateTo={this.initialDateTo}
103
+ value={this.value}
119
104
  lapisDateField={this.lapisDateField}
120
105
  width={this.width}
121
106
  />
@@ -150,15 +135,7 @@ type CustomSelectOptionsMatches = Expect<
150
135
  type EarliestDateMatches = Expect<
151
136
  Equals<typeof DateRangeSelectorComponent.prototype.earliestDate, DateRangeSelectorProps['earliestDate']>
152
137
  >;
153
- type InitialValueMatches = Expect<
154
- Equals<typeof DateRangeSelectorComponent.prototype.initialValue, DateRangeSelectorProps['initialValue']>
155
- >;
156
- type InitialDateFromMatches = Expect<
157
- Equals<typeof DateRangeSelectorComponent.prototype.initialDateFrom, DateRangeSelectorProps['initialDateFrom']>
158
- >;
159
- type InitialDateToMatches = Expect<
160
- Equals<typeof DateRangeSelectorComponent.prototype.initialDateTo, DateRangeSelectorProps['initialDateTo']>
161
- >;
138
+ type ValueMatches = Expect<Equals<typeof DateRangeSelectorComponent.prototype.value, DateRangeSelectorProps['value']>>;
162
139
  type WidthMatches = Expect<Equals<typeof DateRangeSelectorComponent.prototype.width, DateRangeSelectorProps['width']>>;
163
140
  type DateColumnMatches = Expect<
164
141
  Equals<typeof DateRangeSelectorComponent.prototype.lapisDateField, DateRangeSelectorProps['lapisDateField']>
@@ -5,7 +5,7 @@ import { html } from 'lit';
5
5
  import { withComponentDocs } from '../../../.storybook/ComponentDocsBlock';
6
6
  import { previewHandles } from '../../../.storybook/preview';
7
7
  import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
8
- import '../app';
8
+ import '../gs-app';
9
9
  import './gs-lineage-filter';
10
10
  import aggregatedData from '../../preact/lineageFilter/__mockData__/aggregated.json';
11
11
  import { type LineageFilterProps } from '../../preact/lineageFilter/lineage-filter';
@@ -6,7 +6,7 @@ import { ifDefined } from 'lit/directives/if-defined.js';
6
6
  import { withComponentDocs } from '../../../.storybook/ComponentDocsBlock';
7
7
  import { previewHandles } from '../../../.storybook/preview';
8
8
  import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
9
- import '../app';
9
+ import '../gs-app';
10
10
  import './gs-location-filter';
11
11
  import data from '../../preact/locationFilter/__mockData__/aggregated.json';
12
12
  import { type LocationFilterProps } from '../../preact/locationFilter/location-filter';