@molgenis/vip-report-template 3.0.0 → 3.1.2

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 (40) hide show
  1. package/package.json +3 -3
  2. package/src/__tests__/query.test.ts +33 -1
  3. package/src/components/Anchor.tsx +10 -7
  4. package/src/components/ConsequenceTable.tsx +11 -4
  5. package/src/components/HpoTerm.tsx +13 -0
  6. package/src/components/InfoCollapsablePane.tsx +29 -22
  7. package/src/components/SampleTable.tsx +4 -3
  8. package/src/components/VariantInfoNestedTable.tsx +26 -16
  9. package/src/components/VariantInfoTable.tsx +9 -4
  10. package/src/components/VariantSampleTable.tsx +4 -4
  11. package/src/components/VariantsSampleTable.tsx +3 -2
  12. package/src/components/VariantsTable.tsx +13 -32
  13. package/src/components/filter/Filter.tsx +12 -8
  14. package/src/components/filter/FilterCategorical.tsx +11 -10
  15. package/src/components/filter/FilterClinVar.tsx +21 -0
  16. package/src/components/filter/FilterIntegerDp.tsx +2 -9
  17. package/src/components/filter/FilterIntegerVid.tsx +2 -9
  18. package/src/components/filter/FilterIntegerVim.tsx +2 -9
  19. package/src/components/filter/InfoFilter.tsx +3 -9
  20. package/src/components/record/Format.tsx +13 -4
  21. package/src/components/record/Info.tsx +18 -32
  22. package/src/components/record/field/Field.tsx +22 -7
  23. package/src/components/record/info/ClinVar.tsx +77 -33
  24. package/src/components/record/info/Consequence.tsx +7 -8
  25. package/src/components/record/info/Gene.tsx +52 -7
  26. package/src/components/record/info/GnomAD.tsx +40 -20
  27. package/src/components/record/info/Hgvs.tsx +11 -9
  28. package/src/components/record/info/PubMed.tsx +17 -13
  29. package/src/mocks/GRCh37/vcf/family.vcf.blob +39 -39
  30. package/src/utils/ApiUtils.ts +10 -9
  31. package/src/utils/csqUtils.ts +27 -0
  32. package/src/utils/query.ts +21 -0
  33. package/src/views/Home.tsx +1 -1
  34. package/src/views/SampleVariant.tsx +2 -2
  35. package/src/views/SampleVariantConsequence.tsx +12 -5
  36. package/src/views/SampleVariants.tsx +16 -7
  37. package/src/views/Variant.tsx +1 -1
  38. package/src/views/VariantConsequence.tsx +2 -2
  39. package/src/views/Variants.tsx +11 -5
  40. package/src/components/record/info/HpoTerm.tsx +0 -12
@@ -1,14 +1,8 @@
1
1
  import { Component } from "solid-js";
2
- import { FieldMetadata } from "@molgenis/vip-report-vcf/src/MetadataParser";
3
- import { Filter, FilterChangeEvent, FilterClearEvent } from "./Filter";
4
- import { QueryClause, SelectorPart } from "@molgenis/vip-report-api/src/Api";
2
+ import { Filter, FilterChangeEvent, FilterClearEvent, FilterProps } from "./Filter";
3
+ import { SelectorPart } from "@molgenis/vip-report-api/src/Api";
5
4
 
