@genspectrum/dashboard-components 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +488 -117
- package/dist/dashboard-components.js +904 -466
- package/dist/dashboard-components.js.map +1 -1
- package/dist/genspectrum-components.d.ts +473 -67
- package/dist/style.css +273 -153
- package/package.json +11 -7
- package/src/preact/aggregatedData/aggregate.stories.tsx +7 -5
- package/src/preact/aggregatedData/aggregate.tsx +16 -7
- package/src/preact/components/ReferenceGenomesAwaiter.tsx +25 -0
- package/src/preact/components/csv-download-button.tsx +8 -2
- package/src/preact/components/headline.stories.tsx +19 -1
- package/src/preact/components/headline.tsx +25 -5
- package/src/preact/components/info.stories.tsx +24 -3
- package/src/preact/components/info.tsx +49 -5
- package/src/preact/components/min-max-range-slider.tsx +4 -4
- package/src/preact/components/percent-intput.tsx +2 -3
- package/src/preact/components/resize-container.tsx +23 -0
- package/src/preact/components/table.tsx +1 -0
- package/src/preact/components/tabs.stories.tsx +2 -2
- package/src/preact/components/tabs.tsx +47 -24
- package/src/preact/dateRangeSelector/date-range-selector.stories.tsx +36 -4
- package/src/preact/dateRangeSelector/date-range-selector.tsx +67 -53
- package/src/preact/locationFilter/location-filter.tsx +2 -2
- package/src/preact/mutationComparison/getMutationComparisonTableData.spec.ts +5 -5
- package/src/preact/mutationComparison/getMutationComparisonTableData.ts +45 -10
- package/src/preact/mutationComparison/mutation-comparison-table.tsx +20 -22
- package/src/preact/mutationComparison/mutation-comparison-venn.tsx +6 -3
- package/src/preact/mutationComparison/mutation-comparison.stories.tsx +11 -1
- package/src/preact/mutationComparison/mutation-comparison.tsx +16 -7
- package/src/preact/mutationFilter/mutation-filter.stories.tsx +70 -31
- package/src/preact/mutationFilter/mutation-filter.tsx +62 -14
- package/src/preact/mutations/getInsertionsTableData.spec.ts +6 -4
- package/src/preact/mutations/getInsertionsTableData.ts +1 -1
- package/src/preact/mutations/getMutationsTableData.spec.ts +9 -19
- package/src/preact/mutations/getMutationsTableData.ts +1 -1
- package/src/preact/mutations/mutations-insertions-table.tsx +3 -1
- package/src/preact/mutations/mutations-table.tsx +3 -1
- package/src/preact/mutations/mutations.stories.tsx +11 -1
- package/src/preact/mutations/mutations.tsx +24 -7
- package/src/preact/prevalenceOverTime/prevalence-over-time-bar-chart.tsx +1 -0
- package/src/preact/prevalenceOverTime/prevalence-over-time-bubble-chart.tsx +1 -0
- package/src/preact/prevalenceOverTime/prevalence-over-time-line-chart.tsx +1 -0
- package/src/preact/prevalenceOverTime/prevalence-over-time.stories.tsx +8 -0
- package/src/preact/prevalenceOverTime/prevalence-over-time.tsx +31 -13
- package/src/preact/relativeGrowthAdvantage/relative-growth-advantage-chart.tsx +8 -5
- package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.stories.tsx +15 -0
- package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.tsx +62 -12
- package/src/preact/shared/sort/sortInsertions.spec.ts +11 -10
- package/src/preact/shared/sort/sortInsertions.ts +10 -17
- package/src/preact/shared/sort/sortSubstitutionsAndDeletions.spec.ts +19 -10
- package/src/preact/shared/sort/sortSubstitutionsAndDeletions.ts +45 -12
- package/src/preact/textInput/text-input.stories.tsx +22 -1
- package/src/preact/textInput/text-input.tsx +3 -1
- package/src/utils/typeAssertions.spec.ts +31 -0
- package/src/utils/typeAssertions.ts +16 -0
- package/src/web-components/PreactLitAdapter.tsx +0 -1
- package/src/web-components/app.stories.ts +129 -0
- package/src/web-components/app.ts +27 -6
- package/src/web-components/display/aggregate-component.stories.ts +24 -11
- package/src/web-components/display/aggregate-component.tsx +26 -5
- package/src/web-components/display/mutation-comparison-component.stories.ts +32 -11
- package/src/web-components/display/mutation-comparison-component.tsx +79 -4
- package/src/web-components/display/mutations-component.stories.ts +40 -19
- package/src/web-components/display/mutations-component.tsx +71 -4
- package/src/web-components/display/prevalence-over-time-component.stories.ts +44 -18
- package/src/web-components/display/prevalence-over-time-component.tsx +105 -5
- package/src/web-components/display/relative-growth-advantage-component.stories.ts +32 -10
- package/src/web-components/display/relative-growth-advantage-component.tsx +66 -3
- package/src/web-components/input/date-range-selector-component.stories.ts +51 -9
- package/src/web-components/input/date-range-selector-component.tsx +69 -4
- package/src/web-components/input/location-filter-component.stories.ts +15 -4
- package/src/web-components/input/location-filter-component.tsx +2 -6
- package/src/web-components/input/mutation-filter-component.stories.ts +33 -12
- package/src/web-components/input/mutation-filter-component.tsx +60 -4
- package/src/web-components/input/text-input-component.stories.ts +26 -6
- package/src/web-components/input/text-input-component.tsx +34 -3
- package/src/web-components/display/aggregate-component.mdx +0 -25
- package/src/web-components/input/location-filter.mdx +0 -25
|
@@ -1,21 +1,77 @@
|
|
|
1
1
|
import { customElement, property } from 'lit/decorators.js';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
type CustomSelectOption,
|
|
5
|
+
DateRangeSelector,
|
|
6
|
+
type PresetOptionValues,
|
|
7
|
+
} from '../../preact/dateRangeSelector/date-range-selector';
|
|
8
|
+
import { type Equals, type Expect } from '../../utils/typeAssertions';
|
|
4
9
|
import { PreactLitAdapter } from '../PreactLitAdapter';
|
|
5
10
|
|
|
6
11
|
/**
|
|
7
|
-
*
|
|
12
|
+
* ## Context
|
|
13
|
+
* This component is a group of input fields designed to specify a date range. It consists of 3 fields:
|
|
14
|
+
*
|
|
15
|
+
* - a select field to choose a predefined date range,
|
|
16
|
+
* - an input field with an attached date picker for the start date,
|
|
17
|
+
* - an input field with an attached date picker for the end date.
|
|
18
|
+
*
|
|
19
|
+
* Setting a value in the select field will overwrite the previous values of the start and end date.
|
|
20
|
+
* Setting a value in either of the date pickers will set the select field to "custom",
|
|
21
|
+
* which represents an arbitrary date range.
|
|
22
|
+
*
|
|
23
|
+
* @fires {CustomEvent<{ dateFrom: string; dateTo: string; }>} gs-date-range-changed
|
|
24
|
+
* Fired when:
|
|
25
|
+
* - The select field is changed,
|
|
26
|
+
* - A date is selected in either of the date pickers,
|
|
27
|
+
* - A date was typed into either of the date input fields, and the input field loses focus ("on blur").
|
|
28
|
+
* Contains the dates in the format `YYYY-MM-DD`.
|
|
8
29
|
*/
|
|
9
30
|
@customElement('gs-date-range-selector')
|
|
10
31
|
export class DateRangeSelectorComponent extends PreactLitAdapter {
|
|
32
|
+
/**
|
|
33
|
+
* An array of custom options that the select field should provide,
|
|
34
|
+
* in addition to the predefined options.
|
|
35
|
+
* The `label` will be shown to the user, and it will be available as `initialValue`.
|
|
36
|
+
* The dates must be in the format `YYYY-MM-DD`.
|
|
37
|
+
*/
|
|
11
38
|
@property({ type: Array })
|
|
12
|
-
customSelectOptions:
|
|
39
|
+
customSelectOptions: { label: string; dateFrom: string; dateTo: string }[] = [];
|
|
13
40
|
|
|
41
|
+
/**
|
|
42
|
+
* The `dateFrom` value to use in the `allTimes` preset in the format `YYYY-MM-DD`.
|
|
43
|
+
*/
|
|
14
44
|
@property({ type: String })
|
|
15
45
|
earliestDate: string | undefined = '1900-01-01';
|
|
16
46
|
|
|
47
|
+
// prettier-ignore
|
|
48
|
+
// The multiline union type must not start with `| 'custom'` - Storybook will list "" as the first type which is wrong
|
|
49
|
+
/**
|
|
50
|
+
* The initial value to use for this date range selector.
|
|
51
|
+
* Must be a valid label from the preset labels or a `label` given in the `customSelectOptions`.
|
|
52
|
+
*
|
|
53
|
+
* If the value is invalid, the component will default to `'last6Months'`.
|
|
54
|
+
*/
|
|
55
|
+
@property()
|
|
56
|
+
initialValue:
|
|
57
|
+
'custom'
|
|
58
|
+
| 'allTimes'
|
|
59
|
+
| 'last2Weeks'
|
|
60
|
+
| 'lastMonth'
|
|
61
|
+
| 'last2Months'
|
|
62
|
+
| 'last3Months'
|
|
63
|
+
| 'last6Months'
|
|
64
|
+
| string
|
|
65
|
+
| undefined = 'last6Months';
|
|
66
|
+
|
|
17
67
|
override render() {
|
|
18
|
-
return
|
|
68
|
+
return (
|
|
69
|
+
<DateRangeSelector
|
|
70
|
+
customSelectOptions={this.customSelectOptions}
|
|
71
|
+
earliestDate={this.earliestDate}
|
|
72
|
+
initialValue={this.initialValue}
|
|
73
|
+
/>
|
|
74
|
+
);
|
|
19
75
|
}
|
|
20
76
|
}
|
|
21
77
|
|
|
@@ -31,3 +87,12 @@ declare global {
|
|
|
31
87
|
}>;
|
|
32
88
|
}
|
|
33
89
|
}
|
|
90
|
+
|
|
91
|
+
/* eslint-disable @typescript-eslint/no-unused-vars, no-unused-vars */
|
|
92
|
+
type CustomSelectOptionsMatches = Expect<
|
|
93
|
+
Equals<typeof DateRangeSelectorComponent.prototype.customSelectOptions, CustomSelectOption<string>[]>
|
|
94
|
+
>;
|
|
95
|
+
type InitialValueMatches = Expect<
|
|
96
|
+
Equals<typeof DateRangeSelectorComponent.prototype.initialValue, PresetOptionValues | string | undefined>
|
|
97
|
+
>;
|
|
98
|
+
/* eslint-enable @typescript-eslint/no-unused-vars, no-unused-vars */
|
|
@@ -4,6 +4,7 @@ import type { Meta, StoryObj } from '@storybook/web-components';
|
|
|
4
4
|
import { html } from 'lit';
|
|
5
5
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
6
6
|
|
|
7
|
+
import { withComponentDocs } from '../../../.storybook/ComponentDocsBlock';
|
|
7
8
|
import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
|
|
8
9
|
import '../app';
|
|
9
10
|
import './location-filter-component';
|
|
@@ -14,12 +15,19 @@ import { withinShadowRoot } from '../withinShadowRoot.story';
|
|
|
14
15
|
const meta: Meta = {
|
|
15
16
|
title: 'Input/Location filter',
|
|
16
17
|
component: 'gs-location-filter',
|
|
17
|
-
parameters: {
|
|
18
|
+
parameters: withComponentDocs({
|
|
18
19
|
actions: {
|
|
19
20
|
handles: ['gs-location-changed'],
|
|
20
21
|
},
|
|
21
|
-
|
|
22
|
+
componentDocs: {
|
|
23
|
+
tag: 'gs-location-filter',
|
|
24
|
+
opensShadowDom: true,
|
|
25
|
+
expectsChildren: false,
|
|
26
|
+
codeExample: `<gs-location-filter fields="['continent', 'country']" value='Europe / Switzerland'></gs-location-filter>`,
|
|
27
|
+
},
|
|
28
|
+
}),
|
|
22
29
|
decorators: [withActions],
|
|
30
|
+
tags: ['autodocs'],
|
|
23
31
|
};
|
|
24
32
|
|
|
25
33
|
export default meta;
|
|
@@ -28,13 +36,16 @@ const Template: StoryObj<LocationFilterProps> = {
|
|
|
28
36
|
render: (args) => {
|
|
29
37
|
return html` <gs-app lapis="${LAPIS_URL}">
|
|
30
38
|
<div class="max-w-screen-lg">
|
|
31
|
-
<gs-location-filter
|
|
39
|
+
<gs-location-filter
|
|
40
|
+
.fields=${args.fields}
|
|
41
|
+
initialValue=${ifDefined(args.initialValue)}
|
|
42
|
+
></gs-location-filter>
|
|
32
43
|
</div>
|
|
33
44
|
</gs-app>`;
|
|
34
45
|
},
|
|
35
46
|
args: {
|
|
36
47
|
fields: ['region', 'country', 'division', 'location'],
|
|
37
|
-
|
|
48
|
+
initialValue: '',
|
|
38
49
|
},
|
|
39
50
|
};
|
|
40
51
|
|
|
@@ -4,10 +4,6 @@ import { LocationFilter } from '../../preact/locationFilter/location-filter';
|
|
|
4
4
|
import { PreactLitAdapter } from '../PreactLitAdapter';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* ## Tag
|
|
8
|
-
*
|
|
9
|
-
* `gs-location-filter`
|
|
10
|
-
*
|
|
11
7
|
* ## Context
|
|
12
8
|
*
|
|
13
9
|
* This component provides an input field to specify filters for locations.
|
|
@@ -41,7 +37,7 @@ export class LocationFilterComponent extends PreactLitAdapter {
|
|
|
41
37
|
* Must be of the form `valueForField1 / valueForField2 / ... / valueForFieldN`.
|
|
42
38
|
*/
|
|
43
39
|
@property()
|
|
44
|
-
|
|
40
|
+
initialValue = '';
|
|
45
41
|
|
|
46
42
|
/**
|
|
47
43
|
* The fields to display in the location filter, in hierarchical order.
|
|
@@ -53,7 +49,7 @@ export class LocationFilterComponent extends PreactLitAdapter {
|
|
|
53
49
|
fields: string[] = [];
|
|
54
50
|
|
|
55
51
|
override render() {
|
|
56
|
-
return <LocationFilter
|
|
52
|
+
return <LocationFilter initialValue={this.initialValue} fields={this.fields} />;
|
|
57
53
|
}
|
|
58
54
|
}
|
|
59
55
|
|
|
@@ -3,41 +3,62 @@ import { expect, fn, userEvent, waitFor } from '@storybook/test';
|
|
|
3
3
|
import type { Meta, StoryObj } from '@storybook/web-components';
|
|
4
4
|
import { html } from 'lit';
|
|
5
5
|
|
|
6
|
+
import { withComponentDocs } from '../../../.storybook/ComponentDocsBlock';
|
|
6
7
|
import { LAPIS_URL } from '../../constants';
|
|
7
8
|
import '../app';
|
|
9
|
+
import { type MutationFilterProps } from '../../preact/mutationFilter/mutation-filter';
|
|
8
10
|
import { withinShadowRoot } from '../withinShadowRoot.story';
|
|
9
11
|
import './mutation-filter-component';
|
|
10
12
|
|
|
11
|
-
const
|
|
13
|
+
const codeExample = String.raw`<gs-mutation-filter initialValue='["A123T"]'></gs-mutation-filter>`;
|
|
14
|
+
|
|
15
|
+
const meta: Meta<MutationFilterProps> = {
|
|
12
16
|
title: 'Input/Mutation filter',
|
|
13
17
|
component: 'gs-mutation-filter',
|
|
14
|
-
parameters: {
|
|
18
|
+
parameters: withComponentDocs({
|
|
15
19
|
actions: {
|
|
16
20
|
handles: ['gs-mutation-filter-changed', 'gs-mutation-filter-on-blur'],
|
|
17
21
|
},
|
|
18
22
|
fetchMock: {},
|
|
19
|
-
|
|
23
|
+
componentDocs: {
|
|
24
|
+
tag: 'gs-mutation-filter',
|
|
25
|
+
opensShadowDom: true,
|
|
26
|
+
expectsChildren: false,
|
|
27
|
+
codeExample,
|
|
28
|
+
},
|
|
29
|
+
}),
|
|
20
30
|
decorators: [withActions],
|
|
31
|
+
tags: ['autodocs'],
|
|
21
32
|
};
|
|
22
33
|
|
|
23
34
|
export default meta;
|
|
24
35
|
|
|
25
|
-
|
|
26
|
-
render: () => {
|
|
36
|
+
const Template: StoryObj<MutationFilterProps> = {
|
|
37
|
+
render: (args) => {
|
|
27
38
|
return html` <gs-app lapis="${LAPIS_URL}">
|
|
28
39
|
<div class="max-w-screen-lg">
|
|
29
|
-
<gs-mutation-filter></gs-mutation-filter>
|
|
40
|
+
<gs-mutation-filter .initialValue=${args.initialValue}></gs-mutation-filter>
|
|
30
41
|
</div>
|
|
31
42
|
</gs-app>`;
|
|
32
43
|
},
|
|
44
|
+
args: {
|
|
45
|
+
initialValue: [],
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const Default: StoryObj<MutationFilterProps> = {
|
|
50
|
+
...Template,
|
|
51
|
+
args: {
|
|
52
|
+
initialValue: ['A123T'],
|
|
53
|
+
},
|
|
33
54
|
};
|
|
34
55
|
|
|
35
|
-
export const FiresFilterChangedEvent: StoryObj<
|
|
36
|
-
...
|
|
56
|
+
export const FiresFilterChangedEvent: StoryObj<MutationFilterProps> = {
|
|
57
|
+
...Template,
|
|
37
58
|
play: async ({ canvasElement, step }) => {
|
|
38
59
|
const canvas = await withinShadowRoot(canvasElement, 'gs-mutation-filter');
|
|
39
60
|
|
|
40
|
-
const inputField = () => canvas.getByPlaceholderText('Enter a mutation');
|
|
61
|
+
const inputField = () => canvas.getByPlaceholderText('Enter a mutation', { exact: false });
|
|
41
62
|
const submitButton = () => canvas.getByRole('button', { name: '+' });
|
|
42
63
|
const listenerMock = fn();
|
|
43
64
|
await step('Setup event listener mock', async () => {
|
|
@@ -70,12 +91,12 @@ export const FiresFilterChangedEvent: StoryObj<{ lapisField: string; placeholder
|
|
|
70
91
|
},
|
|
71
92
|
};
|
|
72
93
|
|
|
73
|
-
export const FiresFilterOnBlurEvent: StoryObj<
|
|
74
|
-
...
|
|
94
|
+
export const FiresFilterOnBlurEvent: StoryObj<MutationFilterProps> = {
|
|
95
|
+
...Template,
|
|
75
96
|
play: async ({ canvasElement, step }) => {
|
|
76
97
|
const canvas = await withinShadowRoot(canvasElement, 'gs-mutation-filter');
|
|
77
98
|
|
|
78
|
-
const inputField = () => canvas.getByPlaceholderText('Enter a mutation');
|
|
99
|
+
const inputField = () => canvas.getByPlaceholderText('Enter a mutation', { exact: false });
|
|
79
100
|
const listenerMock = fn();
|
|
80
101
|
await step('Setup event listener mock', async () => {
|
|
81
102
|
canvasElement.addEventListener('gs-mutation-filter-on-blur', listenerMock);
|
|
@@ -1,17 +1,73 @@
|
|
|
1
|
-
import { customElement } from 'lit/decorators.js';
|
|
1
|
+
import { customElement, property } from 'lit/decorators.js';
|
|
2
2
|
|
|
3
3
|
import { type TextInputComponent } from './text-input-component';
|
|
4
|
+
import { ReferenceGenomesAwaiter } from '../../preact/components/ReferenceGenomesAwaiter';
|
|
4
5
|
import { MutationFilter, type SelectedMutationFilterStrings } from '../../preact/mutationFilter/mutation-filter';
|
|
5
6
|
import { PreactLitAdapter } from '../PreactLitAdapter';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
9
|
+
* ## Context
|
|
10
|
+
* This component provides an input field to specify filters for nucleotide and amino acid mutations and insertions.
|
|
11
|
+
*
|
|
12
|
+
* Input values have to be provided one at a time and submitted by pressing the Enter key or by clicking the '+' button.
|
|
13
|
+
* After submission, the component validates the input and fires an event with the selected mutations.
|
|
14
|
+
* All previously selected mutations are displayed at the input field and added to the event.
|
|
15
|
+
* Users can remove a mutation by clicking the 'x' button next to the mutation.
|
|
16
|
+
*
|
|
17
|
+
* Validation of the input is performed according to the following rules:
|
|
18
|
+
*
|
|
19
|
+
* Mutations have to conform to the following format: `<gene/segment>:<symbol at reference><position><Substituted symbol/Deletion>`
|
|
20
|
+
* - Gene/segment: The gene or segment where the mutation occurs. Must be contained in the reference genome
|
|
21
|
+
* (Optional for elements with only one gene/segment)
|
|
22
|
+
* - Symbol at reference: The symbol at the reference position. (Optional)
|
|
23
|
+
* - Position: The position of the mutation. (Required)
|
|
24
|
+
* - Substituted symbol/Deletion: The substituted symbol or '-' for a deletion. (Required)
|
|
25
|
+
* Example: S:614G, 614G, 614- or 614G
|
|
26
|
+
*
|
|
27
|
+
* Insertions have to conform to the following format: `ins_<gene/segment>:<position>:<Inserted symbols>`
|
|
28
|
+
* - Gene/segment: The gene or segment where the insertion occurs. Must be contained in the reference genome
|
|
29
|
+
* (Optional for elements with only one gene/segment)
|
|
30
|
+
* - Position: The position of the insertion. (Required)
|
|
31
|
+
* - Inserted symbols: The symbols that are inserted. (Required)
|
|
32
|
+
* Example: ins_S:614:G, ins_614:G
|
|
33
|
+
*
|
|
34
|
+
* @fires {CustomEvent<{
|
|
35
|
+
* nucleotideMutations: string[],
|
|
36
|
+
* aminoAcidMutations: string[],
|
|
37
|
+
* nucleotideInsertions: string[],
|
|
38
|
+
* aminoAcidInsertions: string[]
|
|
39
|
+
* }>} gs-mutation-filter-changed
|
|
40
|
+
* Fired when:
|
|
41
|
+
* - The user has submitted a valid mutation or insertion
|
|
42
|
+
* - The user has removed a mutation or insertion
|
|
43
|
+
*
|
|
44
|
+
* @fires {CustomEvent<{
|
|
45
|
+
* nucleotideMutations: string[],
|
|
46
|
+
* aminoAcidMutations: string[],
|
|
47
|
+
* nucleotideInsertions: string[],
|
|
48
|
+
* aminoAcidInsertions: string[]
|
|
49
|
+
* }>} gs-mutation-filter-on-blur
|
|
50
|
+
* Fired when:
|
|
51
|
+
* - the mutation filter has lost focus
|
|
52
|
+
* Contains the selected mutations in the format
|
|
10
53
|
*/
|
|
11
54
|
@customElement('gs-mutation-filter')
|
|
12
55
|
export class MutationFilterComponent extends PreactLitAdapter {
|
|
56
|
+
/**
|
|
57
|
+
* The initial value to use for this mutation filter.
|
|
58
|
+
* Must be either
|
|
59
|
+
* - an array of strings of valid mutations.
|
|
60
|
+
* - an object with the keys `nucleotideMutations`, `aminoAcidMutations`, `nucleotideInsertions` and `aminoAcidInsertions` and corresponding string arrays.
|
|
61
|
+
*/
|
|
62
|
+
@property()
|
|
63
|
+
initialValue: SelectedMutationFilterStrings | string[] | undefined = undefined;
|
|
64
|
+
|
|
13
65
|
override render() {
|
|
14
|
-
return
|
|
66
|
+
return (
|
|
67
|
+
<ReferenceGenomesAwaiter>
|
|
68
|
+
<MutationFilter initialValue={this.initialValue} />
|
|
69
|
+
</ReferenceGenomesAwaiter>
|
|
70
|
+
);
|
|
15
71
|
}
|
|
16
72
|
}
|
|
17
73
|
|
|
@@ -3,16 +3,21 @@ import { expect, fn, userEvent, waitFor } from '@storybook/test';
|
|
|
3
3
|
import type { Meta, StoryObj } from '@storybook/web-components';
|
|
4
4
|
import { html } from 'lit';
|
|
5
5
|
|
|
6
|
+
import { withComponentDocs } from '../../../.storybook/ComponentDocsBlock';
|
|
6
7
|
import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
|
|
7
8
|
import '../app';
|
|
8
9
|
import './text-input-component';
|
|
9
10
|
import data from '../../preact/textInput/__mockData__/aggregated_hosts.json';
|
|
11
|
+
import type { TextInputProps } from '../../preact/textInput/text-input';
|
|
10
12
|
import { withinShadowRoot } from '../withinShadowRoot.story';
|
|
11
13
|
|
|
12
|
-
const
|
|
14
|
+
const codeExample = String.raw`
|
|
15
|
+
<gs-text-input lapisField="host" placeholderText="Enter host name" initialValue="Homo sapiens"></gs-text-input>`;
|
|
16
|
+
|
|
17
|
+
const meta: Meta<TextInputProps> = {
|
|
13
18
|
title: 'Input/Text input',
|
|
14
19
|
component: 'gs-text-input',
|
|
15
|
-
parameters: {
|
|
20
|
+
parameters: withComponentDocs({
|
|
16
21
|
actions: {
|
|
17
22
|
handles: ['gs-text-input-changed'],
|
|
18
23
|
},
|
|
@@ -33,28 +38,39 @@ const meta: Meta = {
|
|
|
33
38
|
},
|
|
34
39
|
],
|
|
35
40
|
},
|
|
36
|
-
|
|
41
|
+
componentDocs: {
|
|
42
|
+
tag: 'gs-text-input',
|
|
43
|
+
opensShadowDom: true,
|
|
44
|
+
expectsChildren: false,
|
|
45
|
+
codeExample,
|
|
46
|
+
},
|
|
47
|
+
}),
|
|
37
48
|
decorators: [withActions],
|
|
38
49
|
tags: ['autodocs'],
|
|
39
50
|
};
|
|
40
51
|
|
|
41
52
|
export default meta;
|
|
42
53
|
|
|
43
|
-
export const Default: StoryObj<
|
|
54
|
+
export const Default: StoryObj<TextInputProps> = {
|
|
44
55
|
render: (args) => {
|
|
45
56
|
return html` <gs-app lapis="${LAPIS_URL}">
|
|
46
57
|
<div class="max-w-screen-lg">
|
|
47
|
-
<gs-text-input
|
|
58
|
+
<gs-text-input
|
|
59
|
+
.lapisField=${args.lapisField}
|
|
60
|
+
.placeholderText=${args.placeholderText}
|
|
61
|
+
.initialValue=${args.initialValue}
|
|
62
|
+
></gs-text-input>
|
|
48
63
|
</div>
|
|
49
64
|
</gs-app>`;
|
|
50
65
|
},
|
|
51
66
|
args: {
|
|
52
67
|
lapisField: 'host',
|
|
53
68
|
placeholderText: 'Enter host name',
|
|
69
|
+
initialValue: 'Homo sapiens',
|
|
54
70
|
},
|
|
55
71
|
};
|
|
56
72
|
|
|
57
|
-
export const FiresEvent: StoryObj<
|
|
73
|
+
export const FiresEvent: StoryObj<TextInputProps> = {
|
|
58
74
|
...Default,
|
|
59
75
|
play: async ({ canvasElement, step }) => {
|
|
60
76
|
const canvas = await withinShadowRoot(canvasElement, 'gs-text-input');
|
|
@@ -89,4 +105,8 @@ export const FiresEvent: StoryObj<{ lapisField: string; placeholderText: string
|
|
|
89
105
|
);
|
|
90
106
|
});
|
|
91
107
|
},
|
|
108
|
+
args: {
|
|
109
|
+
...Default.args,
|
|
110
|
+
initialValue: '',
|
|
111
|
+
},
|
|
92
112
|
};
|
|
@@ -4,18 +4,49 @@ import { TextInput } from '../../preact/textInput/text-input';
|
|
|
4
4
|
import { PreactLitAdapter } from '../PreactLitAdapter';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
*
|
|
8
|
+
* ## Context
|
|
9
|
+
*
|
|
10
|
+
* This component provides a text input field to specify filters for arbitrary fields of this Lapis instance.
|
|
11
|
+
*
|
|
12
|
+
* @fires {CustomEvent<Record<string, string>>} gs-text-input-changed
|
|
13
|
+
* Fired when the input field is changed.
|
|
14
|
+
* The `details` of this event contain an object with the `lapisField` as key and the input value as value.
|
|
15
|
+
* Example:
|
|
16
|
+
* ```
|
|
17
|
+
* {
|
|
18
|
+
* "host": "Homo sapiens"
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
8
21
|
*/
|
|
9
22
|
@customElement('gs-text-input')
|
|
10
23
|
export class TextInputComponent extends PreactLitAdapter {
|
|
24
|
+
/**
|
|
25
|
+
* The initial value to use for this text input.
|
|
26
|
+
*/
|
|
27
|
+
@property()
|
|
28
|
+
initialValue: string | undefined = '';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The Lapis field name to use for this text input.
|
|
32
|
+
*/
|
|
11
33
|
@property()
|
|
12
34
|
lapisField = '';
|
|
13
35
|
|
|
36
|
+
/**
|
|
37
|
+
* The placeholder text to display in the input field.
|
|
38
|
+
*/
|
|
14
39
|
@property()
|
|
15
|
-
placeholderText = '';
|
|
40
|
+
placeholderText: string | undefined = '';
|
|
16
41
|
|
|
17
42
|
override render() {
|
|
18
|
-
return
|
|
43
|
+
return (
|
|
44
|
+
<TextInput
|
|
45
|
+
lapisField={this.lapisField}
|
|
46
|
+
placeholderText={this.placeholderText}
|
|
47
|
+
initialValue={this.initialValue}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
19
50
|
}
|
|
20
51
|
}
|
|
21
52
|
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { ArgTypes, Description, Meta, Story, Title, Source } from '@storybook/blocks';
|
|
2
|
-
|
|
3
|
-
import * as AggregateComponentStories from './aggregate-component.stories.ts';
|
|
4
|
-
|
|
5
|
-
<Meta of={AggregateComponentStories} name='Docs' />
|
|
6
|
-
|
|
7
|
-
<Title of={AggregateComponentStories} />
|
|
8
|
-
|
|
9
|
-
<Description of={AggregateComponentStories} />
|
|
10
|
-
|
|
11
|
-
## Specification
|
|
12
|
-
|
|
13
|
-
<ArgTypes of={AggregateComponentStories} />
|
|
14
|
-
|
|
15
|
-
## Example
|
|
16
|
-
|
|
17
|
-
<Source
|
|
18
|
-
code={`<gs-aggregate-component fields="['division', 'host']" filter='{"country": "USA"}'></gs-aggregate-component>`}
|
|
19
|
-
/>
|
|
20
|
-
|
|
21
|
-
### Live Example
|
|
22
|
-
|
|
23
|
-
[See here](?path=/story/visualization-aggregate--template)
|
|
24
|
-
|
|
25
|
-
<Story of={AggregateComponentStories.Table} />
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { ArgTypes, Description, Meta, Story, Title, Source } from '@storybook/blocks';
|
|
2
|
-
|
|
3
|
-
import * as LocationFilterStories from './location-filter-component.stories.ts';
|
|
4
|
-
|
|
5
|
-
<Meta of={LocationFilterStories} name='Docs' />
|
|
6
|
-
|
|
7
|
-
<Title of={LocationFilterStories} />
|
|
8
|
-
|
|
9
|
-
<Description of={LocationFilterStories} />
|
|
10
|
-
|
|
11
|
-
## Specification
|
|
12
|
-
|
|
13
|
-
<ArgTypes of={LocationFilterStories} />
|
|
14
|
-
|
|
15
|
-
## Example
|
|
16
|
-
|
|
17
|
-
<Source
|
|
18
|
-
code={`<gs-location-filter fields="['continent', 'country']" value='Europe / Switzerland'></gs-location-filter>`}
|
|
19
|
-
/>
|
|
20
|
-
|
|
21
|
-
### Live Example
|
|
22
|
-
|
|
23
|
-
[See here](?path=/story/input-location-filter--location-filter)
|
|
24
|
-
|
|
25
|
-
<Story of={LocationFilterStories.LocationFilter} />
|