merge with softNavigate pagination changes from #601

This commit is contained in:
James Fenn
2023-07-11 11:29:07 -04:00
parent 0f99740cba
commit 6b9df317a1
4 changed files with 67 additions and 11 deletions

View File

@@ -0,0 +1,26 @@
export const onSoftNavClick =
(softNavigate: (href: string) => void) => (e: MouseEvent) => {
let link = e.target as HTMLElement;
// Could click on a child element of an anchor
while (link && !(link instanceof HTMLAnchorElement)) {
link = link.parentElement;
}
if (!link) return;
if (
link instanceof HTMLAnchorElement &&
link.href &&
(!link.target || link.target === "_self") &&
link.origin === location.origin &&
e.button === 0 && // left click only
!e.metaKey && // open in new tab (mac)
!e.ctrlKey && // open in new tab (windows)
!e.altKey && // download
!e.shiftKey && // open in new window
!e.defaultPrevented
) {
e.preventDefault();
softNavigate(link.href);
}
};

View File

@@ -11,7 +11,7 @@ import {
} from "@floating-ui/react";
import { useRef, useState } from "preact/hooks";
import { Fragment } from "preact";
import { createPortal } from "preact/compat";
import { createPortal, StateUpdater } from "preact/compat";
import mainStyles from "./pagination.module.scss";
import more from "src/icons/more_horiz.svg?raw";
import { PaginationProps } from "components/pagination/types";
@@ -21,14 +21,23 @@ import subtract from "../../icons/subtract.svg?raw";
import add from "../../icons/add.svg?raw";
import { Input } from "components/input/input";
function PopupContents(props: Pick<PaginationProps, "page" | "getPageHref">) {
function PopupContents(
props: Pick<PaginationProps, "page" | "getPageHref" | "softNavigate"> & {
setIsOpen: StateUpdater<boolean>;
}
) {
const [count, setCount] = useState(props.page.currentPage);
return (
<form
class={style.popupInner}
onSubmit={(e) => {
e.preventDefault();
location.href = `/page/${count}`;
if (props.softNavigate) {
props.softNavigate(props.getPageHref(count));
props.setIsOpen(false);
return;
}
location.href = props.getPageHref(count);
}}
>
<div class={style.popupTopArea}>
@@ -80,7 +89,7 @@ function PopupContents(props: Pick<PaginationProps, "page" | "getPageHref">) {
}
export function PaginationMenuAndPopover(
props: Pick<PaginationProps, "page" | "getPageHref">
props: Pick<PaginationProps, "page" | "getPageHref" | "softNavigate">
) {
const [isOpen, setIsOpen] = useState(false);
const arrowRef = useRef(null);
@@ -90,7 +99,7 @@ export function PaginationMenuAndPopover(
placement: "top",
onOpenChange: setIsOpen,
middleware: [
offset(32 - (14 / 2)),
offset(32 - 14 / 2),
arrow({
element: arrowRef,
}),
@@ -120,7 +129,7 @@ export function PaginationMenuAndPopover(
{...getFloatingProps()}
class={style.popup}
>
<PopupContents {...props} />
<PopupContents {...props} setIsOpen={setIsOpen} />
<FloatingArrow
ref={arrowRef}
context={context}

View File

@@ -5,12 +5,14 @@ import { PaginationMenuAndPopover } from "components/pagination/pagination-popov
import { useEffect, useState } from "preact/hooks";
import { PaginationButtonProps, PaginationProps } from "components/pagination/types";
import { usePagination } from "./use-pagination";
import { onSoftNavClick } from "./on-click-base";
function PaginationButton({
pageInfo,
pageNum,
href,
selected
selected,
softNavigate,
}: PaginationButtonProps) {
const pageOptionalMin = Math.min(Math.max(1, pageInfo.currentPage - 1), pageInfo.lastPage - 3);
const isOptional = pageNum < pageOptionalMin || pageNum > pageOptionalMin + 3;
@@ -22,6 +24,7 @@ function PaginationButton({
selected ? styles.selected : ""
}`}
href={href}
onClick={softNavigate ? onSoftNavClick(softNavigate) : undefined}
aria-label={`Go to page ${pageNum}`}
aria-current={selected || undefined}
>
@@ -35,7 +38,7 @@ function PaginationButton({
* This prevents the pagination menu from rendering on SSR, which throws errors
*/
function PaginationMenuWrapper(
props: Pick<PaginationProps, "page" | "getPageHref">
props: Pick<PaginationProps, "page" | "getPageHref" | "softNavigate">
) {
const [shouldRender, setShouldRender] = useState(false);
@@ -54,6 +57,7 @@ export const Pagination = ({
class: className = "",
id = "post-list-pagination",
getPageHref = (pageNum: number) => `${rootURL}${pageNum}`,
softNavigate,
}: PaginationProps) => {
// if there's only one page, don't render anything
if (page.currentPage === 1 && page.lastPage < 2) return <></>;
@@ -68,7 +72,12 @@ export const Pagination = ({
<a
className={`text-style-body-medium-bold ${styles.paginationButton} ${styles.paginationIconButton}`}
aria-label="Previous"
href={!isPreviousEnabled ? "javascript:void(0)" : getPageHref(page.currentPage - 1)}
href={
!isPreviousEnabled
? "javascript:void(0)"
: getPageHref(page.currentPage - 1)
}
onClick={softNavigate ? onSoftNavClick(softNavigate) : undefined}
aria-disabled={!isPreviousEnabled}
dangerouslySetInnerHTML={{ __html: back }}
/>
@@ -81,16 +90,26 @@ export const Pagination = ({
pageNum={pageNum}
selected={pageNum === page.currentPage}
href={getPageHref(pageNum)}
softNavigate={softNavigate}
/>
) : (
<PaginationMenuWrapper page={page} getPageHref={getPageHref} />
<PaginationMenuWrapper
page={page}
getPageHref={getPageHref}
softNavigate={softNavigate}
/>
);
})}
<li className={`${styles.paginationItem}`}>
<a
className={`text-style-body-medium-bold ${styles.paginationButton} ${styles.paginationIconButton}`}
href={!isNextEnabled ? "javascript:void(0)" : getPageHref(page.currentPage + 1)}
href={
!isNextEnabled
? "javascript:void(0)"
: getPageHref(page.currentPage + 1)
}
onClick={softNavigate ? onSoftNavClick(softNavigate) : undefined}
aria-label="Next"
aria-disabled={!isNextEnabled}
dangerouslySetInnerHTML={{ __html: forward }}

View File

@@ -8,6 +8,7 @@ export interface PaginationButtonProps {
pageNum: number;
selected: boolean;
href: string;
softNavigate?: (href: string) => void;
}
export interface PaginationProps {
@@ -16,4 +17,5 @@ export interface PaginationProps {
id?: string;
rootURL?: string;
getPageHref?: (pageNum: number) => string;
softNavigate?: (href: string) => void;
}