@genspectrum/dashboard-components 0.1.3 → 0.1.4

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 (75) hide show
  1. package/custom-elements.json +311 -75
  2. package/dist/dashboard-components.js +622 -434
  3. package/dist/dashboard-components.js.map +1 -1
  4. package/dist/genspectrum-components.d.ts +229 -42
  5. package/dist/style.css +132 -139
  6. package/package.json +9 -5
  7. package/src/preact/aggregatedData/aggregate.stories.tsx +5 -5
  8. package/src/preact/aggregatedData/aggregate.tsx +8 -4
  9. package/src/preact/components/ReferenceGenomesAwaiter.tsx +25 -0
  10. package/src/preact/components/csv-download-button.tsx +8 -2
  11. package/src/preact/components/headline.tsx +16 -4
  12. package/src/preact/components/min-max-range-slider.tsx +4 -4
  13. package/src/preact/components/percent-intput.tsx +2 -3
  14. package/src/preact/components/resize-container.tsx +23 -0
  15. package/src/preact/components/table.tsx +1 -0
  16. package/src/preact/components/tabs.stories.tsx +2 -2
  17. package/src/preact/components/tabs.tsx +47 -24
  18. package/src/preact/dateRangeSelector/date-range-selector.stories.tsx +36 -4
  19. package/src/preact/dateRangeSelector/date-range-selector.tsx +57 -43
  20. package/src/preact/locationFilter/location-filter.tsx +2 -2
  21. package/src/preact/mutationComparison/getMutationComparisonTableData.spec.ts +5 -5
  22. package/src/preact/mutationComparison/getMutationComparisonTableData.ts +45 -10
  23. package/src/preact/mutationComparison/mutation-comparison-table.tsx +20 -22
  24. package/src/preact/mutationComparison/mutation-comparison-venn.tsx +6 -3
  25. package/src/preact/mutationComparison/mutation-comparison.stories.tsx +8 -1
  26. package/src/preact/mutationComparison/mutation-comparison.tsx +13 -4
  27. package/src/preact/mutationFilter/mutation-filter.stories.tsx +70 -31
  28. package/src/preact/mutationFilter/mutation-filter.tsx +62 -14
  29. package/src/preact/mutations/getInsertionsTableData.spec.ts +6 -4
  30. package/src/preact/mutations/getInsertionsTableData.ts +1 -1
  31. package/src/preact/mutations/getMutationsTableData.spec.ts +9 -19
  32. package/src/preact/mutations/getMutationsTableData.ts +1 -1
  33. package/src/preact/mutations/mutations-insertions-table.tsx +3 -1
  34. package/src/preact/mutations/mutations-table.tsx +3 -1
  35. package/src/preact/mutations/mutations.stories.tsx +8 -1
  36. package/src/preact/mutations/mutations.tsx +16 -5
  37. package/src/preact/prevalenceOverTime/prevalence-over-time-bar-chart.tsx +1 -0
  38. package/src/preact/prevalenceOverTime/prevalence-over-time-bubble-chart.tsx +1 -0
  39. package/src/preact/prevalenceOverTime/prevalence-over-time-line-chart.tsx +1 -0
  40. package/src/preact/prevalenceOverTime/prevalence-over-time.stories.tsx +4 -0
  41. package/src/preact/prevalenceOverTime/prevalence-over-time.tsx +17 -9
  42. package/src/preact/relativeGrowthAdvantage/relative-growth-advantage-chart.tsx +8 -5
  43. package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.stories.tsx +12 -0
  44. package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.tsx +13 -8
  45. package/src/preact/shared/sort/sortInsertions.spec.ts +11 -10
  46. package/src/preact/shared/sort/sortInsertions.ts +10 -17
  47. package/src/preact/shared/sort/sortSubstitutionsAndDeletions.spec.ts +19 -10
  48. package/src/preact/shared/sort/sortSubstitutionsAndDeletions.ts +45 -12
  49. package/src/preact/textInput/text-input.stories.tsx +22 -1
  50. package/src/preact/textInput/text-input.tsx +3 -1
  51. package/src/utils/typeAssertions.spec.ts +31 -0
  52. package/src/utils/typeAssertions.ts +16 -0
  53. package/src/web-components/PreactLitAdapter.tsx +0 -1
  54. package/src/web-components/app.stories.ts +129 -0
  55. package/src/web-components/app.ts +27 -6
  56. package/src/web-components/display/aggregate-component.stories.ts +21 -11
  57. package/src/web-components/display/aggregate-component.tsx +12 -5
  58. package/src/web-components/display/mutation-comparison-component.stories.ts +29 -11
  59. package/src/web-components/display/mutation-comparison-component.tsx +72 -4
  60. package/src/web-components/display/mutations-component.stories.ts +14 -13
  61. package/src/web-components/display/mutations-component.tsx +14 -1
  62. package/src/web-components/display/prevalence-over-time-component.stories.ts +20 -18
  63. package/src/web-components/display/prevalence-over-time-component.tsx +12 -0
  64. package/src/web-components/display/relative-growth-advantage-component.stories.ts +11 -10
  65. package/src/web-components/display/relative-growth-advantage-component.tsx +12 -0
  66. package/src/web-components/input/date-range-selector-component.stories.ts +35 -8
  67. package/src/web-components/input/date-range-selector-component.tsx +18 -5
  68. package/src/web-components/input/location-filter-component.stories.ts +15 -4
  69. package/src/web-components/input/location-filter-component.tsx +2 -6
  70. package/src/web-components/input/mutation-filter-component.stories.ts +20 -9
  71. package/src/web-components/input/mutation-filter-component.tsx +10 -2
  72. package/src/web-components/input/text-input-component.stories.ts +13 -4
  73. package/src/web-components/input/text-input-component.tsx +11 -2
  74. package/src/web-components/display/aggregate-component.mdx +0 -25
  75. package/src/web-components/input/location-filter.mdx +0 -25
@@ -56,12 +56,44 @@
56
56
  },
57
57
  {
58
58
  "kind": "javascript-module",
59
- "path": "src/web-components/app.ts",
59
+ "path": "src/web-components/app.stories.ts",
60
60
  "declarations": [
61
+ {
62
+ "kind": "variable",
63
+ "name": "meta",
64
+ "type": {
65
+ "text": "Meta"
66
+ },
67
+ "default": "{\n title: 'Wrapper/App',\n component: 'gs-app',\n parameters: withComponentDocs({\n fetchMock: {},\n componentDocs: {\n tag: 'gs-app',\n opensShadowDom: false,\n expectsChildren: true,\n codeExample,\n },\n }),\n decorators: [withActions],\n tags: ['autodocs'],\n}"
68
+ },
69
+ {
70
+ "kind": "variable",
71
+ "name": "Default",
72
+ "type": {
73
+ "text": "StoryObj<{ lapis: string }>"
74
+ },
75
+ "default": "{\n ...Template,\n play: async ({ canvasElement }) => {\n const canvas = within(canvasElement);\n\n await waitFor(() => {\n expect(canvas.getByText(LAPIS_URL)).toBeVisible();\n expect(canvas.getByText('\"name\": \"ORF1a\",', { exact: false })).toBeVisible();\n });\n },\n}"
76
+ },
77
+ {
78
+ "kind": "variable",
79
+ "name": "DelayFetchingReferenceGenome",
80
+ "type": {
81
+ "text": "StoryObj<{ lapis: string }>"
82
+ },
83
+ "default": "{\n ...Template,\n parameters: {\n fetchMock: {\n mocks: [\n {\n matcher: {\n name: 'referenceGenome',\n url: REFERENCE_GENOME_ENDPOINT,\n },\n response: {\n status: 200,\n body: referenceGenome,\n },\n options: {\n delay: 5000,\n },\n },\n ],\n },\n },\n}"
84
+ },
85
+ {
86
+ "kind": "variable",
87
+ "name": "FailsToFetchReferenceGenome",
88
+ "type": {
89
+ "text": "StoryObj<{ lapis: string }>"
90
+ },
91
+ "default": "{\n ...Template,\n args: {\n lapis: 'definitely-not-a-valid-url',\n },\n play: async ({ canvasElement }) => {\n const canvas = within(canvasElement);\n\n await waitFor(() => {\n expect(canvas.getByText('Error')).toBeVisible();\n });\n },\n}"
92
+ },
61
93
  {
62
94
  "kind": "class",
63
95
  "description": "",
64
- "name": "App",
96
+ "name": "AppDisplay",
65
97
  "members": [
66
98
  {
67
99
  "kind": "field",
@@ -69,8 +101,7 @@
69
101
  "type": {
70
102
  "text": "string"
71
103
  },
72
- "default": "''",
73
- "attribute": "lapis"
104
+ "default": "''"
74
105
  },
75
106
  {
76
107
  "kind": "field",
@@ -79,16 +110,77 @@
79
110
  "text": "ReferenceGenome"
80
111
  },
81
112
  "default": "{\n nucleotideSequences: [],\n genes: [],\n }"
82
- },
113
+ }
114
+ ],
115
+ "superclass": {
116
+ "name": "LitElement",
117
+ "package": "lit"
118
+ },
119
+ "tagName": "gs-app-display",
120
+ "customElement": true
121
+ }
122
+ ],
123
+ "exports": [
124
+ {
125
+ "kind": "js",
126
+ "name": "default",
127
+ "declaration": {
128
+ "name": "meta",
129
+ "module": "src/web-components/app.stories.ts"
130
+ }
131
+ },
132
+ {
133
+ "kind": "js",
134
+ "name": "Default",
135
+ "declaration": {
136
+ "name": "Default",
137
+ "module": "src/web-components/app.stories.ts"
138
+ }
139
+ },
140
+ {
141
+ "kind": "js",
142
+ "name": "DelayFetchingReferenceGenome",
143
+ "declaration": {
144
+ "name": "DelayFetchingReferenceGenome",
145
+ "module": "src/web-components/app.stories.ts"
146
+ }
147
+ },
148
+ {
149
+ "kind": "js",
150
+ "name": "FailsToFetchReferenceGenome",
151
+ "declaration": {
152
+ "name": "FailsToFetchReferenceGenome",
153
+ "module": "src/web-components/app.stories.ts"
154
+ }
155
+ },
156
+ {
157
+ "kind": "custom-element-definition",
158
+ "name": "gs-app-display",
159
+ "declaration": {
160
+ "name": "AppDisplay",
161
+ "module": "src/web-components/app.stories.ts"
162
+ }
163
+ }
164
+ ]
165
+ },
166
+ {
167
+ "kind": "javascript-module",
168
+ "path": "src/web-components/app.ts",
169
+ "declarations": [
170
+ {
171
+ "kind": "class",
172
+ "description": "## Context\n\nThis component provides the main application context.\nAll other `gs-*` components must be (possibly nested) children of this component.\nIt makes use of the [Lit Context](https://lit.dev/docs/data/context/) to\n- provide the URL to the LAPIS instance to all its children\n- fetch the reference genomes from LAPIS and provide it to all its children\n\nThis will show an error message if the reference genome cannot be fetched\n(e.g., due to an invalid LAPIS URL).\n\n## Shadow DOM\n\nThis component does __not__ use a shadow DOM. Children of this component will be rendered directly in the light DOM.",
173
+ "name": "App",
174
+ "members": [
83
175
  {
84
176
  "kind": "field",
85
- "name": "updateReferenceGenome",
86
- "privacy": "private",
87
- "default": "new Task(this, {\n task: async () => {\n this.referenceGenome = await fetchReferenceGenome(this.lapis);\n },\n args: () => [this.lapis],\n })"
88
- },
89
- {
90
- "kind": "method",
91
- "name": "createRenderRoot"
177
+ "name": "lapis",
178
+ "type": {
179
+ "text": "string"
180
+ },
181
+ "default": "''",
182
+ "description": "The URL of the LAPIS instance that all children of this component will use.",
183
+ "attribute": "lapis"
92
184
  }
93
185
  ],
94
186
  "attributes": [
@@ -98,6 +190,7 @@
98
190
  "text": "string"
99
191
  },
100
192
  "default": "''",
193
+ "description": "The URL of the LAPIS instance that all children of this component will use.",
101
194
  "fieldName": "lapis"
102
195
  }
103
196
  ],
@@ -128,12 +221,6 @@
128
221
  }
