Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: dark mode #29

Merged
merged 7 commits into from
Nov 4, 2024
Merged
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
17 changes: 9 additions & 8 deletions configs/biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@
"include": [
"**/*.js",
"**/*.ts",
"**/*.tsx",
"**/*.jsx",
"**/*.json",
"**/*.md",
"**/*.yml",
"**/*.yaml",
"**/*.html"
"**/*.tsx",
"**/*.cjs",
"**/*.cts",
"**/*.mjs",
"**/*.mts",
"**/*.json"
],
"ignore": [
"**/packages/**",
"**/node_modules/**",
"**/dist/**",
"**/.million/**",
"**/build/**",
"**/.next/**",
"**/out/**",
Expand Down Expand Up @@ -46,7 +46,8 @@
"noDangerouslySetInnerHtml": "off"
},
"correctness": {
"useExhaustiveDependencies": "off"
"useExhaustiveDependencies": "off",
"noUnusedImports": "error"
},
"a11y": {
"useKeyWithClickEvents": "off"
Expand Down
14 changes: 3 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,7 @@
"name": "@pseudobun/me-monorepo",
"private": true,
"description": "Personal monorepo.",
"keywords": [
"Computer Science",
"Rust",
"Typescript",
"NextJS",
"Portfolio"
],
"keywords": ["Computer Science", "Rust", "Typescript", "NextJS", "Portfolio"],
"homepage": "https://pseudobun.dev",
"repository": {
"type": "git",
Expand All @@ -20,13 +14,11 @@
"email": "[email protected]",
"url": "https://pseudobun.dev"
},
"workspaces": [
"packages/*"
],
"workspaces": ["packages/*"],
"scripts": {
"build": "pnpm nx run-many --target=build",
"lint": "biome check --config-path configs . && pnpm nx run-many --target=lint",
"lint:fix": "biome check --config-path configs --apply . && pnpm nx run-many --target=lint:fix",
"lint:fix": "biome check --config-path configs --write . && pnpm nx run-many --target=lint:fix",
"prepare": "is-ci || husky install",
"test": "pnpm nx run-many --target=test",
"test:ci": "pnpm nx run-many --target=test:ci",
Expand Down
2 changes: 2 additions & 0 deletions packages/portfolio/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"type": "commonjs",
"scripts": {
"build": "rimraf .next && next build",
"clean": "rimraf .next",
"postbuild": "next-sitemap",
"dev": "next dev",
"lint": "biome check .",
Expand All @@ -14,6 +15,7 @@
"dependencies": {
"@headlessui/react": "^2.0.4",
"@heroicons/react": "^2.1.3",
"@radix-ui/react-dropdown-menu": "^2.1.2",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-navigation-menu": "^1.2.1",
"@radix-ui/react-slot": "^1.1.0",
Expand Down
10 changes: 3 additions & 7 deletions packages/portfolio/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import './globals.css';
import { Analytics } from '@vercel/analytics/react';
import Navigation from '@/components/Navigation';
import { METADATA } from '@/constants/metadata';
import { Providers } from '@/app/providers';
import { SpeedInsights } from '@vercel/speed-insights/next';
import { monoFont } from 'src/fonts';
import Navigation from '@/components/Navigation';
import Footer from '@/components/Footer';

export const metadata = METADATA.root;
Expand All @@ -18,15 +18,11 @@ export default function RootLayout({
<html lang="en" className={monoFont.className} suppressHydrationWarning>
<body className="flex flex-col min-h-[100dvh]">
<Providers>
<header className="flex p-4 justify-center">
<Navigation />
</header>
<Navigation />
<main className="flex-grow flex flex-col no-scrollbar min-w-full sm:p-24 p-6 items-center justify-center max-w-4xl">
{children}
</main>
<footer className="flex p-4 items-center justify-center w-screen">
<Footer />
</footer>
<Footer />
<Analytics />
<SpeedInsights />
</Providers>
Expand Down
1 change: 0 additions & 1 deletion packages/portfolio/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
'use client';
import ExoticLink from '@/components/ExoticLink';
import { PERSONAL } from '@/constants/data.mjs';

Expand Down
2 changes: 1 addition & 1 deletion packages/portfolio/src/app/projects/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const metadata = {

export default function Projects() {
return (
<div className="flex flex-1 flex-col h-full max-w-[1024px] gap-y-10 justify-center mb-12 text-stone-200">
<div className="flex flex-1 flex-col h-full max-w-[1024px] gap-y-10 justify-center mb-12">
<div>
<p className="sm:text-3xl text-3xl">Projects</p>
<p className="sm:text-xl text-xl">I 🤍 building things.</p>
Expand Down
2 changes: 1 addition & 1 deletion packages/portfolio/src/components/Footer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { PERSONAL } from '@/constants/data.mjs';

export default function Footer() {
return (
<footer className="flex max-md:flex-col w-full gap-x-12 gap-y-4 max-w-[2048px] justify-between items-center text-muted-foreground fill-muted-foreground">
<footer className="flex p-4 max-md:flex-col gap-x-12 w-screen gap-y-4 justify-between items-center text-muted-foreground fill-muted-foreground">
<div className="max-md:order-2">
<p className="text-center">
&copy; {new Date().getFullYear()} Urban Vidovič. All rights reserved.
Expand Down
2 changes: 1 addition & 1 deletion packages/portfolio/src/components/Link/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default function Link({
href={href}
target={isExternal ? '_blank' : undefined}
className={cn(
'hover:text-cappuccino flex gap-2 items-center',
'hover:text-cappuccino text-left flex items-center gap-2',
isActive ? 'underline text-cappuccino' : '',
)}
{...props}
Expand Down
90 changes: 74 additions & 16 deletions packages/portfolio/src/components/Navigation/index.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,86 @@
'use client';
import { useState } from 'react';
import { motion } from 'framer-motion';
import {
NavigationMenu,
NavigationMenuItem,
NavigationMenuList,
} from '@/components/ui/navigation-menu';
import { type MenuInput, MENUS } from '@/config/menu';
import Link from '@/components/Link';
import { Link as LinkIcon } from 'lucide-react';
import { Link as LinkIcon, Menu, X } from 'lucide-react';
import { ThemeToggle } from '@/components/ThemeToggle';

export default function Navigation() {
const [menuOpen, setMenuOpen] = useState(false);

const handleLinkClick = () => {
setMenuOpen(false);
};

return (
<NavigationMenu>
<NavigationMenuList className="max-md:gap-x-4 gap-x-12">
{MENUS.map((menu: MenuInput) => (
<NavigationMenuItem key={menu.label}>
<Link
href={menu.href}
isExternal={menu.external ? true : undefined}
>
{menu.label}
{menu.external ? <LinkIcon className="w-3 h-3" /> : null}
</Link>
</NavigationMenuItem>
))}
</NavigationMenuList>
</NavigationMenu>
<header className="relative flex justify-between items-center p-4 w-full">
<button
className="md:hidden block"
onClick={() => setMenuOpen(!menuOpen)}
type="button"
>
<Menu className="w-6 h-6 text-cappuccino" />
</button>
<motion.div
initial={{ x: '-115%' }}
animate={{ x: menuOpen ? -5 : '-115%' }}
transition={{ type: 'tween', ease: 'easeInOut', duration: 0.5 }}
className="flex min-w-32 flex-col fixed top-4 left-4 border rounded-lg backdrop-blur-2xl shadow-lg md:hidden z-20"
>
<div className="flex p-2 pb-0 justify-end">
<button onClick={() => setMenuOpen(false)} type="button">
<X className="w-6 h-6 text-cappuccino" />
</button>
</div>
<NavigationMenu>
<NavigationMenuList className="flex flex-col px-4 pb-4">
{MENUS.map((menu: MenuInput) => (
<NavigationMenuItem key={menu.label}>
<Link
href={menu.href}
isExternal={menu.external ? true : undefined}
onClick={handleLinkClick}
>
{menu.label}
{menu.external ? <LinkIcon className="w-3 h-3" /> : null}
</Link>
</NavigationMenuItem>
))}
</NavigationMenuList>
</NavigationMenu>
</motion.div>
{menuOpen && (
<div
className="fixed inset-0 opacity-50 z-10"
onClick={() => setMenuOpen(false)}
/>
)}
<div className="hidden md:block">
<NavigationMenu>
<NavigationMenuList className="flex gap-x-12">
{MENUS.map((menu: MenuInput) => (
<NavigationMenuItem key={menu.label}>
<Link
href={menu.href}
isExternal={menu.external ? true : undefined}
>
{menu.label}
{menu.external ? <LinkIcon className="w-3 h-3" /> : null}
</Link>
</NavigationMenuItem>
))}
</NavigationMenuList>
</NavigationMenu>
</div>
<div>
<ThemeToggle />
</div>
</header>
);
}
38 changes: 38 additions & 0 deletions packages/portfolio/src/components/ThemeToggle/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
'use client';
import { MoonIcon, SunIcon } from '@radix-ui/react-icons';
import { useTheme } from 'next-themes';

import { Button } from '@/components/ui/button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';

export function ThemeToggle() {
const { setTheme } = useTheme();

return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="icon">
<SunIcon className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<MoonIcon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only">Toggle theme</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => setTheme('light')}>
Light
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('dark')}>
Dark
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('system')}>
System
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}
Loading