5 Commits

Author SHA1 Message Date
Renovate Bot
8db9fde31b Update dependency eslint to v9 2024-10-07 20:14:22 +00:00
ed67edde09 remove heroicons
All checks were successful
Deploy / deploy (ubuntu-latest, 2.44.0) (push) Successful in 1m45s
Took 12 minutes
2024-10-07 16:13:16 -04:00
1f18d6fb45 better theme switcher
All checks were successful
Deploy / deploy (ubuntu-latest, 2.44.0) (push) Successful in 1m16s
Took 42 minutes
2024-10-07 16:00:33 -04:00
96687ea94c update how the links in the sidebar look
All checks were successful
Deploy / deploy (ubuntu-latest, 2.44.0) (push) Successful in 1m1s
Took 21 seconds
2024-10-07 14:25:18 -04:00
61d052fc62 update how the links in the sidebar look
Some checks failed
Deploy / deploy (ubuntu-latest, 2.44.0) (push) Has been cancelled
Took 40 minutes
2024-10-07 14:24:57 -04:00
10 changed files with 64 additions and 78 deletions

BIN
bun.lockb

Binary file not shown.

View File

@ -14,7 +14,6 @@
"lint": "next lint" "lint": "next lint"
}, },
"dependencies": { "dependencies": {
"@heroicons/react": "^2.1.5",
"@radix-ui/react-collapsible": "^1.1.1", "@radix-ui/react-collapsible": "^1.1.1",
"@radix-ui/react-dialog": "^1.1.2", "@radix-ui/react-dialog": "^1.1.2",
"@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-icons": "^1.3.0",
@ -41,7 +40,7 @@
"@types/node": "^22.0.0", "@types/node": "^22.0.0",
"@types/react": "^18", "@types/react": "^18",
"@types/react-dom": "^18", "@types/react-dom": "^18",
"eslint": "^8", "eslint": "^9.0.0",
"eslint-config-next": "14.2.8", "eslint-config-next": "14.2.8",
"postcss": "^8", "postcss": "^8",
"tailwindcss": "^3.4.1", "tailwindcss": "^3.4.1",

View File

@ -3,10 +3,10 @@
import { ReactElement, useEffect, useState } from "react"; import { ReactElement, useEffect, useState } from "react";
import { usePathname } from "next/navigation"; import { usePathname } from "next/navigation";
import Link from "next/link"; import Link from "next/link";
import { ChevronLeftIcon, ChevronRightIcon } from "@heroicons/react/24/outline";
import { Separator } from "@/components/ui/separator"; import { Separator } from "@/components/ui/separator";
import { DateTime } from "luxon"; import { DateTime } from "luxon";
import SimpleTooltip from "@/components/simple-tooltip"; import SimpleTooltip from "@/components/simple-tooltip";
import { ChevronLeft, ChevronRight } from "lucide-react";
const DocsFooter = ({ const DocsFooter = ({
pages, pages,
@ -53,7 +53,7 @@ const DocsFooter = ({
</div> </div>
{/* Pages */} {/* Pages */}
<Separator className="my-4" /> <Separator className="my-4 bg-separator-gradient" />
<div className="flex justify-between"> <div className="flex justify-between">
{/* Previous */} {/* Previous */}
{previous && ( {previous && (
@ -62,7 +62,7 @@ const DocsFooter = ({
href={`/${previous.slug}` || "#"} href={`/${previous.slug}` || "#"}
draggable={false} draggable={false}
> >
<ChevronLeftIcon className="pb-1 w-4 h-4 group-hover:-translate-x-0.5 transition-all transform-gpu" /> <ChevronLeft className="pb-1 w-4 h-4 group-hover:-translate-x-0.5 transition-all transform-gpu" />
<div className="flex flex-col"> <div className="flex flex-col">
<h1 className="text-sm opacity-75">Previous</h1> <h1 className="text-sm opacity-75">Previous</h1>
<p>{previous.title}</p> <p>{previous.title}</p>
@ -81,7 +81,7 @@ const DocsFooter = ({
<h1 className="text-sm opacity-75">Next</h1> <h1 className="text-sm opacity-75">Next</h1>
<p>{next.title}</p> <p>{next.title}</p>
</div> </div>
<ChevronRightIcon className="pb-1 w-4 h-4 group-hover:translate-x-0.5 transition-all transform-gpu" /> <ChevronRight className="pb-1 w-4 h-4 group-hover:translate-x-0.5 transition-all transform-gpu" />
</Link> </Link>
)} )}
</div> </div>

View File

@ -4,11 +4,8 @@ import { ReactElement, ReactNode } from "react";
import AnimatedGridPattern from "@/components/ui/animated-grid-pattern"; import AnimatedGridPattern from "@/components/ui/animated-grid-pattern";
import Link from "next/link"; import Link from "next/link";
import Image from "next/image"; import Image from "next/image";
import {
ArrowTopRightOnSquareIcon,
EnvelopeIcon,
} from "@heroicons/react/24/outline";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { ExternalLink, Mail } from "lucide-react";
const links = { const links = {
Resources: [ Resources: [
@ -69,9 +66,7 @@ const Footer = (): ReactElement => (
/> />
<SocialLink <SocialLink
name="Email" name="Email"
logo={ logo={<Mail className="opacity-95 w-6 h-6" />}
<EnvelopeIcon className="opacity-95 w-6 h-6" />
}
href="mailto:support@pulseapp.cc" href="mailto:support@pulseapp.cc"
/> />
</div> </div>
@ -187,7 +182,7 @@ const FooterLink = ({
{name} {name}
</span> </span>
{shortName && <span className="flex sm:hidden">{shortName}</span>} {shortName && <span className="flex sm:hidden">{shortName}</span>}
{external && <ArrowTopRightOnSquareIcon className="w-3.5 h-3.5" />} {external && <ExternalLink className="w-3.5 h-3.5" />}
</Link> </Link>
); );
}; };

View File

@ -9,10 +9,10 @@ import {
CommandItem, CommandItem,
CommandList, CommandList,
} from "@/components/ui/command"; } from "@/components/ui/command";
import { MagnifyingGlassIcon } from "@heroicons/react/24/outline";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime"; import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime";
import { Search } from "lucide-react";
/** /**
* The dialog for quickly searching the docs. * The dialog for quickly searching the docs.
@ -53,7 +53,7 @@ const QuickSearchDialog = ({
onClick={() => setOpen(true)} onClick={() => setOpen(true)}
> >
<div className="absolute top-2.5 left-3 z-10"> <div className="absolute top-2.5 left-3 z-10">
<MagnifyingGlassIcon className="w-[1.15rem] h-[1.15rem]" /> <Search className="w-[1.15rem] h-[1.15rem]" />
</div> </div>
<Input <Input

View File

@ -1,17 +1,13 @@
"use client"; "use client";
import { ReactElement, useEffect, useRef, useState } from "react"; import { ReactElement, useEffect, useRef, useState } from "react";
import {
ArrowLongRightIcon,
ArrowLongUpIcon,
Bars3CenterLeftIcon,
} from "@heroicons/react/24/outline";
import Link from "next/link"; import Link from "next/link";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { truncateText } from "@/lib/string"; import { truncateText } from "@/lib/string";
import { motion, useInView } from "framer-motion"; import { motion, useInView } from "framer-motion";
import { Separator } from "@/components/ui/separator"; import { Separator } from "@/components/ui/separator";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { AlignLeftIcon, ArrowUpFromDot, MoveRight } from "lucide-react";
type Header = { type Header = {
id: string; id: string;
@ -90,7 +86,7 @@ const OnThisPage = ({ page }: { page: DocsContentMetadata }): ReactElement => {
> >
{/* Title */} {/* Title */}
<div className="flex gap-2.5 items-center"> <div className="flex gap-2.5 items-center">
<Bars3CenterLeftIcon className="w-5 h-5" /> <AlignLeftIcon className="w-5 h-5" />
<h1>On This Page</h1> <h1>On This Page</h1>
</div> </div>
@ -157,7 +153,7 @@ const Footer = ({ page }: { page: DocsContentMetadata }): ReactElement => {
draggable={false} draggable={false}
> >
<span>Edit this page on GitHub</span> <span>Edit this page on GitHub</span>
<ArrowLongRightIcon className="w-4 h-4 group-hover:translate-x-0.5 transition-all transform-gpu" /> <MoveRight className="w-4 h-4 group-hover:translate-x-px transition-all transform-gpu" />
</Link> </Link>
{/* Scroll to Top */} {/* Scroll to Top */}
@ -177,7 +173,7 @@ const Footer = ({ page }: { page: DocsContentMetadata }): ReactElement => {
} }
> >
<span>Scroll to Top</span> <span>Scroll to Top</span>
<ArrowLongUpIcon className="w-4 h-4 group-hover:translate-x-0.5 transition-all transform-gpu" /> <ArrowUpFromDot className="w-4 h-4 group-hover:-translate-y-px transition-all transform-gpu" />
</Button> </Button>
</div> </div>
</footer> </footer>

View File

@ -11,7 +11,7 @@ import Link from "next/link";
import { usePathname } from "next/navigation"; import { usePathname } from "next/navigation";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { AnimatePresence, motion } from "framer-motion"; import { AnimatePresence, motion } from "framer-motion";
import { ChevronRightIcon } from "@heroicons/react/24/outline"; import { ChevronRight } from "lucide-react";
const SidebarLinks = ({ const SidebarLinks = ({
pages, pages,
@ -51,14 +51,15 @@ const CategoryItem = ({
const hasChildren = Object.keys(node.children).length > 0; const hasChildren = Object.keys(node.children).length > 0;
return ( return (
<div className={`relative ${depth > 0 ? "ml-2.5" : ""} select-none`}> <div className={cn(`relative select-none`, depth > 0 && "ml-2.5")}>
{/* Indentation */} {/* Indentation */}
{depth > 0 && ( {depth > 0 && (
<div <div
className={`absolute left-0 top-1 bottom-0 border-l-2 border-muted`} className={cn(
style={{ "absolute left-0 bottom-0 border-l border-muted",
height: isLast ? "30px" : "100%", isLast ? "h-[32px]" : "h-[100%]",
}} active && "border-primary"
)}
/> />
)} )}
@ -71,9 +72,10 @@ const CategoryItem = ({
> >
<Button <Button
className={cn( className={cn(
`relative px-1.5 ${depth > 0 ? "pl-4" : ""} w-full justify-between`, `relative w-full px-1.5 h-8 text-base justify-between hover:bg-accent/20`,
depth > 0 && "pl-4",
active && active &&
"bg-primary/15 hover:bg-primary/20 text-primary/95 hover:text-primary" "text-primary/95 font-bold hover:text-primary"
)} )}
variant="ghost" variant="ghost"
> >
@ -84,7 +86,7 @@ const CategoryItem = ({
animate={{ rotate: isOpen ? 90 : 180 }} animate={{ rotate: isOpen ? 90 : 180 }}
transition={{ duration: 0.2 }} transition={{ duration: 0.2 }}
> >
<ChevronRightIcon className="w-4 h-4" /> <ChevronRight className="w-4 h-4" />
</motion.div> </motion.div>
)} )}
</Button> </Button>
@ -134,7 +136,7 @@ const CategoryItem = ({
const buildTree = (pages: DocsContentMetadata[]): Record<string, TreeNode> => { const buildTree = (pages: DocsContentMetadata[]): Record<string, TreeNode> => {
const tree: Record<string, TreeNode> = {}; const tree: Record<string, TreeNode> = {};
pages.forEach((page) => { pages.forEach((page: DocsContentMetadata) => {
const parts: string[] | undefined = page.slug?.split("/"); const parts: string[] | undefined = page.slug?.split("/");
let currentLevel = tree; let currentLevel = tree;

View File

@ -5,7 +5,7 @@ import SidebarLinks from "@/components/sidebar/sidebar-links";
import ThemeSwitcher from "@/components/theme-switcher"; import ThemeSwitcher from "@/components/theme-switcher";
import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet"; import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet";
import QuickSearchDialog from "@/components/navbar/search-dialog"; import QuickSearchDialog from "@/components/navbar/search-dialog";
import { Bars3BottomRightIcon } from "@heroicons/react/24/outline"; import { AlignRightIcon } from "lucide-react";
const Sidebar = (): ReactElement => ( const Sidebar = (): ReactElement => (
<> <>
@ -13,7 +13,7 @@ const Sidebar = (): ReactElement => (
<div className="xs:hidden"> <div className="xs:hidden">
<Sheet> <Sheet>
<SheetTrigger className="flex items-center"> <SheetTrigger className="flex items-center">
<Bars3BottomRightIcon className="w-6 h-6" /> <AlignRightIcon className="w-6 h-6" />
</SheetTrigger> </SheetTrigger>
<SheetContent className="h-full px-5 pt-11" side="right"> <SheetContent className="h-full px-5 pt-11" side="right">
<SidebarContent /> <SidebarContent />
@ -41,8 +41,8 @@ const SidebarContent = (): ReactElement => {
</div> </div>
{/* Theme Switcher */} {/* Theme Switcher */}
<div className="flex flex-col"> <div className="flex flex-col items-center">
<Separator className="mb-3" /> <Separator className="mb-3 bg-separator-gradient" />
<ThemeSwitcher /> <ThemeSwitcher />
</div> </div>
</div> </div>

View File

@ -1,12 +1,17 @@
"use client"; "use client";
import { ReactElement, useEffect, useState } from "react"; import { ReactElement, useEffect, useState } from "react";
import { MoonStar, Sun } from "lucide-react";
import { useTheme } from "next-themes"; import { useTheme } from "next-themes";
import { Button } from "@/components/ui/button";
import { motion } from "framer-motion";
import { UseThemeProps } from "next-themes/dist/types"; import { UseThemeProps } from "next-themes/dist/types";
import { capitalizeWords } from "@/lib/string"; import { Monitor, MoonStar, Sun } from "lucide-react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
const themes = {
dark: <MoonStar className="w-4 h-4" />,
light: <Sun className="w-4 h-4" />,
system: <Monitor className="w-4 h-4" />,
};
/** /**
* The theme switcher component. * The theme switcher component.
@ -15,47 +20,32 @@ import { capitalizeWords } from "@/lib/string";
*/ */
const ThemeSwitcher = (): ReactElement => { const ThemeSwitcher = (): ReactElement => {
const [mounted, setMounted] = useState(false); const [mounted, setMounted] = useState(false);
const { theme, setTheme }: UseThemeProps = useTheme(); const { theme: activeTheme, setTheme }: UseThemeProps = useTheme();
const isLight = theme === "light";
useEffect(() => { useEffect(() => {
setMounted(true); setMounted(true);
}, []); }, []);
return mounted ? ( return (
<Button <div className="w-fit p-1 flex gap-1.5 bg-black/30 ring-1 ring-white/5 rounded-full">
className="p-1.5 flex gap-7 justify-start items-center hover:opacity-85 select-none" {Object.entries(themes).map(([theme, icon]) => {
variant="ghost" const active: boolean = mounted && theme === activeTheme;
onClick={() => setTheme(isLight ? "dark" : "light")} return (
> <Button
<div className="relative flex items-center"> key={theme}
<motion.div className={cn(
className="absolute" "p-1 h-6 opacity-80 rounded-full",
initial={{ rotate: 0, scale: 1 }} active &&
animate={{ "ring-1 bg-zinc-900 ring-white/15 opacity-100"
rotate: isLight ? 0 : -90, )}
scale: isLight ? 1 : 0, variant="ghost"
}} onClick={() => setTheme(theme)}
transition={{ duration: 0.5 }} >
> {icon}
<Sun className="w-[1.1rem] h-[1.1rem]" /> </Button>
</motion.div> );
<motion.div })}
className="absolute" </div>
initial={{ rotate: 90, scale: 0 }}
animate={{
rotate: isLight ? 90 : 0,
scale: isLight ? 0 : 1,
}}
transition={{ duration: 0.5 }}
>
<MoonStar className="w-[1.1rem] h-[1.1rem]" />
</motion.div>
</div>
<span>{capitalizeWords(theme)}</span>
</Button>
) : (
<></>
); );
}; };

View File

@ -63,6 +63,10 @@ const config: Config = {
md: "calc(var(--radius) - 2px)", md: "calc(var(--radius) - 2px)",
sm: "calc(var(--radius) - 4px)", sm: "calc(var(--radius) - 4px)",
}, },
backgroundImage: {
"separator-gradient":
"linear-gradient(90deg, #161619, hsl(var(--muted)), #161619)",
},
}, },
}, },
plugins: [require("tailwindcss-animate")], plugins: [require("tailwindcss-animate")],