-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathApp.tsx
More file actions
71 lines (64 loc) · 2.31 KB
/
Copy pathApp.tsx
File metadata and controls
71 lines (64 loc) · 2.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import "./App.css";
import { FC } from "react";
import allTrees from "./data.json";
// Types
type Tree = typeof allTrees[number];
type TaxonomicRank = keyof Tree;
type TaxonomyProps = { children: Array<Tree>; rank: TaxonomicRank }
// This is only a subset of - domain, kingdom, phylum, class, order, family, genus, species
const taxonomicRanks: Array<TaxonomicRank> = [
"Kingdom",
"Order",
"Family",
"Genus",
"Species"
];
// Our recursive taxonomy which calls itself where child taxonomies exist
const Taxonomy: FC<TaxonomyProps> = (props) => {
const { children, rank } = props;
// Find the unique taxa in our child taxonomies
// EG unique taxa with a key of "Genus"
const taxaInRank = children.reduce<Array<Tree>>((a, c) => {
if (a.find((v) => v[rank] === c[rank])) {
return a;
}
return [...a, c];
}, []);
return (
<div>
{/* Loop through the taxa in the rank */}
{taxaInRank.map((taxon) => {
// Crucially we are only passing the taxa of this rank to the next Taxonomy
// Without this filter, the component will call itself indefinitely
const childrenOfTaxon = children.filter(
(t) => t[rank] === taxon[rank]
);
// By using the .at method typescript includes undefined in the type
// should our index not be in the array
// https://www.typescriptlang.org/play?target=9&ts=4.6.2#code/MYewdgzgLgBFDuIAyBTKUUCcIwLwwG0ByAQSIBoYiAhIgXQG4BYAKFYHp2ZRJYoALAJaYAJqnRYAXDGiZBYAOase0OENHiMmPHESasEAgCZGrDlxV91YtFpJRps+QpgAfGAFcwIlADN5KCLK4KoCwjYSmPY6CMi2BgB0AIZQABRGAJRAA
const subRank = taxonomicRanks.at(taxonomicRanks.indexOf(rank) + 1);
return (
// For those unfamilar with the element
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details
<details open>
<summary>
{taxon[rank]}
</summary>
{/* Should a subRank exist then render our taxonomy */}
{/* The element calls itself */}
{subRank && <Taxonomy rank={subRank}>{childrenOfTaxon}</Taxonomy>}
</details>
);
})}
</div>
);
};
function App() {
return (
<div className="App">
{/* Our initial call to our Taxonomy */}
<Taxonomy rank={taxonomicRanks[0]}>{allTrees}</Taxonomy>
</div>
);
}
export default App;