129
222
  ]
130
223
  },
131
- {
132
- "kind": "javascript-module",
133
- "path": "src/web-components/display/aggregate-component.mdx",
134
- "declarations": [],
135
- "exports": []
136
- },
137
224
  {
138
225
  "kind": "javascript-module",
139
226
  "path": "src/web-components/display/aggregate-component.stories.ts",
@@ -144,7 +231,7 @@
144
231
  "type": {
145
232
  "text": "Meta<AggregateProps>"
146
233
  },
147
- "default": "{\n title: 'Visualization/Aggregate',\n component: 'gs-aggregate-component',\n argTypes: {\n fields: [{ control: 'object' }],\n views: {\n options: ['table'],\n control: { type: 'check' },\n },\n },\n parameters: {\n fetchMock: {\n mocks: [\n {\n matcher: {\n name: 'aggregatedData',\n url: AGGREGATED_ENDPOINT,\n body: {\n fields: ['division', 'host'],\n country: 'USA',\n },\n },\n response: {\n status: 200,\n body: aggregatedData,\n },\n },\n ],\n },\n },\n}"
234
+ "default": "{\n title: 'Visualization/Aggregate',\n component: 'gs-aggregate-component',\n argTypes: {\n fields: [{ control: 'object' }],\n views: {\n options: ['table'],\n control: { type: 'check' },\n },\n size: [{ control: 'object' }],\n },\n parameters: withComponentDocs({\n fetchMock: {\n mocks: [\n {\n matcher: {\n name: 'aggregatedData',\n url: AGGREGATED_ENDPOINT,\n body: {\n fields: ['division', 'host'],\n country: 'USA',\n },\n },\n response: {\n status: 200,\n body: aggregatedData,\n },\n },\n ],\n },\n componentDocs: {\n tag: 'gs-aggregate-component',\n opensShadowDom: true,\n expectsChildren: false,\n codeExample: `<gs-aggregate-component fields='[\"division\", \"host\"]' filter='{\"country\": \"USA\"}' views='[\"table\"]'></gs-aggregate-component>`,\n },\n }),\n tags: ['autodocs'],\n}"
148
235
  },
149
236
  {
150
237
  "kind": "variable",
@@ -152,7 +239,7 @@
152
239
  "type": {
153
240
  "text": "StoryObj<AggregateProps>"
154
241
  },
155
- "default": "{\n render: (args) => html`\n <div class=\"w-11/12 h-11/12\">\n <gs-app lapis=\"${LAPIS_URL}\">\n <gs-aggregate-component\n .fields=${args.fields}\n .filter=${args.filter}\n .views=${args.views}\n ></gs-aggregate-component>\n </gs-app>\n </div>\n `,\n args: {\n fields: ['division', 'host'],\n views: ['table'],\n filter: {\n country: 'USA',\n },\n },\n}"
242
+ "default": "{\n render: (args) => html`\n <gs-app lapis=\"${LAPIS_URL}\">\n <gs-aggregate-component\n .fields=${args.fields}\n .filter=${args.filter}\n .views=${args.views}\n .size=${args.size}\n ></gs-aggregate-component>\n </gs-app>\n `,\n args: {\n fields: ['division', 'host'],\n views: ['table'],\n filter: {\n country: 'USA',\n },\n size: { width: '100%', height: '700px' },\n },\n}"
156
243
  }
157
244
  ],
