Added support for gestures to open close menus
This commit is contained in:
		
							parent
							
								
									76deea2aa7
								
							
						
					
					
						commit
						7dd2325e97
					
				
							
								
								
									
										17
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										17
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -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", | ||||
|  | ||||
| @ -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", | ||||
|  | ||||
| @ -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> | ||||
|   ); | ||||
| } | ||||
|  | ||||
| @ -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> | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| @ -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 /> | ||||
|     </> | ||||
|   ); | ||||
| } | ||||
|  | ||||
| @ -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()} | ||||
|  | ||||
| @ -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> | ||||
|   ); | ||||
|  | ||||
| @ -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’s Library aims at gathering and archiving all of Yoko | ||||
|  | ||||
| @ -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> | ||||
|   ); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 DrMint
						DrMint