@genspectrum/dashboard-components 0.16.3 → 0.17.0
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 +86 -61
- package/dist/{LineageFilterChangedEvent-COWV-Y0k.js → LineageFilterChangedEvent-DkvWdq_G.js} +2 -2
- package/dist/LineageFilterChangedEvent-DkvWdq_G.js.map +1 -0
- package/dist/assets/{mutationOverTimeWorker-DJcZmEH9.js.map → mutationOverTimeWorker-CPfQDLe6.js.map} +1 -1
- package/dist/components.d.ts +64 -51
- package/dist/components.js +1134 -937
- package/dist/components.js.map +1 -1
- package/dist/style.css +81 -9
- package/dist/util.d.ts +76 -34
- package/dist/util.js +1 -1
- package/package.json +2 -1
- package/src/preact/components/annotated-mutation.stories.tsx +2 -1
- package/src/preact/components/annotated-mutation.tsx +6 -2
- package/src/preact/components/clearable-select.stories.tsx +75 -0
- package/src/preact/components/clearable-select.tsx +76 -0
- package/src/preact/components/downshift-combobox.tsx +9 -7
- package/src/preact/dateRangeFilter/computeInitialValues.spec.ts +31 -33
- package/src/preact/dateRangeFilter/computeInitialValues.ts +2 -15
- package/src/preact/dateRangeFilter/date-picker.tsx +66 -0
- package/src/preact/dateRangeFilter/date-range-filter.stories.tsx +69 -31
- package/src/preact/dateRangeFilter/date-range-filter.tsx +136 -139
- package/src/preact/dateRangeFilter/dateRangeOption.ts +11 -11
- package/src/preact/mutationComparison/mutation-comparison-table.tsx +14 -1
- package/src/preact/mutationComparison/mutation-comparison-venn.tsx +39 -8
- package/src/preact/mutationComparison/mutation-comparison.stories.tsx +36 -12
- package/src/preact/mutationComparison/mutation-comparison.tsx +2 -0
- package/src/preact/mutations/mutations.stories.tsx +3 -9
- package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +3 -8
- package/src/preact/shared/WithClassName/WithClassName.ts +1 -0
- package/src/preact/shared/icons/DeleteIcon.tsx +3 -0
- package/src/preact/shared/stories/expectMutationAnnotation.ts +13 -0
- package/src/preact/shared/stories/expectOptionSelected.tsx +7 -0
- package/src/utilEntrypoint.ts +3 -1
- package/src/web-components/MutationAnnotations.mdx +33 -0
- package/src/web-components/ResizeContainer.mdx +1 -1
- package/src/web-components/errorHandling.mdx +1 -1
- package/src/web-components/gs-app.ts +2 -2
- package/src/web-components/input/gs-date-range-filter.stories.ts +38 -32
- package/src/web-components/input/gs-date-range-filter.tsx +8 -2
- package/src/web-components/input/gs-lineage-filter.tsx +1 -1
- package/src/web-components/input/gs-location-filter.tsx +1 -1
- package/src/web-components/input/gs-mutation-filter.tsx +1 -1
- package/src/web-components/input/gs-text-filter.tsx +1 -1
- package/src/web-components/visualization/gs-aggregate.tsx +2 -2
- package/src/web-components/visualization/gs-mutation-comparison.stories.ts +18 -1
- package/src/web-components/visualization/gs-mutation-comparison.tsx +24 -10
- package/src/web-components/visualization/gs-mutations-over-time.stories.ts +2 -1
- package/src/web-components/visualization/gs-mutations-over-time.tsx +5 -2
- package/src/web-components/visualization/gs-mutations.stories.ts +2 -1
- package/src/web-components/visualization/gs-mutations.tsx +5 -2
- package/src/web-components/visualization/gs-number-sequences-over-time.tsx +2 -2
- package/src/web-components/visualization/gs-prevalence-over-time.tsx +2 -2
- package/src/web-components/visualization/gs-relative-growth-advantage.tsx +2 -2
- package/src/web-components/visualization/gs-sequences-by-location.tsx +2 -2
- package/src/web-components/visualization/gs-statistics.tsx +2 -2
- package/src/web-components/wastewaterVisualization/gs-wastewater-mutations-over-time.tsx +2 -2
- package/standalone-bundle/assets/mutationOverTimeWorker-CERZSdcA.js.map +1 -1
- package/standalone-bundle/dashboard-components.js +13293 -12635
- package/standalone-bundle/dashboard-components.js.map +1 -1
- package/standalone-bundle/style.css +1 -1
- package/dist/LineageFilterChangedEvent-COWV-Y0k.js.map +0 -1
package/dist/style.css
CHANGED
|
@@ -1073,12 +1073,6 @@ html {
|
|
|
1073
1073
|
--tw-bg-opacity: 1;
|
|
1074
1074
|
background-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-bg-opacity)));
|
|
1075
1075
|
}
|
|
1076
|
-
|
|
1077
|
-
.table-zebra tr.hover:hover,
|
|
1078
|
-
.table-zebra tr.hover:nth-child(even):hover {
|
|
1079
|
-
--tw-bg-opacity: 1;
|
|
1080
|
-
background-color: var(--fallback-b3,oklch(var(--b3)/var(--tw-bg-opacity)));
|
|
1081
|
-
}
|
|
1082
1076
|
}
|
|
1083
1077
|
.btn {
|
|
1084
1078
|
display: inline-flex;
|
|
@@ -3098,6 +3092,9 @@ input.tab:checked + .tab-content,
|
|
|
3098
3092
|
.right-0 {
|
|
3099
3093
|
right: 0px;
|
|
3100
3094
|
}
|
|
3095
|
+
.right-10 {
|
|
3096
|
+
right: 2.5rem;
|
|
3097
|
+
}
|
|
3101
3098
|
.right-2 {
|
|
3102
3099
|
right: 0.5rem;
|
|
3103
3100
|
}
|
|
@@ -3247,9 +3244,6 @@ input.tab:checked + .tab-content,
|
|
|
3247
3244
|
.w-\[6rem\] {
|
|
3248
3245
|
width: 6rem;
|
|
3249
3246
|
}
|
|
3250
|
-
.w-\[7\.5rem\] {
|
|
3251
|
-
width: 7.5rem;
|
|
3252
|
-
}
|
|
3253
3247
|
.w-full {
|
|
3254
3248
|
width: 100%;
|
|
3255
3249
|
}
|
|
@@ -3257,6 +3251,9 @@ input.tab:checked + .tab-content,
|
|
|
3257
3251
|
width: -moz-max-content;
|
|
3258
3252
|
width: max-content;
|
|
3259
3253
|
}
|
|
3254
|
+
.min-w-24 {
|
|
3255
|
+
min-width: 6rem;
|
|
3256
|
+
}
|
|
3260
3257
|
.min-w-32 {
|
|
3261
3258
|
min-width: 8rem;
|
|
3262
3259
|
}
|
|
@@ -3278,6 +3275,10 @@ input.tab:checked + .tab-content,
|
|
|
3278
3275
|
.grow {
|
|
3279
3276
|
flex-grow: 1;
|
|
3280
3277
|
}
|
|
3278
|
+
.-translate-y-1\/2 {
|
|
3279
|
+
--tw-translate-y: -50%;
|
|
3280
|
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
3281
|
+
}
|
|
3281
3282
|
.translate-x-\[-50\%\] {
|
|
3282
3283
|
--tw-translate-x: -50%;
|
|
3283
3284
|
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
@@ -3292,6 +3293,11 @@ input.tab:checked + .tab-content,
|
|
|
3292
3293
|
.cursor-pointer {
|
|
3293
3294
|
cursor: pointer;
|
|
3294
3295
|
}
|
|
3296
|
+
.select-text {
|
|
3297
|
+
-webkit-user-select: text;
|
|
3298
|
+
-moz-user-select: text;
|
|
3299
|
+
user-select: text;
|
|
3300
|
+
}
|
|
3295
3301
|
.list-inside {
|
|
3296
3302
|
list-style-position: inside;
|
|
3297
3303
|
}
|
|
@@ -3371,12 +3377,27 @@ input.tab:checked + .tab-content,
|
|
|
3371
3377
|
border-bottom-right-radius: 0.375rem;
|
|
3372
3378
|
border-bottom-left-radius: 0.375rem;
|
|
3373
3379
|
}
|
|
3380
|
+
.rounded-b-none {
|
|
3381
|
+
border-bottom-right-radius: 0px;
|
|
3382
|
+
border-bottom-left-radius: 0px;
|
|
3383
|
+
}
|
|
3384
|
+
.rounded-t-md {
|
|
3385
|
+
border-top-left-radius: 0.375rem;
|
|
3386
|
+
border-top-right-radius: 0.375rem;
|
|
3387
|
+
}
|
|
3388
|
+
.rounded-t-none {
|
|
3389
|
+
border-top-left-radius: 0px;
|
|
3390
|
+
border-top-right-radius: 0px;
|
|
3391
|
+
}
|
|
3374
3392
|
.rounded-tr-md {
|
|
3375
3393
|
border-top-right-radius: 0.375rem;
|
|
3376
3394
|
}
|
|
3377
3395
|
.border {
|
|
3378
3396
|
border-width: 1px;
|
|
3379
3397
|
}
|
|
3398
|
+
.border-0 {
|
|
3399
|
+
border-width: 0px;
|
|
3400
|
+
}
|
|
3380
3401
|
.border-2 {
|
|
3381
3402
|
border-width: 2px;
|
|
3382
3403
|
}
|
|
@@ -3418,6 +3439,9 @@ input.tab:checked + .tab-content,
|
|
|
3418
3439
|
--tw-bg-opacity: 1;
|
|
3419
3440
|
background-color: rgb(226 232 240 / var(--tw-bg-opacity, 1));
|
|
3420
3441
|
}
|
|
3442
|
+
.bg-transparent {
|
|
3443
|
+
background-color: transparent;
|
|
3444
|
+
}
|
|
3421
3445
|
.bg-white {
|
|
3422
3446
|
--tw-bg-opacity: 1;
|
|
3423
3447
|
background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
|
|
@@ -3465,6 +3489,9 @@ input.tab:checked + .tab-content,
|
|
|
3465
3489
|
.pl-2 {
|
|
3466
3490
|
padding-left: 0.5rem;
|
|
3467
3491
|
}
|
|
3492
|
+
.pr-14 {
|
|
3493
|
+
padding-right: 3.5rem;
|
|
3494
|
+
}
|
|
3468
3495
|
.text-center {
|
|
3469
3496
|
text-align: center;
|
|
3470
3497
|
}
|
|
@@ -3663,6 +3690,51 @@ input.tab:checked + .tab-content,
|
|
|
3663
3690
|
visibility: visible;
|
|
3664
3691
|
}
|
|
3665
3692
|
}
|
|
3693
|
+
@container (min-width: 14rem) {
|
|
3694
|
+
|
|
3695
|
+
.\@4xs\:flex-row {
|
|
3696
|
+
flex-direction: row;
|
|
3697
|
+
}
|
|
3698
|
+
|
|
3699
|
+
.\@4xs\:rounded-l-none {
|
|
3700
|
+
border-top-left-radius: 0px;
|
|
3701
|
+
border-bottom-left-radius: 0px;
|
|
3702
|
+
}
|
|
3703
|
+
|
|
3704
|
+
.\@4xs\:rounded-bl-md {
|
|
3705
|
+
border-bottom-left-radius: 0.375rem;
|
|
3706
|
+
}
|
|
3707
|
+
|
|
3708
|
+
.\@4xs\:rounded-tr-none {
|
|
3709
|
+
border-top-right-radius: 0px;
|
|
3710
|
+
}
|
|
3711
|
+
}
|
|
3712
|
+
@container (min-width: 28rem) {
|
|
3713
|
+
|
|
3714
|
+
.\@md\:flex-row {
|
|
3715
|
+
flex-direction: row;
|
|
3716
|
+
}
|
|
3717
|
+
|
|
3718
|
+
.\@md\:rounded-l-md {
|
|
3719
|
+
border-top-left-radius: 0.375rem;
|
|
3720
|
+
border-bottom-left-radius: 0.375rem;
|
|
3721
|
+
}
|
|
3722
|
+
|
|
3723
|
+
.\@md\:rounded-l-none {
|
|
3724
|
+
border-top-left-radius: 0px;
|
|
3725
|
+
border-bottom-left-radius: 0px;
|
|
3726
|
+
}
|
|
3727
|
+
|
|
3728
|
+
.\@md\:rounded-r-md {
|
|
3729
|
+
border-top-right-radius: 0.375rem;
|
|
3730
|
+
border-bottom-right-radius: 0.375rem;
|
|
3731
|
+
}
|
|
3732
|
+
|
|
3733
|
+
.\@md\:rounded-r-none {
|
|
3734
|
+
border-top-right-radius: 0px;
|
|
3735
|
+
border-bottom-right-radius: 0px;
|
|
3736
|
+
}
|
|
3737
|
+
}
|
|
3666
3738
|
@media (min-width: 640px) {
|
|
3667
3739
|
|
|
3668
3740
|
.sm\:max-w-5xl {
|
package/dist/util.d.ts
CHANGED
|
@@ -73,8 +73,8 @@ declare const confidenceIntervalMethodSchema: default_2.ZodUnion<[default_2.ZodL
|
|
|
73
73
|
|
|
74
74
|
export declare type DateRangeOption = default_2.infer<typeof dateRangeOptionSchema>;
|
|
75
75
|
|
|
76
|
-
export declare class DateRangeOptionChangedEvent extends CustomEvent<
|
|
77
|
-
constructor(detail:
|
|
76
|
+
export declare class DateRangeOptionChangedEvent extends CustomEvent<DateRangeValue> {
|
|
77
|
+
constructor(detail: DateRangeValue);
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
/**
|
|
@@ -136,11 +136,9 @@ declare const dateRangeOptionSchema: default_2.ZodObject<{
|
|
|
136
136
|
dateTo?: string | undefined;
|
|
137
137
|
}>;
|
|
138
138
|
|
|
139
|
-
export declare type
|
|
139
|
+
export declare type DateRangeValue = default_2.infer<typeof dateRangeValueSchema>;
|
|
140
140
|
|
|
141
|
-
declare
|
|
142
|
-
|
|
143
|
-
declare const dateRangeValueSchema: default_2.ZodUnion<[default_2.ZodString, default_2.ZodObject<{
|
|
141
|
+
declare const dateRangeValueSchema: default_2.ZodOptional<default_2.ZodUnion<[default_2.ZodString, default_2.ZodObject<{
|
|
144
142
|
dateFrom: default_2.ZodOptional<default_2.ZodString>;
|
|
145
143
|
dateTo: default_2.ZodOptional<default_2.ZodString>;
|
|
146
144
|
}, "strip", default_2.ZodTypeAny, {
|
|
@@ -149,7 +147,7 @@ declare const dateRangeValueSchema: default_2.ZodUnion<[default_2.ZodString, def
|
|
|
149
147
|
}, {
|
|
150
148
|
dateFrom?: string | undefined;
|
|
151
149
|
dateTo?: string | undefined;
|
|
152
|
-
}>]
|
|
150
|
+
}>]>>;
|
|
153
151
|
|
|
154
152
|
export declare type LapisFilter = default_2.infer<typeof lapisFilterSchema>;
|
|
155
153
|
|
|
@@ -202,6 +200,50 @@ declare const mapSourceSchema: default_2.ZodObject<{
|
|
|
202
200
|
topologyObjectsKey: string;
|
|
203
201
|
}>;
|
|
204
202
|
|
|
203
|
+
export declare type MutationAnnotation = default_2.infer<typeof mutationAnnotationSchema>;
|
|
204
|
+
|
|
205
|
+
export declare type MutationAnnotations = default_2.infer<typeof mutationAnnotationsSchema>;
|
|
206
|
+
|
|
207
|
+
declare const mutationAnnotationSchema: default_2.ZodObject<{
|
|
208
|
+
name: default_2.ZodString;
|
|
209
|
+
description: default_2.ZodString;
|
|
210
|
+
symbol: default_2.ZodString;
|
|
211
|
+
nucleotideMutations: default_2.ZodArray<default_2.ZodString, "many">;
|
|
212
|
+
aminoAcidMutations: default_2.ZodArray<default_2.ZodString, "many">;
|
|
213
|
+
}, "strip", default_2.ZodTypeAny, {
|
|
214
|
+
symbol: string;
|
|
215
|
+
name: string;
|
|
216
|
+
description: string;
|
|
217
|
+
nucleotideMutations: string[];
|
|
218
|
+
aminoAcidMutations: string[];
|
|
219
|
+
}, {
|
|
220
|
+
symbol: string;
|
|
221
|
+
name: string;
|
|
222
|
+
description: string;
|
|
223
|
+
nucleotideMutations: string[];
|
|
224
|
+
aminoAcidMutations: string[];
|
|
225
|
+
}>;
|
|
226
|
+
|
|
227
|
+
declare const mutationAnnotationsSchema: default_2.ZodArray<default_2.ZodObject<{
|
|
228
|
+
name: default_2.ZodString;
|
|
229
|
+
description: default_2.ZodString;
|
|
230
|
+
symbol: default_2.ZodString;
|
|
231
|
+
nucleotideMutations: default_2.ZodArray<default_2.ZodString, "many">;
|
|
232
|
+
aminoAcidMutations: default_2.ZodArray<default_2.ZodString, "many">;
|
|
233
|
+
}, "strip", default_2.ZodTypeAny, {
|
|
234
|
+
symbol: string;
|
|
235
|
+
name: string;
|
|
236
|
+
description: string;
|
|
237
|
+
nucleotideMutations: string[];
|
|
238
|
+
aminoAcidMutations: string[];
|
|
239
|
+
}, {
|
|
240
|
+
symbol: string;
|
|
241
|
+
name: string;
|
|
242
|
+
description: string;
|
|
243
|
+
nucleotideMutations: string[];
|
|
244
|
+
aminoAcidMutations: string[];
|
|
245
|
+
}>, "many">;
|
|
246
|
+
|
|
205
247
|
export declare type MutationComparisonProps = default_2.infer<typeof mutationComparisonPropsSchema>;
|
|
206
248
|
|
|
207
249
|
declare const mutationComparisonPropsSchema: default_2.ZodObject<{
|
|
@@ -247,6 +289,7 @@ declare const mutationComparisonPropsSchema: default_2.ZodObject<{
|
|
|
247
289
|
pageSize: default_2.ZodUnion<[default_2.ZodBoolean, default_2.ZodNumber]>;
|
|
248
290
|
}, "strip", default_2.ZodTypeAny, {
|
|
249
291
|
width: string;
|
|
292
|
+
sequenceType: "nucleotide" | "amino acid";
|
|
250
293
|
pageSize: number | boolean;
|
|
251
294
|
lapisFilters: {
|
|
252
295
|
lapisFilter: Record<string, string | number | boolean | string[] | null | undefined> & {
|
|
@@ -257,11 +300,11 @@ declare const mutationComparisonPropsSchema: default_2.ZodObject<{
|
|
|
257
300
|
};
|
|
258
301
|
displayName: string;
|
|
259
302
|
}[];
|
|
260
|
-
sequenceType: "nucleotide" | "amino acid";
|
|
261
303
|
views: ("table" | "venn")[];
|
|
262
304
|
height?: string | undefined;
|
|
263
305
|
}, {
|
|
264
306
|
width: string;
|
|
307
|
+
sequenceType: "nucleotide" | "amino acid";
|
|
265
308
|
pageSize: number | boolean;
|
|
266
309
|
lapisFilters: {
|
|
267
310
|
lapisFilter: Record<string, string | number | boolean | string[] | null | undefined> & {
|
|
@@ -272,7 +315,6 @@ declare const mutationComparisonPropsSchema: default_2.ZodObject<{
|
|
|
272
315
|
};
|
|
273
316
|
displayName: string;
|
|
274
317
|
}[];
|
|
275
|
-
sequenceType: "nucleotide" | "amino acid";
|
|
276
318
|
views: ("table" | "venn")[];
|
|
277
319
|
height?: string | undefined;
|
|
278
320
|
}>;
|
|
@@ -348,8 +390,8 @@ declare const mutationsPropsSchema: default_2.ZodObject<{
|
|
|
348
390
|
aminoAcidInsertions?: string[] | undefined;
|
|
349
391
|
};
|
|
350
392
|
width: string;
|
|
351
|
-
pageSize: number | boolean;
|
|
352
393
|
sequenceType: "nucleotide" | "amino acid";
|
|
394
|
+
pageSize: number | boolean;
|
|
353
395
|
views: ("table" | "grid" | "insertions")[];
|
|
354
396
|
height?: string | undefined;
|
|
355
397
|
baselineLapisFilter?: (Record<string, string | number | boolean | string[] | null | undefined> & {
|
|
@@ -366,8 +408,8 @@ declare const mutationsPropsSchema: default_2.ZodObject<{
|
|
|
366
408
|
aminoAcidInsertions?: string[] | undefined;
|
|
367
409
|
};
|
|
368
410
|
width: string;
|
|
369
|
-
pageSize: number | boolean;
|
|
370
411
|
sequenceType: "nucleotide" | "amino acid";
|
|
412
|
+
pageSize: number | boolean;
|
|
371
413
|
views: ("table" | "grid" | "insertions")[];
|
|
372
414
|
height?: string | undefined;
|
|
373
415
|
baselineLapisFilter?: (Record<string, string | number | boolean | string[] | null | undefined> & {
|
|
@@ -880,7 +922,7 @@ declare global {
|
|
|
880
922
|
|
|
881
923
|
declare global {
|
|
882
924
|
interface HTMLElementTagNameMap {
|
|
883
|
-
'gs-
|
|
925
|
+
'gs-prevalence-over-time': PrevalenceOverTimeComponent;
|
|
884
926
|
}
|
|
885
927
|
}
|
|
886
928
|
|
|
@@ -888,7 +930,7 @@ declare global {
|
|
|
888
930
|
declare global {
|
|
889
931
|
namespace JSX {
|
|
890
932
|
interface IntrinsicElements {
|
|
891
|
-
'gs-
|
|
933
|
+
'gs-prevalence-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
892
934
|
}
|
|
893
935
|
}
|
|
894
936
|
}
|
|
@@ -896,7 +938,7 @@ declare global {
|
|
|
896
938
|
|
|
897
939
|
declare global {
|
|
898
940
|
interface HTMLElementTagNameMap {
|
|
899
|
-
'gs-
|
|
941
|
+
'gs-relative-growth-advantage': RelativeGrowthAdvantageComponent;
|
|
900
942
|
}
|
|
901
943
|
}
|
|
902
944
|
|
|
@@ -904,7 +946,7 @@ declare global {
|
|
|
904
946
|
declare global {
|
|
905
947
|
namespace JSX {
|
|
906
948
|
interface IntrinsicElements {
|
|
907
|
-
'gs-
|
|
949
|
+
'gs-relative-growth-advantage': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
908
950
|
}
|
|
909
951
|
}
|
|
910
952
|
}
|
|
@@ -912,7 +954,7 @@ declare global {
|
|
|
912
954
|
|
|
913
955
|
declare global {
|
|
914
956
|
interface HTMLElementTagNameMap {
|
|
915
|
-
'gs-
|
|
957
|
+
'gs-aggregate': AggregateComponent;
|
|
916
958
|
}
|
|
917
959
|
}
|
|
918
960
|
|
|
@@ -920,7 +962,7 @@ declare global {
|
|
|
920
962
|
declare global {
|
|
921
963
|
namespace JSX {
|
|
922
964
|
interface IntrinsicElements {
|
|
923
|
-
'gs-
|
|
965
|
+
'gs-aggregate': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
924
966
|
}
|
|
925
967
|
}
|
|
926
968
|
}
|
|
@@ -928,7 +970,7 @@ declare global {
|
|
|
928
970
|
|
|
929
971
|
declare global {
|
|
930
972
|
interface HTMLElementTagNameMap {
|
|
931
|
-
'gs-
|
|
973
|
+
'gs-number-sequences-over-time': NumberSequencesOverTimeComponent;
|
|
932
974
|
}
|
|
933
975
|
}
|
|
934
976
|
|
|
@@ -936,7 +978,7 @@ declare global {
|
|
|
936
978
|
declare global {
|
|
937
979
|
namespace JSX {
|
|
938
980
|
interface IntrinsicElements {
|
|
939
|
-
'gs-
|
|
981
|
+
'gs-number-sequences-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
940
982
|
}
|
|
941
983
|
}
|
|
942
984
|
}
|
|
@@ -944,7 +986,7 @@ declare global {
|
|
|
944
986
|
|
|
945
987
|
declare global {
|
|
946
988
|
interface HTMLElementTagNameMap {
|
|
947
|
-
'gs-
|
|
989
|
+
'gs-mutations-over-time': MutationsOverTimeComponent;
|
|
948
990
|
}
|
|
949
991
|
}
|
|
950
992
|
|
|
@@ -952,7 +994,7 @@ declare global {
|
|
|
952
994
|
declare global {
|
|
953
995
|
namespace JSX {
|
|
954
996
|
interface IntrinsicElements {
|
|
955
|
-
'gs-
|
|
997
|
+
'gs-mutations-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
956
998
|
}
|
|
957
999
|
}
|
|
958
1000
|
}
|
|
@@ -960,7 +1002,7 @@ declare global {
|
|
|
960
1002
|
|
|
961
1003
|
declare global {
|
|
962
1004
|
interface HTMLElementTagNameMap {
|
|
963
|
-
'gs-
|
|
1005
|
+
'gs-sequences-by-location': SequencesByLocationComponent;
|
|
964
1006
|
}
|
|
965
1007
|
}
|
|
966
1008
|
|
|
@@ -968,7 +1010,7 @@ declare global {
|
|
|
968
1010
|
declare global {
|
|
969
1011
|
namespace JSX {
|
|
970
1012
|
interface IntrinsicElements {
|
|
971
|
-
'gs-
|
|
1013
|
+
'gs-sequences-by-location': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
972
1014
|
}
|
|
973
1015
|
}
|
|
974
1016
|
}
|
|
@@ -976,10 +1018,7 @@ declare global {
|
|
|
976
1018
|
|
|
977
1019
|
declare global {
|
|
978
1020
|
interface HTMLElementTagNameMap {
|
|
979
|
-
'gs-
|
|
980
|
-
}
|
|
981
|
-
interface HTMLElementEventMap {
|
|
982
|
-
'gs-location-changed': LocationChangedEvent;
|
|
1021
|
+
'gs-statistics': StatisticsComponent;
|
|
983
1022
|
}
|
|
984
1023
|
}
|
|
985
1024
|
|
|
@@ -987,7 +1026,7 @@ declare global {
|
|
|
987
1026
|
declare global {
|
|
988
1027
|
namespace JSX {
|
|
989
1028
|
interface IntrinsicElements {
|
|
990
|
-
'gs-
|
|
1029
|
+
'gs-statistics': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
991
1030
|
}
|
|
992
1031
|
}
|
|
993
1032
|
}
|
|
@@ -995,7 +1034,11 @@ declare global {
|
|
|
995
1034
|
|
|
996
1035
|
declare global {
|
|
997
1036
|
interface HTMLElementTagNameMap {
|
|
998
|
-
'gs-
|
|
1037
|
+
'gs-date-range-filter': DateRangeFilterComponent;
|
|
1038
|
+
}
|
|
1039
|
+
interface HTMLElementEventMap {
|
|
1040
|
+
'gs-date-range-filter-changed': CustomEvent<Record<string, string>>;
|
|
1041
|
+
'gs-date-range-option-changed': DateRangeOptionChangedEvent;
|
|
999
1042
|
}
|
|
1000
1043
|
}
|
|
1001
1044
|
|
|
@@ -1003,7 +1046,7 @@ declare global {
|
|
|
1003
1046
|
declare global {
|
|
1004
1047
|
namespace JSX {
|
|
1005
1048
|
interface IntrinsicElements {
|
|
1006
|
-
'gs-
|
|
1049
|
+
'gs-date-range-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1007
1050
|
}
|
|
1008
1051
|
}
|
|
1009
1052
|
}
|
|
@@ -1027,11 +1070,10 @@ declare global {
|
|
|
1027
1070
|
|
|
1028
1071
|
declare global {
|
|
1029
1072
|
interface HTMLElementTagNameMap {
|
|
1030
|
-
'gs-
|
|
1073
|
+
'gs-location-filter': LocationFilterComponent;
|
|
1031
1074
|
}
|
|
1032
1075
|
interface HTMLElementEventMap {
|
|
1033
|
-
'gs-
|
|
1034
|
-
'gs-date-range-option-changed': DateRangeOptionChangedEvent;
|
|
1076
|
+
'gs-location-changed': LocationChangedEvent;
|
|
1035
1077
|
}
|
|
1036
1078
|
}
|
|
1037
1079
|
|
|
@@ -1039,7 +1081,7 @@ declare global {
|
|
|
1039
1081
|
declare global {
|
|
1040
1082
|
namespace JSX {
|
|
1041
1083
|
interface IntrinsicElements {
|
|
1042
|
-
'gs-
|
|
1084
|
+
'gs-location-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1043
1085
|
}
|
|
1044
1086
|
}
|
|
1045
1087
|
}
|
package/dist/util.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@genspectrum/dashboard-components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "GenSpectrum web components for building dashboards",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "AGPL-3.0-only",
|
|
@@ -87,6 +87,7 @@
|
|
|
87
87
|
"chartjs-chart-error-bars": "^4.4.0",
|
|
88
88
|
"chartjs-chart-venn": "^4.3.0",
|
|
89
89
|
"dayjs": "^1.11.10",
|
|
90
|
+
"dompurify": "^3.2.4",
|
|
90
91
|
"downshift": "^9.0.8",
|
|
91
92
|
"flatpickr": "^4.6.13",
|
|
92
93
|
"gridjs": "^6.2.0",
|
|
@@ -66,7 +66,7 @@ export const MutationWithAnnotationEntry: StoryObj<AnnotatedMutationProps & { an
|
|
|
66
66
|
annotations: [
|
|
67
67
|
{
|
|
68
68
|
name: 'Test annotation',
|
|
69
|
-
description: 'This is a test annotation',
|
|
69
|
+
description: 'This is a test annotation <a class="link" href="/">with a link.</a>',
|
|
70
70
|
symbol: '*',
|
|
71
71
|
nucleotideMutations: ['A23403G'],
|
|
72
72
|
aminoAcidMutations: [],
|
|
@@ -81,6 +81,7 @@ export const MutationWithAnnotationEntry: StoryObj<AnnotatedMutationProps & { an
|
|
|
81
81
|
|
|
82
82
|
await userEvent.click(canvas.getByText('A23403G'));
|
|
83
83
|
await waitFor(() => expect(getAnnotationName(canvas)).toBeVisible());
|
|
84
|
+
await expect(canvas.getByRole('link', { name: 'with a link.' })).toBeVisible();
|
|
84
85
|
},
|
|
85
86
|
};
|
|
86
87
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import DOMPurify from 'dompurify';
|
|
1
2
|
import { useRef } from 'gridjs';
|
|
2
3
|
import { Fragment, type FunctionComponent, type RefObject } from 'preact';
|
|
3
4
|
|
|
@@ -56,14 +57,17 @@ const AnnotatedMutationWithoutContext: FunctionComponent<AnnotatedMutationWithou
|
|
|
56
57
|
{mutationAnnotations.map((annotation) => (
|
|
57
58
|
<Fragment key={annotation.name}>
|
|
58
59
|
<InfoHeadline2>{annotation.name}</InfoHeadline2>
|
|
59
|
-
<InfoParagraph>
|
|
60
|
+
<InfoParagraph>
|
|
61
|
+
{/* eslint-disable-next-line react/no-danger */}
|
|
62
|
+
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(annotation.description) }} />
|
|
63
|
+
</InfoParagraph>
|
|
60
64
|
</Fragment>
|
|
61
65
|
))}
|
|
62
66
|
</div>
|
|
63
67
|
);
|
|
64
68
|
|
|
65
69
|
return (
|
|
66
|
-
<ButtonWithModalDialog modalContent={modalContent} modalRef={modalRef}>
|
|
70
|
+
<ButtonWithModalDialog buttonClassName={'select-text'} modalContent={modalContent} modalRef={modalRef}>
|
|
67
71
|
{mutation.code}
|
|
68
72
|
<sup>
|
|
69
73
|
{mutationAnnotations
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { type Meta, type StoryObj } from '@storybook/preact';
|
|
2
|
+
import { fn, userEvent, within } from '@storybook/test';
|
|
3
|
+
|
|
4
|
+
import { ClearableSelect, type ClearableSelectProps } from './clearable-select';
|
|
5
|
+
import { expectOptionSelected } from '../shared/stories/expectOptionSelected';
|
|
6
|
+
|
|
7
|
+
const meta: Meta<ClearableSelectProps> = {
|
|
8
|
+
title: 'Component/ClearableSelect',
|
|
9
|
+
component: ClearableSelect,
|
|
10
|
+
parameters: { fetchMock: {} },
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default meta;
|
|
14
|
+
|
|
15
|
+
export const Default: StoryObj<ClearableSelectProps> = {
|
|
16
|
+
render: (args) => (
|
|
17
|
+
<div class='flex justify-center px-4 py-16'>
|
|
18
|
+
<ClearableSelect {...args} />
|
|
19
|
+
</div>
|
|
20
|
+
),
|
|
21
|
+
args: {
|
|
22
|
+
items: ['firstOption', 'secondOption'],
|
|
23
|
+
onChange: fn(),
|
|
24
|
+
},
|
|
25
|
+
play: async ({ canvasElement, step }) => {
|
|
26
|
+
await step('Show default placeholder', async () => {
|
|
27
|
+
await expectOptionSelected(canvasElement, 'Select an option');
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const UseInitialSelectedItem: StoryObj<ClearableSelectProps> = {
|
|
33
|
+
...Default,
|
|
34
|
+
args: {
|
|
35
|
+
...Default.args,
|
|
36
|
+
initiallySelectedItem: 'firstOption',
|
|
37
|
+
},
|
|
38
|
+
play: async ({ canvasElement, step }) => {
|
|
39
|
+
await step('Show initiallySelectedItem', async () => {
|
|
40
|
+
await expectOptionSelected(canvasElement, 'firstOption');
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const SwitchToOption: StoryObj<ClearableSelectProps> = {
|
|
46
|
+
...Default,
|
|
47
|
+
play: async ({ canvasElement, step }) => {
|
|
48
|
+
const canvas = within(canvasElement);
|
|
49
|
+
|
|
50
|
+
await step('Select an option', async () => {
|
|
51
|
+
await userEvent.selectOptions(getSelectElement(canvas), 'firstOption');
|
|
52
|
+
await expectOptionSelected(canvasElement, 'firstOption');
|
|
53
|
+
});
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const ClearOption: StoryObj<ClearableSelectProps> = {
|
|
58
|
+
...Default,
|
|
59
|
+
args: {
|
|
60
|
+
...Default.args,
|
|
61
|
+
initiallySelectedItem: 'firstOption',
|
|
62
|
+
},
|
|
63
|
+
play: async ({ canvasElement, step }) => {
|
|
64
|
+
const canvas = within(canvasElement);
|
|
65
|
+
|
|
66
|
+
await step('Clear the selected option', async () => {
|
|
67
|
+
await userEvent.click(canvas.getByRole('button', { name: '×' }));
|
|
68
|
+
await expectOptionSelected(canvasElement, 'Select an option');
|
|
69
|
+
});
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const getSelectElement = (canvas: ReturnType<typeof within>) => {
|
|
74
|
+
return canvas.getByRole('combobox');
|
|
75
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { type ChangeEvent } from 'preact/compat';
|
|
2
|
+
import { useEffect, useState } from 'preact/hooks';
|
|
3
|
+
|
|
4
|
+
import { type WithClassName } from '../shared/WithClassName/WithClassName';
|
|
5
|
+
import { DeleteIcon } from '../shared/icons/DeleteIcon';
|
|
6
|
+
|
|
7
|
+
export const undefinedValue = '__undefined__';
|
|
8
|
+
|
|
9
|
+
export type ClearableSelectProps = {
|
|
10
|
+
items: string[];
|
|
11
|
+
initiallySelectedItem?: string | null;
|
|
12
|
+
onChange?: (item: string | null) => void;
|
|
13
|
+
placeholderText?: string;
|
|
14
|
+
value?: string | null;
|
|
15
|
+
selectClassName?: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export function ClearableSelect({
|
|
19
|
+
items,
|
|
20
|
+
initiallySelectedItem,
|
|
21
|
+
onChange,
|
|
22
|
+
placeholderText,
|
|
23
|
+
className,
|
|
24
|
+
value,
|
|
25
|
+
selectClassName,
|
|
26
|
+
}: WithClassName<ClearableSelectProps>) {
|
|
27
|
+
const [selectedOption, setSelectedOption] = useState<string | null>(initiallySelectedItem ?? null);
|
|
28
|
+
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (value !== undefined) {
|
|
31
|
+
setSelectedOption(value);
|
|
32
|
+
}
|
|
33
|
+
}, [value]);
|
|
34
|
+
|
|
35
|
+
const handleClear = () => {
|
|
36
|
+
setSelectedOption(null);
|
|
37
|
+
if (onChange) {
|
|
38
|
+
onChange(null);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const handleChange = (event: ChangeEvent<HTMLSelectElement>) => {
|
|
43
|
+
const newValue = event.currentTarget.value;
|
|
44
|
+
setSelectedOption(newValue);
|
|
45
|
+
if (onChange) {
|
|
46
|
+
onChange(newValue);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<div className={`relative inline min-w-24 ${className}`}>
|
|
52
|
+
<select
|
|
53
|
+
className={`w-full select select-bordered pr-14 ${selectClassName}`}
|
|
54
|
+
value={selectedOption ?? undefinedValue}
|
|
55
|
+
onChange={handleChange}
|
|
56
|
+
>
|
|
57
|
+
<option value={undefinedValue} disabled>
|
|
58
|
+
{placeholderText ?? 'Select an option'}
|
|
59
|
+
</option>
|
|
60
|
+
{items.map((item) => (
|
|
61
|
+
<option key={item} value={item}>
|
|
62
|
+
{item}
|
|
63
|
+
</option>
|
|
64
|
+
))}
|
|
65
|
+
</select>
|
|
66
|
+
{selectedOption && (
|
|
67
|
+
<button
|
|
68
|
+
onClick={handleClear}
|
|
69
|
+
className='absolute right-10 top-1/2 -translate-y-1/2 bg-transparent border-0 cursor-pointer'
|
|
70
|
+
>
|
|
71
|
+
<DeleteIcon />
|
|
72
|
+
</button>
|
|
73
|
+
)}
|
|
74
|
+
</div>
|
|
75
|
+
);
|
|
76
|
+
}
|