refine design and use popover for nav
This commit is contained in:
parent
f1c0dce935
commit
7cd7232521
BIN
data/gallery/DSC02610-2.jpg
(Stored with Git LFS)
Normal file
BIN
data/gallery/DSC02610-2.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -51,6 +51,7 @@
|
|||||||
"react-div-100vh": "^0.7.0",
|
"react-div-100vh": "^0.7.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-helmet": "^6.1.0",
|
"react-helmet": "^6.1.0",
|
||||||
|
"react-tiny-popover": "^7.2.0",
|
||||||
"sass": "^1.34.0",
|
"sass": "^1.34.0",
|
||||||
"tailwindcss": "^3.2.4",
|
"tailwindcss": "^3.2.4",
|
||||||
"use-breakpoint": "^2.0.1"
|
"use-breakpoint": "^2.0.1"
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import classnames from "classnames";
|
import classnames from "classnames";
|
||||||
import { Link } from "gatsby";
|
import { Link } from "gatsby";
|
||||||
import useDimensions from "react-cool-dimensions";
|
import { Popover } from "react-tiny-popover";
|
||||||
|
|
||||||
import Menu from "@spectrum-icons/workflow/Menu";
|
|
||||||
|
|
||||||
const navClasses =
|
const navClasses =
|
||||||
"hover:underline hover:bg-transparentblack block p-3 text-vibrant-light";
|
"hover:underline hover:bg-transparentblack block p-3 text-vibrant-light";
|
||||||
@ -12,7 +10,7 @@ const ExternalLinks = () => (
|
|||||||
<ul
|
<ul
|
||||||
className={classnames(
|
className={classnames(
|
||||||
"z-30 overflow-hidden bg-vibrant-dark",
|
"z-30 overflow-hidden bg-vibrant-dark",
|
||||||
"absolute top-[40px] border border-vibrant-light"
|
"rounded shadow border border-vibrant-light"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<li>
|
<li>
|
||||||
@ -78,27 +76,23 @@ interface NavProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Nav = ({ internalLinks, className }: NavProps) => {
|
const Nav = ({ internalLinks, className }: NavProps) => {
|
||||||
// const { observe, currentBreakpoint } = useDimensions({
|
|
||||||
// breakpoints: { XS: 0, LG: 750 },
|
|
||||||
// updateOnBreakpointChange: true,
|
|
||||||
// });
|
|
||||||
const [linksMenu, setLinksMenu] = useState(false);
|
const [linksMenu, setLinksMenu] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<nav
|
<nav
|
||||||
className={classnames(
|
className={classnames(
|
||||||
"mt-0 flex justify-between items-center w-full font-sans px-6",
|
"mt-0 flex flex-col md:flex-row items-center w-full font-sans px-6",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
// ref={observe}
|
|
||||||
style={{ zIndex: 100 }}
|
style={{ zIndex: 100 }}
|
||||||
>
|
>
|
||||||
<div className="flex items-baseline">
|
<div className="md:flex items-baseline flex-auto">
|
||||||
<h1 className="font-bold mr-2">Chuck Dries</h1>
|
<h1 className="font-bold mr-2">Chuck Dries</h1>
|
||||||
<h2>Software Engineer & Photographer</h2>
|
<h2 className="text-md">Software Engineer & Photographer</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
<ul className="inline-flex flex-wrap justify-center">
|
<ul className="flex">
|
||||||
{internalLinks &&
|
{internalLinks &&
|
||||||
internalLinks.map(({ href, label }) => (
|
internalLinks.map(({ href, label }) => (
|
||||||
<li key={href}>
|
<li key={href}>
|
||||||
@ -112,22 +106,24 @@ const Nav = ({ internalLinks, className }: NavProps) => {
|
|||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
<button
|
<Popover
|
||||||
className={classnames(
|
content={<ExternalLinks />}
|
||||||
"hover:underline inline-flex align-middle items-center",
|
isOpen={linksMenu}
|
||||||
navClasses
|
onClickOutside={() => setLinksMenu(false)}
|
||||||
)}
|
positions={["bottom"]} // preferred positions by priority
|
||||||
onClick={() => setLinksMenu(!linksMenu)}
|
|
||||||
>
|
>
|
||||||
{/* <Menu
|
<button
|
||||||
UNSAFE_className="mr-1"
|
className={classnames(
|
||||||
aria-label="show external links"
|
"hover:underline inline-flex align-middle items-center",
|
||||||
size="S"
|
navClasses
|
||||||
/> */}
|
)}
|
||||||
Links
|
onClick={() => setLinksMenu(!linksMenu)}
|
||||||
</button>
|
>
|
||||||
{linksMenu && <ExternalLinks />}
|
Links
|
||||||
|
</button>
|
||||||
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
|
{/* {linksMenu && } */}
|
||||||
</nav>
|
</nav>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -9,7 +9,7 @@ import { getHelmetSafeBodyStyle, getVibrant, getAspectRatio } from "../utils";
|
|||||||
import Nav from "../components/Nav";
|
import Nav from "../components/Nav";
|
||||||
import ActionButtons from "../components/index/ActionButtons";
|
import ActionButtons from "../components/index/ActionButtons";
|
||||||
// import { use100vh } from "react-div-100vh";
|
// import { use100vh } from "react-div-100vh";
|
||||||
// import { useMediaQuery } from "../useMediaQuery";
|
import { useMediaQuery } from "../useMediaQuery";
|
||||||
|
|
||||||
const env =
|
const env =
|
||||||
process.env.GATSBY_ACTIVE_ENV || process.env.NODE_ENV || "development";
|
process.env.GATSBY_ACTIVE_ENV || process.env.NODE_ENV || "development";
|
||||||
@ -40,70 +40,21 @@ const IndexPage = ({
|
|||||||
return images[imageIndex];
|
return images[imageIndex];
|
||||||
}, [images, imageIndex]);
|
}, [images, imageIndex]);
|
||||||
|
|
||||||
const shuffleImage = React.useCallback(
|
|
||||||
(currentImage?: typeof images[number]) => {
|
|
||||||
const lastThreeImages =
|
|
||||||
JSON.parse(localStorage.getItem("lastHeros") ?? "[]") || [];
|
|
||||||
if (env === "production") {
|
|
||||||
try {
|
|
||||||
window.plausible("Shuffle", {
|
|
||||||
props: { currentImage: currentImage?.base },
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
/* do nothing */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const index = getDifferentRand(images.length, lastThreeImages);
|
|
||||||
localStorage.setItem(
|
|
||||||
"lastHeros",
|
|
||||||
JSON.stringify(take(3, [index, ...lastThreeImages]))
|
|
||||||
);
|
|
||||||
setImageIndex(index);
|
|
||||||
},
|
|
||||||
[images.length]
|
|
||||||
);
|
|
||||||
|
|
||||||
// pick random image on page hydration
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!isClient) {
|
if (!isClient) {
|
||||||
setIsClient(true);
|
setIsClient(true);
|
||||||
shuffleImage(image);
|
|
||||||
}
|
}
|
||||||
}, [isClient, imageIndex, image, shuffleImage]);
|
}, [isClient]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
const browserIsLandscape = useMediaQuery("(orientation: landscape)");
|
||||||
const keyListener = (e: KeyboardEvent) => {
|
|
||||||
switch (e.code) {
|
|
||||||
case "Space": {
|
|
||||||
shuffleImage(image);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
case "ArrowRight": {
|
|
||||||
if (imageIndex === images.length - 1) {
|
|
||||||
setImageIndex(0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setImageIndex(imageIndex + 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "ArrowLeft": {
|
React.useLayoutEffect(() => {
|
||||||
if (imageIndex === 0) {
|
if (browserIsLandscape) {
|
||||||
setImageIndex(images.length - 1);
|
setImageIndex(1);
|
||||||
return;
|
} else {
|
||||||
}
|
setImageIndex(0);
|
||||||
setImageIndex(imageIndex - 1);
|
}
|
||||||
return;
|
}, [browserIsLandscape]);
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
document.addEventListener("keydown", keyListener);
|
|
||||||
return () => {
|
|
||||||
document.removeEventListener("keydown", keyListener);
|
|
||||||
};
|
|
||||||
}, [imageIndex, images.length, image, shuffleImage]);
|
|
||||||
|
|
||||||
// const browserIsLandscape = useMediaQuery("(orientation: landscape)");
|
|
||||||
|
|
||||||
// const vibrant = getVibrant(image);
|
// const vibrant = getVibrant(image);
|
||||||
const ar = getAspectRatio(image);
|
const ar = getAspectRatio(image);
|
||||||
@ -169,12 +120,9 @@ export const query = graphql`
|
|||||||
allFile(
|
allFile(
|
||||||
filter: {
|
filter: {
|
||||||
sourceInstanceName: { eq: "gallery" }
|
sourceInstanceName: { eq: "gallery" }
|
||||||
base: { in: [
|
base: { in: ["DSC02610-2.jpg", "DSC02615-2.jpg"] }
|
||||||
"DSC02615-2.jpg"
|
|
||||||
"DSC02615.jpg"
|
|
||||||
] }
|
|
||||||
}
|
}
|
||||||
sort: { fields: { imageMeta: { dateTaken: DESC } } }
|
sort: { base: ASC }
|
||||||
) {
|
) {
|
||||||
nodes {
|
nodes {
|
||||||
relativePath
|
relativePath
|
||||||
@ -184,8 +132,8 @@ export const query = graphql`
|
|||||||
aspectRatio
|
aspectRatio
|
||||||
}
|
}
|
||||||
gatsbyImageData(
|
gatsbyImageData(
|
||||||
# layout: FULL_WIDTH
|
layout: CONSTRAINED
|
||||||
placeholder: NONE
|
# placeholder: NONE
|
||||||
breakpoints: [750, 1080, 1366, 1920, 2560, 3840]
|
breakpoints: [750, 1080, 1366, 1920, 2560, 3840]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -10782,6 +10782,11 @@ react-side-effect@^2.1.0:
|
|||||||
resolved "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.1.tgz"
|
resolved "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.1.tgz"
|
||||||
integrity sha512-2FoTQzRNTncBVtnzxFOk2mCpcfxQpenBMbk5kSVBg5UcPqV9fRbgY2zhb7GTWWOlpFmAxhClBDlIq8Rsubz1yQ==
|
integrity sha512-2FoTQzRNTncBVtnzxFOk2mCpcfxQpenBMbk5kSVBg5UcPqV9fRbgY2zhb7GTWWOlpFmAxhClBDlIq8Rsubz1yQ==
|
||||||
|
|
||||||
|
react-tiny-popover@^7.2.0:
|
||||||
|
version "7.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-tiny-popover/-/react-tiny-popover-7.2.0.tgz#e6277620efea6acea9c47efbfe5dcb473a552e99"
|
||||||
|
integrity sha512-AIliRDqTFB1+qy4GvWn+8B8JPKA13xtESWYdFkrdCeI8hEnPKufBvcF9a3dO/0SmD21mV6721xxhAnUm8TRXJw==
|
||||||
|
|
||||||
react-transition-group@^2.2.0:
|
react-transition-group@^2.2.0:
|
||||||
version "2.9.0"
|
version "2.9.0"
|
||||||
resolved "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz"
|
resolved "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user