feat: add fuse.js to overview page

This commit is contained in:
Mathias Schopmans
2024-02-19 17:40:48 +01:00
committed by Mathias Schopmans
parent 5f0c2500a4
commit c29e518f90
6 changed files with 56 additions and 18 deletions

9
package-lock.json generated
View File

@@ -11,6 +11,7 @@
"dependencies": { "dependencies": {
"@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-dialog": "^1.0.5",
"clsx": "^2.1.0", "clsx": "^2.1.0",
"fuse.js": "^7.0.0",
"gray-matter": "^4.0.3", "gray-matter": "^4.0.3",
"highlight.js": "^11.9.0", "highlight.js": "^11.9.0",
"marked": "^12.0.0", "marked": "^12.0.0",
@@ -4292,6 +4293,14 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/fuse.js": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.0.0.tgz",
"integrity": "sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==",
"engines": {
"node": ">=10"
}
},
"node_modules/get-east-asian-width": { "node_modules/get-east-asian-width": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz",

View File

@@ -16,6 +16,7 @@
"dependencies": { "dependencies": {
"@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-dialog": "^1.0.5",
"clsx": "^2.1.0", "clsx": "^2.1.0",
"fuse.js": "^7.0.0",
"gray-matter": "^4.0.3", "gray-matter": "^4.0.3",
"highlight.js": "^11.9.0", "highlight.js": "^11.9.0",
"marked": "^12.0.0", "marked": "^12.0.0",

View File

@@ -18,6 +18,7 @@
.ring { .ring {
flex: 0 0 auto; flex: 0 0 auto;
margin-left: 16px;
align-self: baseline; align-self: baseline;
} }
@@ -58,11 +59,10 @@
.link { .link {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
padding: 16px;
} }
.quadrant { .quadrant {
margin: 0 16px 0 auto; margin-left: auto;
} }
@media (min-width: 768px) { @media (min-width: 768px) {

View File

@@ -11,6 +11,7 @@ export interface ItemListProps {
items: Item[]; items: Item[];
activeId?: string; activeId?: string;
size?: "small" | "default" | "large"; size?: "small" | "default" | "large";
hideRing?: boolean;
className?: string; className?: string;
} }
@@ -18,6 +19,7 @@ export function ItemList({
items, items,
activeId, activeId,
size = "default", size = "default",
hideRing = false,
className, className,
}: ItemListProps) { }: ItemListProps) {
return ( return (
@@ -48,11 +50,13 @@ export function ItemList({
<span className={styles.quadrant}> <span className={styles.quadrant}>
{getQuadrant(item.quadrant)?.title} {getQuadrant(item.quadrant)?.title}
</span> </span>
{!hideRing && (
<RingBadge <RingBadge
className={styles.ring} className={styles.ring}
ring={item.ring} ring={item.ring}
size="small" size="small"
/> />
)}
</div> </div>
)} )}
</Link> </Link>

View File

@@ -1,3 +1,4 @@
import Fuse from "fuse.js";
import Head from "next/head"; import Head from "next/head";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { useCallback, useMemo } from "react"; import { useCallback, useMemo } from "react";
@@ -11,7 +12,7 @@ import { CustomPage } from "@/pages/_app";
const Overview: CustomPage = () => { const Overview: CustomPage = () => {
const router = useRouter(); const router = useRouter();
const ring = router.query.ring as string | undefined; const ring = router.query.ring as string | undefined;
const query = router.query.query as string | undefined; const query = (router.query.query as string) || "";
const onRingChange = useCallback( const onRingChange = useCallback(
(ring: string) => { (ring: string) => {
@@ -27,15 +28,38 @@ const Overview: CustomPage = () => {
[router, ring], [router, ring],
); );
const items = useMemo(() => { const { items, index } = useMemo(() => {
if (!ring && !query) return getItems(); const items = getItems().filter((item) => !ring || item.ring === ring);
return getItems().filter((item) => { const index = new Fuse(items, {
if (ring && item.ring !== ring) return false; threshold: 0.3,
return !( includeScore: true,
query && !item.title.toLowerCase().includes(query.toLowerCase()) keys: [
); {
name: "title",
weight: 1.5,
},
{
name: "tags",
weight: 1,
},
{
name: "body",
weight: 0.9,
},
{
name: "revision.body",
weight: 0.7,
},
],
}); });
}, [query, ring]);
return { items, index };
}, [ring]);
const results = useMemo(() => {
if (!query) return items;
return index.search(query).map((result) => result.item);
}, [query, index, items]);
return ( return (
<> <>
@@ -51,7 +75,7 @@ const Overview: CustomPage = () => {
onQueryChange={onQueryChange} onQueryChange={onQueryChange}
/> />
<ItemList items={items} size="large" /> <ItemList items={results} size="large" hideRing={!!ring} />
</> </>
); );
}; };

View File

@@ -95,7 +95,7 @@ input {
color: var(--background); color: var(--background);
border: 1px solid transparent; border: 1px solid transparent;
padding: 10px 12px; padding: 10px 12px;
border-radius: 6px; border-radius: 3px;
width: 100%; width: 100%;
font-size: 16px; font-size: 16px;