158
245
  "exports": [
@@ -180,7 +267,7 @@
180
267
  "declarations": [
181
268
  {
182
269
  "kind": "class",
183
- "description": "## Tag\n\n`gs-aggregate-component`\n\n## Context\n\nThis component displays aggregated data, which can provide an overview of the underlying data.\n\nIt expects a list of fields to aggregate by and a filter to apply to the data.",
270
+ "description": "## Context\n\nThis component displays aggregated data, which can provide an overview of the underlying data.\n\nIt expects a list of fields to aggregate by and a filter to apply to the data.",
184
271
  "name": "AggregateComponent",
185
272
  "members": [
186
273
  {
@@ -212,6 +299,16 @@
212
299
  "default": "{}",
213
300
  "description": "The filter to apply to the data.",
214
301
  "attribute": "filter"
302
+ },
303
+ {
304
+ "kind": "field",
305
+ "name": "size",
306
+ "type": {
307
+ "text": "{ width?: string; height?: string } | undefined"
308
+ },
309
+ "default": "undefined",
310
+ "description": "The size of the component.\n\nIf not set, the component will take the full width of its container with height 700px.\n\nThe width and height should be a string with a unit in css style, e.g. '100%', '500px' or '50vh'.\nIf the unit is %, the size will be relative to the container of the component.",
311
+ "attribute": "size"
215
312
  }
216
313
  ],
217
314
  "attributes": [
@@ -241,6 +338,15 @@
241
338
  "default": "{}",
242
339
  "description": "The filter to apply to the data.",
243
340
  "fieldName": "filter"
341
+ },
342
+ {
343
+ "name": "size",
344
+ "type": {
345
+ "text": "{ width?: string; height?: string } | undefined"
346
+ },
347
+ "default": "undefined",
348
+ "description": "The size of the component.\n\nIf not set, the component will take the full width of its container with height 700px.\n\nThe width and height should be a string with a unit in css style, e.g. '100%', '500px' or '50vh'.\nIf the unit is %, the size will be relative to the container of the component.",
349
+ "fieldName": "size"
244
350
  }
245
351
  ],
246
352
  "superclass": {
@@ -327,7 +433,7 @@
327
433
  "type": {
328
434
  "text": "Meta<MutationComparisonProps>"
329
435
  },
330
- "default": "{\n title: 'Visualization/Mutation comparison',\n component: 'gs-mutation-comparison-component',\n argTypes: {\n variants: { control: 'object' },\n sequenceType: {\n options: ['nucleotide', 'amino acid'],\n control: { type: 'radio' },\n },\n views: {\n options: ['table', 'venn'],\n control: { type: 'check' },\n },\n },\n}"
436
+ "default": "{\n title: 'Visualization/Mutation comparison',\n component: 'gs-mutation-comparison-component',\n argTypes: {\n variants: { control: 'object' },\n sequenceType: {\n options: ['nucleotide', 'amino acid'],\n control: { type: 'radio' },\n },\n views: {\n options: ['table', 'venn'],\n control: { type: 'check' },\n },\n size: { control: 'object' },\n },\n parameters: withComponentDocs({\n componentDocs: {\n tag: 'gs-mutation-comparison-component',\n opensShadowDom: true,\n expectsChildren: false,\n codeExample,\n },\n }),\n tags: ['autodocs'],\n}"
331
437
  },
332
438
  {
333
439
  "kind": "variable",
@@ -335,7 +441,7 @@
335
441
  "type": {
336
442
  "text": "StoryObj<MutationComparisonProps>"
337
443
  },
338
- "default": "{\n ...Template,\n args: {\n variants: [\n {\n displayName: 'Some variant',\n lapisFilter: { country: 'Switzerland', pangoLineage: 'B.1.1.7', dateTo },\n },\n {\n displayName: 'Other variant',\n lapisFilter: {\n country: 'Switzerland',\n pangoLineage: 'B.1.1.7',\n dateFrom,\n dateTo,\n },\n },\n ],\n sequenceType: 'nucleotide',\n views: ['table', 'venn'],\n },\n parameters: {\n fetchMock: {\n mocks: [\n {\n matcher: {\n name: 'nucleotideMutationsSomeVariant',\n url: NUCLEOTIDE_MUTATIONS_ENDPOINT,\n body: {\n country: 'Switzerland',\n pangoLineage: 'B.1.1.7',\n dateTo,\n minProportion: 0,\n },\n },\n response: {\n status: 200,\n body: nucleotideMutationsSomeVariant,\n },\n },\n {\n matcher: {\n name: 'nucleotideMutationsOtherVariant',\n url: NUCLEOTIDE_MUTATIONS_ENDPOINT,\n body: {\n country: 'Switzerland',\n pangoLineage: 'B.1.1.7',\n dateFrom,\n dateTo,\n minProportion: 0,\n },\n },\n response: {\n status: 200,\n body: nucleotideMutationsOtherVariant,\n },\n },\n ],\n },\n },\n play: async ({ canvasElement, step }) => {\n const canvas = await withinShadowRoot(canvasElement, 'gs-mutation-comparison-component');\n\n await step('Min and max proportions should be 50% and 100%', async () => {\n const minInput = () => canvas.getAllByLabelText('%')[0];\n const maxInput = () => canvas.getAllByLabelText('%')[1];\n\n await waitFor(() => expect(minInput()).toHaveValue(50));\n await waitFor(() => expect(maxInput()).toHaveValue(100));\n });\n },\n}"
444
+ "default": "{\n ...Template,\n args: {\n variants: [\n {\n displayName: 'Some variant',\n lapisFilter: { country: 'Switzerland', pangoLineage: 'B.1.1.7', dateTo },\n },\n {\n displayName: 'Other variant',\n lapisFilter: {\n country: 'Switzerland',\n pangoLineage: 'B.1.1.7',\n dateFrom,\n dateTo,\n },\n },\n ],\n sequenceType: 'nucleotide',\n views: ['table', 'venn'],\n size: { width: '100%', height: '700px' },\n },\n parameters: {\n fetchMock: {\n mocks: [\n {\n matcher: {\n name: 'nucleotideMutationsSomeVariant',\n url: NUCLEOTIDE_MUTATIONS_ENDPOINT,\n body: {\n country: 'Switzerland',\n pangoLineage: 'B.1.1.7',\n dateTo,\n minProportion: 0,\n },\n },\n response: {\n status: 200,\n body: nucleotideMutationsSomeVariant,\n },\n },\n {\n matcher: {\n name: 'nucleotideMutationsOtherVariant',\n url: NUCLEOTIDE_MUTATIONS_ENDPOINT,\n body: {\n country: 'Switzerland',\n pangoLineage: 'B.1.1.7',\n dateFrom,\n dateTo,\n minProportion: 0,\n },\n },\n response: {\n status: 200,\n body: nucleotideMutationsOtherVariant,\n },\n },\n ],\n },\n },\n play: async ({ canvasElement, step }) => {\n const canvas = await withinShadowRoot(canvasElement, 'gs-mutation-comparison-component');\n\n await step('Min and max proportions should be 50% and 100%', async () => {\n const minInput = () => canvas.getAllByLabelText('%')[0];\n const maxInput = () => canvas.getAllByLabelText('%')[1];\n\n await waitFor(() => expect(minInput()).toHaveValue(50));\n await waitFor(() => expect(maxInput()).toHaveValue(100));\n });\n },\n}"
339
445
  },
340
446
  {
341
447
  "kind": "variable",
@@ -343,7 +449,7 @@
343
449
  "type": {
344
450
  "text": "StoryObj<MutationComparisonProps>"
345
451
  },
346
- "default": "{\n ...Default,\n play: async ({ canvasElement, step }) => {\n const canvas = await withinShadowRoot(canvasElement, 'gs-mutation-comparison-component');\n\n await step('Switch to Venn diagram view', async () => {\n await waitFor(() => expect(canvas.getByLabelText('Venn', { selector: 'input' })).toBeInTheDocument());\n\n await fireEvent.click(canvas.getByLabelText('Venn', { selector: 'input' }));\n\n await waitFor(() =>\n expect(\n canvas.getByText('You have no elements selected. Click in the venn diagram to select.'),\n ).toBeVisible(),\n );\n });\n },\n}"
452
+ "default": "{\n ...Default,\n play: async ({ canvasElement, step }) => {\n const canvas = await withinShadowRoot(canvasElement, 'gs-mutation-comparison-component');\n\n await step('Switch to Venn diagram view', async () => {\n await waitFor(() => expect(canvas.getByRole('button', { name: 'Venn' })).toBeInTheDocument());\n\n await fireEvent.click(canvas.getByRole('button', { name: 'Venn' }));\n\n await waitFor(() =>\n expect(\n canvas.getByText('You have no elements selected. Click in the venn diagram to select.'),\n ).toBeVisible(),\n );\n });\n },\n}"
347
453
  }
348
454
  ],
349
455
  "exports": [
@@ -379,61 +485,86 @@
379
485
  "declarations": [
380
486
  {
381
487
  "kind": "class",
382
- "description": "",
488
+ "description": "This component allows to compare mutations between different variants.\nA variant is defined by its LAPIS filter.\n\nIt only shows substitutions and deletions, it does not show insertions.\n\n## Views\n\n### Table View\n\nThe table view shows mutations\nand the proportions with which the mutation occurs in the respective variant.\nIt only shows mutations that are present in at least one of the variants\nand where the proportion is within the selected proportion interval for at least one variant.\n\n### Venn View\n\nThe Venn view shows the overlap of mutations between the variants in a Venn diagram.\nA variant is considered to have a certain mutation,\nif the proportion of the mutation in the variant is within the selected proportion interval.\nThus, changing the proportion interval may change a mutations from being \"common\" between variant\nto being \"for one variant only\".",
383
489
  "name": "MutationComparisonComponent",
384
490
  "members": [
385
491
  {
386
492
  "kind": "field",
387
493
  "name": "variants",
388
494
  "type": {
389
- "text": "MutationComparisonVariant[]"
495
+ "text": "{\n lapisFilter: Record<string, string | number | null | boolean>;\n displayName: string;\n }[]"
390
496
  },
391
497
  "default": "[]",
498
+ "description": "An array of variants to compare.\n\nThe `lapisFilter` will be sent as is to LAPIS to filter the mutation data.\nIt must be a valid LAPIS filter object.\n\nThe `displayName` will be used as the label for the variant in the views.\nIt should be human-readable.",
392
499
  "attribute": "variants"
393
500
  },
394
501
  {
395
502
  "kind": "field",
396
503
  "name": "sequenceType",
397
504
  "type": {
398
- "text": "SequenceType"
505
+ "text": "'nucleotide' | 'amino acid'"
399
506
  },
400
507
  "default": "'nucleotide'",
508
+ "description": "The type of the sequence for which the mutations should be shown.",
401
509
  "attribute": "sequenceType"
402
510
  },
403
511
  {
404
512
  "kind": "field",
405
513
  "name": "views",
406
514
  "type": {
407
- "text": "View[]"
515
+ "text": "('table' | 'venn')[]"
408
516
  },
409
517
  "default": "['table']",
518
+ "description": "A list of tabs with views that this component should provide.",
410
519
  "attribute": "views"
520
+ },
521
+ {
522
+ "kind": "field",
523
+ "name": "size",
524
+ "type": {
525
+ "text": "{ width?: string; height?: string } | undefined"
526
+ },
527
+ "default": "undefined",
528
+ "description": "The size of the component.\n\nIf not set, the component will take the full width of its container with height 700px.\n\nThe width and height should be a string with a unit in css style, e.g. '100%', '500px' or '50vh'.\nIf the unit is %, the size will be relative to the container of the component.",
529
+ "attribute": "size"
411
530
  }
412
531
  ],
413
532
  "attributes": [
414
533
  {
415
534
  "name": "variants",
416
535
  "type": {
417
- "text": "MutationComparisonVariant[]"
536
+ "text": "{\n lapisFilter: Record<string, string | number | null | boolean>;\n displayName: string;\n }[]"
418
537
  },
419
538
  "default": "[]",
539
+ "description": "An array of variants to compare.\n\nThe `lapisFilter` will be sent as is to LAPIS to filter the mutation data.\nIt must be a valid LAPIS filter object.\n\nThe `displayName` will be used as the label for the variant in the views.\nIt should be human-readable.",
420
540
  "fieldName": "variants"
421
541
  },
422
542
  {
423
543
  "name": "sequenceType",
424
544
  "type": {
425
- "text": "SequenceType"
545
+ "text": "'nucleotide' | 'amino acid'"
426
546
  },
427
547
  "default": "'nucleotide'",
548
+ "description": "The type of the sequence for which the mutations should be shown.",
428
549
  "fieldName": "sequenceType"
429
550
  },
430
551
  {
431
552
  "name": "views",
432
553
  "type": {
433
- "text": "View[]"
554
+ "text": "('table' | 'venn')[]"
434
555
  },
435
556
  "default": "['table']",
557
+ "description": "A list of tabs with views that this component should provide.",
436
558
  "fieldName": "views"
559
+ },
560
+ {
561
+ "name": "size",
562
+ "type": {
563
+ "text": "{ width?: string; height?: string } | undefined"
564
+ },
565
+ "default": "undefined",
566
+ "description": "The size of the component.\n\nIf not set, the component will take the full width of its container with height 700px.\n\nThe width and height should be a string with a unit in css style, e.g. '100%', '500px' or '50vh'.\nIf the unit is %, the size will be relative to the container of the component.",
567
+ "fieldName": "size"
437
568
  }
438
569
  ],
439
570
  "superclass": {
@@ -473,7 +604,7 @@
473
604
  "type": {
474
605
  "text": "Meta<MutationsProps>"
475
606
  },
476
- "default": "{\n title: 'Visualization/Mutations',\n component: 'gs-mutations',\n argTypes: {\n variant: { control: 'object' },\n sequenceType: {\n options: ['nucleotide', 'amino acid'],\n control: { type: 'radio' },\n },\n views: {\n options: ['table', 'grid', 'insertions'],\n control: { type: 'check' },\n },\n },\n}"
607
+ "default": "{\n title: 'Visualization/Mutations',\n component: 'gs-mutations',\n argTypes: {\n variant: { control: 'object' },\n sequenceType: {\n options: ['nucleotide', 'amino acid'],\n control: { type: 'radio' },\n },\n views: {\n options: ['table', 'grid', 'insertions'],\n control: { type: 'check' },\n },\n size: { control: 'object' },\n },\n}"
477
608
  },
478
609
  {
479
610
  "kind": "variable",
@@ -481,7 +612,7 @@
481
612
  "type": {
482
613
  "text": "StoryObj<MutationsProps>"
483
614
  },
484
- "default": "{\n ...Template,\n args: {\n variant: { country: 'Switzerland', pangoLineage: 'B.1.1.7', dateTo: '2022-01-01' },\n sequenceType: 'nucleotide',\n views: ['grid', 'table', 'insertions'],\n },\n parameters: {\n fetchMock: {\n mocks: [\n {\n matcher: {\n name: 'nucleotideMutations',\n url: NUCLEOTIDE_MUTATIONS_ENDPOINT,\n body: {\n country: 'Switzerland',\n pangoLineage: 'B.1.1.7',\n dateTo: '2022-01-01',\n minProportion: 0,\n },\n },\n response: {\n status: 200,\n body: nucleotideMutations,\n },\n },\n {\n matcher: {\n name: 'nucleotideInsertions',\n url: NUCLEOTIDE_INSERTIONS_ENDPOINT,\n body: { country: 'Switzerland', pangoLineage: 'B.1.1.7', dateTo: '2022-01-01' },\n },\n response: {\n status: 200,\n body: nucleotideInsertions,\n },\n },\n ],\n },\n },\n}"
615
+ "default": "{\n ...Template,\n args: {\n variant: { country: 'Switzerland', pangoLineage: 'B.1.1.7', dateTo: '2022-01-01' },\n sequenceType: 'nucleotide',\n views: ['grid', 'table', 'insertions'],\n size: { width: '100%', height: '700px' },\n },\n parameters: {\n fetchMock: {\n mocks: [\n {\n matcher: {\n name: 'nucleotideMutations',\n url: NUCLEOTIDE_MUTATIONS_ENDPOINT,\n body: {\n country: 'Switzerland',\n pangoLineage: 'B.1.1.7',\n dateTo: '2022-01-01',\n minProportion: 0,\n },\n },\n response: {\n status: 200,\n body: nucleotideMutations,\n },\n },\n {\n matcher: {\n name: 'nucleotideInsertions',\n url: NUCLEOTIDE_INSERTIONS_ENDPOINT,\n body: { country: 'Switzerland', pangoLineage: 'B.1.1.7', dateTo: '2022-01-01' },\n },\n response: {\n status: 200,\n body: nucleotideInsertions,\n },\n },\n ],\n },\n },\n}"
485
616
  },
486
617
  {
487
618
  "kind": "variable",
@@ -489,7 +620,7 @@
489
620
  "type": {
490
621
  "text": "StoryObj<MutationsProps>"
491
622
  },
492
- "default": "{\n ...Default,\n play: async ({ canvasElement }) => {\n const canvas = await withinShadowRoot(canvasElement, 'gs-mutations-component');\n\n await waitFor(() => expect(canvas.getByLabelText('Table', { selector: 'input' })).toBeInTheDocument());\n\n await fireEvent.click(canvas.getByLabelText('Table', { selector: 'input' }));\n },\n}"
623
+ "default": "{\n ...Default,\n play: async ({ canvasElement }) => {\n const canvas = await withinShadowRoot(canvasElement, 'gs-mutations-component');\n\n await waitFor(() => expect(canvas.getByRole('button', { name: 'Table' })).toBeInTheDocument());\n\n await fireEvent.click(canvas.getByRole('button', { name: 'Table' }));\n },\n}"
493
624
  },
494
625
  {
495
626
  "kind": "variable",
@@ -497,7 +628,7 @@
497
628
  "type": {
498
629
  "text": "StoryObj<MutationsProps>"
499
630
  },
500
- "default": "{\n ...Default,\n play: async ({ canvasElement }) => {\n const canvas = await withinShadowRoot(canvasElement, 'gs-mutations-component');\n\n await waitFor(() => expect(canvas.getByLabelText('Insertions', { selector: 'input' })).toBeInTheDocument());\n\n await fireEvent.click(canvas.getByLabelText('Insertions', { selector: 'input' }));\n },\n}"
631
+ "default": "{\n ...Default,\n play: async ({ canvasElement }) => {\n const canvas = await withinShadowRoot(canvasElement, 'gs-mutations-component');\n\n await waitFor(() => expect(canvas.getByRole('button', { name: 'Insertions' })).toBeInTheDocument());\n\n await fireEvent.click(canvas.getByRole('button', { name: 'Insertions' }));\n },\n}"
501
632
  }
502
633
  ],
503
634
  "exports": [
@@ -570,6 +701,16 @@
570
701
  },
571
702
  "default": "['table', 'grid']",
572
703
  "attribute": "views"
704
+ },
705
+ {
706
+ "kind": "field",
707
+ "name": "size",
708
+ "type": {
709
+ "text": "{ width?: string; height?: string } | undefined"
710
+ },
711
+ "default": "undefined",
712
+ "description": "The size of the component.\n\nIf not set, the component will take the full width of its container with height 700px.\n\nThe width and height should be a string with a unit in css style, e.g. '100%', '500px' or '50vh'.\nIf the unit is %, the size will be relative to the container of the component.",
713
+ "attribute": "size"
573
714
  }
574
715
  ],
575
716
  "attributes": [
@@ -596,6 +737,15 @@
596
737
  },
597
738
  "default": "['table', 'grid']",
598
739
  "fieldName": "views"
740
+ },
741
+ {
742
+ "name": "size",
743
+ "type": {
744
+ "text": "{ width?: string; height?: string } | undefined"
745
+ },
746
+ "default": "undefined",
747
+ "description": "The size of the component.\n\nIf not set, the component will take the full width of its container with height 700px.\n\nThe width and height should be a string with a unit in css style, e.g. '100%', '500px' or '50vh'.\nIf the unit is %, the size will be relative to the container of the component.",
748
+ "fieldName": "size"
599
749
  }
