forked from pbclife/gitopener.vercel.app
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Complete Layout Design (pbclife#13)
* style: designed scroll-bar * build: added styling dependency * build: updated module import/export * style: updated progress-color * feat: added menu section * style: added new variables to theme * refactor: separated theme-button from navbar * feat: added links to menu * style: git opener logo updated * feat: created some utility components
- Loading branch information
Showing
20 changed files
with
498 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import Glow from '@utilities/glow'; | ||
import Logo from '@utilities/logo'; | ||
import { AnimatePresence, Variants, motion } from 'framer-motion'; | ||
import { FC, useEffect, useState } from 'react'; | ||
import Container from '../layouts/container'; | ||
import ThemeButton from '../navbar/theme-button'; | ||
import MenuList from './menu-list'; | ||
|
||
export default function Menu() { | ||
const [isSticky, setIsSticky] = useState<boolean>(false); | ||
useEffect(() => { | ||
function handleScroll() { | ||
const scrollTop = window.scrollY; | ||
|
||
if (scrollTop >= 53) { | ||
setIsSticky(true); | ||
} else { | ||
setIsSticky(false); | ||
} | ||
} | ||
window.addEventListener('scroll', handleScroll); | ||
|
||
return () => window.removeEventListener('scroll', handleScroll); | ||
}, []); | ||
|
||
const displayLogoVarient: Variants = { | ||
initial: { | ||
opacity: 0, | ||
transition: { | ||
duration: 0.8, | ||
ease: 'easeInOut', | ||
}, | ||
scale: 0.5, | ||
}, | ||
onEnter: { | ||
opacity: 1, | ||
scale: 0.95, | ||
}, | ||
onExit: { | ||
opacity: 0, | ||
scale: 0.65, | ||
}, | ||
}; | ||
const displayIconVarient: Variants = { | ||
initial: { | ||
opacity: 0, | ||
transition: { | ||
duration: 0.8, | ||
ease: 'easeInOut', | ||
}, | ||
scale: 0.5, | ||
rotate: 150, | ||
}, | ||
onEnter: { | ||
opacity: 1, | ||
scale: 1, | ||
rotate: 360, | ||
transition: { | ||
delay: 0.25, | ||
}, | ||
}, | ||
onExit: { | ||
opacity: 0, | ||
scale: 0.65, | ||
}, | ||
}; | ||
|
||
function getAnimComp(Comp: FC, varient: Variants, key: string) { | ||
return ( | ||
<AnimatePresence> | ||
{isSticky && ( | ||
<motion.div | ||
variants={varient} | ||
key={key} | ||
initial={`initial`} | ||
animate={`onEnter`} | ||
exit={`onExit`} | ||
className="flex items-center gap-x-12 " | ||
> | ||
<Comp /> | ||
</motion.div> | ||
)} | ||
</AnimatePresence> | ||
); | ||
} | ||
|
||
const displayLogo = getAnimComp(Logo, displayLogoVarient, `displayLogo`); | ||
const displayIcon = getAnimComp( | ||
ThemeButton, | ||
displayIconVarient, | ||
`displayIcon` | ||
); | ||
|
||
return ( | ||
<div className="relative w-full border-b border-skin-base bg-skin-base text-skin-base "> | ||
<Glow className="sm:right-0 sm:max-w-3xl " /> | ||
<Container className="relative z-0 flex min-h-[4rem] flex-col items-center justify-end sm:min-h-[5rem] sm:flex-row sm:justify-between"> | ||
{/* upper section */} | ||
<div className="z-10 flex items-center gap-x-12"> | ||
{displayLogo} | ||
{displayIcon} | ||
</div> | ||
{/* links section */} | ||
<div className="z-0 sm:self-end"> | ||
<MenuList /> | ||
</div> | ||
</Container> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { links } from '@/data/menu-links'; | ||
import Link from 'next/link'; | ||
import { useRouter } from 'next/router'; | ||
import ToolTip from '../utilities/tooltip'; | ||
|
||
export default function MenuList() { | ||
const { pathname } = useRouter(); | ||
return ( | ||
<ul className="flex items-center "> | ||
{links.map((link, indx) => { | ||
const isActive: boolean = pathname === link.to; | ||
return ( | ||
<Link href={link.to} key={link.title + indx}> | ||
<li | ||
className={`border-b-2 px-4 py-2 text-lg font-semibold capitalize tracking-tight transition-all duration-300 ease-in-out hover:text-accent | ||
${isActive ? ` border-accent text-accent ` : `border-transparent`} | ||
`} | ||
> | ||
<ToolTip tip={link.title}> | ||
<link.icon className="h-6 w-6" /> | ||
</ToolTip> | ||
</li> | ||
</Link> | ||
); | ||
})} | ||
</ul> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,14 @@ | ||
import GitOpenerIcon from '@/components/icons/git-opener'; | ||
import { useThemeContext } from '@/context/theme-context'; | ||
import { MoonIcon, SunIcon } from '@heroicons/react/24/solid'; | ||
import Container from '@layouts/container'; | ||
import Pop from '@utilities/pop'; | ||
import Themes from './theme'; | ||
import Logo from '@utilities/logo'; | ||
import ThemeButton from './theme-button'; | ||
|
||
export default function Navbar() { | ||
const { isDark } = useThemeContext(); | ||
return ( | ||
<Container className="z-10 flex items-center justify-between"> | ||
{/* logo */} | ||
<div className="flex items-center gap-x-2 py-4 text-skin-base"> | ||
<GitOpenerIcon className="h-10 w-10 rotate-90 " /> | ||
<span className="text-2xl font-bold tracking-tight">Git Opener</span> | ||
</div> | ||
<Logo /> | ||
{/* social icons */} | ||
<div className=""> | ||
<Pop Icon={isDark ? MoonIcon : SunIcon} className="!z-50"> | ||
<Themes /> | ||
</Pop> | ||
</div> | ||
<ThemeButton /> | ||
</Container> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { useThemeContext } from '@/context/theme-context'; | ||
import { MoonIcon, SunIcon } from '@heroicons/react/24/solid'; | ||
import Pop from '@utilities/pop'; | ||
import Themes from './theme'; | ||
|
||
export default function ThemeButton() { | ||
const { isDark } = useThemeContext(); | ||
return ( | ||
<div className=""> | ||
<Pop Icon={isDark ? MoonIcon : SunIcon} className="!z-50"> | ||
<Themes /> | ||
</Pop> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
import { useThemeContext } from '@/context/theme-context'; | ||
import React, { useEffect, useId, useState } from 'react'; | ||
import colors from 'tailwindcss/colors'; | ||
|
||
interface GlowType { | ||
className: string; | ||
} | ||
|
||
const Glow: React.FC<GlowType> = ({ className }) => { | ||
const id = useId(); | ||
const [from, setFrom] = useState<string>(``); | ||
const [to, setTo] = useState<string>(``); | ||
const { isDark } = useThemeContext(); | ||
|
||
useEffect(() => { | ||
if (isDark) { | ||
setFrom(colors.pink[500]); | ||
setTo(colors.fuchsia[400]); | ||
} else { | ||
setFrom(colors.blue[500]); | ||
setTo(colors.sky[500]); | ||
} | ||
}, [isDark]); | ||
|
||
return ( | ||
<svg | ||
viewBox="0 0 384 12" | ||
fill="none" | ||
aria-hidden="true" | ||
className={`!pointer-events-none absolute top-full w-full transition ${className}`} | ||
> | ||
<mask | ||
id={`${id}-a`} | ||
style={{ maskType: 'alpha' }} | ||
maskUnits="userSpaceOnUse" | ||
x={48} | ||
y={0} | ||
width={269} | ||
height={4} | ||
> | ||
<path | ||
transform="rotate(180 316.656 4)" | ||
fill="#C4C4C4" | ||
d="M316.656 4h268v4h-268z" | ||
/> | ||
</mask> | ||
<g filter={`url(#${id}-b)`} mask={`url(#${id}-a)`}> | ||
<path | ||
transform="rotate(180 292.656 1)" | ||
fill={`url(#${id}-c)`} | ||
d="M292.656 1h220v2h-220z" | ||
/> | ||
</g> | ||
<mask | ||
id={`${id}-d`} | ||
style={{ maskType: 'alpha' }} | ||
maskUnits="userSpaceOnUse" | ||
x={116} | ||
y={0} | ||
width={268} | ||
height={12} | ||
> | ||
<path | ||
transform="rotate(180 384 12)" | ||
fill="#C4C4C4" | ||
d="M384 12h268v12H384z" | ||
/> | ||
</mask> | ||
<g filter={`url(#${id}-e)`} mask={`url(#${id}-d)`}> | ||
<path | ||
transform="rotate(180 360 1)" | ||
fill={`url(#${id}-f)`} | ||
d="M360 1h220v2H360z" | ||
/> | ||
</g> | ||
<defs> | ||
<linearGradient | ||
id={`${id}-c`} | ||
x1="292.656" | ||
y1={1} | ||
x2="512.656" | ||
y2={1} | ||
gradientUnits="userSpaceOnUse" | ||
> | ||
<stop stopColor={from} stopOpacity={0} /> | ||
<stop offset=".323" stopColor={from} /> | ||
<stop offset=".672" stopColor={to} stopOpacity=".3" /> | ||
<stop offset={1} stopColor={to} stopOpacity={0} /> | ||
</linearGradient> | ||
<linearGradient | ||
id={`${id}-f`} | ||
x1={360} | ||
y1={1} | ||
x2={580} | ||
y2={1} | ||
gradientUnits="userSpaceOnUse" | ||
> | ||
<stop stopColor={from} stopOpacity={0} /> | ||
<stop offset=".323" stopColor={from} /> | ||
<stop offset=".672" stopColor={to} stopOpacity=".3" /> | ||
<stop offset={1} stopColor={to} stopOpacity={0} /> | ||
</linearGradient> | ||
<filter | ||
id={`${id}-b`} | ||
x="71.656" | ||
y={-2} | ||
width={222} | ||
height={4} | ||
filterUnits="userSpaceOnUse" | ||
colorInterpolationFilters="sRGB" | ||
> | ||
<feFlood floodOpacity={0} result="BackgroundImageFix" /> | ||
<feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape" /> | ||
<feGaussianBlur | ||
stdDeviation=".5" | ||
result="effect1_foregroundBlur_311_43467" | ||
/> | ||
</filter> | ||
<filter | ||
id={`${id}-e`} | ||
x={131} | ||
y={-10} | ||
width={238} | ||
height={20} | ||
filterUnits="userSpaceOnUse" | ||
colorInterpolationFilters="sRGB" | ||
> | ||
<feFlood floodOpacity={0} result="BackgroundImageFix" /> | ||
<feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape" /> | ||
<feGaussianBlur | ||
stdDeviation="4.5" | ||
result="effect1_foregroundBlur_311_43467" | ||
/> | ||
</filter> | ||
</defs> | ||
</svg> | ||
); | ||
}; | ||
|
||
export default Glow; |
Oops, something went wrong.