fix: styling updates

This commit is contained in:
Mythie
2023-08-21 19:56:18 +10:00
parent 2f2d5dfc0b
commit 6d360e581d
5 changed files with 98 additions and 157 deletions

View File

@ -3,7 +3,7 @@ import { HTMLAttributes } from 'react';
import Image from 'next/image'; import Image from 'next/image';
import Link from 'next/link'; import Link from 'next/link';
import { Github, Slack, Twitter } from 'lucide-react'; import { Github, MessagesSquare, Twitter } from 'lucide-react';
import { cn } from '@documenso/ui/lib/utils'; import { cn } from '@documenso/ui/lib/utils';
@ -36,11 +36,11 @@ export const Footer = ({ className, ...props }: FooterProps) => {
</Link> </Link>
<Link <Link
href="https://documenso.slack.com" href="https://documen.so/discord"
target="_blank" target="_blank"
className="hover:text-[#6D6D6D]" className="hover:text-[#6D6D6D]"
> >
<Slack className="h-6 w-6" /> <MessagesSquare className="h-6 w-6" />
</Link> </Link>
</div> </div>
</div> </div>

View File

@ -13,16 +13,12 @@ import { MobileNavigation } from './mobile-navigation';
export type HeaderProps = HTMLAttributes<HTMLElement>; export type HeaderProps = HTMLAttributes<HTMLElement>;
export const Header = ({ className, ...props }: HeaderProps) => { export const Header = ({ className, ...props }: HeaderProps) => {
const [isMobileOpen, setIsMobileOpen] = useState<boolean>(false); const [isHamburgerMenuOpen, setIsHamburgerMenuOpen] = useState(false);
const handleMenuToggle = () => {
setIsMobileOpen(!isMobileOpen);
};
return ( return (
<header className={cn('flex items-center justify-between', className)} {...props}> <header className={cn('flex items-center justify-between', className)} {...props}>
<Link href="/" className="z-10" onClick={() => isMobileOpen && handleMenuToggle()}> <Link href="/" className="z-10" onClick={() => setIsHamburgerMenuOpen(false)}>
<Image src="/logo.png" alt="Documenso Logo" width={170} height={0}></Image> <Image src="/logo.png" alt="Documenso Logo" width={170} height={25} />
</Link> </Link>
<div className="hidden items-center gap-x-6 md:flex"> <div className="hidden items-center gap-x-6 md:flex">
@ -47,8 +43,14 @@ export const Header = ({ className, ...props }: HeaderProps) => {
</Link> </Link>
</div> </div>
<HamburgerMenu menuToggle={handleMenuToggle} isMenuOpen={isMobileOpen} /> <HamburgerMenu
<MobileNavigation isMenuOpen={isMobileOpen} menuToggle={handleMenuToggle} /> onToggleMenuOpen={() => setIsHamburgerMenuOpen((v) => !v)}
isMenuOpen={isHamburgerMenuOpen}
/>
<MobileNavigation
isMenuOpen={isHamburgerMenuOpen}
onMenuOpenChange={setIsHamburgerMenuOpen}
/>
</header> </header>
); );
}; };

View File

@ -1,34 +1,18 @@
'use client'; 'use client';
import { useEffect } from 'react';
import { Menu, X } from 'lucide-react'; import { Menu, X } from 'lucide-react';
import { Button } from '@documenso/ui/primitives/button'; import { Button } from '@documenso/ui/primitives/button';
import { useWindowSize } from '~/hooks/use-window-size';
export interface HamburgerMenuProps { export interface HamburgerMenuProps {
isMenuOpen: boolean; isMenuOpen: boolean;
menuToggle: () => void; onToggleMenuOpen?: () => void;
} }
export const HamburgerMenu = ({ isMenuOpen, menuToggle }: HamburgerMenuProps) => { export const HamburgerMenu = ({ isMenuOpen, onToggleMenuOpen }: HamburgerMenuProps) => {
const { width } = useWindowSize();
useEffect(() => {
// Update document.body.style.overflow based on the menu state
// If the window width is less than 768px, we want to prevent scrolling when the menu is open
if (width < 768 && isMenuOpen) {
document.body.style.overflow = 'hidden';
} else {
document.body.style.overflow = 'auto';
}
}, [isMenuOpen, width]);
return ( return (
<div className="flex md:hidden"> <div className="flex md:hidden">
<Button variant="default" className="z-20 w-10 p-0" onClick={menuToggle}> <Button variant="outline" className="z-20 w-10 p-0" onClick={onToggleMenuOpen}>
{isMenuOpen ? <X /> : <Menu />} {isMenuOpen ? <X /> : <Menu />}
</Button> </Button>
</div> </div>

View File

@ -3,24 +3,17 @@
import Image from 'next/image'; import Image from 'next/image';
import Link from 'next/link'; import Link from 'next/link';
import { Variants, motion, useReducedMotion } from 'framer-motion'; import { motion, useReducedMotion } from 'framer-motion';
import { Github, Slack, Twitter } from 'lucide-react'; import { Github, MessagesSquare, Twitter } from 'lucide-react';
import { cn } from '@documenso/ui/lib/utils'; import { Sheet, SheetContent } from '@documenso/ui/primitives/sheet';
import backgroundPattern from '~/assets/background-pattern.png';
export type MobileNavigationProps = { export type MobileNavigationProps = {
isMenuOpen: boolean; isMenuOpen: boolean;
menuToggle: () => void; onMenuOpenChange?: (_value: boolean) => void;
}; };
export interface MenuNavigationLinksProps { export const MENU_NAVIGATION_LINKS = [
href: string;
text: string;
}
export const MenuNavigationLinks = [
{ {
href: '/blog', href: '/blog',
text: 'Blog', text: 'Blog',
@ -47,112 +40,82 @@ export const MenuNavigationLinks = [
}, },
]; ];
export const MobileNavigation = ({ isMenuOpen, menuToggle }: MobileNavigationProps) => { export const MobileNavigation = ({ isMenuOpen, onMenuOpenChange }: MobileNavigationProps) => {
const shouldReduceMotion = useReducedMotion(); const shouldReduceMotion = useReducedMotion();
const handleMenuItemClick = () => { const handleMenuItemClick = () => {
menuToggle(); onMenuOpenChange?.(false);
}; };
const itemVariants: Variants = {
open: {
opacity: 1,
y: 0,
x: 0,
transition: { type: 'spring', stiffness: 300, damping: 24 },
},
closed: { opacity: 0, y: 0, x: shouldReduceMotion ? 0 : 60, transition: { duration: 0.2 } },
exit: {
opacity: 0,
y: 0,
x: shouldReduceMotion ? 0 : 60,
transition: { duration: 0.2 },
},
};
// used for testing alternate animations
// const vertical = `${!isMenuOpen ? '-translate-y-full' : 'translate-y-0'}`;
const horizontal = `${!isMenuOpen ? 'translate-x-full' : 'translate-x-0'}`;
return ( return (
<motion.div <Sheet open={isMenuOpen} onOpenChange={onMenuOpenChange}>
animate={isMenuOpen ? 'open' : 'closed'} <SheetContent className="w-full max-w-[400px]">
className={cn( <Link href="/" className="z-10" onClick={handleMenuItemClick}>
horizontal, <Image src="/logo.png" alt="Documenso Logo" width={170} height={25} />
'bg-secondary fixed left-0 right-0 top-16 z-10 flex h-[94dvh] w-full transform flex-col items-center justify-start gap-4 shadow-md backdrop-blur-lg transition duration-500 ease-in-out md:hidden', </Link>
)}
variants={{ <motion.div
open: { className="mt-12 flex w-full flex-col items-start gap-y-4"
transition: { initial="initial"
type: 'spring', animate="animate"
bounce: 0, transition={{
duration: shouldReduceMotion ? 0 : 0.7, staggerChildren: 0.2,
delayChildren: shouldReduceMotion ? 0 : 0.3, }}
staggerChildren: shouldReduceMotion ? 0 : 0.05, >
}, {MENU_NAVIGATION_LINKS.map(({ href, text }) => (
}, <motion.div
closed: { key={href}
transition: { variants={{
type: 'spring', initial: {
bounce: 0, opacity: 0,
duration: shouldReduceMotion ? 0 : 0.3, x: shouldReduceMotion ? 0 : 100,
}, },
}, animate: {
exit: { opacity: 1,
transition: { x: 0,
type: 'spring', transition: {
bounce: 0, duration: 0.5,
duration: shouldReduceMotion ? 0 : 0.3, },
}, },
}, }}
}} >
> <Link
<motion.div className="flex w-full flex-col items-center gap-y-4 px-8 pt-12"> className="text-2xl font-semibold text-[#8D8D8D] hover:text-[#6D6D6D]"
{MenuNavigationLinks.map((link: MenuNavigationLinksProps) => ( href={href}
onClick={() => handleMenuItemClick()}
>
{text}
</Link>
</motion.div>
))}
</motion.div>
<div className="mx-auto mt-8 flex w-full flex-wrap items-center gap-x-4 gap-y-4 ">
<Link <Link
key={link.href} href="https://twitter.com/documenso"
passHref target="_blank"
onClick={() => handleMenuItemClick()} className="text-[#8D8D8D] hover:text-[#6D6D6D]"
href={link.href}
className="text-4xl font-semibold text-[#8D8D8D] hover:text-[#6D6D6D]"
> >
<motion.p variants={itemVariants}>{link.text}</motion.p> <Twitter className="h-6 w-6" />
</Link> </Link>
))}
</motion.div>
<div className="mx-auto mt-8 flex w-full flex-wrap items-center justify-center gap-x-4 gap-y-4 "> <Link
<Link href="https://github.com/documenso/documenso"
href="https://twitter.com/documenso" target="_blank"
target="_blank" className="text-[#8D8D8D] hover:text-[#6D6D6D]"
className="text-[#8D8D8D] hover:text-[#6D6D6D]" >
> <Github className="h-6 w-6" />
<Twitter className="h-8 w-8" /> </Link>
</Link>
<Link <Link
href="https://github.com/documenso/documenso" href="https://documen.so/discord"
target="_blank" target="_blank"
className="text-[#8D8D8D] hover:text-[#6D6D6D]" className="text-[#8D8D8D] hover:text-[#6D6D6D]"
> >
<Github className="h-8 w-8" /> <MessagesSquare className="h-6 w-6" />
</Link> </Link>
</div>
<Link </SheetContent>
href="https://documenso.slack.com" </Sheet>
target="_blank"
className="text-[#8D8D8D] hover:text-[#6D6D6D]"
>
<Slack className="h-8 w-8" />
</Link>
</div>
<div className="absolute inset-0 -z-10 flex items-start justify-center">
<Image
src={backgroundPattern}
alt="background pattern"
className="-mr-[15vw] mt-[12vh] h-full max-h-[150vh] scale-125 object-cover md:-mr-[50vw] md:scale-150 lg:scale-[175%]"
/>
</div>
</motion.div>
); );
}; };

View File

@ -1,35 +1,27 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
// This hook is used to get the window size export function useWindowSize() {
// It returns an object with the width and height of the window const [size, setSize] = useState({
// Works with window resizing as well, not to be confused with isMobile from is-mobile package
interface WindowSize {
width: number;
height: number;
}
export function useWindowSize(): WindowSize {
const [windowSize, setWindowSize] = useState<WindowSize>({
width: 0, width: 0,
height: 0, height: 0,
}); });
const handleSize = () => { const onResize = () => {
setWindowSize({ setSize({
width: window.innerWidth, width: window.innerWidth,
height: window.innerHeight, height: window.innerHeight,
}); });
}; };
useEffect(() => { useEffect(() => {
handleSize(); onResize();
window.addEventListener('resize', handleSize);
window.addEventListener('resize', onResize);
return () => { return () => {
window.removeEventListener('resize', handleSize); window.removeEventListener('resize', onResize);
}; };
}, []); }, []);
return windowSize; return size;
} }