600
750
  ],
601
751
  "superclass": {
@@ -635,7 +785,7 @@
635
785
  "type": {
636
786
  "text": "Meta<PrevalenceOverTimeProps>"
637
787
  },
638
- "default": "{\n title: 'Visualization/Prevalence over time',\n component: 'gs-prevalence-over-time',\n argTypes: {\n numerator: { control: 'object' },\n denominator: { control: 'object' },\n granularity: {\n options: ['day', 'week', 'month', 'year'],\n control: { type: 'radio' },\n },\n smoothingWindow: { control: 'number' },\n views: {\n options: ['bar', 'line', 'bubble', 'table'],\n control: { type: 'check' },\n },\n confidenceIntervalMethods: {\n options: ['wilson'],\n control: { type: 'check' },\n },\n },\n}"
788
+ "default": "{\n title: 'Visualization/Prevalence over time',\n component: 'gs-prevalence-over-time',\n argTypes: {\n numerator: { control: 'object' },\n denominator: { control: 'object' },\n granularity: {\n options: ['day', 'week', 'month', 'year'],\n control: { type: 'radio' },\n },\n smoothingWindow: { control: 'number' },\n views: {\n options: ['bar', 'line', 'bubble', 'table'],\n control: { type: 'check' },\n },\n confidenceIntervalMethods: {\n options: ['wilson'],\n control: { type: 'check' },\n },\n size: [{ control: 'object' }],\n },\n}"
639
789
  },
