@genspectrum/dashboard-components 0.8.2 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dashboard-components.js +39 -51
- package/dist/dashboard-components.js.map +1 -1
- package/dist/genspectrum-components.d.ts +4 -4
- package/dist/style.css +29 -20
- package/package.json +7 -1
- package/src/preact/components/chart.tsx +7 -13
- package/src/preact/mutationsOverTime/mutations-over-time-grid.tsx +5 -35
- package/standalone-bundle/dashboard-components.js +2829 -2833
- package/standalone-bundle/dashboard-components.js.map +1 -1
|
@@ -1045,7 +1045,7 @@ declare global {
|
|
|
1045
1045
|
|
|
1046
1046
|
declare global {
|
|
1047
1047
|
interface HTMLElementTagNameMap {
|
|
1048
|
-
'gs-
|
|
1048
|
+
'gs-prevalence-over-time': PrevalenceOverTimeComponent;
|
|
1049
1049
|
}
|
|
1050
1050
|
}
|
|
1051
1051
|
|
|
@@ -1053,7 +1053,7 @@ declare global {
|
|
|
1053
1053
|
declare global {
|
|
1054
1054
|
namespace JSX {
|
|
1055
1055
|
interface IntrinsicElements {
|
|
1056
|
-
'gs-
|
|
1056
|
+
'gs-prevalence-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1057
1057
|
}
|
|
1058
1058
|
}
|
|
1059
1059
|
}
|
|
@@ -1061,7 +1061,7 @@ declare global {
|
|
|
1061
1061
|
|
|
1062
1062
|
declare global {
|
|
1063
1063
|
interface HTMLElementTagNameMap {
|
|
1064
|
-
'gs-
|
|
1064
|
+
'gs-mutations-component': MutationsComponent;
|
|
1065
1065
|
}
|
|
1066
1066
|
}
|
|
1067
1067
|
|
|
@@ -1069,7 +1069,7 @@ declare global {
|
|
|
1069
1069
|
declare global {
|
|
1070
1070
|
namespace JSX {
|
|
1071
1071
|
interface IntrinsicElements {
|
|
1072
|
-
'gs-
|
|
1072
|
+
'gs-mutations-component': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1073
1073
|
}
|
|
1074
1074
|
}
|
|
1075
1075
|
}
|
package/dist/style.css
CHANGED
|
@@ -482,7 +482,7 @@ input[type="range"] {
|
|
|
482
482
|
--tw-contain-paint: ;
|
|
483
483
|
--tw-contain-style: ;
|
|
484
484
|
}/*
|
|
485
|
-
! tailwindcss v3.4.
|
|
485
|
+
! tailwindcss v3.4.15 | MIT License | https://tailwindcss.com
|
|
486
486
|
*//*
|
|
487
487
|
1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
|
|
488
488
|
2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
|
|
@@ -3194,35 +3194,35 @@ input.tab:checked + .tab-content,
|
|
|
3194
3194
|
}
|
|
3195
3195
|
.border-error {
|
|
3196
3196
|
--tw-border-opacity: 1;
|
|
3197
|
-
border-color: var(--fallback-er,oklch(var(--er)/var(--tw-border-opacity)));
|
|
3197
|
+
border-color: var(--fallback-er,oklch(var(--er)/var(--tw-border-opacity, 1)));
|
|
3198
3198
|
}
|
|
3199
3199
|
.border-gray-100 {
|
|
3200
3200
|
--tw-border-opacity: 1;
|
|
3201
|
-
border-color: rgb(243 244 246 / var(--tw-border-opacity));
|
|
3201
|
+
border-color: rgb(243 244 246 / var(--tw-border-opacity, 1));
|
|
3202
3202
|
}
|
|
3203
3203
|
.border-gray-200 {
|
|
3204
3204
|
--tw-border-opacity: 1;
|
|
3205
|
-
border-color: rgb(229 231 235 / var(--tw-border-opacity));
|
|
3205
|
+
border-color: rgb(229 231 235 / var(--tw-border-opacity, 1));
|
|
3206
3206
|
}
|
|
3207
3207
|
.border-gray-300 {
|
|
3208
3208
|
--tw-border-opacity: 1;
|
|
3209
|
-
border-color: rgb(209 213 219 / var(--tw-border-opacity));
|
|
3209
|
+
border-color: rgb(209 213 219 / var(--tw-border-opacity, 1));
|
|
3210
3210
|
}
|
|
3211
3211
|
.border-gray-400 {
|
|
3212
3212
|
--tw-border-opacity: 1;
|
|
3213
|
-
border-color: rgb(156 163 175 / var(--tw-border-opacity));
|
|
3213
|
+
border-color: rgb(156 163 175 / var(--tw-border-opacity, 1));
|
|
3214
3214
|
}
|
|
3215
3215
|
.border-red-500 {
|
|
3216
3216
|
--tw-border-opacity: 1;
|
|
3217
|
-
border-color: rgb(239 68 68 / var(--tw-border-opacity));
|
|
3217
|
+
border-color: rgb(239 68 68 / var(--tw-border-opacity, 1));
|
|
3218
3218
|
}
|
|
3219
3219
|
.bg-red-200 {
|
|
3220
3220
|
--tw-bg-opacity: 1;
|
|
3221
|
-
background-color: rgb(254 202 202 / var(--tw-bg-opacity));
|
|
3221
|
+
background-color: rgb(254 202 202 / var(--tw-bg-opacity, 1));
|
|
3222
3222
|
}
|
|
3223
3223
|
.bg-white {
|
|
3224
3224
|
--tw-bg-opacity: 1;
|
|
3225
|
-
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
|
|
3225
|
+
background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
|
|
3226
3226
|
}
|
|
3227
3227
|
.p-1 {
|
|
3228
3228
|
padding: 0.25rem;
|
|
@@ -3301,23 +3301,23 @@ input.tab:checked + .tab-content,
|
|
|
3301
3301
|
}
|
|
3302
3302
|
.text-\[\#606060\] {
|
|
3303
3303
|
--tw-text-opacity: 1;
|
|
3304
|
-
color: rgb(96 96 96 / var(--tw-text-opacity));
|
|
3304
|
+
color: rgb(96 96 96 / var(--tw-text-opacity, 1));
|
|
3305
3305
|
}
|
|
3306
3306
|
.text-blue-600 {
|
|
3307
3307
|
--tw-text-opacity: 1;
|
|
3308
|
-
color: rgb(37 99 235 / var(--tw-text-opacity));
|
|
3308
|
+
color: rgb(37 99 235 / var(--tw-text-opacity, 1));
|
|
3309
3309
|
}
|
|
3310
3310
|
.text-gray-600 {
|
|
3311
3311
|
--tw-text-opacity: 1;
|
|
3312
|
-
color: rgb(75 85 99 / var(--tw-text-opacity));
|
|
3312
|
+
color: rgb(75 85 99 / var(--tw-text-opacity, 1));
|
|
3313
3313
|
}
|
|
3314
3314
|
.text-neutral-500 {
|
|
3315
3315
|
--tw-text-opacity: 1;
|
|
3316
|
-
color: rgb(115 115 115 / var(--tw-text-opacity));
|
|
3316
|
+
color: rgb(115 115 115 / var(--tw-text-opacity, 1));
|
|
3317
3317
|
}
|
|
3318
3318
|
.text-red-700 {
|
|
3319
3319
|
--tw-text-opacity: 1;
|
|
3320
|
-
color: rgb(185 28 28 / var(--tw-text-opacity));
|
|
3320
|
+
color: rgb(185 28 28 / var(--tw-text-opacity, 1));
|
|
3321
3321
|
}
|
|
3322
3322
|
.underline {
|
|
3323
3323
|
text-decoration-line: underline;
|
|
@@ -3347,6 +3347,9 @@ input.tab:checked + .tab-content,
|
|
|
3347
3347
|
.duration-150 {
|
|
3348
3348
|
transition-duration: 150ms;
|
|
3349
3349
|
}
|
|
3350
|
+
.\@container {
|
|
3351
|
+
container-type: inline-size;
|
|
3352
|
+
}
|
|
3350
3353
|
.mdi--fullscreen {
|
|
3351
3354
|
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='black' d='M5 5h5v2H7v3H5zm9 0h5v5h-2V7h-3zm3 9h2v5h-5v-2h3zm-7 3v2H5v-5h2v3z'/%3E%3C/svg%3E");
|
|
3352
3355
|
}
|
|
@@ -3377,7 +3380,7 @@ input.tab:checked + .tab-content,
|
|
|
3377
3380
|
}
|
|
3378
3381
|
.focus-within\:border-gray-400:focus-within {
|
|
3379
3382
|
--tw-border-opacity: 1;
|
|
3380
|
-
border-color: rgb(156 163 175 / var(--tw-border-opacity));
|
|
3383
|
+
border-color: rgb(156 163 175 / var(--tw-border-opacity, 1));
|
|
3381
3384
|
}
|
|
3382
3385
|
.hover\:scale-110:hover {
|
|
3383
3386
|
--tw-scale-x: 1.1;
|
|
@@ -3391,26 +3394,26 @@ input.tab:checked + .tab-content,
|
|
|
3391
3394
|
}
|
|
3392
3395
|
.hover\:bg-gray-100:hover {
|
|
3393
3396
|
--tw-bg-opacity: 1;
|
|
3394
|
-
background-color: rgb(243 244 246 / var(--tw-bg-opacity));
|
|
3397
|
+
background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
|
|
3395
3398
|
}
|
|
3396
3399
|
.hover\:font-bold:hover {
|
|
3397
3400
|
font-weight: 700;
|
|
3398
3401
|
}
|
|
3399
3402
|
.hover\:text-blue-700:hover {
|
|
3400
3403
|
--tw-text-opacity: 1;
|
|
3401
|
-
color: rgb(29 78 216 / var(--tw-text-opacity));
|
|
3404
|
+
color: rgb(29 78 216 / var(--tw-text-opacity, 1));
|
|
3402
3405
|
}
|
|
3403
3406
|
.hover\:text-blue-800:hover {
|
|
3404
3407
|
--tw-text-opacity: 1;
|
|
3405
|
-
color: rgb(30 64 175 / var(--tw-text-opacity));
|
|
3408
|
+
color: rgb(30 64 175 / var(--tw-text-opacity, 1));
|
|
3406
3409
|
}
|
|
3407
3410
|
.hover\:text-gray-400:hover {
|
|
3408
3411
|
--tw-text-opacity: 1;
|
|
3409
|
-
color: rgb(156 163 175 / var(--tw-text-opacity));
|
|
3412
|
+
color: rgb(156 163 175 / var(--tw-text-opacity, 1));
|
|
3410
3413
|
}
|
|
3411
3414
|
.hover\:text-gray-700:hover {
|
|
3412
3415
|
--tw-text-opacity: 1;
|
|
3413
|
-
color: rgb(55 65 81 / var(--tw-text-opacity));
|
|
3416
|
+
color: rgb(55 65 81 / var(--tw-text-opacity, 1));
|
|
3414
3417
|
}
|
|
3415
3418
|
.focus\:outline-none:focus {
|
|
3416
3419
|
outline: 2px solid transparent;
|
|
@@ -3424,6 +3427,12 @@ input.tab:checked + .tab-content,
|
|
|
3424
3427
|
.peer:hover ~ .peer-hover\:visible {
|
|
3425
3428
|
visibility: visible;
|
|
3426
3429
|
}
|
|
3430
|
+
@container (min-width: 30rem) {
|
|
3431
|
+
|
|
3432
|
+
.\@\[30rem\]\:visible {
|
|
3433
|
+
visibility: visible;
|
|
3434
|
+
}
|
|
3435
|
+
}
|
|
3427
3436
|
@media (min-width: 640px) {
|
|
3428
3437
|
|
|
3429
3438
|
.sm\:max-w-5xl {
|
package/package.json
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@genspectrum/dashboard-components",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.3",
|
|
4
4
|
"description": "GenSpectrum web components for building dashboards",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "AGPL-3.0-only",
|
|
7
7
|
"main": "dist/genspectrum-components.js",
|
|
8
8
|
"module": "dist/genspectrum-components.js",
|
|
9
9
|
"types": "dist/genspectrum-components.d.ts",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/GenSpectrum/dashboard-components.git",
|
|
13
|
+
"directory": "components"
|
|
14
|
+
},
|
|
10
15
|
"publishConfig": {
|
|
11
16
|
"access": "public"
|
|
12
17
|
},
|
|
@@ -101,6 +106,7 @@
|
|
|
101
106
|
"@storybook/types": "^8.0.9",
|
|
102
107
|
"@storybook/web-components": "^8.0.9",
|
|
103
108
|
"@storybook/web-components-vite": "^8.0.9",
|
|
109
|
+
"@tailwindcss/container-queries": "^0.1.1",
|
|
104
110
|
"@types/node": "^22.0.0",
|
|
105
111
|
"@typescript-eslint/eslint-plugin": "^8.2.0",
|
|
106
112
|
"@typescript-eslint/parser": "^8.2.0",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Chart, type ChartConfiguration } from 'chart.js';
|
|
2
|
-
import {
|
|
2
|
+
import { useEffect, useRef } from 'preact/hooks';
|
|
3
3
|
|
|
4
4
|
export interface GsChartProps {
|
|
5
5
|
configuration: ChartConfiguration;
|
|
@@ -21,9 +21,14 @@ const GsChart = ({ configuration }: GsChartProps) => {
|
|
|
21
21
|
|
|
22
22
|
chartRef.current = new Chart(ctx, configuration);
|
|
23
23
|
|
|
24
|
-
resizeChartAfterFullscreenChange(
|
|
24
|
+
const resizeChartAfterFullscreenChange = () => {
|
|
25
|
+
chartRef.current?.destroy();
|
|
26
|
+
chartRef.current = new Chart(ctx, configuration);
|
|
27
|
+
};
|
|
28
|
+
document.addEventListener('fullscreenchange', resizeChartAfterFullscreenChange);
|
|
25
29
|
|
|
26
30
|
return () => {
|
|
31
|
+
document.removeEventListener('fullscreenchange', resizeChartAfterFullscreenChange);
|
|
27
32
|
chartRef.current?.destroy();
|
|
28
33
|
};
|
|
29
34
|
}, [canvasRef, configuration]);
|
|
@@ -32,14 +37,3 @@ const GsChart = ({ configuration }: GsChartProps) => {
|
|
|
32
37
|
};
|
|
33
38
|
|
|
34
39
|
export default GsChart;
|
|
35
|
-
|
|
36
|
-
const resizeChartAfterFullscreenChange = (
|
|
37
|
-
chartRef: MutableRef<Chart | null>,
|
|
38
|
-
ctx: CanvasRenderingContext2D,
|
|
39
|
-
configuration: ChartConfiguration,
|
|
40
|
-
) => {
|
|
41
|
-
document.addEventListener('fullscreenchange', () => {
|
|
42
|
-
chartRef.current?.destroy();
|
|
43
|
-
chartRef.current = new Chart(ctx, configuration);
|
|
44
|
-
});
|
|
45
|
-
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Fragment, type FunctionComponent
|
|
2
|
-
import {
|
|
1
|
+
import { Fragment, type FunctionComponent } from 'preact';
|
|
2
|
+
import { useRef } from 'preact/hooks';
|
|
3
3
|
|
|
4
4
|
import { type MutationOverTimeDataMap } from './MutationOverTimeData';
|
|
5
5
|
import { type MutationOverTimeMutationValue } from '../../query/queryMutationsOverTime';
|
|
@@ -23,9 +23,7 @@ const MutationsOverTimeGrid: FunctionComponent<MutationsOverTimeGridProps> = ({
|
|
|
23
23
|
|
|
24
24
|
const dates = data.getSecondAxisKeys();
|
|
25
25
|
|
|
26
|
-
const [showProportionText, setShowProportionText] = useState(false);
|
|
27
26
|
const gridRef = useRef<HTMLDivElement>(null);
|
|
28
|
-
useShowProportion(gridRef, dates.length, setShowProportionText);
|
|
29
27
|
|
|
30
28
|
return (
|
|
31
29
|
<>
|
|
@@ -45,6 +43,7 @@ const MutationsOverTimeGrid: FunctionComponent<MutationsOverTimeGridProps> = ({
|
|
|
45
43
|
gridTemplateRows: `repeat(${shownMutations.length}, 24px)`,
|
|
46
44
|
gridTemplateColumns: `${MUTATION_CELL_WIDTH_REM}rem repeat(${dates.length}, minmax(0.05rem, 1fr))`,
|
|
47
45
|
}}
|
|
46
|
+
className='@container'
|
|
48
47
|
>
|
|
49
48
|
{shownMutations.map((mutation, rowIndex) => {
|
|
50
49
|
return (
|
|
@@ -73,7 +72,6 @@ const MutationsOverTimeGrid: FunctionComponent<MutationsOverTimeGridProps> = ({
|
|
|
73
72
|
date={date}
|
|
74
73
|
mutation={mutation}
|
|
75
74
|
tooltipPosition={tooltipPosition}
|
|
76
|
-
showProportionText={showProportionText}
|
|
77
75
|
colorScale={colorScale}
|
|
78
76
|
/>
|
|
79
77
|
</div>
|
|
@@ -87,33 +85,6 @@ const MutationsOverTimeGrid: FunctionComponent<MutationsOverTimeGridProps> = ({
|
|
|
87
85
|
);
|
|
88
86
|
};
|
|
89
87
|
|
|
90
|
-
function useShowProportion(
|
|
91
|
-
gridRef: RefObject<HTMLDivElement>,
|
|
92
|
-
girdColumns: number,
|
|
93
|
-
setShowProportionText: (value: ((prevState: boolean) => boolean) | boolean) => void,
|
|
94
|
-
) {
|
|
95
|
-
useEffect(() => {
|
|
96
|
-
const checkWidth = () => {
|
|
97
|
-
if (gridRef.current) {
|
|
98
|
-
const width = gridRef.current.getBoundingClientRect().width;
|
|
99
|
-
const widthPerDate = (width - remToPx(MUTATION_CELL_WIDTH_REM)) / girdColumns;
|
|
100
|
-
const maxWidthProportionText = 28;
|
|
101
|
-
|
|
102
|
-
setShowProportionText(widthPerDate > maxWidthProportionText);
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
checkWidth();
|
|
107
|
-
window.addEventListener('resize', checkWidth);
|
|
108
|
-
|
|
109
|
-
return () => {
|
|
110
|
-
window.removeEventListener('resize', checkWidth);
|
|
111
|
-
};
|
|
112
|
-
}, [girdColumns, gridRef, setShowProportionText]);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const remToPx = (rem: number) => rem * parseFloat(getComputedStyle(document.documentElement).fontSize);
|
|
116
|
-
|
|
117
88
|
function getTooltipPosition(rowIndex: number, rows: number, columnIndex: number, columns: number) {
|
|
118
89
|
const tooltipX = rowIndex < rows / 2 ? 'bottom' : 'top';
|
|
119
90
|
const tooltipY = columnIndex < columns / 2 ? 'start' : 'end';
|
|
@@ -125,9 +96,8 @@ const ProportionCell: FunctionComponent<{
|
|
|
125
96
|
date: Temporal;
|
|
126
97
|
mutation: Substitution | Deletion;
|
|
127
98
|
tooltipPosition: TooltipPosition;
|
|
128
|
-
showProportionText: boolean;
|
|
129
99
|
colorScale: ColorScale;
|
|
130
|
-
}> = ({ value, mutation, date, tooltipPosition,
|
|
100
|
+
}> = ({ value, mutation, date, tooltipPosition, colorScale }) => {
|
|
131
101
|
const dateClass = toTemporalClass(date);
|
|
132
102
|
|
|
133
103
|
const tooltipContent = (
|
|
@@ -154,7 +124,7 @@ const ProportionCell: FunctionComponent<{
|
|
|
154
124
|
}}
|
|
155
125
|
className={`w-full h-full text-center hover:font-bold text-xs group`}
|
|
156
126
|
>
|
|
157
|
-
|
|
127
|
+
<span className='invisible @[30rem]:visible'>{formatProportion(value.proportion, 0)}</span>
|
|
158
128
|
</div>
|
|
159
129
|
</Tooltip>
|
|
160
130
|
</div>
|