mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2025-04-26 15:28:28 -04:00
bump next to 13.5
This commit is contained in:
parent
1d8c2eab99
commit
893db7e951
@ -1 +1 @@
|
|||||||
18.17.1
|
18.18.0
|
||||||
|
@ -11,9 +11,9 @@ I keep an ongoing list of [post ideas](https://github.com/jakejarvis/jarv.is/iss
|
|||||||
|
|
||||||
## 🕹️ Getting Started
|
## 🕹️ Getting Started
|
||||||
|
|
||||||
Run `pnpm install` to install the necessary dependencies and `pnpm run dev` to start the local server, and then open [http://localhost:3000/](http://localhost:3000/). Pages will live-refresh when source files are changed. ([pnpm is required!](https://pnpm.io/installation))
|
Run `pnpm install` to install the necessary dependencies and `pnpm dev` to start the local server, and then open [http://localhost:3000/](http://localhost:3000/). Pages will live-refresh when source files are changed.
|
||||||
|
|
||||||
Most production steps are handled [automatically by Vercel](https://vercel.com/docs/concepts/next.js/overview#supported-next.js-features), but running `pnpm build` locally will still generate an unoptimized, less-than-ideal static version.
|
Most production steps are handled [automatically by Vercel](https://vercel.com/docs/frameworks/nextjs), but running `pnpm build` locally will still generate an unoptimized, less-than-ideal static version which can be served via `pnpm start`.
|
||||||
|
|
||||||
**⚡ Bonus tip:** [Volta](https://volta.sh/), a magical, blazing-fast alternative to [nvm](https://github.com/nvm-sh/nvm), is used to pin the exact Node.js version used for development. It's completely optional but I highly recommend it in general!
|
**⚡ Bonus tip:** [Volta](https://volta.sh/), a magical, blazing-fast alternative to [nvm](https://github.com/nvm-sh/nvm), is used to pin the exact Node.js version used for development. It's completely optional but I highly recommend it in general!
|
||||||
|
|
||||||
|
@ -3,7 +3,8 @@ import { Formik, Form, Field } from "formik";
|
|||||||
import TextareaAutosize from "react-textarea-autosize";
|
import TextareaAutosize from "react-textarea-autosize";
|
||||||
import Link from "../Link";
|
import Link from "../Link";
|
||||||
import Captcha from "../Captcha";
|
import Captcha from "../Captcha";
|
||||||
import { CheckOcticon, XOcticon, MarkdownIcon } from "../Icons";
|
import { GoCheck, GoX } from "react-icons/go";
|
||||||
|
import { SiMarkdown } from "react-icons/si";
|
||||||
import { styled, theme, css } from "../../lib/styles/stitches.config";
|
import { styled, theme, css } from "../../lib/styles/stitches.config";
|
||||||
import type { FormikHelpers, FormikProps, FieldInputProps, FieldMetaProps } from "formik";
|
import type { FormikHelpers, FormikProps, FieldInputProps, FieldMetaProps } from "formik";
|
||||||
|
|
||||||
@ -47,8 +48,7 @@ const MarkdownTip = styled("div", {
|
|||||||
lineHeight: 1.75,
|
lineHeight: 1.75,
|
||||||
});
|
});
|
||||||
|
|
||||||
const MarkdownTipIcon = styled(MarkdownIcon, {
|
const MarkdownTipIcon = styled(SiMarkdown, {
|
||||||
fill: "currentColor",
|
|
||||||
width: "1.25em",
|
width: "1.25em",
|
||||||
height: "1.25em",
|
height: "1.25em",
|
||||||
verticalAlign: "-0.25em",
|
verticalAlign: "-0.25em",
|
||||||
@ -288,7 +288,7 @@ const ContactForm = ({ className }: ContactFormProps) => {
|
|||||||
</SubmitButton>
|
</SubmitButton>
|
||||||
|
|
||||||
<Result status={success ? "success" : "error"} hidden={!submitted || !feedback || isSubmitting}>
|
<Result status={success ? "success" : "error"} hidden={!submitted || !feedback || isSubmitting}>
|
||||||
<ResultIcon as={success ? CheckOcticon : XOcticon} /> {feedback}
|
<ResultIcon as={success ? GoCheck : GoX} /> {feedback}
|
||||||
</Result>
|
</Result>
|
||||||
</ActionRow>
|
</ActionRow>
|
||||||
</Form>
|
</Form>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { forwardRef, useState, useEffect } from "react";
|
import { forwardRef, useState, useEffect } from "react";
|
||||||
import innerText from "react-innertext";
|
import innerText from "react-innertext";
|
||||||
import copy from "copy-to-clipboard";
|
import copy from "copy-to-clipboard";
|
||||||
import { ClipboardOcticon, CheckOcticon } from "../Icons";
|
import { FiClipboard, FiCheck } from "react-icons/fi";
|
||||||
import { styled, theme } from "../../lib/styles/stitches.config";
|
import { styled, theme } from "../../lib/styles/stitches.config";
|
||||||
import type { ReactNode, Ref, ComponentPropsWithoutRef, ElementRef, MouseEventHandler } from "react";
|
import type { ReactNode, Ref, ComponentPropsWithoutRef, ElementRef, MouseEventHandler } from "react";
|
||||||
|
|
||||||
@ -29,7 +29,6 @@ const Icon = styled("svg", {
|
|||||||
width: "1.25em",
|
width: "1.25em",
|
||||||
height: "1.25em",
|
height: "1.25em",
|
||||||
verticalAlign: "-0.3em",
|
verticalAlign: "-0.3em",
|
||||||
fill: "currentColor",
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export type CopyButtonProps = ComponentPropsWithoutRef<typeof Button> & {
|
export type CopyButtonProps = ComponentPropsWithoutRef<typeof Button> & {
|
||||||
@ -77,7 +76,7 @@ const CopyButton = ({ source, timeout = 2000, ...rest }: CopyButtonProps, ref: R
|
|||||||
copied={copied}
|
copied={copied}
|
||||||
{...rest}
|
{...rest}
|
||||||
>
|
>
|
||||||
<Icon as={copied ? CheckOcticon : ClipboardOcticon} />
|
<Icon as={copied ? FiCheck : FiClipboard} />
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import innerText from "react-innertext";
|
import innerText from "react-innertext";
|
||||||
import Image, { ImageProps } from "../Image";
|
import Image from "../Image";
|
||||||
import { styled, theme } from "../../lib/styles/stitches.config";
|
import { styled, theme } from "../../lib/styles/stitches.config";
|
||||||
import type { PropsWithChildren } from "react";
|
import type { PropsWithChildren, ComponentPropsWithoutRef } from "react";
|
||||||
|
|
||||||
const Wrapper = styled("figure", {
|
const Wrapper = styled("figure", {
|
||||||
margin: "1em auto",
|
margin: "1em auto",
|
||||||
@ -15,7 +15,7 @@ const Caption = styled("figcaption", {
|
|||||||
marginTop: "-0.4em",
|
marginTop: "-0.4em",
|
||||||
});
|
});
|
||||||
|
|
||||||
export type FigureProps = Omit<ImageProps, "alt"> &
|
export type FigureProps = Omit<ComponentPropsWithoutRef<typeof Image>, "alt"> &
|
||||||
PropsWithChildren<{
|
PropsWithChildren<{
|
||||||
alt?: string; // becomes optional -- pulled from plaintext-ified caption if missing
|
alt?: string; // becomes optional -- pulled from plaintext-ified caption if missing
|
||||||
}>;
|
}>;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import Link from "../Link";
|
import Link from "../Link";
|
||||||
import { HeartIcon, NextjsLogo } from "../Icons";
|
import { GoHeartFill } from "react-icons/go";
|
||||||
|
import { SiNextdotjs } from "react-icons/si";
|
||||||
import { styled, theme, keyframes } from "../../lib/styles/stitches.config";
|
import { styled, theme, keyframes } from "../../lib/styles/stitches.config";
|
||||||
import * as config from "../../lib/config";
|
import * as config from "../../lib/config";
|
||||||
import type { ComponentPropsWithoutRef } from "react";
|
import type { ComponentPropsWithoutRef } from "react";
|
||||||
@ -37,27 +38,11 @@ const PlainLink = styled(Link, {
|
|||||||
color: theme.colors.mediumDark,
|
color: theme.colors.mediumDark,
|
||||||
});
|
});
|
||||||
|
|
||||||
const NextjsLink = styled(PlainLink, {
|
|
||||||
"&:hover, &:focus-visible": {
|
|
||||||
color: theme.colors.medium,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const ViewSourceLink = styled(PlainLink, {
|
|
||||||
paddingBottom: "2px",
|
|
||||||
borderBottom: `1px solid ${theme.colors.light}`,
|
|
||||||
|
|
||||||
"&:hover, &:focus-visible": {
|
|
||||||
borderColor: theme.colors.kindaLight,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const Icon = styled("svg", {
|
const Icon = styled("svg", {
|
||||||
width: "1.25em",
|
width: "1.25em",
|
||||||
height: "1.25em",
|
height: "1.25em",
|
||||||
verticalAlign: "-0.25em",
|
verticalAlign: "-0.25em",
|
||||||
margin: "0 0.075em",
|
margin: "0 0.075em",
|
||||||
fill: "currentColor",
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const Heart = styled("span", {
|
const Heart = styled("span", {
|
||||||
@ -99,20 +84,38 @@ const Footer = ({ ...rest }: FooterProps) => {
|
|||||||
<div>
|
<div>
|
||||||
Made with{" "}
|
Made with{" "}
|
||||||
<Heart title="Love">
|
<Heart title="Love">
|
||||||
<Icon as={HeartIcon} />
|
<Icon as={GoHeartFill} css={{ strokeWidth: 2 }} />
|
||||||
</Heart>{" "}
|
</Heart>{" "}
|
||||||
and{" "}
|
and{" "}
|
||||||
<NextjsLink href="https://nextjs.org/" title="Powered by Next.js" aria-label="Next.js" underline={false}>
|
<PlainLink
|
||||||
<Icon as={NextjsLogo} />
|
href="https://nextjs.org/"
|
||||||
</NextjsLink>
|
title="Powered by Next.js"
|
||||||
|
aria-label="Next.js"
|
||||||
|
underline={false}
|
||||||
|
css={{
|
||||||
|
"&:hover, &:focus-visible": {
|
||||||
|
color: theme.colors.medium,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Icon as={SiNextdotjs} />
|
||||||
|
</PlainLink>
|
||||||
.{" "}
|
.{" "}
|
||||||
<ViewSourceLink
|
<PlainLink
|
||||||
href={`https://github.com/${config.githubRepo}`}
|
href={`https://github.com/${config.githubRepo}`}
|
||||||
title="View Source on GitHub"
|
title="View Source on GitHub"
|
||||||
underline={false}
|
underline={false}
|
||||||
|
css={{
|
||||||
|
paddingBottom: "2px",
|
||||||
|
borderBottom: `1px solid ${theme.colors.light}`,
|
||||||
|
|
||||||
|
"&:hover, &:focus-visible": {
|
||||||
|
borderColor: theme.colors.kindaLight,
|
||||||
|
},
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
View source.
|
View source.
|
||||||
</ViewSourceLink>
|
</PlainLink>
|
||||||
</div>
|
</div>
|
||||||
</Row>
|
</Row>
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
|
@ -1,27 +1,17 @@
|
|||||||
import Link from "../Link";
|
import Link from "../Link";
|
||||||
import { LinkIcon } from "../Icons";
|
import { FiLink } from "react-icons/fi";
|
||||||
import { styled } from "../../lib/styles/stitches.config";
|
|
||||||
import type { ComponentPropsWithoutRef } from "react";
|
import type { ComponentPropsWithoutRef } from "react";
|
||||||
|
|
||||||
const AnchorLink = styled(Link, {
|
export type HeadingAnchorProps = Omit<ComponentPropsWithoutRef<typeof Link>, "href"> & {
|
||||||
lineHeight: 1,
|
|
||||||
});
|
|
||||||
|
|
||||||
const Icon = styled(LinkIcon, {
|
|
||||||
width: "0.8em",
|
|
||||||
height: "0.8em",
|
|
||||||
});
|
|
||||||
|
|
||||||
export type HeadingAnchorProps = Omit<ComponentPropsWithoutRef<typeof AnchorLink>, "href"> & {
|
|
||||||
id: string;
|
id: string;
|
||||||
title: string;
|
title: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const HeadingAnchor = ({ id, title, ...rest }: HeadingAnchorProps) => {
|
const HeadingAnchor = ({ id, title, ...rest }: HeadingAnchorProps) => {
|
||||||
return (
|
return (
|
||||||
<AnchorLink href={`#${id}`} title={`Jump to "${title}"`} aria-hidden underline={false} {...rest}>
|
<Link href={`#${id}`} title={`Jump to "${title}"`} aria-hidden underline={false} css={{ lineHeight: 1 }} {...rest}>
|
||||||
<Icon />
|
<FiLink size="0.8em" />
|
||||||
</AnchorLink>
|
</Link>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
// Icons from various packs, imported directly from the package's SVG files instead of their exports so they're all
|
|
||||||
// processed consistently via svgr/webpack into React components.
|
|
||||||
// NOTE: each package's path inside ./node_modules *must* be listed in svgr's webpack config in next.config.js.
|
|
||||||
|
|
||||||
// feather icons: https://feathericons.com/
|
|
||||||
export { default as ContactIcon } from "feather-icons/dist/icons/mail.svg";
|
|
||||||
export { default as DateIcon } from "feather-icons/dist/icons/calendar.svg";
|
|
||||||
export { default as EditIcon } from "feather-icons/dist/icons/edit.svg";
|
|
||||||
export { default as HomeIcon } from "feather-icons/dist/icons/home.svg";
|
|
||||||
export { default as LinkIcon } from "feather-icons/dist/icons/link.svg";
|
|
||||||
export { default as NotesIcon } from "feather-icons/dist/icons/edit-3.svg";
|
|
||||||
export { default as ProjectsIcon } from "feather-icons/dist/icons/code.svg";
|
|
||||||
export { default as TagIcon } from "feather-icons/dist/icons/tag.svg";
|
|
||||||
export { default as ViewsIcon } from "feather-icons/dist/icons/eye.svg";
|
|
||||||
|
|
||||||
// octicons: https://primer.style/octicons/
|
|
||||||
export { default as CheckOcticon } from "@primer/octicons/build/svg/check-16.svg";
|
|
||||||
export { default as ClipboardOcticon } from "@primer/octicons/build/svg/paste-16.svg";
|
|
||||||
export { default as ForkOcticon } from "@primer/octicons/build/svg/repo-forked-16.svg";
|
|
||||||
export { default as HeartIcon } from "@primer/octicons/build/svg/heart-fill-16.svg";
|
|
||||||
export { default as MarkdownIcon } from "@primer/octicons/build/svg/markdown-16.svg";
|
|
||||||
export { default as OctocatOcticon } from "@primer/octicons/build/svg/mark-github-16.svg";
|
|
||||||
export { default as StarOcticon } from "@primer/octicons/build/svg/star-16.svg";
|
|
||||||
export { default as XOcticon } from "@primer/octicons/build/svg/x-16.svg";
|
|
||||||
|
|
||||||
// simple icons: https://simpleicons.org/
|
|
||||||
export { default as NextjsLogo } from "simple-icons/icons/nextdotjs.svg";
|
|
||||||
export { default as Windows95Logo } from "simple-icons/icons/windows95.svg";
|
|
@ -1,5 +1,6 @@
|
|||||||
import Link from "../Link";
|
import Link from "../Link";
|
||||||
import { styled, theme } from "../../lib/styles/stitches.config";
|
import { styled, theme } from "../../lib/styles/stitches.config";
|
||||||
|
import type { IconType } from "react-icons";
|
||||||
|
|
||||||
const MenuLink = styled(Link, {
|
const MenuLink = styled(Link, {
|
||||||
display: "inline-block",
|
display: "inline-block",
|
||||||
@ -45,20 +46,17 @@ const Label = styled("span", {
|
|||||||
});
|
});
|
||||||
|
|
||||||
export type MenuItemProps = {
|
export type MenuItemProps = {
|
||||||
href?: string;
|
icon?: IconType;
|
||||||
text?: string;
|
text?: string;
|
||||||
|
href?: string;
|
||||||
current?: boolean;
|
current?: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
|
||||||
// `any` avoids conflicts with @svgr/webpack, see: node_modules/next/image-types/global.d.ts
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
icon: any;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const MenuItem = ({ icon: ItemIcon, href, text, current, className }: MenuItemProps) => {
|
const MenuItem = ({ icon, text, href, current, className }: MenuItemProps) => {
|
||||||
const linkContent = (
|
const item = (
|
||||||
<>
|
<>
|
||||||
<Icon as={ItemIcon} />
|
{icon && <Icon as={icon} />}
|
||||||
{text && <Label>{text}</Label>}
|
{text && <Label>{text}</Label>}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
@ -67,12 +65,12 @@ const MenuItem = ({ icon: ItemIcon, href, text, current, className }: MenuItemPr
|
|||||||
if (href) {
|
if (href) {
|
||||||
return (
|
return (
|
||||||
<MenuLink href={href} className={className} current={current} title={text} underline={false} aria-label={text}>
|
<MenuLink href={href} className={className} current={current} title={text} underline={false} aria-label={text}>
|
||||||
{linkContent}
|
{item}
|
||||||
</MenuLink>
|
</MenuLink>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return linkContent;
|
return item;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default MenuItem;
|
export default MenuItem;
|
||||||
|
@ -2,7 +2,7 @@ import Link from "../Link";
|
|||||||
import Time from "../Time";
|
import Time from "../Time";
|
||||||
import HitCounter from "../HitCounter";
|
import HitCounter from "../HitCounter";
|
||||||
import NoteTitle from "../NoteTitle";
|
import NoteTitle from "../NoteTitle";
|
||||||
import { DateIcon, TagIcon, EditIcon, ViewsIcon } from "../Icons";
|
import { FiCalendar, FiTag, FiEdit, FiEye } from "react-icons/fi";
|
||||||
import { styled, theme } from "../../lib/styles/stitches.config";
|
import { styled, theme } from "../../lib/styles/stitches.config";
|
||||||
import * as config from "../../lib/config";
|
import * as config from "../../lib/config";
|
||||||
import type { NoteFrontMatter } from "../../types";
|
import type { NoteFrontMatter } from "../../types";
|
||||||
@ -68,14 +68,14 @@ const NoteMeta = ({ slug, date, title, htmlTitle, tags }: NoteMetaProps) => {
|
|||||||
}}
|
}}
|
||||||
underline={false}
|
underline={false}
|
||||||
>
|
>
|
||||||
<Icon as={DateIcon} />
|
<Icon as={FiCalendar} />
|
||||||
<Time date={date} format="MMMM D, YYYY" />
|
<Time date={date} format="MMMM D, YYYY" />
|
||||||
</MetaLink>
|
</MetaLink>
|
||||||
</MetaItem>
|
</MetaItem>
|
||||||
|
|
||||||
{tags && (
|
{tags && (
|
||||||
<MetaItem>
|
<MetaItem>
|
||||||
<Icon as={TagIcon} />
|
<Icon as={FiTag} />
|
||||||
<TagsList>
|
<TagsList>
|
||||||
{tags.map((tag) => (
|
{tags.map((tag) => (
|
||||||
<Tag key={tag} title={tag} aria-label={`Tagged with ${tag}`}>
|
<Tag key={tag} title={tag} aria-label={`Tagged with ${tag}`}>
|
||||||
@ -92,7 +92,7 @@ const NoteMeta = ({ slug, date, title, htmlTitle, tags }: NoteMetaProps) => {
|
|||||||
title={`Edit "${title}" on GitHub`}
|
title={`Edit "${title}" on GitHub`}
|
||||||
underline={false}
|
underline={false}
|
||||||
>
|
>
|
||||||
<Icon as={EditIcon} />
|
<Icon as={FiEdit} />
|
||||||
<span>Improve This Post</span>
|
<span>Improve This Post</span>
|
||||||
</MetaLink>
|
</MetaLink>
|
||||||
</MetaItem>
|
</MetaItem>
|
||||||
@ -106,7 +106,7 @@ const NoteMeta = ({ slug, date, title, htmlTitle, tags }: NoteMetaProps) => {
|
|||||||
marginRight: 0,
|
marginRight: 0,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Icon as={ViewsIcon} />
|
<Icon as={FiEye} />
|
||||||
<HitCounter slug={`notes/${slug}`} />
|
<HitCounter slug={`notes/${slug}`} />
|
||||||
</MetaItem>
|
</MetaItem>
|
||||||
)}
|
)}
|
||||||
|
@ -18,23 +18,20 @@ const Title = styled("h1", {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const TitleLink = styled(Link, {
|
|
||||||
color: theme.colors.text,
|
|
||||||
});
|
|
||||||
|
|
||||||
export type NoteTitleProps = Pick<NoteFrontMatter, "slug" | "title" | "htmlTitle"> &
|
export type NoteTitleProps = Pick<NoteFrontMatter, "slug" | "title" | "htmlTitle"> &
|
||||||
ComponentPropsWithoutRef<typeof Title>;
|
ComponentPropsWithoutRef<typeof Title>;
|
||||||
|
|
||||||
const NoteTitle = ({ slug, title, htmlTitle, ...rest }: NoteTitleProps) => {
|
const NoteTitle = ({ slug, title, htmlTitle, ...rest }: NoteTitleProps) => {
|
||||||
return (
|
return (
|
||||||
<Title {...rest}>
|
<Title {...rest}>
|
||||||
<TitleLink
|
<Link
|
||||||
href={{
|
href={{
|
||||||
pathname: "/notes/[slug]/",
|
pathname: "/notes/[slug]/",
|
||||||
query: { slug },
|
query: { slug },
|
||||||
}}
|
}}
|
||||||
dangerouslySetInnerHTML={{ __html: htmlTitle || title }}
|
dangerouslySetInnerHTML={{ __html: htmlTitle || title }}
|
||||||
underline={false}
|
underline={false}
|
||||||
|
css={{ color: theme.colors.text }}
|
||||||
/>
|
/>
|
||||||
</Title>
|
</Title>
|
||||||
);
|
);
|
||||||
|
@ -1,33 +1,35 @@
|
|||||||
import Link from "../Link";
|
import Link from "../Link";
|
||||||
import { OctocatOcticon } from "../Icons";
|
import { SiGithub } from "react-icons/si";
|
||||||
import { styled, theme } from "../../lib/styles/stitches.config";
|
import { styled, theme } from "../../lib/styles/stitches.config";
|
||||||
import type { ComponentPropsWithoutRef } from "react";
|
import type { ComponentPropsWithoutRef } from "react";
|
||||||
|
|
||||||
const GitHubLink = styled(Link, {
|
const Octocat = styled(SiGithub, {
|
||||||
margin: "0 0.4em",
|
|
||||||
color: theme.colors.text,
|
|
||||||
|
|
||||||
"&:hover, &:focus-visible": {
|
|
||||||
color: theme.colors.link,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const Octocat = styled(OctocatOcticon, {
|
|
||||||
width: "1.2em",
|
width: "1.2em",
|
||||||
height: "1.2em",
|
height: "1.2em",
|
||||||
verticalAlign: "-0.2em",
|
verticalAlign: "-0.2em",
|
||||||
fill: "currentColor",
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export type OctocatLinkProps = Omit<ComponentPropsWithoutRef<typeof GitHubLink>, "href"> & {
|
export type OctocatLinkProps = Omit<ComponentPropsWithoutRef<typeof Link>, "href"> & {
|
||||||
repo: string;
|
repo: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const OctocatLink = ({ repo, className, ...rest }: OctocatLinkProps) => {
|
const OctocatLink = ({ repo, className, ...rest }: OctocatLinkProps) => {
|
||||||
return (
|
return (
|
||||||
<GitHubLink href={`https://github.com/${repo}`} underline={false} {...rest}>
|
<Link
|
||||||
|
href={`https://github.com/${repo}`}
|
||||||
|
underline={false}
|
||||||
|
css={{
|
||||||
|
margin: "0 0.4em",
|
||||||
|
color: theme.colors.text,
|
||||||
|
|
||||||
|
"&:hover, &:focus-visible": {
|
||||||
|
color: theme.colors.link,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
{...rest}
|
||||||
|
>
|
||||||
<Octocat className={className} />
|
<Octocat className={className} />
|
||||||
</GitHubLink>
|
</Link>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -15,10 +15,6 @@ const Title = styled("h1", {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const TitleLink = styled(Link, {
|
|
||||||
color: theme.colors.text,
|
|
||||||
});
|
|
||||||
|
|
||||||
export type PageTitleProps = ComponentPropsWithoutRef<typeof Title>;
|
export type PageTitleProps = ComponentPropsWithoutRef<typeof Title>;
|
||||||
|
|
||||||
const PageTitle = ({ children, ...rest }: PageTitleProps) => {
|
const PageTitle = ({ children, ...rest }: PageTitleProps) => {
|
||||||
@ -26,9 +22,9 @@ const PageTitle = ({ children, ...rest }: PageTitleProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Title {...rest}>
|
<Title {...rest}>
|
||||||
<TitleLink href={router.pathname} underline={false}>
|
<Link href={router.pathname} underline={false} css={{ color: theme.colors.text }}>
|
||||||
{children}
|
{children}
|
||||||
</TitleLink>
|
</Link>
|
||||||
</Title>
|
</Title>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import commaNumber from "comma-number";
|
import commaNumber from "comma-number";
|
||||||
import Link from "../Link";
|
import Link from "../Link";
|
||||||
import RelativeTime from "../RelativeTime";
|
import RelativeTime from "../RelativeTime";
|
||||||
import { StarOcticon, ForkOcticon } from "../Icons";
|
import { GoStar, GoRepoForked } from "react-icons/go";
|
||||||
import { styled, theme } from "../../lib/styles/stitches.config";
|
import { styled, theme } from "../../lib/styles/stitches.config";
|
||||||
import type { Project } from "../../types";
|
import type { Project } from "../../types";
|
||||||
|
|
||||||
@ -50,9 +50,9 @@ const MetaLink = styled(Link, {
|
|||||||
const MetaIcon = styled("svg", {
|
const MetaIcon = styled("svg", {
|
||||||
width: "16px",
|
width: "16px",
|
||||||
height: "16px",
|
height: "16px",
|
||||||
verticalAlign: "text-bottom",
|
verticalAlign: "-0.3em",
|
||||||
marginRight: "0.5em",
|
marginRight: "0.5em",
|
||||||
fill: "currentColor",
|
strokeWidth: 0.75,
|
||||||
});
|
});
|
||||||
|
|
||||||
const LanguageCircle = styled("span", {
|
const LanguageCircle = styled("span", {
|
||||||
@ -100,7 +100,7 @@ const RepositoryCard = ({
|
|||||||
title={`${commaNumber(stars)} ${stars === 1 ? "star" : "stars"}`}
|
title={`${commaNumber(stars)} ${stars === 1 ? "star" : "stars"}`}
|
||||||
underline={false}
|
underline={false}
|
||||||
>
|
>
|
||||||
<MetaIcon as={StarOcticon} />
|
<MetaIcon as={GoStar} />
|
||||||
{commaNumber(stars)}
|
{commaNumber(stars)}
|
||||||
</MetaLink>
|
</MetaLink>
|
||||||
</MetaItem>
|
</MetaItem>
|
||||||
@ -113,7 +113,7 @@ const RepositoryCard = ({
|
|||||||
title={`${commaNumber(forks)} ${forks === 1 ? "fork" : "forks"}`}
|
title={`${commaNumber(forks)} ${forks === 1 ? "fork" : "forks"}`}
|
||||||
underline={false}
|
underline={false}
|
||||||
>
|
>
|
||||||
<MetaIcon as={ForkOcticon} />
|
<MetaIcon as={GoRepoForked} />
|
||||||
{commaNumber(forks)}
|
{commaNumber(forks)}
|
||||||
</MetaLink>
|
</MetaLink>
|
||||||
</MetaItem>
|
</MetaItem>
|
||||||
|
@ -17,9 +17,9 @@ const ThemeScript = memo<ThemeScriptProps>(({ themeClassNames, themeStorageKey }
|
|||||||
// since the client function will end up being injected as a static hard-coded string, we need to determine all of
|
// since the client function will end up being injected as a static hard-coded string, we need to determine all of
|
||||||
// the dynamic values within it *before* generating the final script.
|
// the dynamic values within it *before* generating the final script.
|
||||||
const source = String(clientScript)
|
const source = String(clientScript)
|
||||||
.replace("__MEDIA_QUERY__", "(prefers-color-scheme: dark)")
|
.replaceAll("__MEDIA_QUERY__", "(prefers-color-scheme: dark)")
|
||||||
.replace("__STORAGE_KEY__", themeStorageKey)
|
.replaceAll("__STORAGE_KEY__", themeStorageKey)
|
||||||
.replace("__CLASS_NAMES__", Object.values(themeClassNames).join('","'));
|
.replaceAll("__CLASS_NAMES__", Object.values(themeClassNames).join('","'));
|
||||||
|
|
||||||
// turn the raw function into an iife
|
// turn the raw function into an iife
|
||||||
const unminified = `(${source})()`;
|
const unminified = `(${source})()`;
|
||||||
|
@ -17,7 +17,7 @@ export const clientScript = () => {
|
|||||||
const newTheme = (pref && pref === "dark") ?? window.matchMedia("__MEDIA_QUERY__").matches ? 1 : 0;
|
const newTheme = (pref && pref === "dark") ?? window.matchMedia("__MEDIA_QUERY__").matches ? 1 : 0;
|
||||||
|
|
||||||
// remove both `classNames` to start fresh...
|
// remove both `classNames` to start fresh...
|
||||||
classList.remove(classNames[0], classNames[1]);
|
classList.remove(...classNames);
|
||||||
|
|
||||||
// ...and then FINALLY set the root class
|
// ...and then FINALLY set the root class
|
||||||
classList.add(classNames[newTheme]);
|
classList.add(classNames[newTheme]);
|
||||||
|
@ -1,24 +1,24 @@
|
|||||||
import { HomeIcon, NotesIcon, ProjectsIcon, ContactIcon } from "../../components/Icons";
|
import { FiHome, FiEdit3, FiCode, FiMail } from "react-icons/fi";
|
||||||
import type { MenuItemProps } from "../../components/MenuItem";
|
import type { MenuItemProps } from "../../components/MenuItem";
|
||||||
|
|
||||||
export const menuItems: MenuItemProps[] = [
|
export const menuItems: MenuItemProps[] = [
|
||||||
{
|
{
|
||||||
icon: HomeIcon,
|
icon: FiHome,
|
||||||
text: "Home",
|
text: "Home",
|
||||||
href: "/",
|
href: "/",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: NotesIcon,
|
icon: FiEdit3,
|
||||||
text: "Notes",
|
text: "Notes",
|
||||||
href: "/notes",
|
href: "/notes",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: ProjectsIcon,
|
icon: FiCode,
|
||||||
text: "Projects",
|
text: "Projects",
|
||||||
href: "/projects",
|
href: "/projects",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: ContactIcon,
|
icon: FiMail,
|
||||||
text: "Contact",
|
text: "Contact",
|
||||||
href: "/contact",
|
href: "/contact",
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
// @ts-check
|
// @ts-check
|
||||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||||
const path = require("path");
|
|
||||||
const config = require("./lib/config");
|
const config = require("./lib/config");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,37 +35,8 @@ const nextConfig = {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
experimental: {
|
experimental: {
|
||||||
legacyBrowsers: false,
|
largePageDataBytes: 512 * 1000, // raise getStaticProps limit to 512 kB since compiled MDX will exceed the default.
|
||||||
newNextLinkBehavior: true, // https://github.com/vercel/next.js/pull/36436
|
|
||||||
optimisticClientCache: false, // https://github.com/vercel/next.js/discussions/40268#discussioncomment-3572642
|
optimisticClientCache: false, // https://github.com/vercel/next.js/discussions/40268#discussioncomment-3572642
|
||||||
largePageDataBytes: 128 * 1000, // raise getStaticProps limit to 512 kB since compiled MDX might exceed this.
|
|
||||||
},
|
|
||||||
webpack: (config) => {
|
|
||||||
// allow processing SVGs from the below packages directly instead of through their different exports, and leave
|
|
||||||
// other static imports of SVGs alone.
|
|
||||||
// see: ./components/Icons/index.ts
|
|
||||||
config.module.rules.push({
|
|
||||||
test: /\.svg$/i,
|
|
||||||
issuer: { and: [/\.(js|ts)x?$/] },
|
|
||||||
use: [
|
|
||||||
{
|
|
||||||
loader: "@svgr/webpack",
|
|
||||||
options: {
|
|
||||||
icon: true,
|
|
||||||
typescript: true,
|
|
||||||
svgProps: {
|
|
||||||
"aria-hidden": true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
include: ["@primer/octicons", "feather-icons", "simple-icons"].map(
|
|
||||||
// pnpm uses symlinks extensively, so path.resolve(__dirname, "node_modules/...") won't cut it here.
|
|
||||||
(pkg) => path.dirname(require.resolve(pkg)) // => node_modules/.pnpm/feather-icons@4.29.0/node_modules/feather-icons/dist
|
|
||||||
),
|
|
||||||
});
|
|
||||||
|
|
||||||
return config;
|
|
||||||
},
|
},
|
||||||
eslint: {
|
eslint: {
|
||||||
// https://nextjs.org/docs/basic-features/eslint#linting-custom-directories-and-files
|
// https://nextjs.org/docs/basic-features/eslint#linting-custom-directories-and-files
|
||||||
|
59
package.json
59
package.json
@ -20,24 +20,22 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@giscus/react": "^2.3.0",
|
"@giscus/react": "^2.3.0",
|
||||||
"@hcaptcha/react-hcaptcha": "^1.8.1",
|
"@hcaptcha/react-hcaptcha": "^1.8.1",
|
||||||
"@novnc/novnc": "1.4.0-ge81602d",
|
"@novnc/novnc": "1.4.0",
|
||||||
"@octokit/graphql": "^7.0.1",
|
"@octokit/graphql": "^7.0.2",
|
||||||
"@octokit/graphql-schema": "^14.27.3",
|
"@octokit/graphql-schema": "^14.33.0",
|
||||||
"@primer/octicons": "^19.7.0",
|
"@prisma/client": "^5.3.1",
|
||||||
"@prisma/client": "^5.2.0",
|
|
||||||
"@react-spring/web": "^9.7.3",
|
"@react-spring/web": "^9.7.3",
|
||||||
"@stitches/react": "1.3.1-1",
|
"@stitches/react": "1.3.1-1",
|
||||||
"@vercel/postgres": "^0.4.1",
|
"@vercel/postgres": "^0.5.0",
|
||||||
"comma-number": "^2.1.0",
|
"comma-number": "^2.1.0",
|
||||||
"copy-to-clipboard": "^3.3.3",
|
"copy-to-clipboard": "^3.3.3",
|
||||||
"dayjs": "^1.11.9",
|
"dayjs": "^1.11.10",
|
||||||
"fast-glob": "^3.3.1",
|
"fast-glob": "^3.3.1",
|
||||||
"fathom-client": "^3.5.0",
|
"fathom-client": "^3.5.0",
|
||||||
"feather-icons": "^4.29.1",
|
|
||||||
"feed": "^4.2.2",
|
"feed": "^4.2.2",
|
||||||
"formik": "^2.4.4",
|
"formik": "^2.4.5",
|
||||||
"gray-matter": "^4.0.3",
|
"gray-matter": "^4.0.3",
|
||||||
"next": "13.4.19",
|
"next": "13.5.3",
|
||||||
"next-mdx-remote": "^4.4.1",
|
"next-mdx-remote": "^4.4.1",
|
||||||
"next-seo": "^6.1.0",
|
"next-seo": "^6.1.0",
|
||||||
"obj-str": "^1.1.0",
|
"obj-str": "^1.1.0",
|
||||||
@ -50,6 +48,7 @@
|
|||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"react-error-boundary": "^4.0.11",
|
"react-error-boundary": "^4.0.11",
|
||||||
"react-gist": "^1.2.4",
|
"react-gist": "^1.2.4",
|
||||||
|
"react-icons": "^4.11.0",
|
||||||
"react-innertext": "^1.1.5",
|
"react-innertext": "^1.1.5",
|
||||||
"react-intersection-observer": "^9.5.2",
|
"react-intersection-observer": "^9.5.2",
|
||||||
"react-is": "18.2.0",
|
"react-is": "18.2.0",
|
||||||
@ -66,41 +65,39 @@
|
|||||||
"remark-smartypants": "^2.0.0",
|
"remark-smartypants": "^2.0.0",
|
||||||
"remark-unwrap-images": "^3.0.1",
|
"remark-unwrap-images": "^3.0.1",
|
||||||
"remove-markdown": "^0.5.0",
|
"remove-markdown": "^0.5.0",
|
||||||
"simple-icons": "^9.13.0",
|
|
||||||
"sitemap": "^7.1.1",
|
"sitemap": "^7.1.1",
|
||||||
"stitches-normalize": "^2.0.0",
|
"stitches-normalize": "^2.0.0",
|
||||||
"swr": "^2.2.2",
|
"swr": "^2.2.4",
|
||||||
"unified": "^10.1.2"
|
"unified": "^10.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@jakejarvis/eslint-config": "^3.1.0",
|
"@jakejarvis/eslint-config": "^3.1.0",
|
||||||
"@svgr/webpack": "^8.1.0",
|
|
||||||
"@types/comma-number": "^2.1.0",
|
"@types/comma-number": "^2.1.0",
|
||||||
"@types/node": "^18.17.14",
|
"@types/node": "^18.17.14",
|
||||||
"@types/novnc__novnc": "^1.3.0",
|
"@types/novnc__novnc": "^1.3.2",
|
||||||
"@types/prop-types": "^15.7.5",
|
"@types/prop-types": "^15.7.8",
|
||||||
"@types/react": "^18.2.21",
|
"@types/react": "^18.2.24",
|
||||||
"@types/react-dom": "^18.2.7",
|
"@types/react-dom": "^18.2.8",
|
||||||
"@types/react-is": "^18.2.1",
|
"@types/react-is": "^18.2.2",
|
||||||
"@types/remove-markdown": "^0.3.1",
|
"@types/remove-markdown": "^0.3.2",
|
||||||
"@types/uglify-js": "^3.17.2",
|
"@types/uglify-js": "^3.17.2",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.6.0",
|
"@typescript-eslint/eslint-plugin": "^6.7.3",
|
||||||
"@typescript-eslint/parser": "^6.6.0",
|
"@typescript-eslint/parser": "^6.7.3",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"eslint": "~8.48.0",
|
"eslint": "~8.50.0",
|
||||||
"eslint-config-next": "13.4.19",
|
"eslint-config-next": "13.5.3",
|
||||||
"eslint-config-prettier": "~8.8.0",
|
"eslint-config-prettier": "~9.0.0",
|
||||||
"eslint-plugin-mdx": "~2.2.0",
|
"eslint-plugin-mdx": "~2.2.0",
|
||||||
"eslint-plugin-prettier": "~4.2.1",
|
"eslint-plugin-prettier": "~5.0.0",
|
||||||
"lint-staged": "^14.0.1",
|
"lint-staged": "^14.0.1",
|
||||||
"prettier": "^2.8.8",
|
"prettier": "^3.0.3",
|
||||||
"prisma": "^5.2.0",
|
"prisma": "^5.3.1",
|
||||||
"simple-git-hooks": "^2.9.0",
|
"simple-git-hooks": "^2.9.0",
|
||||||
"typescript": "^5.2.2",
|
"typescript": "^5.2.2",
|
||||||
"uglify-js": "^3.17.4"
|
"uglify-js": "^3.17.4"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"sharp": "^0.32.5"
|
"sharp": "^0.32.6"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16.x"
|
"node": ">=16.x"
|
||||||
@ -117,9 +114,9 @@
|
|||||||
"eslint"
|
"eslint"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@8.7.4",
|
"packageManager": "pnpm@8.8.0",
|
||||||
"volta": {
|
"volta": {
|
||||||
"node": "18.17.1",
|
"node": "18.18.0",
|
||||||
"pnpm": "8.7.4"
|
"pnpm": "8.8.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,6 @@ import Link from "../components/Link";
|
|||||||
import ContactForm from "../components/ContactForm";
|
import ContactForm from "../components/ContactForm";
|
||||||
import { styled } from "../lib/styles/stitches.config";
|
import { styled } from "../lib/styles/stitches.config";
|
||||||
|
|
||||||
const Wrapper = styled(Content, {
|
|
||||||
maxWidth: "600px",
|
|
||||||
margin: "0 auto",
|
|
||||||
});
|
|
||||||
|
|
||||||
const PGPKey = styled("code", {
|
const PGPKey = styled("code", {
|
||||||
fontSize: "0.925em",
|
fontSize: "0.925em",
|
||||||
wordSpacing: "-0.25em",
|
wordSpacing: "-0.25em",
|
||||||
@ -27,7 +22,12 @@ const Contact = () => {
|
|||||||
|
|
||||||
<PageTitle>📬 Contact Me</PageTitle>
|
<PageTitle>📬 Contact Me</PageTitle>
|
||||||
|
|
||||||
<Wrapper>
|
<Content
|
||||||
|
css={{
|
||||||
|
maxWidth: "600px",
|
||||||
|
margin: "0 auto",
|
||||||
|
}}
|
||||||
|
>
|
||||||
<p>
|
<p>
|
||||||
Fill out this quick form and I'll get back to you as soon as I can! You can also{" "}
|
Fill out this quick form and I'll get back to you as soon as I can! You can also{" "}
|
||||||
<Link href="mailto:jake@jarv.is">email me directly</Link>, send me a{" "}
|
<Link href="mailto:jake@jarv.is">email me directly</Link>, send me a{" "}
|
||||||
@ -43,7 +43,7 @@ const Contact = () => {
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<ContactForm />
|
<ContactForm />
|
||||||
</Wrapper>
|
</Content>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
import Link, { LinkProps } from "../components/Link";
|
import Link from "../components/Link";
|
||||||
|
import { GoLock } from "react-icons/go";
|
||||||
import { styled, theme, darkTheme, keyframes, stitchesConfig } from "../lib/styles/stitches.config";
|
import { styled, theme, darkTheme, keyframes, stitchesConfig } from "../lib/styles/stitches.config";
|
||||||
|
import type { ComponentPropsWithoutRef } from "react";
|
||||||
|
|
||||||
const ColorfulLink = ({
|
const ColorfulLink = ({
|
||||||
lightColor,
|
lightColor,
|
||||||
darkColor,
|
darkColor,
|
||||||
css,
|
css,
|
||||||
...rest
|
...rest
|
||||||
}: LinkProps & {
|
}: ComponentPropsWithoutRef<typeof Link> & {
|
||||||
lightColor: string;
|
lightColor: string;
|
||||||
darkColor: string;
|
darkColor: string;
|
||||||
}) => {
|
}) => {
|
||||||
@ -333,7 +335,8 @@ const Index = () => {
|
|||||||
underline={false}
|
underline={false}
|
||||||
openInNewTab
|
openInNewTab
|
||||||
>
|
>
|
||||||
🔐 <PGPKey>2B0C 9CF2 51E6 9A39</PGPKey>
|
<GoLock size="1.25em" style={{ verticalAlign: "-0.25em", strokeWidth: 0.5 }} />{" "}
|
||||||
|
<PGPKey>2B0C 9CF2 51E6 9A39</PGPKey>
|
||||||
</ColorfulLink>
|
</ColorfulLink>
|
||||||
</Sup>
|
</Sup>
|
||||||
,{" "}
|
,{" "}
|
||||||
|
@ -7,7 +7,7 @@ import Figure from "../components/Figure";
|
|||||||
import IFrame from "../components/IFrame";
|
import IFrame from "../components/IFrame";
|
||||||
import CodeInline from "../components/CodeInline";
|
import CodeInline from "../components/CodeInline";
|
||||||
import HorizontalRule from "../components/HorizontalRule";
|
import HorizontalRule from "../components/HorizontalRule";
|
||||||
import { Windows95Logo } from "../components/Icons";
|
import { SiWindows95 } from "react-icons/si";
|
||||||
import { styled, theme } from "../lib/styles/stitches.config";
|
import { styled, theme } from "../lib/styles/stitches.config";
|
||||||
import { ComicNeue } from "../lib/styles/fonts";
|
import { ComicNeue } from "../lib/styles/fonts";
|
||||||
import type { ReactElement } from "react";
|
import type { ReactElement } from "react";
|
||||||
@ -41,11 +41,11 @@ const Divider = styled(HorizontalRule, {
|
|||||||
margin: "1em auto",
|
margin: "1em auto",
|
||||||
});
|
});
|
||||||
|
|
||||||
const Icon = styled("svg", {
|
const WindowsLogo = styled(SiWindows95, {
|
||||||
width: "1.2em",
|
width: "1.2em",
|
||||||
height: "1.2em",
|
height: "1.2em",
|
||||||
verticalAlign: "-0.15em",
|
verticalAlign: "-0.15em",
|
||||||
marginRight: "0.15em",
|
marginRight: "0.1em",
|
||||||
fill: "currentColor",
|
fill: "currentColor",
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ const Previously = () => {
|
|||||||
fontSize: "0.95em",
|
fontSize: "0.95em",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Icon as={Windows95Logo} /> Click here for the <em>full</em> experience anyway.
|
<WindowsLogo /> Click here for the <em>full</em> experience anyway.
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<ScreenShot as="figure">
|
<ScreenShot as="figure">
|
||||||
|
@ -4,7 +4,7 @@ import Content from "../components/Content";
|
|||||||
import PageTitle from "../components/PageTitle";
|
import PageTitle from "../components/PageTitle";
|
||||||
import Link from "../components/Link";
|
import Link from "../components/Link";
|
||||||
import RepositoryCard from "../components/RepositoryCard";
|
import RepositoryCard from "../components/RepositoryCard";
|
||||||
import { OctocatOcticon } from "../components/Icons";
|
import { SiGithub } from "react-icons/si";
|
||||||
import { styled, theme } from "../lib/styles/stitches.config";
|
import { styled, theme } from "../lib/styles/stitches.config";
|
||||||
import { authorSocial } from "../lib/config";
|
import { authorSocial } from "../lib/config";
|
||||||
import type { GetStaticProps, InferGetStaticPropsType } from "next";
|
import type { GetStaticProps, InferGetStaticPropsType } from "next";
|
||||||
@ -34,7 +34,7 @@ const ViewMore = styled("p", {
|
|||||||
fontWeight: 500,
|
fontWeight: 500,
|
||||||
});
|
});
|
||||||
|
|
||||||
const GitHubLogo = styled(OctocatOcticon, {
|
const GitHubLogo = styled(SiGithub, {
|
||||||
width: "1.2em",
|
width: "1.2em",
|
||||||
height: "1.2em",
|
height: "1.2em",
|
||||||
verticalAlign: "-0.2em",
|
verticalAlign: "-0.2em",
|
||||||
|
2884
pnpm-lock.yaml
generated
2884
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user