640
790
  {
641
791
  "kind": "variable",
@@ -643,7 +793,7 @@
643
793
  "type": {
644
794
  "text": "StoryObj<PrevalenceOverTimeProps>"
645
795
  },
646
- "default": "{\n ...Template,\n args: {\n numerator: [\n { displayName: 'EG', country: 'USA', pangoLineage: 'EG*', dateFrom: '2023-01-01' },\n { displayName: 'JN.1', country: 'USA', pangoLineage: 'JN.1*', dateFrom: '2023-01-01' },\n ],\n denominator: { country: 'USA', dateFrom: '2023-01-01', displayName: 'All' },\n granularity: 'month',\n smoothingWindow: 0,\n views: ['bar', 'line', 'bubble', 'table'],\n confidenceIntervalMethods: ['wilson'],\n },\n parameters: {\n fetchMock: {\n mocks: [\n {\n matcher: {\n name: 'numeratorEG',\n url: AGGREGATED_ENDPOINT,\n body: {\n country: 'USA',\n pangoLineage: 'EG*',\n dateFrom: '2023-01-01',\n fields: ['date'],\n },\n },\n response: {\n status: 200,\n body: numeratorEG,\n },\n },\n {\n matcher: {\n name: 'numeratorJN1',\n url: AGGREGATED_ENDPOINT,\n body: {\n country: 'USA',\n pangoLineage: 'JN.1*',\n dateFrom: '2023-01-01',\n fields: ['date'],\n },\n },\n response: {\n status: 200,\n body: numeratorJN1,\n },\n },\n {\n matcher: {\n name: 'denominator',\n url: AGGREGATED_ENDPOINT,\n body: {\n country: 'USA',\n dateFrom: '2023-01-01',\n fields: ['date'],\n },\n },\n response: {\n status: 200,\n body: denominator,\n },\n },\n ],\n },\n },\n}"
796
+ "default": "{\n ...Template,\n args: {\n numerator: [\n { displayName: 'EG', country: 'USA', pangoLineage: 'EG*', dateFrom: '2023-01-01' },\n { displayName: 'JN.1', country: 'USA', pangoLineage: 'JN.1*', dateFrom: '2023-01-01' },\n ],\n denominator: { country: 'USA', dateFrom: '2023-01-01', displayName: 'All' },\n granularity: 'month',\n smoothingWindow: 0,\n views: ['bar', 'line', 'bubble', 'table'],\n confidenceIntervalMethods: ['wilson'],\n size: { width: '100%', height: '700px' },\n },\n parameters: {\n fetchMock: {\n mocks: [\n {\n matcher: {\n name: 'numeratorEG',\n url: AGGREGATED_ENDPOINT,\n body: {\n country: 'USA',\n pangoLineage: 'EG*',\n dateFrom: '2023-01-01',\n fields: ['date'],\n },\n },\n response: {\n status: 200,\n body: numeratorEG,\n },\n },\n {\n matcher: {\n name: 'numeratorJN1',\n url: AGGREGATED_ENDPOINT,\n body: {\n country: 'USA',\n pangoLineage: 'JN.1*',\n dateFrom: '2023-01-01',\n fields: ['date'],\n },\n },\n response: {\n status: 200,\n body: numeratorJN1,\n },\n },\n {\n matcher: {\n name: 'denominator',\n url: AGGREGATED_ENDPOINT,\n body: {\n country: 'USA',\n dateFrom: '2023-01-01',\n fields: ['date'],\n },\n },\n response: {\n status: 200,\n body: denominator,\n },\n },\n ],\n },\n },\n}"
647
797
  },
648
798
  {
649
799
  "kind": "variable",
@@ -651,7 +801,7 @@
651
801
  "type": {
652
802
  "text": "StoryObj<PrevalenceOverTimeProps>"
653
803
  },
654
- "default": "{\n ...Template,\n args: {\n numerator: { displayName: 'EG', country: 'USA', pangoLineage: 'BA.2.86*', dateFrom: '2023-10-01' },\n denominator: { country: 'USA', dateFrom: '2023-10-01', displayName: 'All' },\n granularity: 'day',\n smoothingWindow: 7,\n views: ['bar', 'line', 'bubble', 'table'],\n confidenceIntervalMethods: ['wilson'],\n },\n parameters: {\n fetchMock: {\n mocks: [\n {\n matcher: {\n name: 'numeratorOneVariant',\n url: AGGREGATED_ENDPOINT,\n body: {\n country: 'USA',\n pangoLineage: 'BA.2.86*',\n dateFrom: '2023-10-01',\n fields: ['date'],\n },\n },\n response: {\n status: 200,\n body: numeratorOneVariant,\n },\n },\n {\n matcher: {\n name: 'denominatorOneVariant',\n url: AGGREGATED_ENDPOINT,\n body: {\n country: 'USA',\n dateFrom: '2023-10-01',\n fields: ['date'],\n },\n },\n response: {\n status: 200,\n body: denominatorOneVariant,\n },\n },\n ],\n },\n },\n}"
804
+ "default": "{\n ...Template,\n args: {\n numerator: { displayName: 'EG', country: 'USA', pangoLineage: 'BA.2.86*', dateFrom: '2023-10-01' },\n denominator: { country: 'USA', dateFrom: '2023-10-01', displayName: 'All' },\n granularity: 'day',\n smoothingWindow: 7,\n views: ['bar', 'line', 'bubble', 'table'],\n confidenceIntervalMethods: ['wilson'],\n size: { width: '100%', height: '700px' },\n },\n parameters: {\n fetchMock: {\n mocks: [\n {\n matcher: {\n name: 'numeratorOneVariant',\n url: AGGREGATED_ENDPOINT,\n body: {\n country: 'USA',\n pangoLineage: 'BA.2.86*',\n dateFrom: '2023-10-01',\n fields: ['date'],\n },\n },\n response: {\n status: 200,\n body: numeratorOneVariant,\n },\n },\n {\n matcher: {\n name: 'denominatorOneVariant',\n url: AGGREGATED_ENDPOINT,\n body: {\n country: 'USA',\n dateFrom: '2023-10-01',\n fields: ['date'],\n },\n },\n response: {\n status: 200,\n body: denominatorOneVariant,\n },\n },\n ],\n },\n },\n}"
655
805
  },
656
806
  {
657
807
  "kind": "variable",
@@ -659,7 +809,7 @@
659
809
  "type": {
660
810
  "text": "StoryObj<PrevalenceOverTimeProps>"
661
811
  },
662
- "default": "{\n ...OneVariant,\n play: async ({ canvasElement }) => {\n const canvas = await withinShadowRoot(canvasElement, 'gs-prevalence-over-time');\n\n await waitFor(() => expect(canvas.getByLabelText('Line', { selector: 'input' })).toBeInTheDocument());\n\n await fireEvent.click(canvas.getByLabelText('Line', { selector: 'input' }));\n },\n}"
812
+ "default": "{\n ...OneVariant,\n play: async ({ canvasElement }) => {\n const canvas = await withinShadowRoot(canvasElement, 'gs-prevalence-over-time');\n\n await waitFor(() => expect(canvas.getByRole('button', { name: 'Line' })).toBeInTheDocument());\n\n await fireEvent.click(canvas.getByRole('button', { name: 'Line' }));\n },\n}"
663
813
  },
664
814
  {
665
815
  "kind": "variable",
@@ -667,7 +817,7 @@
667
817
  "type": {
668
818
  "text": "StoryObj<PrevalenceOverTimeProps>"
669
819
  },
670
- "default": "{\n ...OneVariant,\n play: async ({ canvasElement }) => {\n const canvas = await withinShadowRoot(canvasElement, 'gs-prevalence-over-time');\n\n await waitFor(() => expect(canvas.getByLabelText('Bubble', { selector: 'input' })).toBeInTheDocument());\n\n await fireEvent.click(canvas.getByLabelText('Bubble', { selector: 'input' }));\n },\n}"
820
+ "default": "{\n ...OneVariant,\n play: async ({ canvasElement }) => {\n const canvas = await withinShadowRoot(canvasElement, 'gs-prevalence-over-time');\n\n await waitFor(() => expect(canvas.getByRole('button', { name: 'Bubble' })).toBeInTheDocument());\n\n await fireEvent.click(canvas.getByRole('button', { name: 'Bubble' }));\n },\n}"
671
821
  },
672
822
  {
673
823
  "kind": "variable",
@@ -675,7 +825,7 @@
675
825
  "type": {
676
826
  "text": "StoryObj<PrevalenceOverTimeProps>"
677
827
  },
678
- "default": "{\n ...OneVariant,\n play: async ({ canvasElement }) => {\n const canvas = await withinShadowRoot(canvasElement, 'gs-prevalence-over-time');\n\n await waitFor(() => expect(canvas.getByLabelText('Table', { selector: 'input' })).toBeInTheDocument());\n\n await fireEvent.click(canvas.getByLabelText('Table', { selector: 'input' }));\n },\n}"
828
+ "default": "{\n ...OneVariant,\n play: async ({ canvasElement }) => {\n const canvas = await withinShadowRoot(canvasElement, 'gs-prevalence-over-time');\n\n await waitFor(() => expect(canvas.getByRole('button', { name: 'Table' })).toBeInTheDocument());\n\n await fireEvent.click(canvas.getByRole('button', { name: 'Table' }));\n },\n}"
679
829
  }
680
830
  ],
681
831
  "exports": [
@@ -791,6 +941,16 @@
791
941
  },
792
942
  "default": "['wilson']",
793
943
  "attribute": "confidenceIntervalMethods"
944
+ },
945
+ {
946
+ "kind": "field",
947
+ "name": "size",
948
+ "type": {
949
+ "text": "{ width?: string; height?: string } | undefined"
950
+ },
951
+ "default": "undefined",
952
+ "description": "The size of the component.\n\nIf not set, the component will take the full width of its container with height 700px.\n\nThe width and height should be a string with a unit in css style, e.g. '100%', '500px' or '50vh'.\nIf the unit is %, the size will be relative to the container of the component.",
953
+ "attribute": "size"
794
954
  }
795
955
  ],
796
956
  "attributes": [
@@ -841,6 +1001,15 @@
841
1001
  },
842
1002
  "default": "['wilson']",
843
1003
  "fieldName": "confidenceIntervalMethods"