6
- export const InfoFilter: Component<{
7
- field: FieldMetadata;
8
- query?: QueryClause;
9
- onChange: (event: FilterChangeEvent) => void;
10
- onClear: (event: FilterClearEvent) => void;
11
- }> = (props) => {
5
+ export const InfoFilter: Component<FilterProps> = (props) => {
12
6
  const label = () => (props.field.label !== undefined ? props.field.label : props.field.id);
13
7
 
14
8
  const onChange = (event: FilterChangeEvent) => {
@@ -5,22 +5,31 @@ import { FieldMetadata } from "@molgenis/vip-report-vcf/src/MetadataParser";
5
5
  import { Field } from "./field/Field";
6
6
  import { GenotypeField } from "./format/GenotypeField";
7
7
  import { Record } from "@molgenis/vip-report-vcf/src/Vcf";
8
+ import { Item } from "@molgenis/vip-report-api/src/Api";
8
9
 
9
10
  export const Format: Component<{
10
11
  format: RecordSampleType;
11
12
  formatMetadata: FieldMetadata;
12
- record: Record;
13
+ record: Item<Record>;
13
14
  isAbbreviate: boolean;
14
15
  allelicDepth: number[] | undefined;
15
16
  readDepth: number | undefined;
16
17
  }> = (props) => {
17
18
  return (
18
- <Switch fallback={<Field info={props.format as Value | Value[]} infoMetadata={props.formatMetadata} />}>
19
+ <Switch
20
+ fallback={
21
+ <Field
22
+ info={{ value: props.format as Value | Value[], record: props.record }}
23
+ infoMeta={props.formatMetadata}
24
+ context={{}}
25
+ />
26
+ }
27
+ >
19
28
  <Match when={props.formatMetadata.id === "GT"}>
20
29
  <GenotypeField
21
30
  genotype={props.format as Genotype}
22
- refAllele={props.record.r}
23
- altAlleles={props.record.a}
31
+ refAllele={props.record.data.r}
32
+ altAlleles={props.record.data.a}
24
33
  isAbbreviate={props.isAbbreviate}
25
34
  allelicDepth={props.allelicDepth}
26
35
  readDepth={props.readDepth}
@@ -1,52 +1,38 @@
1
1
  import { Component, Match, Switch } from "solid-js";
2
- import { Value } from "@molgenis/vip-report-vcf/src/ValueParser";
3
2
  import { FieldMetadata } from "@molgenis/vip-report-vcf/src/MetadataParser";
4
3
  import { Consequence } from "./info/Consequence";
5
- import { Field } from "./field/Field";
4
+ import { Field, FieldContext, FieldValue } from "./field/Field";
6
5
  import { Gene } from "./info/Gene";
7
6
  import { PubMed } from "./info/PubMed";
8
7
  import { Hgvs } from "./info/Hgvs";
9
8
  import { ClinVar } from "./info/ClinVar";
10
- import { Record } from "@molgenis/vip-report-vcf/src/Vcf";
11
9
  import { GnomAD } from "./info/GnomAD";
10
+ import { isAnyCsqInfo, isCsqInfo } from "../../utils/csqUtils";
12
11
 
13
12
  export const Info: Component<{
14
- info: Value | Value[];
15
- infoMetadata: FieldMetadata;
16
- href?: string;
17
- variant: Record;
13
+ info: FieldValue;
14
+ infoMeta: FieldMetadata;
15
+ context: FieldContext;
18
16
  }> = (props) => {
19
17
  return (
20
- <Switch fallback={<Field info={props.info} infoMetadata={props.infoMetadata} />}>
21
- <Match when={props.infoMetadata.id === "Consequence" && props.infoMetadata.parent?.id === "CSQ"}>
22
- <Consequence terms={props.info as string[]} href={props.href} />
18
+ <Switch fallback={<Field {...props} />}>
19
+ <Match when={isCsqInfo(props.infoMeta, "Consequence")}>
20
+ <Consequence {...props} />
23
21
  </Match>
24
- <Match when={props.infoMetadata.id === "PUBMED" && props.infoMetadata.parent?.id === "CSQ"}>
25
- <PubMed ids={props.info as number[]} />
22
+ <Match when={isCsqInfo(props.infoMeta, "PUBMED")}>
23
+ <PubMed {...props} />
26
24
  </Match>
27
- <Match when={props.infoMetadata.id === "SYMBOL" && props.infoMetadata.parent?.id === "CSQ"}>
28
- {props.info !== null && <Gene symbol={props.info as string} />}
25
+ <Match when={isCsqInfo(props.infoMeta, "SYMBOL")}>
26
+ <Gene {...props} />
29
27
  </Match>
30
- <Match
31
- when={
32
- (props.infoMetadata.id === "gnomAD_HN" || props.infoMetadata.id === "gnomAD_AF") &&
33
- props.infoMetadata.parent?.id === "CSQ"
34
- }
35
- >
36
- {props.info !== null && (
37
- <GnomAD id={props.infoMetadata.id} variant={props.variant} value={props.info as number} />
38
- )}
28
+ <Match when={isCsqInfo(props.infoMeta, "gnomAD_AF")}>
29
+ <GnomAD {...props} />
39
30
  </Match>
40
- <Match
41
- when={
42
- (props.infoMetadata.id === "HGVSc" || props.infoMetadata.id === "HGVSp") &&
43
- props.infoMetadata.parent?.id === "CSQ"
44
- }
45
- >
46
- {props.info !== null && <Hgvs notation={props.info as string} />}
31
+ <Match when={isAnyCsqInfo(props.infoMeta, ["HGVSc", "HGVSp"])}>
32
+ <Hgvs {...props} />
47
33
  </Match>
48
- <Match when={props.infoMetadata.id === "CLIN_SIG" && props.infoMetadata.parent?.id === "CSQ"}>
49
- {props.info !== null && <ClinVar value={props.info as string} />}
34
+ <Match when={isCsqInfo(props.infoMeta, "clinVar_CLNSIG")}>
35
+ <ClinVar {...props} />
50
36
  </Match>
51
37
  </Switch>
52
38
  );
@@ -3,17 +3,32 @@ import { Value } from "@molgenis/vip-report-vcf/src/ValueParser";
3
3
  import { FieldMetadata } from "@molgenis/vip-report-vcf/src/MetadataParser";
4
4
  import { FieldSingleValue } from "./FieldSingleValue";
5
5
  import { FieldMultipleValue } from "./FieldMultipleValue";
6
+ import { Record } from "@molgenis/vip-report-vcf/src/Vcf";
7
+ import { Item } from "@molgenis/vip-report-api/src/Api";
6
8
 
7
- export const Field: Component<{
8
- info: Value | Value[];
9
- infoMetadata: FieldMetadata;
10
- }> = (props) => {
9
+ export type FieldProps = {
10
+ info: FieldValue;
11
+ infoMeta: FieldMetadata;
12
+ context: FieldContext;
13
+ };
14
+
15
+ export type FieldValue = {
16
+ value: Value | Value[];
17
+ valueParent?: Value | Value[];
18
+ record: Item<Record>;
19
+ };
20
+
21
+ export type FieldContext = {
22
+ genomeAssembly?: string;
23
+ };
24
+
25
+ export const Field: Component<FieldProps> = (props) => {
11
26
  return (
12
27
  <>
13
- {props.infoMetadata.number.count === 1 ? (
14
- <FieldSingleValue info={props.info as Value} infoMetadata={props.infoMetadata} />
28
+ {props.infoMeta.number.count === 1 ? (
29
+ <FieldSingleValue info={props.info.value as Value} infoMetadata={props.infoMeta} />
15
30
  ) : (
16
- <FieldMultipleValue info={props.info as Value[]} infoMetadata={props.infoMetadata} />
31
+ <FieldMultipleValue info={props.info.value as Value[]} infoMetadata={props.infoMeta} />
17
32
  )}
18
33
  </>
19
34
  );
@@ -1,37 +1,81 @@
1
- import { Component } from "solid-js";
1
+ import { Component, Show } from "solid-js";
2
+ import { FieldProps } from "../field/Field";
3
+ import { Anchor } from "../../Anchor";
4
+ import { Abbr } from "../../Abbr";
5
+ import { getCsqInfo, getCsqInfoIndex } from "../../../utils/csqUtils";
2
6
 
3
- export const ClinVar: Component<{
4
- value: string;
5
- }> = (props) => {
6
- function getClass(value: string): string {
7
- const vClasses = [];
8
- for (const token of value) {
9
- for (const subToken of token.split("/")) {
10
- let vClass;
11
- switch (subToken) {
12
- case "benign":
13
- vClass = "B";
14
- break;
15
- case "likely_benign":
16
- vClass = "LB";
17
- break;
18
- case "uncertain_significance":
19
- vClass = "VUS";
20
- break;
21
- case "likely_pathogenic":
22
- vClass = "LP";
23
- break;
24
- case "pathogenic":
25
- vClass = "P";
26
- break;
27
- default:
28
- vClass = value;
29
- }
30
- vClasses.push(vClass);
31
- }
7
+ export const ClinVar: Component<FieldProps> = (props) => {
8
+ const label = () => {
9
+ const classes = props.info.value as string[] | null;
10
+ return classes
11
+ ? classes
12
+ .map((token) => {
13
+ switch (token.toLowerCase()) {
14
+ case "benign":
15
+ return "B";
16
+ case "likely_benign":
17
+ return "LB";
18
+ case "uncertain_significance":
19
+ return "VUS";
20
+ case "likely_pathogenic":
21
+ return "LP";
22
+ case "pathogenic":
23
+ return "P";
24
+ case "conflicting_interpretations_of_pathogenicity":
25
+ return "Conflict";
26
+ default:
27
+ return token;
28
+ }
29
+ })
30
+ .join(", ")
31
+ : null;
32
+ };
33
+
34
+ const href = () => {
35
+ const clinVarIdsField = getCsqInfoIndex(props.infoMeta, "clinVar");
36
+ const clinVarIds = clinVarIdsField ? (getCsqInfo(props.info, clinVarIdsField) as number[]) : [];
37
+ return clinVarIds.length === 1 ? `https://www.ncbi.nlm.nih.gov/clinvar/variation/${clinVarIds[0]}/` : undefined;
38
+ };
39
+
40
+ const description = () => {
41
+ const statusField = getCsqInfoIndex(props.infoMeta, "clinVar_CLNREVSTAT");
42
+ const status = statusField ? (getCsqInfo(props.info, statusField) as string[]) : [];
43
+ if (status.length === 0) return;
44
+
45
+ let description;
46
+ if (status.length === 1 && status.includes("practice_guideline")) {
47
+ description = "\u2605\u2605\u2605\u2605";
48
+ } else if (status.length === 1 && status.includes("reviewed_by_expert_panel")) {
49
+ description = "\u2605\u2605\u2605\u2606";
50
+ } else if (
51
+ status.length === 3 &&
52
+ status.includes("criteria_provided") &&
53
+ status.includes("_multiple_submitters") &&
54
+ status.includes("_no_conflicts")
55
+ ) {
56
+ description = "\u2605\u2605\u2606\u2606";
57
+ } else if (
58
+ status.length === 2 &&
59
+ status.includes("criteria_provided") &&
60
+ status.includes("_conflicting_interpretations")
61
+ ) {
62
+ description = "\u2605\u2606\u2606\u2606";
63
+ } else if (status.length === 2 && status.includes("criteria_provided") && status.includes("_single_submitter")) {
64
+ description = "\u2605\u2606\u2606\u2606";
65
+ } else {
66
+ description = "\u2606\u2606\u2606\u2606";
32
67
  }
33
- return [...new Set(vClasses)].sort().join("/");
34
- }
68
+ description += " (" + status.map((status) => status.replaceAll("_", " ").trim()).join(", ") + ")";
69
+ return description;
70
+ };
35
71
 
36
- return <span>{getClass(props.value)}</span>;
72
+ return (
73
+ <Show when={label()}>
74
+ {(label) => (
75
+ <Anchor href={href()}>
76
+ {description() ? <Abbr title={description()!} value={label} /> : <span>{label}</span>}
77
+ </Anchor>
78
+ )}
79
+ </Show>
80
+ );
37
81
  };
@@ -1,17 +1,16 @@
1
1
  import { Component } from "solid-js";
2
+ import { FieldProps } from "../field/Field";
2
3
  import { Abbr } from "../../Abbr";
3
- import { Link } from "solid-app-router";
4
4
 
5
- export const Consequence: Component<{
6
- terms: string[];
7
- href?: string;
8
- }> = (props) => {
5
+ export const Consequence: Component<FieldProps> = (props) => {
6
+ const consequence = (): string[] => props.info.value as string[];
7
+
9
8
  return (
10
9
  <>
11
- {props.href ? <Link href={props.href}>{props.terms[0]}</Link> : <span>{props.terms[0]}</span>}
12
- {props.terms.length > 1 && (
10
+ <span>{consequence()[0]}</span>
11
+ {consequence().length > 1 && (
13
12
  <span>
14
- , <Abbr title={props.terms.slice(1).join(", ")} value="\u2026" />
13
+ , <Abbr title={consequence().slice(1).join(", ")} value="\u2026" />
15
14
  </span>
16
15
  )}
17
16
  </>
@@ -1,11 +1,56 @@
1
- import { Component } from "solid-js";
1
+ import { Component, createMemo, Show } from "solid-js";
2
2
  import { Anchor } from "../../Anchor";
3
+ import { FieldProps } from "../field/Field";
4
+ import { ValueFlag, ValueString } from "@molgenis/vip-report-vcf/src/ValueParser";
5
+ import { getCsqInfo, getCsqInfoIndex } from "../../../utils/csqUtils";
6
+ import { Abbr } from "../../Abbr";
3
7
 
4
- export const Gene: Component<{
5
- symbol: string;
6
- }> = (props) => {
7
- const toHref = (symbol: string) =>
8
- `https://www.genenames.org/tools/search/#!/?query=${symbol}&filter=document_type:%22gene%22`;
8
+ export const Gene: Component<FieldProps> = (props) => {
9
+ const symbol = (): ValueString => props.info.value as ValueString;
9
10
 
10
- return <Anchor href={toHref(props.symbol)} value={props.symbol} />;
11
+ const symbolSource = createMemo((): ValueString | undefined => {
12
+ if (symbol() === null) return undefined;
13
+
14
+ const symbolSourceFieldIndex = getCsqInfoIndex(props.infoMeta, "SYMBOL_SOURCE");
15
+ return symbolSourceFieldIndex !== -1 ? (getCsqInfo(props.info, symbolSourceFieldIndex) as ValueString) : undefined;
16
+ });
17
+
18
+ const geneId = createMemo((): ValueString | undefined => {
19
+ if (symbol() === null) return undefined;
20
+
21
+ const geneFieldIndex = getCsqInfoIndex(props.infoMeta, "Gene");
22
+ return geneFieldIndex !== -1 ? (getCsqInfo(props.info, geneFieldIndex) as ValueString) : undefined;
23
+ });
24
+
25
+ const href = (): string | undefined => {
26
+ if (symbol() === null) return undefined;
27
+
28
+ const queryString =
29
+ symbolSource() === "EntrezGene" && geneId()
30
+ ? `query=ncbi_gene_id:${geneId()!}`
31
+ : `query=${encodeURIComponent(symbol()!)}&filter=document_type:%22gene%22`;
32
+ return `https://www.genenames.org/tools/search/#!/?${queryString}`;
33
+ };
34
+
35
+ const incompletePenetrance = (): ValueFlag | undefined => {
36
+ const ipFieldIndex = getCsqInfoIndex(props.infoMeta, "IncompletePenetrance");
37
+ return ipFieldIndex !== -1 ? (getCsqInfo(props.info, ipFieldIndex) as ValueFlag) : undefined;
38
+ };
39
+
40
+ return (
41
+ <Show when={symbol()}>
42
+ {(symbol) => (
43
+ <>
44
+ <Anchor href={href()}>
45
+ <span>{symbol}</span>
46
+ </Anchor>
47
+ {incompletePenetrance() && (
48
+ <sup class="ml-1">
49
+ <Abbr title="gene is known for incomplete penetrance" value="IP" />
50
+ </sup>
51
+ )}
52
+ </>
53
+ )}
54
+ </Show>
55
+ );
11
56
  };
@@ -1,29 +1,49 @@
1
- import { Component, createResource, Show } from "solid-js";
2
- import { Record } from "@molgenis/vip-report-vcf/src/Vcf";
1
+ import { Component, Show } from "solid-js";
3
2
  import { FieldValueFloat } from "../field/FieldValueFloat";
4
- import { EMPTY_HTS_FILE_METADATA, fetchHtsFileMetadata } from "../../../utils/ApiUtils";
5
- import { FieldValueInteger } from "../field/FieldValueInteger";
3
+ import { FieldProps } from "../field/Field";
4
+ import { ValueFloat } from "@molgenis/vip-report-vcf/src/ValueParser";
5
+ import { Anchor } from "../../Anchor";
6
6
 
7
- export const GnomAD: Component<{
8
- id: string;
9
- variant: Record;
10
- value: number;
11
- }> = (props) => {
12
- const [htsFileMetadata] = createResource({}, fetchHtsFileMetadata, { initialValue: EMPTY_HTS_FILE_METADATA });
7
+ export const GnomAD: Component<FieldProps> = (props) => {
8
+ const af = (): number | null => props.info.value as ValueFloat;
13
9
 
14
- function getHref(genomeAssembly: string) {
15
- return `https://gnomad.broadinstitute.org/variant/${encodeURIComponent(
16
- [props.variant.c, props.variant.p, props.variant.r, props.variant.a].join("-")
17
- )}?dataset=${genomeAssembly === "GRCh38" ? "gnomad_r3" : "gnomad_r2_1"}`;
18
- }
10
+ const href = (): string | undefined => {
11
+ let href;
12
+ if (af()) {
13
+ let dataset;
14
+ switch (props.context.genomeAssembly) {
15
+ case "GRCh37":
16
+ dataset = "gnomad_r2_1";
17
+ break;
18
+ case "GRCh38":
19
+ dataset = "gnomad_r3";
20
+ break;
21
+ default:
22
+ dataset = null;
23
+ break;
24
+ }
25
+
26
+ if (dataset) {
27
+ const record = props.info.record.data;
28
+ // FIXME record.a incorrect: select record.a through CSQ:ALLELE_NUM
29
+ const variantId = [record.c, record.p, record.r, record.a].join("-");
30
+ href = `https://gnomad.broadinstitute.org/variant/${encodeURIComponent(variantId)}?dataset=${dataset}`;
31
+ }
32
+ }
33
+ return href;
34
+ };
19
35
 
20
36
  return (
21
- <Show when={!htsFileMetadata.loading}>
22
- <a href={getHref(htsFileMetadata().genomeAssembly)} target="_blank" rel="noopener noreferrer nofollow">
23
- <Show when={props.id === "GNOMAD_AD"} fallback={<FieldValueFloat value={props.value} />}>
24
- <FieldValueInteger value={props.value} />
37
+ <Show when={af()}>
38
+ {(af) => (
39
+ <Show when={href()} fallback={<FieldValueFloat value={af} />}>
40
+ {(href) => (
41
+ <Anchor href={href}>
42
+ <FieldValueFloat value={af} />
43
+ </Anchor>
44
+ )}
25
45
  </Show>
26
- </a>
46
+ )}
27
47
  </Show>
28
48
  );
29
49
  };
@@ -1,18 +1,20 @@
1
- import { Component } from "solid-js";
1
+ import { Component, Show } from "solid-js";
2
2
  import { Abbr } from "../../Abbr";
3
+ import { FieldProps } from "../field/Field";
4
+ import { ValueString } from "@molgenis/vip-report-vcf/src/ValueParser";
3
5
 
4
6
  function abbreviate(notation: string): string {
5
7
  let abbreviated;
6
- const splitted = notation.split(":");
7
- if (splitted.length === 2) {
8
- abbreviated = splitted[1];
8
+ const tokens = notation.split(":");
9
+ if (tokens.length === 2) {
10
+ abbreviated = tokens[1];
9
11
  } else {
10
12
  abbreviated = notation;
11
13
  }
12
- return abbreviated;
14
+ return abbreviated.length > 20 ? abbreviated.slice(0, 18) + "\u2026" : abbreviated;
13
15
  }
14
- export const Hgvs: Component<{
15
- notation: string;
16
- }> = (props) => {
17
- return <Abbr title={props.notation} value={abbreviate(props.notation)} />;
16
+
17
+ export const Hgvs: Component<FieldProps> = (props) => {
18
+ const value = () => props.info.value as ValueString;
19
+ return <Show when={value()}>{(value) => <Abbr title={value} value={abbreviate(value)} />}</Show>;
18
20
  };
@@ -1,19 +1,23 @@
1
- import { Component } from "solid-js";
1
+ import { Component, Show } from "solid-js";
2
2
  import { Anchor } from "../../Anchor";
3
+ import { FieldProps } from "../field/Field";
3
4
 
4
- export const PubMed: Component<{
5
- ids: number[];
6
- }> = (props) => {
7
- const term = () => props.ids.map((pubMedId) => `${pubMedId}[UID]`).join("+OR+");
5
+ export const PubMed: Component<FieldProps> = (props) => {
6
+ const pubmedIds = () => props.info.value as number[];
7
+
8
+ const href = () => {
9
+ const ids = pubmedIds();
10
+ if (ids) {
11
+ const term = ids.map((id) => `${id}[UID]`).join("+OR+");
12
+ return `https://pubmed.ncbi.nlm.nih.gov/?term=${term}&sort=pubdate`;
13
+ }
14
+ };
8
15
 
9
16
  return (
10
- <>
11
- {term.length > 0 && (
12
- <Anchor
13
- href={`https://pubmed.ncbi.nlm.nih.gov/?term=${term()}&sort=pubdate`}
14
- value={`citations (${props.ids.length})`}
15
- />
16
- )}
17
- </>
17
+ <Show when={pubmedIds().length > 0}>
18
+ <Anchor href={href()}>
19
+ <span>{`citations (${pubmedIds().length})`}</span>
20
+ </Anchor>
21
+ </Show>
18
22
  );
19
23
  };