diff --git a/components/CellList.tsx b/components/CellList.tsx index b15c4b4..091866d 100644 --- a/components/CellList.tsx +++ b/components/CellList.tsx @@ -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 = ({ cells }) => { + const cellSearch = useRef | null>( + null + ) as React.MutableRefObject>; + + 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(""); + const [filterResults, setFilterResults] = useState>(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 && ( <> -

Exterior Cells ({cells.length})

+

Exterior Cells ({filteredCells.length})

+
+
+
+ + setFilter(event.target.value)} + /> +
+
+
) diff --git a/styles/CellList.module.css b/styles/CellList.module.css new file mode 100644 index 0000000..6ec5d5a --- /dev/null +++ b/styles/CellList.module.css @@ -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; +} diff --git a/styles/ModCellList.module.css b/styles/ModCellList.module.css deleted file mode 100644 index 45f50d0..0000000 --- a/styles/ModCellList.module.css +++ /dev/null @@ -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; -}