1004
+ },
1005
+ {
1006
+ "name": "size",
1007
+ "type": {
1008
+ "text": "{ width?: string; height?: string } | undefined"
1009
+ },
1010
+ "default": "undefined",
1011
+ "description": "The size of the component.\n\nIf not set, the component will take the full width of its container with height 700px.\n\nThe width and height should be a string with a unit in css style, e.g. '100%', '500px' or '50vh'.\nIf the unit is %, the size will be relative to the container of the component.",
1012
+ "fieldName": "size"
844
1013
  }
845
1014
  ],
846
1015
  "superclass": {
@@ -880,7 +1049,7 @@
880
1049
  "type": {
881
1050
  "text": "Meta<RelativeGrowthAdvantageProps>"
882
1051
  },
883
- "default": "{\n title: 'Visualization/Relative growth advantage',\n component: 'gs-relative-growth-advantage',\n argTypes: {\n numerator: { control: 'object' },\n denominator: { control: 'object' },\n generationTime: { control: 'number' },\n views: {\n options: ['line'],\n control: { type: 'check' },\n },\n },\n}"
1052
+ "default": "{\n title: 'Visualization/Relative growth advantage',\n component: 'gs-relative-growth-advantage',\n argTypes: {\n numerator: { control: 'object' },\n denominator: { control: 'object' },\n generationTime: { control: 'number' },\n views: {\n options: ['line'],\n control: { type: 'check' },\n },\n size: [{ control: 'object' }],\n },\n}"
884
1053
  },
885
1054
  {
886
1055
  "kind": "variable",
@@ -888,7 +1057,7 @@
888
1057
  "type": {
889
1058
  "text": "StoryObj<RelativeGrowthAdvantageProps>"
890
1059
  },
891
- "default": "{\n ...Template,\n args: {\n numerator: { country: 'Switzerland', pangoLineage: 'B.1.1.7', dateFrom: '2020-12-01', dateTo: '2021-03-01' },\n denominator: { country: 'Switzerland', dateFrom: '2020-12-01', dateTo: '2021-03-01' },\n generationTime: 7,\n views: ['line'],\n },\n parameters: {\n fetchMock: {\n mocks: [\n {\n matcher: {\n name: 'numerator',\n url: AGGREGATED_ENDPOINT,\n body: {\n country: 'Switzerland',\n pangoLineage: 'B.1.1.7',\n dateFrom: '2020-12-01',\n dateTo: '2021-03-01',\n fields: ['date'],\n },\n },\n response: {\n status: 200,\n body: numerator,\n },\n },\n {\n matcher: {\n name: 'denominator',\n url: AGGREGATED_ENDPOINT,\n body: {\n country: 'Switzerland',\n dateFrom: '2020-12-01',\n dateTo: '2021-03-01',\n fields: ['date'],\n },\n },\n response: {\n status: 200,\n body: denominator,\n },\n },\n ],\n },\n },\n}"
1060
+ "default": "{\n ...Template,\n args: {\n numerator: { country: 'Switzerland', pangoLineage: 'B.1.1.7', dateFrom: '2020-12-01', dateTo: '2021-03-01' },\n denominator: { country: 'Switzerland', dateFrom: '2020-12-01', dateTo: '2021-03-01' },\n generationTime: 7,\n views: ['line'],\n size: { width: '100%', height: '700px' },\n },\n parameters: {\n fetchMock: {\n mocks: [\n {\n matcher: {\n name: 'numerator',\n url: AGGREGATED_ENDPOINT,\n body: {\n country: 'Switzerland',\n pangoLineage: 'B.1.1.7',\n dateFrom: '2020-12-01',\n dateTo: '2021-03-01',\n fields: ['date'],\n },\n },\n response: {\n status: 200,\n body: numerator,\n },\n },\n {\n matcher: {\n name: 'denominator',\n url: AGGREGATED_ENDPOINT,\n body: {\n country: 'Switzerland',\n dateFrom: '2020-12-01',\n dateTo: '2021-03-01',\n fields: ['date'],\n },\n },\n response: {\n status: 200,\n body: denominator,\n },\n },\n ],\n },\n },\n}"
892
1061
  }
893
1062
  ],
894
1063
  "exports": [
@@ -954,6 +1123,16 @@
954
1123
  },
955
1124
  "default": "['line']",
956
1125
  "attribute": "views"
1126
+ },
1127
+ {
1128
+ "kind": "field",
1129
+ "name": "size",
1130
+ "type": {
1131
+ "text": "{ width?: string; height?: string } | undefined"
1132
+ },
1133
+ "default": "undefined",
1134
+ "description": "The size of the component.\n\nIf not set, the component will take the full width of its container with height 700px.\n\nThe width and height should be a string with a unit in css style, e.g. '100%', '500px' or '50vh'.\nIf the unit is %, the size will be relative to the container of the component.",
1135
+ "attribute": "size"
957
1136
  }
958
1137
  ],
959
1138
  "attributes": [
@@ -988,6 +1167,15 @@
988
1167
  },
989
1168
  "default": "['line']",
990
1169
  "fieldName": "views"
1170
+ },
1171
+ {
1172
+ "name": "size",
1173
+ "type": {
1174
+ "text": "{ width?: string; height?: string } | undefined"
1175
+ },
1176
+ "default": "undefined",
1177
+ "description": "The size of the component.\n\nIf not set, the component will take the full width of its container with height 700px.\n\nThe width and height should be a string with a unit in css style, e.g. '100%', '500px' or '50vh'.\nIf the unit is %, the size will be relative to the container of the component.",
1178
+ "fieldName": "size"
991
1179
  }
992
1180
  ],
993
1181
  "superclass": {
@@ -1056,17 +1244,17 @@
1056
1244
  "kind": "variable",
1057
1245
  "name": "meta",
1058
1246
  "type": {
1059
- "text": "Meta<DateRangeSelectorProps>"
1247
+ "text": "Meta<DateRangeSelectorProps<'CustomDateRange'>>"
1060
1248
  },
1061
- "default": "{\n title: 'Input/DateRangeSelector',\n component: 'gs-date-range-selector',\n parameters: {\n actions: {\n handles: ['gs-date-range-changed'],\n },\n fetchMock: {},\n },\n decorators: [withActions],\n}"
1249
+ "default": "{\n title: 'Input/DateRangeSelector',\n component: 'gs-date-range-selector',\n parameters: {\n actions: {\n handles: ['gs-date-range-changed'],\n },\n fetchMock: {},\n },\n argTypes: {\n initialValue: {\n control: {\n type: 'select',\n },\n options: [\n PRESET_VALUE_CUSTOM,\n PRESET_VALUE_ALL_TIMES,\n PRESET_VALUE_LAST_2_WEEKS,\n PRESET_VALUE_LAST_MONTH,\n PRESET_VALUE_LAST_2_MONTHS,\n PRESET_VALUE_LAST_3_MONTHS,\n PRESET_VALUE_LAST_6_MONTHS,\n 'CustomDateRange',\n ],\n },\n },\n args: {\n customSelectOptions: [{ label: 'CustomDateRange', dateFrom: '2021-01-01', dateTo: '2021-12-31' }],\n earliestDate: '1970-01-01',\n initialValue: PRESET_VALUE_LAST_6_MONTHS,\n },\n decorators: [withActions],\n}"
1062
1250
  },
1063
1251
  {
1064
1252
  "kind": "variable",
1065
1253
  "name": "DateRangeSelectorStory",
1066
1254
  "type": {
1067
- "text": "StoryObj<DateRangeSelectorProps>"
1255
+ "text": "StoryObj<DateRangeSelectorProps<'CustomDateRange'>>"
1068
1256
  },
1069
- "default": "{\n render: (args) =>\n html` <gs-app lapis=\"${LAPIS_URL}\">\n <div class=\"max-w-screen-lg\">\n <gs-date-range-selector\n .customSelectOptions=${args.customSelectOptions}\n .earliestDate=${args.earliestDate}\n ></gs-date-range-selector>\n </div>\n </gs-app>`,\n\n play: async ({ canvasElement, step }) => {\n const canvas = await withinShadowRoot(canvasElement, 'gs-date-range-selector');\n const dateTo = () => canvas.getByPlaceholderText('Date to');\n\n await step('Expect last 6 months to be selected', async () => {\n await expect(canvas.getByRole('combobox')).toHaveValue('last6Months');\n await waitFor(() => {\n expect(dateTo()).toHaveValue(toYYYYMMDD(new Date()));\n });\n });\n },\n args: {\n customSelectOptions: [{ label: 'CustomDateRange', dateFrom: '2021-01-01', dateTo: '2021-12-31' }],\n earliestDate: '1970-01-01',\n },\n}"
1257
+ "default": "{\n render: (args) =>\n html` <gs-app lapis=\"${LAPIS_URL}\">\n <div class=\"max-w-screen-lg\">\n <gs-date-range-selector\n .customSelectOptions=${args.customSelectOptions}\n .earliestDate=${args.earliestDate}\n .initialValue=${args.initialValue}\n ></gs-date-range-selector>\n </div>\n </gs-app>`,\n play: async ({ canvasElement, step }) => {\n const canvas = await withinShadowRoot(canvasElement, 'gs-date-range-selector');\n const dateTo = () => canvas.getByPlaceholderText('Date to');\n\n await step('Expect last 6 months to be selected', async () => {\n await expect(canvas.getByRole('combobox')).toHaveValue('last6Months');\n await waitFor(() => {\n expect(dateTo()).toHaveValue(toYYYYMMDD(new Date()));\n });\n });\n },\n}"
1070
1258
  }
1071
1259
  ],
