Add filter to CellList

This commit is contained in:
Tyler Hallada 2022-03-17 20:24:25 -04:00
parent 1d40fb16df
commit f120090039
3 changed files with 122 additions and 39 deletions

View File

@ -1,7 +1,8 @@
import React from "react"; import React, { useEffect, useRef, useState } from "react";
import Link from "next/link"; 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"; import type { CellCoord } from "./ModData";
const NEXUS_MODS_URL = "https://www.nexusmods.com/skyrimspecialedition"; const NEXUS_MODS_URL = "https://www.nexusmods.com/skyrimspecialedition";
@ -11,33 +12,78 @@ type Props = {
}; };
const CellList: React.FC<Props> = ({ cells }) => { 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 ( 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"]}> <ul className={styles["cell-list"]}>
{cells {filteredCells.map((cell) => (
// .sort((a, b) => b.unique_downloads - a.unique_downloads) <li
.map((cell) => ( key={`cell-${cell.x},${cell.y}`}
<li className={styles["cell-list-item"]}
key={`cell-${cell.x},${cell.y}`} >
className={styles["cell-list-item"]} <div className={styles["cell-title"]}>
> <strong>
<div className={styles["cell-title"]}> <Link
<strong> href={`/?cell=${encodeURIComponent(`${cell.x},${cell.y}`)}`}
<Link >
href={`/?cell=${encodeURIComponent( <a>
`${cell.x},${cell.y}` {cell.x}, {cell.y}
)}`} </a>
> </Link>
<a> </strong>
{cell.x}, {cell.y} </div>
</a> </li>
</Link> ))}
</strong>
</div>
</li>
))}
</ul> </ul>
</> </>
) )

View 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;
}

View File

@ -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;
}