Added support for gestures to open close menus

This commit is contained in:
DrMint 2022-02-17 05:50:18 +01:00
parent 76deea2aa7
commit 7dd2325e97
9 changed files with 56 additions and 102 deletions

17
package-lock.json generated
View File

@ -12,7 +12,8 @@
"markdown-to-jsx": "^7.1.6",
"next": "^12.0.7",
"react": "17.0.2",
"react-dom": "17.0.2"
"react-dom": "17.0.2",
"react-swipeable": "^6.2.0"
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.0",
@ -3316,6 +3317,14 @@
"react": "17.0.2"
}
},
"node_modules/react-swipeable": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/react-swipeable/-/react-swipeable-6.2.0.tgz",
"integrity": "sha512-nWQ8dEM8e/uswZLSIkXUsAnQmnX4MTcryOHBQIQYRMJFDpgDBSiVbKsz/BZVCIScF4NtJh16oyxwaNOepR6xSw==",
"peerDependencies": {
"react": "^16.8.3 || ^17"
}
},
"node_modules/regenerator-runtime": {
"version": "0.13.4",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.4.tgz",
@ -6464,6 +6473,12 @@
"scheduler": "^0.20.2"
}
},
"react-swipeable": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/react-swipeable/-/react-swipeable-6.2.0.tgz",
"integrity": "sha512-nWQ8dEM8e/uswZLSIkXUsAnQmnX4MTcryOHBQIQYRMJFDpgDBSiVbKsz/BZVCIScF4NtJh16oyxwaNOepR6xSw==",
"requires": {}
},
"regenerator-runtime": {
"version": "0.13.4",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.4.tgz",

View File

@ -15,7 +15,8 @@
"markdown-to-jsx": "^7.1.6",
"next": "^12.0.7",
"react": "17.0.2",
"react-dom": "17.0.2"
"react-dom": "17.0.2",
"react-swipeable": "^6.2.0"
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.0",

View File

@ -2,6 +2,7 @@ import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
import MainPanel from "./Panels/MainPanel";
import { useState } from "react";
import Head from "next/head";
import { useSwipeable } from "react-swipeable";
type AppLayoutProps = {
subPanel?: React.ReactNode;
@ -17,6 +18,14 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
const [mainPanelOpen, setMainPanelOpen] = useState(false);
const [subPanelOpen, setsubPanelOpen] = useState(false);
const handlers = useSwipeable({
onSwipedLeft: () =>
mainPanelOpen ? setMainPanelOpen(false) : props.subPanel && props.contentPanel ? setsubPanelOpen(true) : "",
onSwipedRight: () =>
subPanelOpen ? setsubPanelOpen(false) : setMainPanelOpen(true),
preventDefaultTouchmoveEvent: true,
});
const mainPanelClass =
"fixed desktop:left-0 desktop:top-0 desktop:bottom-0 desktop:w-[20rem]";
const subPanelClass =
@ -34,7 +43,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
}
return (
<>
<div {...handlers}>
<Head>
<title>
{props.title ? `${titlePrefix} - ${props.title}` : titlePrefix}
@ -75,7 +84,9 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
<div className="grid place-content-center h-full">
<div className="text-dark border-dark border-2 border-dotted rounded-2xl p-8 grid grid-flow-col place-items-center gap-9">
<p className="text-4xl"></p>
<p className="text-2xl w-64">Select one of the options in the sidebar</p>
<p className="text-2xl w-64">
Select one of the options in the sidebar
</p>
</div>
</div>
</div>
@ -99,7 +110,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
{/* Sub panel */}
{props.subPanel ? (
<div
className={`${subPanelClass} border-r-[1px] mobile:border-r-0 mobile:border-l-[1px] border-black top-0 bottom-0 right-0 left-12 bg-light overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-500
className={`${subPanelClass} border-r-[1px] mobile:border-r-0 mobile:border-l-[1px] border-black top-0 bottom-0 right-0 left-12 bg-light overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300
${
turnSubIntoContent
? "mobile:mobile:translate-x-0 mobile:bottom-20 mobile:left-0 mobile:border-l-0"
@ -115,11 +126,11 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
{/* Main panel */}
<div
className={`${mainPanelClass} border-r-[1px] border-black top-0 bottom-0 left-0 right-12 bg-light overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-500 z-20
className={`${mainPanelClass} border-r-[1px] border-black top-0 bottom-0 left-0 right-12 bg-light overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 z-20
${mainPanelOpen ? "" : "mobile:-translate-x-full"}`}
>
<MainPanel langui={props.langui} />
</div>
</>
</div>
);
}

View File

@ -1,67 +0,0 @@
import Link from "next/link";
import { GetLibraryItemsPreviewQuery } from "graphql/operations-types";
import { getAssetURL, prettyDate, prettyPrice } from "queries/helpers";
import Image from "next/image";
export type LibraryContentPreviewProps = {
item: {
slug: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["slug"];
thumbnail: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["thumbnail"];
title: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["title"];
subtitle: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["subtitle"];
price?: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["price"];
release_date?: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["release_date"];
};
};
export default function LibraryContentPreview(
props: LibraryContentPreviewProps
): JSX.Element {
const item = props.item;
return (
<Link href={"/library/media/" + item.slug} passHref>
<div className="drop-shadow-dark-xl cursor-pointer grid items-end hover:rounded-3xl [--cover-opacity:0] hover:[--cover-opacity:1] hover:scale-[1.02] transition-transform">
{item.thumbnail.data ? (
<Image
src={getAssetURL(item.thumbnail.data.attributes.url)}
alt={item.thumbnail.data.attributes.alternativeText}
height={item.thumbnail.data.attributes.height}
width={item.thumbnail.data.attributes.width}
/>
) : (
<div className="w-full aspect-[21/29.7] bg-light rounded-lg"></div>
)}
<div className="linearbg-1 drop-shadow-dark-lg absolute bottom-2 inset-x-[-0.15rem] opacity-[var(--cover-opacity)] transition-opacity z-20 grid p-4 gap-4 text-left">
<div>
<h2 className="text-lg leading-7">{item.title}</h2>
<h3 className="leading-3">{item.subtitle}</h3>
</div>
<div className="grid grid-flow-col">
{item.release_date ? (
<p className="text-sm">
<span className="material-icons !text-base translate-y-[.15em] mr-1">
event
</span>
{prettyDate(item.release_date)}
</p>
) : (
""
)}
{item.price ? (
<p className="text-sm justify-self-end">
<span className="material-icons !text-base translate-y-[.15em] mr-1">
shopping_cart
</span>
{prettyPrice(item.price)}
</p>
) : (
""
)}
</div>
</div>
</div>
</Link>
);
}

View File

@ -8,6 +8,7 @@ type PanelHeaderProps = {
export default function PanelHeader(props: PanelHeaderProps): JSX.Element {
return (
<>
<div className="w-full grid place-items-center">
{props.icon ? (
<span className="material-icons !text-4xl mb-3">{props.icon}</span>
@ -16,7 +17,8 @@ export default function PanelHeader(props: PanelHeaderProps): JSX.Element {
)}
<h2 className="text-2xl">{props.title}</h2>
{props.description ? <p>{props.description}</p> : ""}
<HorizontalLine />
</div>
<HorizontalLine />
</>
);
}

View File

@ -6,6 +6,7 @@ import Button from "components/Button";
import HorizontalLine from "components/HorizontalLine";
import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
import Markdown from "markdown-to-jsx";
import Script from "next/script";
type MainPanelProps = {
langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"];
@ -15,18 +16,21 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
const langui = props.langui;
const router = useRouter();
return (
<div className="grid justify-center content-start p-8 gap-y-2 justify-items-center text-center">
<div
id="mainPanel"
className="flex flex-col justify-center content-start p-8 gap-y-2 justify-items-center text-center"
>
<div className="">
<div className="grid place-items-center">
<div className="grid place-items-center mobile:grid-flow-col">
<Link href="/" passHref>
<div className="w-1/2 cursor-pointer transition-[filter] hover:colorize-dark">
<div className="mobile:w-10 mobile:self-end w-1/2 cursor-pointer transition-[filter] hover:colorize-dark">
<SVG
src={"/icons/accords.svg"}
alt={"Logo of Accord's Library"}
/>
</div>
</Link>
<div className="relative mt-5">
<div className="relative mt-5 mobile:self-start">
{router.locale ? (
<Button className="absolute right-0 top-[-1.3em] text-xs !py-0.5 !px-2.5">
{router.locale.toUpperCase()}

View File

@ -4,7 +4,7 @@ type SubPanelProps = {
export default function SubPanel(props: SubPanelProps): JSX.Element {
return (
<div className="grid p-8 gap-y-2 justify-items-center text-center">
<div className="flex flex-col p-8 gap-y-2 justify-items-center text-center mobile:h-full">
{props.children}
</div>
);

View File

@ -4,7 +4,6 @@ import SVG from "components/SVG";
import { getWebsiteInterface } from "graphql/operations";
import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
import { GetStaticProps } from "next";
import Script from "next/script";
type HomeProps = {
langui: GetWebsiteInterfaceQuery;
};
@ -24,19 +23,6 @@ export default function Home(props: HomeProps): JSX.Element {
<h2 className="mt-0">Discover Analyse Translate Archive</h2>
</div>
<button id="goFS">Go fullscreen</button>
<Script
id="myScript"
strategy="afterInteractive"
dangerouslySetInnerHTML={{
__html: `
var goFS = document.getElementById("goFS");
goFS.addEventListener("click", function() {
document.body.requestFullscreen();
}, false);`,
}}
></Script>
<h2>What is this?</h2>
<p>
Accord&rsquo;s Library aims at gathering and archiving all of Yoko

View File

@ -50,6 +50,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
/>
<HorizontalLine />
<div className="grid gap-4">
<NavOption
title={langui.library_item_summary}
url="#summary"
@ -101,6 +102,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
) : (
""
)}
</div>
</SubPanel>
);