1072
1260
  "exports": [
@@ -1101,7 +1289,7 @@
1101
1289
  "kind": "field",
1102
1290
  "name": "customSelectOptions",
1103
1291
  "type": {
1104
- "text": "CustomSelectOption[]"
1292
+ "text": "CustomSelectOption<CustomLabel>[]"
1105
1293
  },
1106
1294
  "default": "[]",
1107
1295
  "attribute": "customSelectOptions"
@@ -1114,6 +1302,15 @@
1114
1302
  },
1115
1303
  "default": "'1900-01-01'",
1116
1304
  "attribute": "earliestDate"
1305
+ },
1306
+ {
1307
+ "kind": "field",
1308
+ "name": "initialValue",
1309
+ "type": {
1310
+ "text": "PresetOptionValues | CustomLabel | string | undefined"
1311
+ },
1312
+ "default": "''",
1313
+ "attribute": "initialValue"
1117
1314
  }
1118
1315
  ],
1119
1316
  "events": [
@@ -1129,7 +1326,7 @@
1129
1326
  {
1130
1327
  "name": "customSelectOptions",
1131
1328
  "type": {
1132
- "text": "CustomSelectOption[]"
1329
+ "text": "CustomSelectOption<CustomLabel>[]"
1133
1330
  },
1134
1331
  "default": "[]",
1135
1332
  "fieldName": "customSelectOptions"
@@ -1141,6 +1338,14 @@
1141
1338
  },
1142
1339
  "default": "'1900-01-01'",
1143
1340
  "fieldName": "earliestDate"
1341
+ },
1342
+ {
1343
+ "name": "initialValue",
1344
+ "type": {
1345
+ "text": "PresetOptionValues | CustomLabel | string | undefined"
1346
+ },
1347
+ "default": "''",
1348
+ "fieldName": "initialValue"
1144
1349
  }
1145
1350
  ],
1146
1351
  "superclass": {
@@ -1219,7 +1424,7 @@
1219
1424
  "type": {
1220
1425
  "text": "Meta"
1221
1426
  },
1222
- "default": "{\n title: 'Input/Location filter',\n component: 'gs-location-filter',\n parameters: {\n actions: {\n handles: ['gs-location-changed'],\n },\n },\n decorators: [withActions],\n}"
1427
+ "default": "{\n title: 'Input/Location filter',\n component: 'gs-location-filter',\n parameters: withComponentDocs({\n actions: {\n handles: ['gs-location-changed'],\n },\n componentDocs: {\n tag: 'gs-location-filter',\n opensShadowDom: true,\n expectsChildren: false,\n codeExample: `<gs-location-filter fields=\"['continent', 'country']\" value='Europe / Switzerland'></gs-location-filter>`,\n },\n }),\n decorators: [withActions],\n tags: ['autodocs'],\n}"
1223
1428
  },
