Skip to content

Commit

Permalink
switch from buttons to radios
Browse files Browse the repository at this point in the history
  • Loading branch information
pookmish committed Apr 23, 2024
1 parent fe40ea6 commit 94982bc
Showing 1 changed file with 34 additions and 39 deletions.
73 changes: 34 additions & 39 deletions src/components/paragraphs/sup-pre-built/filtering-author-list.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
"use client";

import {twMerge} from "tailwind-merge";
import {HTMLAttributes, JSX, useEffect, useLayoutEffect, useMemo, useRef, useState} from "react";
import {HTMLAttributes, JSX, useEffect, useMemo, useState} from "react";
import PagedList from "@components/elements/paged-list";
import {useRouter, useSearchParams} from "next/navigation";
import useFocusOnRender from "@lib/hooks/useFocusOnRender";
import {useBoolean} from "usehooks-ts";

type Props = HTMLAttributes<HTMLDivElement> & {
authors: Map<string, JSX.Element[]>
}
const FilteringAuthorList = ({authors, ...props}: Props) => {
const searchParams = useSearchParams();
const router = useRouter();
const focusItemRef = useRef<HTMLDivElement>(null);
const {value: focusOnElement, setTrue: enableFocusElement, setFalse: disableFocusElement} = useBoolean(false)
const [alphaChosen, setAlphaChosen] = useState<string>(searchParams.get("author") || "A")
const [alphaChosen, setAlphaChosen] = useState<string>(searchParams.get("author") || "")

const displayedAuthors = useMemo(() => {
if(alphaChosen === "") return authors;
const displayedAuthorMap = new Map<string, JSX.Element[]>();
[...authors.keys()].map(authorName => {
let firstLetter = authorName.charAt(0).toUpperCase()
Expand All @@ -40,58 +37,56 @@ const FilteringAuthorList = ({authors, ...props}: Props) => {
// Use search params to retain any other parameters.
const params = new URLSearchParams(searchParams.toString());

if (alphaChosen !== "A") {
if (alphaChosen !== "") {
params.set("author", alphaChosen)
} else {
params.delete("author")
}
router.replace(`?${params.toString()}`, {scroll: false})
}, [router, searchParams, alphaChosen]);

const setFocusOnItem = useFocusOnRender(focusItemRef, false);

useLayoutEffect(() => {
if (focusOnElement) setFocusOnItem()
}, [focusOnElement, setFocusOnItem]);

return (
<div {...props} className={twMerge("flex justify-between", props?.className)}>
<div className="sr-only" aria-live="polite">Showing authors that start with {alphaChosen}</div>
<a href="#author-filter" className="skiplink">Skip to filter</a>

<PagedList itemsPerPage={50} ulProps={{className: "list-unstyled"}} pageKey={false} key={alphaChosen}>
{[...displayedAuthors.keys()].sort().map((authorName, i) =>
<div
key={authorName}
className="flex flex-wrap gap-2"
ref={i === 0 ? focusItemRef : null}
tabIndex={i === 0 && focusOnElement ? 0 : undefined}
onBlur={disableFocusElement}
>
<span>{authorName}</span>
{[...displayedAuthors.keys()].sort().map(authorName =>
<div key={authorName}>
<span className="pr-4">{authorName}</span>
{authors.get(authorName)}
</div>
)}
</PagedList>
<nav id="author-filter" aria-label="Author name filtering">
<ul className="list-unstyled">

<form role="search" id="author-filter" aria-label="Author name filtering">
<fieldset className="list-unstyled">
<legend className="sr-only">Filter by first letter</legend>
<label className="flex">
<input
type="radio"
defaultChecked={alphaChosen === ""}
name="alpha"
value={""}
onChange={() => setAlphaChosen("")}
/>
All
</label>

{alphaChoices.map(choice =>
<li key={choice}>
<button
className="hocus:underline"
onClick={() => {
setAlphaChosen(choice)
enableFocusElement();
}}
aria-label={`Show authors that start with ${choice}`}
aria-current={alphaChosen === choice}
>
{choice}
</button>
</li>
<label key={choice} className="flex">
<input
type="radio"
defaultChecked={alphaChosen === choice}
name="alpha"
value={choice}
onChange={() => setAlphaChosen(choice)}
/>
{choice}
</label>
)}
</ul>
</nav>
</fieldset>
</form>
</div>
)
}
Expand Down

0 comments on commit 94982bc

Please sign in to comment.