Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions shared/ui/src/lib/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { LogoImageNeutral } from './LogoImageNeutral';

export const Footer = () => (
<div className="absolute inset-x-0 bottom-0 h-40 py-14">
export interface FooterProps {
className?: string;
}

export const Footer = ({ className }: FooterProps) => (
<div className={className}>
<LogoImageNeutral className="mx-auto h-12 w-12" />
</div>
);
9 changes: 6 additions & 3 deletions shared/ui/src/lib/NavLink.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { forwardRef, Ref } from 'react';
import { NavLink as RouterNavLink, NavLinkProps, To } from 'react-router-dom';
import { eventBus } from '@jasonruesch/shared/utils';
import { forwardRef, Ref } from 'react';
import { NavLinkProps, NavLink as RouterNavLink, To } from 'react-router-dom';

export const NavLink = forwardRef(
({ to, ...props }: NavLinkProps, ref: Ref<HTMLAnchorElement>) => {
const intendToNavigate = (to: To) => {
eventBus.dispatch('intendToNavigate', { to: to as string });
eventBus.dispatch('intendToNavigate', {
to: to as string,
y: window.scrollY,
});
};

return (
Expand Down
21 changes: 18 additions & 3 deletions shared/ui/src/lib/PageTransitions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export const PageTransitions = ({
const [isNavigating, setIsNavigating] = useState(false);
const [slideRight, setSlideRight] = useState(false);
const { resolvedTheme } = useTheme();
const [routingPageOffset, setRoutingPageOffset] = useState(0);

useEffect(() => {
if (previousPathname !== pathname) {
Expand All @@ -50,9 +51,10 @@ export const PageTransitions = ({
pageMap.get(next)! < pageMap.get(current)!;

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const handleIntendToNavigate = ({ to }: any) => {
const handleIntendToNavigate = ({ to, y }: any) => {
const slideRight = shouldSlideRight(pathname, to);
setSlideRight(slideRight);
setRoutingPageOffset(y);
};

eventBus.on('intendToNavigate', handleIntendToNavigate);
Expand All @@ -74,7 +76,7 @@ export const PageTransitions = ({
<AnimatePresence
initial={false} // Disabled for now because the animate keyframes are running when the page loads
mode="wait"
onExitComplete={() => window.scrollTo(0, 0)}
// onExitComplete={() => window.scrollTo(0, 0)}
>
<motion.div
ref={pageRef}
Expand Down Expand Up @@ -107,7 +109,20 @@ export const PageTransitions = ({
}
}}
>
{children}
<motion.div
initial={false}
animate={{
y: 0,
}}
exit={{
y: `-${routingPageOffset}px`,
transition: {
duration: 0,
},
}}
>
{children}
</motion.div>
</motion.div>
</AnimatePresence>
</div>
Expand Down
2 changes: 1 addition & 1 deletion shared/ui/src/lib/PageTransitionsVariants.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Variants } from 'framer-motion';

const SCALE = 0.6;
const DURATION = 2; // seconds
const DURATION = 1.5; // seconds

export interface VariantProps {
windowSize: { width: number; height: number };
Expand Down
117 changes: 45 additions & 72 deletions shared/ui/src/lib/ThemeSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,34 @@
import { Fragment, useEffect } from 'react';
import { Menu, Transition } from '@headlessui/react';
import {
SunIcon,
MoonIcon,
ComputerDesktopIcon,
} from '@heroicons/react/24/solid';
import {
SunIcon as SunIconOutline,
MoonIcon as MoonIconOutline,
SunIcon as SunIconOutline,
} from '@heroicons/react/24/outline';
import {
ComputerDesktopIcon,
MoonIcon,
SunIcon,
} from '@heroicons/react/24/solid';
import clsx from 'clsx';
import { useTheme } from 'next-themes';
import { Fragment, useEffect } from 'react';

const menuItems = [
{
name: 'Light',
theme: 'light',
icon: <SunIcon className="mr-3 h-5 w-5" aria-hidden="true" />,
},
{
name: 'Dark',
theme: 'dark',
icon: <MoonIcon className="mr-3 h-5 w-5" aria-hidden="true" />,
},
{
name: 'System',
theme: 'system',
icon: <ComputerDesktopIcon className="mr-3 h-5 w-5" aria-hidden="true" />,
},
];

export interface ThemeSelectorProps {
className?: string;
Expand Down Expand Up @@ -66,72 +84,27 @@ export function ThemeSelector({ className }: ThemeSelectorProps) {
>
<Menu.Items className="absolute right-0 z-50 mt-2 w-36 origin-top-right rounded-md bg-neutral-50 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:bg-neutral-900 dark:shadow-black dark:ring-opacity-50">
<div className="py-1">
<Menu.Item>
<button
className={clsx(
'group flex w-full items-center px-4 py-2 text-sm text-neutral-900 hover:bg-neutral-200 dark:text-neutral-50 dark:hover:bg-neutral-700',
theme === 'light'
? '!text-cyan-500 hover:!text-neutral-900 dark:!text-violet-400 dark:hover:!text-neutral-50'
: ''
)}
onClick={() => setTheme('light')}
>
<SunIcon
className={clsx(
'mr-3 h-5 w-5',
theme === 'light'
? 'text-cyan-500 group-hover:text-neutral-900 dark:text-violet-400 dark:group-hover:text-neutral-50'
: ''
)}
aria-hidden="true"
/>
<span>Light</span>
</button>
</Menu.Item>
<Menu.Item>
<button
className={clsx(
'group flex w-full items-center px-4 py-2 text-sm text-neutral-900 hover:bg-neutral-200 dark:text-neutral-50 dark:hover:bg-neutral-700',
theme === 'dark'
? '!text-cyan-500 hover:!text-neutral-900 dark:!text-violet-400 dark:hover:!text-neutral-50'
: ''
)}
onClick={() => setTheme('dark')}
>
<MoonIcon
className={clsx(
'mr-3 h-5 w-5',
theme === 'dark'
? 'text-cyan-500 group-hover:text-neutral-900 dark:text-violet-400 dark:group-hover:text-neutral-50'
: ''
)}
aria-hidden="true"
/>
<span>Dark</span>
</button>
</Menu.Item>
<Menu.Item>
<button
className={clsx(
'group flex w-full items-center px-4 py-2 text-sm text-neutral-900 hover:bg-neutral-200 dark:text-neutral-50 dark:hover:bg-neutral-700',
theme === 'system'
? '!text-cyan-500 hover:!text-neutral-900 dark:!text-violet-400 dark:hover:!text-neutral-50'
: ''
{menuItems.map((item) => (
<Menu.Item key={item.name}>
{({ active }) => (
<button
className={clsx(
'group flex w-full items-center px-4 py-2 text-sm',
active ? 'bg-neutral-200 dark:bg-neutral-700' : '',
theme === item.theme
? active
? 'text-neutral-900 dark:text-neutral-50'
: 'text-cyan-500 dark:text-violet-400'
: 'text-neutral-900 dark:text-neutral-50'
)}
onClick={() => setTheme(item.theme)}
>
{item.icon}
{item.name}
</button>
)}
onClick={() => setTheme('system')}
>
<ComputerDesktopIcon
className={clsx(
'mr-3 h-5 w-5',
theme === 'system'
? 'text-cyan-500 group-hover:text-neutral-900 dark:text-violet-400 dark:group-hover:text-neutral-50'
: ''
)}
aria-hidden="true"
/>
<span>System</span>
</button>
</Menu.Item>
</Menu.Item>
))}
</div>
</Menu.Items>
</Transition>
Expand Down
6 changes: 3 additions & 3 deletions src/app/about/about.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ export interface AboutProps {}

export function About(props: AboutProps) {
return (
<div className="mx-auto grid h-full max-w-xl pb-40 pt-16 sm:place-items-center sm:pb-16">
<div className="w-full pt-6 sm:pt-0">
<div className="grid h-full sm:place-items-center">
<div className="mx-auto w-full max-w-xl pt-6 sm:pt-0">
<div className="mb-4 space-y-4">
<ProfileImage />

Expand Down Expand Up @@ -38,7 +38,7 @@ export function About(props: AboutProps) {
<span aria-hidden="true"> &rarr;</span>
</NavLink>

<Footer />
<Footer className="pt-16 sm:pt-20" />
</div>
</div>
);
Expand Down
4 changes: 2 additions & 2 deletions src/app/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ export function App() {
</Header>
<PageTransitions>
<main className="flex min-h-screen bg-neutral-100 text-neutral-900 dark:bg-neutral-800 dark:text-neutral-50">
<Beams className="z-10" />
<div className="relative z-20 mx-auto w-full max-w-screen-lg px-4 sm:px-8">
<div className="relative z-20 mx-auto w-full max-w-screen-lg px-4 py-16 sm:px-8 sm:py-20">
<AnimatedOutlet />
</div>
<Beams className="z-10" />
</main>
</PageTransitions>
</ThemeProvider>
Expand Down
6 changes: 3 additions & 3 deletions src/app/contact/contact.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ export function Contact(props: ContactProps) {
});

return (
<div className="mx-auto grid h-full max-w-xl pb-40 pt-16 sm:place-items-center sm:pb-16">
<div className="w-full pt-6 sm:pt-0">
<div className="grid h-full sm:place-items-center">
<div className="mx-auto w-full max-w-xl pt-6 sm:pt-0">
<h1 className="mb-4">Get In Touch</h1>
<form onSubmit={handleSubmit} noValidate>
<div className="grid grid-cols-1 gap-x-6 gap-y-1 sm:grid-cols-6">
Expand Down Expand Up @@ -271,7 +271,7 @@ export function Contact(props: ContactProps) {
</div>
</form>

<Footer />
<Footer className="pt-16 sm:pt-20" />
</div>

{notification && (
Expand Down
4 changes: 2 additions & 2 deletions src/app/errors/404.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export function Error404() {
return (
<div className="mx-auto grid h-full max-w-xl pt-16 pb-4 sm:place-items-center sm:py-20">
<div className="w-full">
<div className="grid h-full sm:place-items-center">
<div className="mx-auto w-full max-w-xl pt-6 sm:pt-0">
<div className="space-y-4">
<h1>404</h1>
<p className="text-neutral-500 dark:text-neutral-400">
Expand Down
8 changes: 4 additions & 4 deletions src/app/errors/500.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,10 @@ export function Error500() {
/>
)}
</Header>
<Beams className="z-10" />
<main className="flex min-h-screen bg-neutral-100 text-neutral-900 dark:bg-neutral-800 dark:text-neutral-50">
<div className="mx-auto w-full max-w-screen-lg px-4 sm:px-8">
<div className="mx-auto grid h-full max-w-xl pt-16 pb-4 sm:place-items-center sm:py-20">
<div className="w-full">
<div className="relative z-20 mx-auto w-full max-w-screen-lg px-4 py-16 sm:px-8 sm:py-20">
<div className="grid h-full sm:place-items-center">
<div className="mx-auto w-full max-w-xl pt-6 sm:pt-0">
<div className="space-y-4">
<h1>500</h1>
<p className="text-neutral-500 dark:text-neutral-400">
Expand All @@ -37,6 +36,7 @@ export function Error500() {
</div>
</div>
</div>
<Beams className="z-10" />
</main>
</ThemeProvider>
);
Expand Down
22 changes: 11 additions & 11 deletions src/app/home/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ export function Home(props: HomeProps) {
}, [isXSmallScreen, handleHoverStart, handleHoverEnd]);

return (
<div className="mx-auto grid h-full max-w-xl place-items-center py-16 sm:py-20">
<div className="w-full">
<div className="grid h-full place-items-center">
<div className="mx-auto max-w-xl w-full">
<ProfileImage large className="mb-4" />

<h1 className="mb-4 text-center text-neutral-500 dark:text-neutral-400">
Expand All @@ -86,14 +86,14 @@ export function Home(props: HomeProps) {
Web Development and Design
</h1>

<NavLink
to="/about"
aria-label="Learn more about me"
className="mx-auto flex w-12 cursor-pointer justify-end text-sm font-medium text-cyan-500 hover:text-cyan-600 dark:text-violet-400 dark:hover:text-violet-500 sm:w-24"
<motion.div
onHoverStart={() => handleHoverStart()}
onHoverEnd={() => handleHoverEnd()}
>
<motion.div
onHoverStart={() => handleHoverStart()}
onHoverEnd={() => handleHoverEnd()}
<NavLink
to="/about"
aria-label="Learn more about me"
className="mx-auto flex w-12 cursor-pointer justify-end text-sm font-medium text-cyan-500 hover:text-cyan-600 dark:text-violet-400 dark:hover:text-violet-500 sm:w-24"
>
<motion.div
initial="initial"
Expand All @@ -109,8 +109,8 @@ export function Home(props: HomeProps) {
aria-hidden="true"
/>
</motion.div>
</motion.div>
</NavLink>
</NavLink>
</motion.div>
</div>
</div>
);
Expand Down
Loading