1
mirror of https://github.com/jakejarvis/jarv.is.git synced 2025-06-27 17:05:42 -04:00

correct some flex/grid spacings

This commit is contained in:
2025-05-08 10:07:40 -04:00
parent d98c3bb775
commit eab84bfee9
19 changed files with 84 additions and 136 deletions

View File

@ -4,7 +4,7 @@ import { Analytics } from "@vercel/analytics/next";
import { ThemeProvider, ThemeScript } from "@/components/layout/theme-context"; import { ThemeProvider, ThemeScript } from "@/components/layout/theme-context";
import Header from "@/components/layout/header"; import Header from "@/components/layout/header";
import Footer from "@/components/layout/footer"; import Footer from "@/components/layout/footer";
import { SkipNavLink, SkipNavTarget } from "@/components/layout/skip-nav"; import SkipNavButton, { SKIP_NAV_ID } from "@/components/layout/skip-nav";
import { defaultMetadata } from "@/lib/metadata"; import { defaultMetadata } from "@/lib/metadata";
import { GeistMono, GeistSans } from "@/lib/fonts"; import { GeistMono, GeistSans } from "@/lib/fonts";
import siteConfig from "@/lib/config/site"; import siteConfig from "@/lib/config/site";
@ -64,13 +64,12 @@ const RootLayout = ({ children }: Readonly<{ children: React.ReactNode }>) => {
<body className="bg-background text-foreground font-sans antialiased"> <body className="bg-background text-foreground font-sans antialiased">
<ThemeProvider> <ThemeProvider>
<SkipNavLink /> <SkipNavButton />
<div className="mx-auto w-full max-w-4xl px-5"> <div className="mx-auto w-full max-w-4xl px-5">
<Header className="mt-4 mb-6 w-full" /> <Header className="mt-4 mb-6 w-full" />
<main> <main id={SKIP_NAV_ID} tabIndex={-1}>
<SkipNavTarget />
{children} {children}
</main> </main>

View File

@ -85,17 +85,17 @@ const Page = async ({ params }: { params: Promise<{ slug: string }> }) => {
}} }}
/> />
<div className="text-foreground/70 -mt-1 flex flex-wrap justify-items-start space-x-4 text-[0.8rem] leading-9 tracking-wide md:text-[0.85rem]"> <div className="text-foreground/70 -mt-1 flex flex-wrap justify-items-start gap-x-4 text-[0.8rem] leading-9 tracking-wide md:text-[0.85rem]">
<Link <Link
href={`/${POSTS_DIR}/${frontmatter!.slug}`} href={`/${POSTS_DIR}/${frontmatter!.slug}`}
className={"text-foreground/70 flex items-center space-x-2 whitespace-nowrap hover:no-underline"} className={"text-foreground/70 flex flex-nowrap items-center gap-x-2 whitespace-nowrap hover:no-underline"}
> >
<CalendarDaysIcon className="inline size-4 shrink-0" /> <CalendarDaysIcon className="inline size-4 shrink-0" />
<Time date={frontmatter!.date} format="MMMM d, y" /> <Time date={frontmatter!.date} format="MMMM d, y" />
</Link> </Link>
{frontmatter!.tags && ( {frontmatter!.tags && (
<div className="flex flex-wrap items-center space-x-2 whitespace-nowrap"> <div className="flex flex-wrap items-center gap-x-2 whitespace-nowrap">
<TagIcon className="inline size-4 shrink-0" /> <TagIcon className="inline size-4 shrink-0" />
{frontmatter!.tags.map((tag) => ( {frontmatter!.tags.map((tag) => (
<span <span
@ -113,13 +113,13 @@ const Page = async ({ params }: { params: Promise<{ slug: string }> }) => {
<Link <Link
href={`https://github.com/${env.NEXT_PUBLIC_GITHUB_REPO}/blob/main/${POSTS_DIR}/${frontmatter!.slug}/index.mdx`} href={`https://github.com/${env.NEXT_PUBLIC_GITHUB_REPO}/blob/main/${POSTS_DIR}/${frontmatter!.slug}/index.mdx`}
title={`Edit "${frontmatter!.title}" on GitHub`} title={`Edit "${frontmatter!.title}" on GitHub`}
className={"text-foreground/70 flex items-center space-x-2 whitespace-nowrap hover:no-underline"} className={"text-foreground/70 flex flex-nowrap items-center gap-x-2 whitespace-nowrap hover:no-underline"}
> >
<SquarePenIcon className="inline size-4 shrink-0" /> <SquarePenIcon className="inline size-4 shrink-0" />
<span>Improve This Post</span> <span>Improve This Post</span>
</Link> </Link>
<div className="flex min-w-14 items-center space-x-2 whitespace-nowrap"> <div className="flex min-w-14 flex-nowrap items-center gap-x-2 whitespace-nowrap">
<EyeIcon className="inline size-4 shrink-0" /> <EyeIcon className="inline size-4 shrink-0" />
<Suspense <Suspense
// when this loads, the component will count up from zero to the actual number of hits, so we can simply // when this loads, the component will count up from zero to the actual number of hits, so we can simply

View File

@ -37,7 +37,7 @@ const Page = async () => {
Object.entries(postsByYear).forEach(([year, posts]) => { Object.entries(postsByYear).forEach(([year, posts]) => {
sections.push( sections.push(
<section className="my-8 first-of-type:mt-0" key={year}> <section className="my-8 first-of-type:mt-6 last-of-type:mb-6" key={year}>
<h2 className="mt-0 mb-4 text-3xl font-bold md:text-4xl">{year}</h2> <h2 className="mt-0 mb-4 text-3xl font-bold md:text-4xl">{year}</h2>
<ul className="space-y-4"> <ul className="space-y-4">
{posts.map(({ slug, date, title, htmlTitle, views }) => ( {posts.map(({ slug, date, title, htmlTitle, views }) => (
@ -50,7 +50,7 @@ const Page = async () => {
dangerouslySetInnerHTML={{ __html: htmlTitle || title }} dangerouslySetInnerHTML={{ __html: htmlTitle || title }}
/> />
{views > 0 && ( {views > 0 && (
<span className="bg-muted text-muted-foreground inline-flex h-5 flex-nowrap items-center space-x-1 rounded-md px-1.5 align-text-top text-xs font-semibold text-nowrap shadow select-none"> <span className="bg-muted text-muted-foreground inline-flex h-5 flex-nowrap items-center gap-1 rounded-md px-1.5 align-text-top text-xs font-semibold text-nowrap shadow select-none">
<EyeIcon className="inline-block size-4 shrink-0" /> <EyeIcon className="inline-block size-4 shrink-0" />
<span className="inline-block leading-5"> <span className="inline-block leading-5">
{Intl.NumberFormat(env.NEXT_PUBLIC_SITE_LOCALE).format(views)} {Intl.NumberFormat(env.NEXT_PUBLIC_SITE_LOCALE).format(views)}

View File

@ -191,15 +191,15 @@ const Page = () => {
<Link href="/contact" title="Send an email" className="[--primary:#de0c0c] dark:[--primary:#ff5050]"> <Link href="/contact" title="Send an email" className="[--primary:#de0c0c] dark:[--primary:#ff5050]">
email email
</Link>{" "} </Link>{" "}
<sup className="mx-0.5 text-[0.6rem]"> <sup className="mx-[3px] text-[0.6rem]">
<Link <Link
href="https://jrvs.io/pgp" href="https://jrvs.io/pgp"
rel="pgpkey" rel="pgpkey"
title="My Public Key" title="My Public Key"
className="text-nowrap decoration-1 [--primary:var(--muted-foreground)]" className="text-nowrap decoration-1 [--primary:var(--muted-foreground)]"
> >
<LockIcon className="mr-0.5 inline size-3 align-text-top" /> <LockIcon className="mr-[5px] inline size-3 align-text-top" />
<code className="mx-0.5 tracking-wider text-wrap [word-spacing:-0.25em]">2B0C 9CF2 51E6 9A39</code> <code className="tracking-wider text-wrap [word-spacing:-3px]">2B0C 9CF2 51E6 9A39</code>
</Link> </Link>
</sup> </sup>
,{" "} ,{" "}

View File

@ -1,5 +1,6 @@
import PageTitle from "@/components/layout/page-title"; import PageTitle from "@/components/layout/page-title";
import Marquee from "@/components/marquee"; import Marquee from "@/components/marquee";
import Comments from "@/components/comments";
import { createMetadata } from "@/lib/metadata"; import { createMetadata } from "@/lib/metadata";
import { ComicNeue } from "@/lib/fonts"; import { ComicNeue } from "@/lib/fonts";
@ -11,7 +12,7 @@ export const metadata = createMetadata({
export const WarningMarquee = () => ( export const WarningMarquee = () => (
<Marquee> <Marquee>
<span className="leading-none select-none"> <span className="leading-none">
🚨 Trigger warning: excessive marquees, animated GIFs, Comic Sans, popups,{" "} 🚨 Trigger warning: excessive marquees, animated GIFs, Comic Sans, popups,{" "}
<code className="text-[0.9rem] font-normal"> <code className="text-[0.9rem] font-normal">
color: <span style={{ color: "#32cd32" }}>limegreen</span> color: <span style={{ color: "#32cd32" }}>limegreen</span>
@ -148,3 +149,7 @@ _[April 2018](https://hungry-mayer-40e790.netlify.app/) ([view source](https://g
![March 2020](./images/2020_03.png) ![March 2020](./images/2020_03.png)
_[March 2020](https://quiet-truffle-92842d.netlify.app/) ([view source](https://github.com/jakejarvis/jarv.is-hugo))_ _[March 2020](https://quiet-truffle-92842d.netlify.app/) ([view source](https://github.com/jakejarvis/jarv.is-hugo))_
---
<Comments title="Previously on..." />

View File

@ -57,16 +57,16 @@ const Page = async () => {
<div className="row-auto grid w-full grid-cols-none gap-4 md:grid-cols-2"> <div className="row-auto grid w-full grid-cols-none gap-4 md:grid-cols-2">
{repos?.map((repo) => ( {repos?.map((repo) => (
<div key={repo!.name} className="border-ring/65 h-fit space-y-1.5 rounded-2xl border-1 px-4 py-3"> <div key={repo!.name} className="border-ring/65 h-fit space-y-1.5 rounded-2xl border-1 px-4 py-3 shadow-xs">
<Link href={repo!.url} className="inline-block text-base leading-relaxed font-semibold"> <Link href={repo!.url} className="inline-block text-base leading-relaxed font-semibold">
{repo!.name} {repo!.name}
</Link> </Link>
{repo!.description && <p className="text-foreground/85 text-sm leading-relaxed">{repo!.description}</p>} {repo!.description && <p className="text-foreground/85 text-sm leading-relaxed">{repo!.description}</p>}
<div className="flex flex-wrap space-x-4 *:inline-flex *:flex-nowrap *:items-center *:text-[0.825rem] *:leading-loose *:whitespace-nowrap"> <div className="flex flex-wrap gap-x-4 text-[0.825rem] leading-loose whitespace-nowrap">
{repo!.primaryLanguage && ( {repo!.primaryLanguage && (
<div className="text-muted-foreground space-x-2"> <div className="text-muted-foreground inline-flex flex-nowrap items-center gap-2">
{repo!.primaryLanguage.color && ( {repo!.primaryLanguage.color && (
<span <span
className="inline-block size-4 rounded-full" className="inline-block size-4 rounded-full"
@ -81,7 +81,7 @@ const Page = async () => {
<Link <Link
href={`${repo!.url}/stargazers`} href={`${repo!.url}/stargazers`}
title={`${Intl.NumberFormat(env.NEXT_PUBLIC_SITE_LOCALE).format(repo!.stargazerCount)} ${repo!.stargazerCount === 1 ? "star" : "stars"}`} title={`${Intl.NumberFormat(env.NEXT_PUBLIC_SITE_LOCALE).format(repo!.stargazerCount)} ${repo!.stargazerCount === 1 ? "star" : "stars"}`}
className="text-muted-foreground hover:text-primary space-x-2 hover:no-underline" className="text-muted-foreground hover:text-primary inline-flex flex-nowrap items-center gap-2 hover:no-underline"
> >
<StarIcon className="inline-block size-4 shrink-0" /> <StarIcon className="inline-block size-4 shrink-0" />
<span>{Intl.NumberFormat(env.NEXT_PUBLIC_SITE_LOCALE).format(repo!.stargazerCount)}</span> <span>{Intl.NumberFormat(env.NEXT_PUBLIC_SITE_LOCALE).format(repo!.stargazerCount)}</span>
@ -92,7 +92,7 @@ const Page = async () => {
<Link <Link
href={`${repo!.url}/network/members`} href={`${repo!.url}/network/members`}
title={`${Intl.NumberFormat(env.NEXT_PUBLIC_SITE_LOCALE).format(repo!.forkCount)} ${repo!.forkCount === 1 ? "fork" : "forks"}`} title={`${Intl.NumberFormat(env.NEXT_PUBLIC_SITE_LOCALE).format(repo!.forkCount)} ${repo!.forkCount === 1 ? "fork" : "forks"}`}
className="text-muted-foreground hover:text-primary space-x-2 hover:no-underline" className="text-muted-foreground hover:text-primary inline-flex flex-nowrap items-center gap-2 hover:no-underline"
> >
<GitForkIcon className="inline-block size-4" /> <GitForkIcon className="inline-block size-4" />
<span>{Intl.NumberFormat(env.NEXT_PUBLIC_SITE_LOCALE).format(repo!.forkCount)}</span> <span>{Intl.NumberFormat(env.NEXT_PUBLIC_SITE_LOCALE).format(repo!.forkCount)}</span>

View File

@ -48,7 +48,7 @@ const Calendar = ({
<Tooltip> <Tooltip>
<TooltipTrigger asChild>{block}</TooltipTrigger> <TooltipTrigger asChild>{block}</TooltipTrigger>
<TooltipContent> <TooltipContent>
<span className="text-xs font-medium">{`${activity.count === 0 ? "No" : activity.count} ${noun}${activity.count === 1 ? "" : "s"} on ${format(activity.date, "MMMM do")}`}</span> <span className="text-[0.825rem] font-medium">{`${activity.count === 0 ? "No" : activity.count} ${noun}${activity.count === 1 ? "" : "s"} on ${format(activity.date, "MMMM do")}`}</span>
</TooltipContent> </TooltipContent>
</Tooltip> </Tooltip>
)} )}

View File

@ -1,6 +1,6 @@
import { codeToHtml } from "shiki"; import { codeToHtml } from "shiki";
import reactToText from "react-to-text"; import reactToText from "react-to-text";
import { CodeIcon } from "lucide-react"; import { CodeIcon, TerminalIcon } from "lucide-react";
import CopyButton from "@/components/copy-button"; import CopyButton from "@/components/copy-button";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import type { ComponentProps, ComponentPropsWithoutRef } from "react"; import type { ComponentProps, ComponentPropsWithoutRef } from "react";
@ -38,37 +38,11 @@ const CodeBlock = async ({
}, },
}); });
const getFullLang = (lang: string) => {
// replace the file extension with the full language name when it makes sense to
switch (lang.toLowerCase()) {
case "js":
return "JavaScript";
case "jsx":
return "JavaScript (JSX)";
case "ts":
return "TypeScript";
case "tsx":
return "TypeScript (JSX)";
case "sh":
case "bash":
case "zsh":
return "Shell";
case "py":
return "Python";
case "md":
return "Markdown";
case "mdx":
return "Markdown (MDX)";
default:
return lang;
}
};
return ( return (
<div className={cn("bg-muted/35 relative isolate rounded-lg border-2 font-mono", className)}> <div className={cn("bg-muted/35 relative isolate rounded-lg border-2 font-mono shadow", className)}>
<div <div
className={cn( className={cn(
"grid max-h-[500px] w-full overflow-x-auto p-4 **:bg-transparent! data-language:pt-9 md:max-h-[650px] dark:**:text-[var(--shiki-dark)]! [&_pre]:whitespace-normal", "grid max-h-[500px] w-full overflow-x-auto overscroll-x-none p-4 **:bg-transparent! data-language:pt-10 md:max-h-[650px] dark:**:text-[var(--shiki-dark)]! [&_pre]:whitespace-normal",
"[&_.line]:inline-block [&_.line]:min-w-full [&_.line]:py-1 [&_.line]:leading-none [&_.line]:whitespace-pre [&_.line]:after:hidden", "[&_.line]:inline-block [&_.line]:min-w-full [&_.line]:py-1 [&_.line]:leading-none [&_.line]:whitespace-pre [&_.line]:after:hidden",
"data-line-numbers:[&_.line]:before:text-muted-foreground data-line-numbers:[counter-reset:line] data-line-numbers:[&_.line]:[counter-increment:line] data-line-numbers:[&_.line]:before:mr-5 data-line-numbers:[&_.line]:before:inline-block data-line-numbers:[&_.line]:before:w-5 data-line-numbers:[&_.line]:before:text-right data-line-numbers:[&_.line]:before:content-[counter(line)]" "data-line-numbers:[&_.line]:before:text-muted-foreground data-line-numbers:[counter-reset:line] data-line-numbers:[&_.line]:[counter-increment:line] data-line-numbers:[&_.line]:before:mr-5 data-line-numbers:[&_.line]:before:inline-block data-line-numbers:[&_.line]:before:w-5 data-line-numbers:[&_.line]:before:text-right data-line-numbers:[&_.line]:before:content-[counter(line)]"
)} )}
@ -77,15 +51,24 @@ const CodeBlock = async ({
dangerouslySetInnerHTML={{ __html: codeHighlighted }} dangerouslySetInnerHTML={{ __html: codeHighlighted }}
/> />
{lang && ( {lang && (
<span className="text-foreground/75 bg-muted/40 absolute top-0 left-0 flex items-center rounded-tl-md rounded-br-lg border-r-2 border-b-2 py-[5px] pr-[10px] font-mono text-xs font-medium tracking-wide uppercase backdrop-blur-xs select-none"> <span className="[&_svg]:stroke-primary/90 text-foreground/75 bg-muted/40 absolute top-0 left-0 z-10 flex items-center gap-[8px] rounded-tl-md rounded-br-lg border-r-2 border-b-2 px-[10px] py-[5px] font-mono text-xs font-medium tracking-wide uppercase backdrop-blur-xs select-none [&_svg]:size-[14px] [&_svg]:shrink-0">
<CodeIcon className="stroke-primary/90 mr-[8px] ml-[10px] inline-block size-[14px]" /> {["sh", "bash", "zsh"].includes(lang) ? (
<span>{getFullLang(lang)}</span> <>
<TerminalIcon />
<span>Shell</span>
</>
) : (
<>
<CodeIcon />
<span>{lang}</span>
</>
)}
</span> </span>
)} )}
{showCopyButton && ( {showCopyButton && (
<CopyButton <CopyButton
source={codeString} source={codeString}
className="text-foreground/75 hover:text-primary bg-muted/40 absolute top-0 right-0 size-10 rounded-tr-md rounded-bl-lg border-b-2 border-l-2 p-0 backdrop-blur-xs select-none [&_svg]:my-auto [&_svg]:inline-block [&_svg]:size-4.5 [&_svg]:align-text-bottom" className="text-foreground/75 hover:text-primary bg-muted/40 absolute top-0 right-0 z-10 size-10 rounded-tr-md rounded-bl-lg border-b-2 border-l-2 p-0 backdrop-blur-xs select-none [&_svg]:my-auto [&_svg]:inline-block [&_svg]:size-4.5 [&_svg]:align-text-bottom"
/> />
)} )}
</div> </div>

View File

@ -13,7 +13,7 @@ const HeadingAnchor = ({ id, title, className }: { id: string; title: string; cl
aria-hidden="true" aria-hidden="true"
tabIndex={-1} tabIndex={-1}
> >
<LinkIcon className="inline-block size-4 align-baseline" /> <LinkIcon className="inline-block size-[0.75em] align-baseline" />
<span className="sr-only">Permalink to &ldquo;{reactToText(title)}&rdquo;</span> <span className="sr-only">Permalink to &ldquo;{reactToText(title)}&rdquo;</span>
</a> </a>
); );

View File

@ -25,7 +25,7 @@ const Footer = ({ className, ...rest }: ComponentPropsWithoutRef<"footer">) => {
<div> <div>
Made with{" "} Made with{" "}
<HeartIcon className="animate-heartbeat stroke-destructive fill-destructive mx-0.5 inline size-4 align-text-top" />{" "} <HeartIcon className="animate-heartbeat stroke-destructive fill-destructive mx-[1px] inline size-4 align-text-top" />{" "}
and{" "} and{" "}
<Link <Link
href="https://nextjs.org/" href="https://nextjs.org/"
@ -39,7 +39,7 @@ const Footer = ({ className, ...rest }: ComponentPropsWithoutRef<"footer">) => {
stroke="currentColor" stroke="currentColor"
strokeWidth="0" strokeWidth="0"
viewBox="0 0 24 24" viewBox="0 0 24 24"
className="mx-0.5 inline size-4 align-text-top" className="mx-[1px] inline size-4 align-text-top"
> >
<path d="M18.665 21.978C16.758 23.255 14.465 24 12 24 5.377 24 0 18.623 0 12S5.377 0 12 0s12 5.377 12 12c0 3.583-1.574 6.801-4.067 9.001L9.219 7.2H7.2v9.596h1.615V9.251l9.85 12.727Zm-3.332-8.533 1.6 2.061V7.2h-1.6v6.245Z" /> <path d="M18.665 21.978C16.758 23.255 14.465 24 12 24 5.377 24 0 18.623 0 12S5.377 0 12 0s12 5.377 12 12c0 3.583-1.574 6.801-4.067 9.001L9.219 7.2H7.2v9.596h1.615V9.251l9.85 12.727Zm-3.332-8.533 1.6 2.061V7.2h-1.6v6.245Z" />
</svg> </svg>

View File

@ -31,7 +31,7 @@ const Header = ({ className, ...rest }: ComponentPropsWithoutRef<"header">) => {
</span> </span>
</Link> </Link>
<Menu className="ml-6 w-full max-w-64 sm:ml-4 sm:max-w-96 md:ml-0 md:max-w-none" /> <Menu className="w-full max-w-64 sm:max-w-96 md:ml-0 md:max-w-none" />
</header> </header>
); );
}; };

View File

@ -13,7 +13,7 @@ const Menu = ({ className, ...rest }: ComponentPropsWithoutRef<"ul">) => {
return ( return (
<ul <ul
className={cn( className={cn(
"flex max-w-2/3 flex-row justify-between md:max-w-none md:justify-end md:space-x-4 max-sm:[&>li]:first-of-type:hidden", "flex max-w-2/3 flex-row justify-between md:max-w-none md:justify-end md:gap-4 max-sm:[&>li]:first-of-type:hidden",
className className
)} )}
{...rest} {...rest}

View File

@ -1,8 +1,8 @@
import Button from "@/components/ui/button"; import Button from "@/components/ui/button";
const SKIP_NAV_ID = "skip-nav"; export const SKIP_NAV_ID = "skip-nav";
export const SkipNavLink = () => { const SkipNavButton = () => {
return ( return (
<Button <Button
asChild asChild
@ -14,8 +14,4 @@ export const SkipNavLink = () => {
); );
}; };
export const SkipNavTarget = () => { export default SkipNavButton;
return <div id={SKIP_NAV_ID} />;
};
export default SkipNavLink;

View File

@ -35,13 +35,13 @@ const TooltipContent = ({
data-slot="tooltip-content" data-slot="tooltip-content"
sideOffset={sideOffset} sideOffset={sideOffset}
className={cn( className={cn(
"animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md bg-black px-3 py-1.5 text-xs text-balance text-white/90 shadow-sm select-none", "animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md bg-black px-3 py-1.5 text-xs text-balance text-white/90 shadow select-none",
className className
)} )}
{...rest} {...rest}
> >
{children} {children}
<TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-black fill-black shadow-sm" /> <TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-black fill-black shadow" />
</TooltipPrimitive.Content> </TooltipPrimitive.Content>
</TooltipPrimitive.Portal> </TooltipPrimitive.Portal>
); );

View File

@ -41,15 +41,16 @@ export const useMDXComponents = (components: MDXComponents): MDXComponents => {
<figcaption className={cn("text-muted-foreground mt-3.5 text-[0.875em] leading-snug", className)} {...rest} /> <figcaption className={cn("text-muted-foreground mt-3.5 text-[0.875em] leading-snug", className)} {...rest} />
), ),
blockquote: ({ className, ...rest }) => ( blockquote: ({ className, ...rest }) => (
<blockquote className={cn("border-border text-muted-foreground mt-6 border-l-4 pl-4", className)} {...rest} /> <blockquote className={cn("text-muted-foreground mt-6 border-l-4 pl-4", className)} {...rest} />
), ),
h1: ({ className, id, children, ...rest }) => ( h1: ({ className, id, children, ...rest }) => (
<h1 <h1
className={cn( className={cn(
"group mt-6 mb-4 scroll-m-4 text-3xl leading-snug font-extrabold md:text-4xl [&_strong]:font-black [&+*]:mt-0", "group mt-6 mb-4 scroll-mt-4 text-3xl leading-snug font-extrabold md:text-4xl [&_strong]:font-black [&+*]:mt-0",
className className
)} )}
id={id} id={id}
tabIndex={-1}
{...rest} {...rest}
> >
{children} {children}
@ -59,10 +60,11 @@ export const useMDXComponents = (components: MDXComponents): MDXComponents => {
h2: ({ className, id, children, ...rest }) => ( h2: ({ className, id, children, ...rest }) => (
<h2 <h2
className={cn( className={cn(
"group mt-6 mb-4 scroll-m-4 text-xl leading-snug font-bold first:mt-0 md:text-2xl [&_code]:text-[0.875em] [&_strong]:font-extrabold [&+*]:mt-0", "group mt-6 mb-4 scroll-mt-4 text-xl leading-snug font-bold first:mt-0 md:text-2xl [&_code]:text-[0.875em] [&_strong]:font-extrabold [&+*]:mt-0",
className className
)} )}
id={id} id={id}
tabIndex={-1}
{...rest} {...rest}
> >
{children} {children}
@ -72,10 +74,11 @@ export const useMDXComponents = (components: MDXComponents): MDXComponents => {
h3: ({ className, id, children, ...rest }) => ( h3: ({ className, id, children, ...rest }) => (
<h3 <h3
className={cn( className={cn(
"group mt-6 mb-4 scroll-m-4 text-lg leading-relaxed font-semibold md:text-xl [&_code]:text-[0.9em] [&_strong]:font-bold [&+*]:mt-0", "group mt-6 mb-4 scroll-mt-4 text-lg leading-relaxed font-semibold md:text-xl [&_code]:text-[0.9em] [&_strong]:font-bold [&+*]:mt-0",
className className
)} )}
id={id} id={id}
tabIndex={-1}
{...rest} {...rest}
> >
{children} {children}
@ -84,12 +87,19 @@ export const useMDXComponents = (components: MDXComponents): MDXComponents => {
), ),
h4: ({ className, ...rest }) => ( h4: ({ className, ...rest }) => (
<h4 <h4
className={cn("mt-6 mb-2 scroll-m-4 leading-normal font-semibold [&_strong]:font-bold [&+*]:mt-0", className)} className={cn(
"mt-6 mb-2 scroll-mt-4 text-base leading-normal font-semibold [&_strong]:font-bold [&+*]:mt-0",
className
)}
{...rest} {...rest}
/> />
), ),
h5: ({ className, ...rest }) => <h5 className={cn("mt-6 mb-2 scroll-m-4 leading-normal", className)} {...rest} />, h5: ({ className, ...rest }) => (
h6: ({ className, ...rest }) => <h6 className={cn("mt-6 mb-2 scroll-m-4 leading-normal", className)} {...rest} />, <h5 className={cn("mt-6 mb-2 scroll-mt-4 text-base leading-normal font-medium", className)} {...rest} />
),
h6: ({ className, ...rest }) => (
<h6 className={cn("mt-6 mb-2 scroll-mt-4 text-sm leading-normal font-normal", className)} {...rest} />
),
ul: ({ className, ...rest }) => <ul className={cn("my-5 list-disc pl-7 [&>li]:pl-1.5", className)} {...rest} />, ul: ({ className, ...rest }) => <ul className={cn("my-5 list-disc pl-7 [&>li]:pl-1.5", className)} {...rest} />,
ol: ({ className, ...rest }) => <ol className={cn("my-5 list-decimal pl-7 [&>li]:pl-1.5", className)} {...rest} />, ol: ({ className, ...rest }) => <ol className={cn("my-5 list-decimal pl-7 [&>li]:pl-1.5", className)} {...rest} />,
li: ({ className, ...rest }) => ( li: ({ className, ...rest }) => (
@ -102,7 +112,7 @@ export const useMDXComponents = (components: MDXComponents): MDXComponents => {
/> />
), ),
hr: ({ className, ...rest }) => ( hr: ({ className, ...rest }) => (
<hr className={cn("border-border mx-auto my-6 w-11/12 border-t-2 [&+*]:mt-0", className)} {...rest} /> <hr className={cn("mx-auto my-6 w-11/12 border-t-2 [&+*]:mt-0", className)} {...rest} />
), ),
// third-party embeds: // third-party embeds:

View File

@ -36,15 +36,6 @@ const nextConfig = {
}, },
productionBrowserSourceMaps: true, productionBrowserSourceMaps: true,
experimental: { experimental: {
optimizePackageImports: [
"date-fns",
"@date-fns/tz",
"@date-fns/utc",
"lucide-react",
"@radix-ui/react-label",
"@radix-ui/react-slot",
"@radix-ui/react-tooltip",
],
reactCompiler: true, reactCompiler: true,
ppr: "incremental", ppr: "incremental",
dynamicOnHover: true, dynamicOnHover: true,

View File

@ -44,12 +44,10 @@
"html-entities": "^2.6.0", "html-entities": "^2.6.0",
"lucide-react": "0.508.0", "lucide-react": "0.508.0",
"next": "15.4.0-canary.26", "next": "15.4.0-canary.26",
"prop-types": "^15.8.1",
"react": "19.1.0", "react": "19.1.0",
"react-activity-calendar": "^2.7.11", "react-activity-calendar": "^2.7.11",
"react-countup": "^6.5.3", "react-countup": "^6.5.3",
"react-dom": "19.1.0", "react-dom": "19.1.0",
"react-is": "19.1.0",
"react-lite-youtube-embed": "^2.5.1", "react-lite-youtube-embed": "^2.5.1",
"react-schemaorg": "^2.0.0", "react-schemaorg": "^2.0.0",
"react-timeago": "^8.2.0", "react-timeago": "^8.2.0",
@ -86,11 +84,9 @@
"@jakejarvis/eslint-config": "^4.0.7", "@jakejarvis/eslint-config": "^4.0.7",
"@tailwindcss/postcss": "^4.1.5", "@tailwindcss/postcss": "^4.1.5",
"@types/mdx": "^2.0.13", "@types/mdx": "^2.0.13",
"@types/node": "^22.15.15", "@types/node": "^22.15.16",
"@types/prop-types": "^15.7.14", "@types/react": "19.1.3",
"@types/react": "^19.1.3", "@types/react-dom": "19.1.3",
"@types/react-dom": "^19.1.3",
"@types/react-is": "^19.0.0",
"babel-plugin-react-compiler": "19.0.0-beta-af1b7da-20250417", "babel-plugin-react-compiler": "19.0.0-beta-af1b7da-20250417",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"eslint": "^9.26.0", "eslint": "^9.26.0",

47
pnpm-lock.yaml generated
View File

@ -86,9 +86,6 @@ importers:
next: next:
specifier: 15.4.0-canary.26 specifier: 15.4.0-canary.26
version: 15.4.0-canary.26(@babel/core@7.26.10)(babel-plugin-react-compiler@19.0.0-beta-af1b7da-20250417)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) version: 15.4.0-canary.26(@babel/core@7.26.10)(babel-plugin-react-compiler@19.0.0-beta-af1b7da-20250417)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
prop-types:
specifier: ^15.8.1
version: 15.8.1
react: react:
specifier: 19.1.0 specifier: 19.1.0
version: 19.1.0 version: 19.1.0
@ -101,9 +98,6 @@ importers:
react-dom: react-dom:
specifier: 19.1.0 specifier: 19.1.0
version: 19.1.0(react@19.1.0) version: 19.1.0(react@19.1.0)
react-is:
specifier: 19.1.0
version: 19.1.0
react-lite-youtube-embed: react-lite-youtube-embed:
specifier: ^2.5.1 specifier: ^2.5.1
version: 2.5.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0) version: 2.5.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
@ -208,20 +202,14 @@ importers:
specifier: ^2.0.13 specifier: ^2.0.13
version: 2.0.13 version: 2.0.13
'@types/node': '@types/node':
specifier: ^22.15.15 specifier: ^22.15.16
version: 22.15.15 version: 22.15.16
'@types/prop-types':
specifier: ^15.7.14
version: 15.7.14
'@types/react': '@types/react':
specifier: ^19.1.3 specifier: 19.1.3
version: 19.1.3 version: 19.1.3
'@types/react-dom': '@types/react-dom':
specifier: ^19.1.3 specifier: 19.1.3
version: 19.1.3(@types/react@19.1.3) version: 19.1.3(@types/react@19.1.3)
'@types/react-is':
specifier: ^19.0.0
version: 19.0.0
babel-plugin-react-compiler: babel-plugin-react-compiler:
specifier: 19.0.0-beta-af1b7da-20250417 specifier: 19.0.0-beta-af1b7da-20250417
version: 19.0.0-beta-af1b7da-20250417 version: 19.0.0-beta-af1b7da-20250417
@ -1242,20 +1230,14 @@ packages:
'@types/nlcst@2.0.3': '@types/nlcst@2.0.3':
resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==} resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==}
'@types/node@22.15.15': '@types/node@22.15.16':
resolution: {integrity: sha512-R5muMcZob3/Jjchn5LcO8jdKwSCbzqmPB6ruBxMcf9kbxtniZHP327s6C37iOfuw8mbKK3cAQa7sEl7afLrQ8A==} resolution: {integrity: sha512-3pr+KjwpVujqWqOKT8mNR+rd09FqhBLwg+5L/4t0cNYBzm/yEiYGCxWttjaPBsLtAo+WFNoXzGJfolM1JuRXoA==}
'@types/prop-types@15.7.14':
resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==}
'@types/react-dom@19.1.3': '@types/react-dom@19.1.3':
resolution: {integrity: sha512-rJXC08OG0h3W6wDMFxQrZF00Kq6qQvw0djHRdzl3U5DnIERz0MRce3WVc7IS6JYBwtaP/DwYtRRjVlvivNveKg==} resolution: {integrity: sha512-rJXC08OG0h3W6wDMFxQrZF00Kq6qQvw0djHRdzl3U5DnIERz0MRce3WVc7IS6JYBwtaP/DwYtRRjVlvivNveKg==}
peerDependencies: peerDependencies:
'@types/react': ^19.0.0 '@types/react': ^19.0.0
'@types/react-is@19.0.0':
resolution: {integrity: sha512-71dSZeeJ0t3aoPyY9x6i+JNSvg5m9EF2i2OlSZI5QoJuI8Ocgor610i+4A10TQmURR+0vLwcVCEYFpXdzM1Biw==}
'@types/react@19.1.3': '@types/react@19.1.3':
resolution: {integrity: sha512-dLWQ+Z0CkIvK1J8+wrDPwGxEYFA4RAyHoZPxHVGspYmFVnwGSNT24cGIhFJrtfRnWVuW8X7NO52gCXmhkVUWGQ==} resolution: {integrity: sha512-dLWQ+Z0CkIvK1J8+wrDPwGxEYFA4RAyHoZPxHVGspYmFVnwGSNT24cGIhFJrtfRnWVuW8X7NO52gCXmhkVUWGQ==}
@ -3476,9 +3458,6 @@ packages:
react-is@16.13.1: react-is@16.13.1:
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
react-is@19.1.0:
resolution: {integrity: sha512-Oe56aUPnkHyyDxxkvqtd7KkdQP5uIUfHxd5XTb3wE9d/kRnZLmKbDB0GWk919tdQ+mxxPtG6EAs6RMT6i1qtHg==}
react-lite-youtube-embed@2.5.1: react-lite-youtube-embed@2.5.1:
resolution: {integrity: sha512-qH/0RumywPtzSx5SmWX/cUGvB3mSB7zMx3VrDe1UwyCEQ0SX785xnjRAodEel1pu3A3EhZyzSjwmLpfcaUN6KQ==} resolution: {integrity: sha512-qH/0RumywPtzSx5SmWX/cUGvB3mSB7zMx3VrDe1UwyCEQ0SX785xnjRAodEel1pu3A3EhZyzSjwmLpfcaUN6KQ==}
peerDependencies: peerDependencies:
@ -5221,7 +5200,7 @@ snapshots:
'@types/concat-stream@2.0.3': '@types/concat-stream@2.0.3':
dependencies: dependencies:
'@types/node': 22.15.15 '@types/node': 22.15.16
'@types/debug@4.1.12': '@types/debug@4.1.12':
dependencies: dependencies:
@ -5257,20 +5236,14 @@ snapshots:
dependencies: dependencies:
'@types/unist': 3.0.3 '@types/unist': 3.0.3
'@types/node@22.15.15': '@types/node@22.15.16':
dependencies: dependencies:
undici-types: 6.21.0 undici-types: 6.21.0
'@types/prop-types@15.7.14': {}
'@types/react-dom@19.1.3(@types/react@19.1.3)': '@types/react-dom@19.1.3(@types/react@19.1.3)':
dependencies: dependencies:
'@types/react': 19.1.3 '@types/react': 19.1.3
'@types/react-is@19.0.0':
dependencies:
'@types/react': 19.1.3
'@types/react@19.1.3': '@types/react@19.1.3':
dependencies: dependencies:
csstype: 3.1.3 csstype: 3.1.3
@ -7977,8 +7950,6 @@ snapshots:
react-is@16.13.1: {} react-is@16.13.1: {}
react-is@19.1.0: {}
react-lite-youtube-embed@2.5.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0): react-lite-youtube-embed@2.5.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0):
dependencies: dependencies:
react: 19.1.0 react: 19.1.0
@ -8799,7 +8770,7 @@ snapshots:
'@types/concat-stream': 2.0.3 '@types/concat-stream': 2.0.3
'@types/debug': 4.1.12 '@types/debug': 4.1.12
'@types/is-empty': 1.2.3 '@types/is-empty': 1.2.3
'@types/node': 22.15.15 '@types/node': 22.15.16
'@types/unist': 3.0.3 '@types/unist': 3.0.3
concat-stream: 2.0.0 concat-stream: 2.0.0
debug: 4.4.0 debug: 4.4.0

View File

@ -16,9 +16,10 @@
"matchPackageNames": [ "matchPackageNames": [
"react", "react",
"react-dom", "react-dom",
"react-is",
"babel-plugin-react-compiler", "babel-plugin-react-compiler",
"eslint-plugin-react-compiler" "eslint-plugin-react-compiler",
"@types/react",
"@types/react-dom"
], ],
"groupName": "react", "groupName": "react",
"rangeStrategy": "pin" "rangeStrategy": "pin"
@ -70,10 +71,6 @@
"ignoreDeps": [ "ignoreDeps": [
"@jakejarvis/eslint-config", "@jakejarvis/eslint-config",
"@types/node", "@types/node",
"@types/react",
"@types/react-dom",
"@types/react-is",
"@types/prop-types",
"lucide-react" "lucide-react"
] ]
} }