1224
1429
  {
1225
1430
  "kind": "variable",
@@ -1303,18 +1508,18 @@
1303
1508
  "declarations": [
1304
1509
  {
1305
1510
  "kind": "class",
1306
- "description": "## Tag\n\n`gs-location-filter`\n\n## Context\n\nThis component provides an input field to specify filters for locations.\n\nIt expects a list of fields that form a strict hierarchical order, such as continent, country, and city.\nThe component retrieves a list of all possible values for these fields from the Lapis instance.\nThis list is then utilized to display autocomplete suggestions and to validate the input.\n\nGiven `fields` are `['field1', 'field2', ..., 'fieldN']`,\nthen valid values for the location filter must be in the form `valueForField1 / valueForField2 / ... / valueForFieldK`,\nwhere `1 <= K <= N`.\nValues for the fields `i > K` are considered `undefined`.",
1511
+ "description": "## Context\n\nThis component provides an input field to specify filters for locations.\n\nIt expects a list of fields that form a strict hierarchical order, such as continent, country, and city.\nThe component retrieves a list of all possible values for these fields from the Lapis instance.\nThis list is then utilized to display autocomplete suggestions and to validate the input.\n\nGiven `fields` are `['field1', 'field2', ..., 'fieldN']`,\nthen valid values for the location filter must be in the form `valueForField1 / valueForField2 / ... / valueForFieldK`,\nwhere `1 <= K <= N`.\nValues for the fields `i > K` are considered `undefined`.",
1307
1512
  "name": "LocationFilterComponent",
1308
1513
  "members": [
1309
1514
  {
1310
1515
  "kind": "field",
1311
- "name": "value",
1516
+ "name": "initialValue",
1312
1517
  "type": {
1313
1518
  "text": "string"
1314
1519
  },
1315
1520
  "default": "''",
1316
1521
  "description": "The initial value to use for this location filter.\nMust be of the form `valueForField1 / valueForField2 / ... / valueForFieldN`.",
1317
- "attribute": "value"
1522
+ "attribute": "initialValue"
1318
1523
  },
1319
1524
  {
1320
1525
  "kind": "field",
@@ -1338,13 +1543,13 @@
1338
1543
  ],
1339
1544
  "attributes": [
1340
1545
  {
1341
- "name": "value",
1546
+ "name": "initialValue",
1342
1547
  "type": {
1343
1548
  "text": "string"
1344
1549
  },
1345
1550
  "default": "''",
1346
1551
  "description": "The initial value to use for this location filter.\nMust be of the form `valueForField1 / valueForField2 / ... / valueForFieldN`.",
1347
- "fieldName": "value"
1552
+ "fieldName": "initialValue"
1348
1553
  },
1349
1554
  {
1350
1555
  "name": "fields",
@@ -1383,12 +1588,6 @@
1383
1588
  }
1384
1589
  ]
1385
1590
  },
1386
- {
1387
- "kind": "javascript-module",
1388
- "path": "src/web-components/input/location-filter.mdx",
1389
- "declarations": [],
1390
- "exports": []
1391
- },
1392
1591
  {
1393
1592
  "kind": "javascript-module",
1394
1593
  "path": "src/web-components/input/mutation-filter-component.stories.ts",
@@ -1405,25 +1604,25 @@
1405
1604
  "kind": "variable",
1406
1605
  "name": "Default",
1407
1606
  "type": {
1408
- "text": "StoryObj<{ lapisField: string; placeholderText: string }>"
1607
+ "text": "StoryObj<MutationFilterProps>"
1409
1608
  },
1410
- "default": "{\n render: () => {\n return html` <gs-app lapis=\"${LAPIS_URL}\">\n <div class=\"max-w-screen-lg\">\n <gs-mutation-filter></gs-mutation-filter>\n </div>\n </gs-app>`;\n },\n}"
1609
+ "default": "{\n ...Template,\n args: {\n initialValue: ['A123T'],\n },\n}"
1411
1610
  },
1412
1611
  {
1413
1612
  "kind": "variable",
1414
1613
  "name": "FiresFilterChangedEvent",
1415
1614
  "type": {
1416
- "text": "StoryObj<{ lapisField: string; placeholderText: string }>"
1615
+ "text": "StoryObj<MutationFilterProps>"
1417
1616
  },
1418
- "default": "{\n ...Default,\n play: async ({ canvasElement, step }) => {\n const canvas = await withinShadowRoot(canvasElement, 'gs-mutation-filter');\n\n const inputField = () => canvas.getByPlaceholderText('Enter a mutation');\n const submitButton = () => canvas.getByRole('button', { name: '+' });\n const listenerMock = fn();\n await step('Setup event listener mock', async () => {\n canvasElement.addEventListener('gs-mutation-filter-changed', listenerMock);\n });\n\n await step('wait until data is loaded', async () => {\n await waitFor(() => {\n return expect(inputField()).toBeEnabled();\n });\n });\n\n await step('Enter a valid mutation', async () => {\n await userEvent.type(inputField(), 'A123T');\n await waitFor(() => submitButton().click());\n\n await waitFor(() =>\n expect(listenerMock).toHaveBeenCalledWith(\n expect.objectContaining({\n detail: {\n nucleotideMutations: ['A123T'],\n aminoAcidMutations: [],\n nucleotideInsertions: [],\n aminoAcidInsertions: [],\n },\n }),\n ),\n );\n });\n },\n}"
1617
+ "default": "{\n ...Template,\n play: async ({ canvasElement, step }) => {\n const canvas = await withinShadowRoot(canvasElement, 'gs-mutation-filter');\n\n const inputField = () => canvas.getByPlaceholderText('Enter a mutation', { exact: false });\n const submitButton = () => canvas.getByRole('button', { name: '+' });\n const listenerMock = fn();\n await step('Setup event listener mock', async () => {\n canvasElement.addEventListener('gs-mutation-filter-changed', listenerMock);\n });\n\n await step('wait until data is loaded', async () => {\n await waitFor(() => {\n return expect(inputField()).toBeEnabled();\n });\n });\n\n await step('Enter a valid mutation', async () => {\n await userEvent.type(inputField(), 'A123T');\n await waitFor(() => submitButton().click());\n\n await waitFor(() =>\n expect(listenerMock).toHaveBeenCalledWith(\n expect.objectContaining({\n detail: {\n nucleotideMutations: ['A123T'],\n aminoAcidMutations: [],\n nucleotideInsertions: [],\n aminoAcidInsertions: [],\n },\n }),\n ),\n );\n });\n },\n}"
1419
1618
  },
1420
1619
  {
1421
1620
  "kind": "variable",
1422
1621
  "name": "FiresFilterOnBlurEvent",
1423
1622
  "type": {
1424
- "text": "StoryObj<{ lapisField: string; placeholderText: string }>"
1623
+ "text": "StoryObj<MutationFilterProps>"
1425
1624
  },
1426
- "default": "{\n ...Default,\n play: async ({ canvasElement, step }) => {\n const canvas = await withinShadowRoot(canvasElement, 'gs-mutation-filter');\n\n const inputField = () => canvas.getByPlaceholderText('Enter a mutation');\n const listenerMock = fn();\n await step('Setup event listener mock', async () => {\n canvasElement.addEventListener('gs-mutation-filter-on-blur', listenerMock);\n });\n\n await step('wait until data is loaded', async () => {\n await waitFor(() => {\n return expect(inputField()).toBeEnabled();\n });\n });\n\n await step('Move outside of input', async () => {\n await userEvent.type(inputField(), 'A123T');\n await userEvent.tab();\n\n await expect(listenerMock).toHaveBeenCalled();\n });\n },\n}"
1625
+ "default": "{\n ...Template,\n play: async ({ canvasElement, step }) => {\n const canvas = await withinShadowRoot(canvasElement, 'gs-mutation-filter');\n\n const inputField = () => canvas.getByPlaceholderText('Enter a mutation', { exact: false });\n const listenerMock = fn();\n await step('Setup event listener mock', async () => {\n canvasElement.addEventListener('gs-mutation-filter-on-blur', listenerMock);\n });\n\n await step('wait until data is loaded', async () => {\n await waitFor(() => {\n return expect(inputField()).toBeEnabled();\n });\n });\n\n await step('Move outside of input', async () => {\n await userEvent.type(inputField(), 'A123T');\n await userEvent.tab();\n\n await expect(listenerMock).toHaveBeenCalled();\n });\n },\n}"
1427
1626
  }
1428
1627
  ],
1429
1628
  "exports": [
@@ -1469,7 +1668,17 @@
1469
1668
  "kind": "class",
1470
1669
  "description": "",
1471
1670
  "name": "MutationFilterComponent",
1472
- "members": [],
1671
+ "members": [
1672
+ {
1673
+ "kind": "field",
1674
+ "name": "initialValue",
1675
+ "type": {
1676
+ "text": "SelectedMutationFilterStrings | string[] | undefined"
1677
+ },
1678
+ "default": "undefined",
1679
+ "attribute": "initialValue"
1680
+ }
1681
+ ],
1473
1682
  "events": [
1474
1683
  {
1475
1684
  "type": {
@@ -1486,6 +1695,16 @@
1486
1695
  "name": "gs-mutation-filter-on-blur"
1487
1696
  }
1488
1697
  ],
1698
+ "attributes": [
1699
+ {
1700
+ "name": "initialValue",
1701
+ "type": {
1702
+ "text": "SelectedMutationFilterStrings | string[] | undefined"
1703
+ },
1704
+ "default": "undefined",
1705
+ "fieldName": "initialValue"
1706
+ }
1707
+ ],
1489
1708
  "superclass": {
1490
1709
  "name": "PreactLitAdapter",
1491
1710
  "module": "/src/web-components/PreactLitAdapter"
@@ -1523,23 +1742,23 @@
1523
1742
  "type": {
1524
1743
  "text": "Meta"
1525
1744
  },
1526
- "default": "{\n title: 'Input/Text input',\n component: 'gs-text-input',\n parameters: {\n actions: {\n handles: ['gs-text-input-changed'],\n },\n fetchMock: {\n mocks: [\n {\n matcher: {\n name: 'hosts',\n url: AGGREGATED_ENDPOINT,\n body: {\n fields: ['host'],\n },\n },\n response: {\n status: 200,\n body: data,\n },\n },\n ],\n },\n },\n decorators: [withActions],\n tags: ['autodocs'],\n}"
1745
+ "default": "{\n title: 'Input/Text input',\n component: 'gs-text-input',\n parameters: {\n actions: {\n handles: ['gs-text-input-changed'],\n },\n fetchMock: {\n mocks: [\n {\n matcher: {\n name: 'hosts',\n url: AGGREGATED_ENDPOINT,\n body: {\n fields: ['host'],\n },\n },\n response: {\n status: 200,\n body: data,\n },\n },\n ],\n },\n },\n decorators: [withActions],\n}"
1527
1746
  },
1528
1747
  {
1529
1748
  "kind": "variable",
1530
1749
  "name": "Default",
1531
1750
  "type": {
1532
- "text": "StoryObj<{ lapisField: string; placeholderText: string }>"
1751
+ "text": "StoryObj<TextInputProps>"
1533
1752
  },
1534
- "default": "{\n render: (args) => {\n return html` <gs-app lapis=\"${LAPIS_URL}\">\n <div class=\"max-w-screen-lg\">\n <gs-text-input .lapisField=${args.lapisField} .placeholderText=${args.placeholderText}></gs-text-input>\n </div>\n </gs-app>`;\n },\n args: {\n lapisField: 'host',\n placeholderText: 'Enter host name',\n },\n}"
1753
+ "default": "{\n render: (args) => {\n return html` <gs-app lapis=\"${LAPIS_URL}\">\n <div class=\"max-w-screen-lg\">\n <gs-text-input\n .lapisField=${args.lapisField}\n .placeholderText=${args.placeholderText}\n .initialValue=${args.initialValue}\n ></gs-text-input>\n </div>\n </gs-app>`;\n },\n args: {\n lapisField: 'host',\n placeholderText: 'Enter host name',\n initialValue: 'Homo sapiens',\n },\n}"
1535
1754
  },
1536
1755
  {
1537
1756
  "kind": "variable",
1538
1757
  "name": "FiresEvent",
1539
1758
  "type": {
1540
- "text": "StoryObj<{ lapisField: string; placeholderText: string }>"
1759
+ "text": "StoryObj<TextInputProps>"
1541
1760
  },
1542
- "default": "{\n ...Default,\n play: async ({ canvasElement, step }) => {\n const canvas = await withinShadowRoot(canvasElement, 'gs-text-input');\n\n const inputField = () => canvas.getByPlaceholderText('Enter host name');\n const listenerMock = fn();\n await step('Setup event listener mock', async () => {\n canvasElement.addEventListener('gs-text-input-changed', listenerMock);\n });\n\n await step('wait until data is loaded', async () => {\n await waitFor(() => {\n return expect(inputField()).toBeEnabled();\n });\n });\n\n await step('Enters an invalid host name', async () => {\n await userEvent.type(inputField(), 'notInList');\n await expect(listenerMock).not.toHaveBeenCalled();\n await userEvent.type(inputField(), '{backspace>9/}');\n });\n\n await step('Enter a valid host name', async () => {\n await userEvent.type(inputField(), 'Homo');\n\n await expect(listenerMock).toHaveBeenCalledWith(\n expect.objectContaining({\n detail: {\n host: 'Homo',\n },\n }),\n );\n });\n },\n}"
1761
+ "default": "{\n ...Default,\n play: async ({ canvasElement, step }) => {\n const canvas = await withinShadowRoot(canvasElement, 'gs-text-input');\n\n const inputField = () => canvas.getByPlaceholderText('Enter host name');\n const listenerMock = fn();\n await step('Setup event listener mock', async () => {\n canvasElement.addEventListener('gs-text-input-changed', listenerMock);\n });\n\n await step('wait until data is loaded', async () => {\n await waitFor(() => {\n return expect(inputField()).toBeEnabled();\n });\n });\n\n await step('Enters an invalid host name', async () => {\n await userEvent.type(inputField(), 'notInList');\n await expect(listenerMock).not.toHaveBeenCalled();\n await userEvent.type(inputField(), '{backspace>9/}');\n });\n\n await step('Enter a valid host name', async () => {\n await userEvent.type(inputField(), 'Homo');\n\n await expect(listenerMock).toHaveBeenCalledWith(\n expect.objectContaining({\n detail: {\n host: 'Homo',\n },\n }),\n );\n });\n },\n args: {\n ...Default.args,\n initialValue: '',\n },\n}"
1543
1762
  }
1544
1763
  ],
1545
1764
  "exports": [
@@ -1578,6 +1797,15 @@
1578
1797
  "description": "",
1579
1798
  "name": "TextInputComponent",
1580
1799
  "members": [
1800
+ {
1801
+ "kind": "field",
1802
+ "name": "initialValue",
1803
+ "type": {
1804
+ "text": "string | undefined"
1805
+ },
1806
+ "default": "''",
1807
+ "attribute": "initialValue"
1808
+ },
1581
1809
  {
1582
1810
  "kind": "field",
1583
1811
  "name": "lapisField",
@@ -1591,7 +1819,7 @@
1591
1819
  "kind": "field",
1592
1820
  "name": "placeholderText",
1593
1821
  "type": {
1594
- "text": "string"
1822
+ "text": "string | undefined"
1595
1823
  },
1596
1824
  "default": "''",
1597
1825
  "attribute": "placeholderText"
@@ -1607,6 +1835,14 @@
1607
1835
  }
1608
1836
  ],
1609
1837
  "attributes": [
1838
+ {
1839
+ "name": "initialValue",
1840
+ "type": {
1841
+ "text": "string | undefined"
1842
+ },
1843
+ "default": "''",
1844
+ "fieldName": "initialValue"
1845
+ },
1610
1846
  {
1611
1847
  "name": "lapisField",
1612
1848
  "type": {
@@ -1618,7 +1854,7 @@
1618
1854
  {
1619
1855
  "name": "placeholderText",
1620
1856
  "type": {
1621
- "text": "string"
1857
+ "text": "string | undefined"
1622
1858
  },
1623
1859
  "default": "''",
1624
1860
  "fieldName": "placeholderText"