Add filter to CellList
This commit is contained in:
parent
1d40fb16df
commit
f120090039
@ -1,7 +1,8 @@
|
||||
import React from "react";
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import Link from "next/link";
|
||||
import MiniSearch from "minisearch";
|
||||
|
||||
import styles from "../styles/ModCellList.module.css";
|
||||
import styles from "../styles/CellList.module.css";
|
||||
import type { CellCoord } from "./ModData";
|
||||
|
||||
const NEXUS_MODS_URL = "https://www.nexusmods.com/skyrimspecialedition";
|
||||
@ -11,33 +12,78 @@ type Props = {
|
||||
};
|
||||
|
||||
const CellList: React.FC<Props> = ({ cells }) => {
|
||||
const cellSearch = useRef<MiniSearch<CellCoord> | null>(
|
||||
null
|
||||
) as React.MutableRefObject<MiniSearch<CellCoord>>;
|
||||
|
||||
useEffect(() => {
|
||||
cellSearch.current = new MiniSearch({
|
||||
fields: ["id"],
|
||||
storeFields: ["id", "x", "y"],
|
||||
tokenize: (s) => [s.replace(/cell\s?|\s/gi, "")],
|
||||
searchOptions: {
|
||||
fields: ["id"],
|
||||
prefix: true,
|
||||
fuzzy: false,
|
||||
},
|
||||
});
|
||||
cellSearch.current.addAll(
|
||||
cells.map((cell) => ({ ...cell, id: `${cell.x},${cell.y}` }))
|
||||
);
|
||||
}, [cells]);
|
||||
|
||||
const [filter, setFilter] = useState<string>("");
|
||||
const [filterResults, setFilterResults] = useState<Set<string>>(new Set());
|
||||
|
||||
const filteredCells = cells
|
||||
.filter((cell) => !filter || filterResults.has(`${cell.x},${cell.y}`))
|
||||
.sort((a, b) => (a.x - b.x) * 1000 + a.y - b.y);
|
||||
|
||||
useEffect(() => {
|
||||
if (cellSearch.current) {
|
||||
setFilterResults(
|
||||
new Set(cellSearch.current.search(filter).map((result) => result.id))
|
||||
);
|
||||
}
|
||||
}, [filter]);
|
||||
|
||||
return (
|
||||
cells && (
|
||||
filteredCells && (
|
||||
<>
|
||||
<h2>Exterior Cells ({cells.length})</h2>
|
||||
<h2>Exterior Cells ({filteredCells.length})</h2>
|
||||
<div className={styles.filters}>
|
||||
<hr />
|
||||
<div className={styles["filter-row"]}>
|
||||
<label htmlFor="filter">Filter:</label>
|
||||
<input
|
||||
type="search"
|
||||
id="filter"
|
||||
className={styles.filter}
|
||||
value={filter}
|
||||
onChange={(event) => setFilter(event.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<hr />
|
||||
</div>
|
||||
<ul className={styles["cell-list"]}>
|
||||
{cells
|
||||
// .sort((a, b) => b.unique_downloads - a.unique_downloads)
|
||||
.map((cell) => (
|
||||
<li
|
||||
key={`cell-${cell.x},${cell.y}`}
|
||||
className={styles["cell-list-item"]}
|
||||
>
|
||||
<div className={styles["cell-title"]}>
|
||||
<strong>
|
||||
<Link
|
||||
href={`/?cell=${encodeURIComponent(
|
||||
`${cell.x},${cell.y}`
|
||||
)}`}
|
||||
>
|
||||
<a>
|
||||
{cell.x}, {cell.y}
|
||||
</a>
|
||||
</Link>
|
||||
</strong>
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
{filteredCells.map((cell) => (
|
||||
<li
|
||||
key={`cell-${cell.x},${cell.y}`}
|
||||
className={styles["cell-list-item"]}
|
||||
>
|
||||
<div className={styles["cell-title"]}>
|
||||
<strong>
|
||||
<Link
|
||||
href={`/?cell=${encodeURIComponent(`${cell.x},${cell.y}`)}`}
|
||||
>
|
||||
<a>
|
||||
{cell.x}, {cell.y}
|
||||
</a>
|
||||
</Link>
|
||||
</strong>
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</>
|
||||
)
|
||||
|
50
styles/CellList.module.css
Normal file
50
styles/CellList.module.css
Normal file
@ -0,0 +1,50 @@
|
||||
.cell-list {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.cell-list-item {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.cell-title {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.filters {
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.filters hr {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.filters hr:first-child {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.filters hr:last-child {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.filter-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
margin-top: 4px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.filter-row label,
|
||||
.filter-row input,
|
||||
.filter-row select {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.filter {
|
||||
width: 175px;
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
.cell-list {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.cell-list-item {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.cell-title {
|
||||
margin-bottom: 8px;
|
||||
}
|
Loading…
Reference in New Issue
Block a user