mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2026-07-30 11:45:21 -04:00
next-mdx-remote -> mdx-bundler (#729)
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
import Gist from "react-gist";
|
||||
|
||||
export default Gist;
|
||||
@@ -0,0 +1,28 @@
|
||||
const Octocat = (props: { repo: string }) => {
|
||||
return (
|
||||
<a
|
||||
className="no-underline"
|
||||
href={`https://github.com/${props.repo}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
style={{ margin: "0 0.3em", color: "var(--text)" }}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
width="1em"
|
||||
height="1em"
|
||||
aria-hidden="true"
|
||||
className="icon"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"
|
||||
></path>
|
||||
</svg>
|
||||
</a>
|
||||
);
|
||||
};
|
||||
|
||||
export default Octocat;
|
||||
@@ -0,0 +1,13 @@
|
||||
import TweetEmbed from "react-tweet-embed";
|
||||
|
||||
const Tweet = (props: { id: string }) => (
|
||||
<TweetEmbed
|
||||
id={props.id}
|
||||
options={{
|
||||
dnt: true,
|
||||
align: "center",
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
export default Tweet;
|
||||
@@ -0,0 +1,9 @@
|
||||
import ReactPlayer, { ReactPlayerProps } from "react-player/lazy";
|
||||
|
||||
const Video = (props: ReactPlayerProps) => (
|
||||
<div style={{ position: "relative", paddingTop: "56.25%" }}>
|
||||
<ReactPlayer width="100%" height="100%" style={{ position: "absolute", top: 0, left: 0 }} {...props} />
|
||||
</div>
|
||||
);
|
||||
|
||||
export default Video;
|
||||
@@ -1,3 +1,5 @@
|
||||
import { memo } from "react";
|
||||
|
||||
type Props = {
|
||||
boxes?: number;
|
||||
timing?: number;
|
||||
@@ -54,4 +56,4 @@ const Loading = ({ boxes = 3, timing = 0.1, width }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default Loading;
|
||||
export default memo(Loading);
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import dynamic from "next/dynamic";
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
import { useTheme } from "next-themes";
|
||||
|
||||
import type { LinkProps } from "next/link";
|
||||
import type { ImageProps } from "next/image";
|
||||
|
||||
// The following components are all passed into <MDXProvider /> as replacement HTML tags or drop-in React components
|
||||
// available in .mdx files containing post content, since they're not directly aware of the components in this folder.
|
||||
// The following components are all passed into <MDXComponent /> in [slug].tsx as replacements for vanilla HTML tags.
|
||||
|
||||
type CustomLinkProps = LinkProps & {
|
||||
target?: string;
|
||||
@@ -23,7 +21,10 @@ const CustomLink = ({ href, target, rel, className, children }: CustomLinkProps)
|
||||
</Link>
|
||||
);
|
||||
|
||||
const CustomImg = (props: ImageProps) => (
|
||||
type CustomImgProps = ImageProps & {
|
||||
caption?: unknown;
|
||||
};
|
||||
const CustomImg = (props: CustomImgProps) => (
|
||||
// the required height and width are part of the props, so they get automatically passed here with {...props}
|
||||
<div className={props.className}>
|
||||
{/* eslint-disable-next-line jsx-a11y/alt-text */}
|
||||
@@ -56,55 +57,11 @@ const CustomCode = (props: any) => {
|
||||
}
|
||||
};
|
||||
|
||||
const CustomTweet = (props: { id: string }) => {
|
||||
const TweetEmbed = dynamic(() => import("react-tweet-embed"));
|
||||
const { resolvedTheme } = useTheme();
|
||||
|
||||
return (
|
||||
<TweetEmbed
|
||||
id={props.id}
|
||||
options={{
|
||||
dnt: true,
|
||||
align: "center",
|
||||
theme: resolvedTheme === "dark" ? "dark" : "light",
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const CustomGist = dynamic(() => import("react-gist"));
|
||||
|
||||
const CustomVideo = dynamic(() => import("./video/Video"));
|
||||
|
||||
const CustomGitHubLink = (props: { repo: string }) => {
|
||||
const OctocatOcticon: any = dynamic(() => import("./icons/octicons").then((mod) => mod.OctocatOcticon));
|
||||
|
||||
return (
|
||||
<a className="no-underline" href={`https://github.com/${props.repo}`} target="_blank" rel="noopener noreferrer">
|
||||
<OctocatOcticon className="icon" fill="currentColor" />
|
||||
<style jsx>{`
|
||||
a {
|
||||
margin: 0 0.3em;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: var(--link);
|
||||
}
|
||||
`}</style>
|
||||
</a>
|
||||
);
|
||||
};
|
||||
|
||||
// These are the actual tags referenced in mdx files:
|
||||
const mdxComponents = {
|
||||
a: CustomLink,
|
||||
img: CustomImg,
|
||||
code: CustomCode,
|
||||
video: CustomVideo,
|
||||
tweet: CustomTweet,
|
||||
gist: CustomGist,
|
||||
octocat: CustomGitHubLink,
|
||||
};
|
||||
|
||||
export default mdxComponents;
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
.wrapper {
|
||||
margin-top: 2em;
|
||||
padding-top: 1em;
|
||||
border-top: 2px solid var(--light);
|
||||
}
|
||||
@@ -3,9 +3,11 @@ import Head from "next/head";
|
||||
import { useTheme } from "next-themes";
|
||||
import { githubRepo } from "../../lib/config";
|
||||
|
||||
import styles from "./Comments.module.css";
|
||||
type Props = {
|
||||
slug: string;
|
||||
};
|
||||
|
||||
const Comments = ({ slug }) => {
|
||||
const Comments = (props: Props) => {
|
||||
const [injected, setInjected] = useState(false);
|
||||
const scriptRef = useRef<HTMLDivElement>(null);
|
||||
const { resolvedTheme } = useTheme();
|
||||
@@ -25,7 +27,7 @@ const Comments = ({ slug }) => {
|
||||
|
||||
// https://utteranc.es/
|
||||
utterances.setAttribute("repo", githubRepo);
|
||||
utterances.setAttribute("issue-term", `notes/${slug}`);
|
||||
utterances.setAttribute("issue-term", `notes/${props.slug}`);
|
||||
utterances.setAttribute("theme", resolvedTheme === "dark" ? "github-dark" : "github-light");
|
||||
utterances.setAttribute("label", "💬 comments");
|
||||
|
||||
@@ -43,7 +45,15 @@ const Comments = ({ slug }) => {
|
||||
<link rel="preload" href="https://utteranc.es/client.js" as="script" crossOrigin="anonymous" />
|
||||
</Head>
|
||||
|
||||
<div ref={scriptRef} id="comments" className={styles.wrapper} />
|
||||
<div ref={scriptRef} id="comments" />
|
||||
|
||||
<style jsx>{`
|
||||
div {
|
||||
margin-top: 2em;
|
||||
padding-top: 1em;
|
||||
border-top: 2px solid var(--light);
|
||||
}
|
||||
`}</style>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -16,52 +16,52 @@ type Props = {
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
const RepoCard = ({ name, url, description, language, stars, forks, updatedAt }: Props) => (
|
||||
const RepoCard = (props: Props) => (
|
||||
<div className={styles.card}>
|
||||
<a className={styles.name} href={url} target="_blank" rel="noopener noreferrer">
|
||||
{name}
|
||||
<a className={styles.name} href={props.url} target="_blank" rel="noopener noreferrer">
|
||||
{props.name}
|
||||
</a>
|
||||
|
||||
{description && <p className={styles.description}>{description}</p>}
|
||||
{props.description && <p className={styles.description}>{props.description}</p>}
|
||||
|
||||
<div className={styles.meta}>
|
||||
{language && (
|
||||
{props.language && (
|
||||
<div className={styles.meta_item}>
|
||||
<span className={styles.language_color}>
|
||||
<style jsx>{`
|
||||
span {
|
||||
background-color: ${language.color};
|
||||
background-color: ${props.language.color};
|
||||
}
|
||||
`}</style>
|
||||
</span>
|
||||
<span>{language.name}</span>
|
||||
<span>{props.language.name}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{stars > 0 && (
|
||||
{props.stars > 0 && (
|
||||
<div className={styles.meta_item}>
|
||||
<a
|
||||
href={`${url}/stargazers`}
|
||||
title={`${stars.toLocaleString("en-US")} ${stars === 1 ? "star" : "stars"}`}
|
||||
href={`${props.url}/stargazers`}
|
||||
title={`${props.stars.toLocaleString("en-US")} ${props.stars === 1 ? "star" : "stars"}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<StarOcticon fill="currentColor" className={styles.octicon} />
|
||||
<span>{stars.toLocaleString("en-US")}</span>
|
||||
<span>{props.stars.toLocaleString("en-US")}</span>
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{forks > 0 && (
|
||||
{props.forks > 0 && (
|
||||
<div className={styles.meta_item}>
|
||||
<a
|
||||
href={`${url}/network/members`}
|
||||
title={`${forks.toLocaleString("en-US")} ${forks === 1 ? "fork" : "forks"}`}
|
||||
href={`${props.url}/network/members`}
|
||||
title={`${props.forks.toLocaleString("en-US")} ${props.forks === 1 ? "fork" : "forks"}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<ForkOcticon fill="currentColor" className={styles.octicon} />
|
||||
<span>{forks.toLocaleString("en-US")}</span>
|
||||
<span>{props.forks.toLocaleString("en-US")}</span>
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
@@ -69,7 +69,7 @@ const RepoCard = ({ name, url, description, language, stars, forks, updatedAt }:
|
||||
<div
|
||||
className={styles.meta_item}
|
||||
title={intlFormat(
|
||||
new Date(updatedAt),
|
||||
new Date(props.updatedAt),
|
||||
{
|
||||
year: "numeric",
|
||||
month: "short",
|
||||
@@ -83,7 +83,7 @@ const RepoCard = ({ name, url, description, language, stars, forks, updatedAt }:
|
||||
}
|
||||
)}
|
||||
>
|
||||
<span>Updated {formatDistanceToNowStrict(new Date(updatedAt), { addSuffix: true })}</span>
|
||||
<span>Updated {formatDistanceToNowStrict(new Date(props.updatedAt), { addSuffix: true })}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
.wrapper {
|
||||
position: relative;
|
||||
padding-top: 56.25%; /* 100 / (1280 / 720) */
|
||||
}
|
||||
|
||||
.react_player {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import dynamic from "next/dynamic";
|
||||
import type { ReactPlayerProps } from "react-player";
|
||||
|
||||
import styles from "./Video.module.css";
|
||||
|
||||
const ReactPlayer = dynamic(() => import("react-player/lazy"));
|
||||
|
||||
const Video = (props: ReactPlayerProps) => (
|
||||
<div className={styles.wrapper}>
|
||||
<ReactPlayer className={styles.react_player} width="100%" height="100%" {...props} />
|
||||
</div>
|
||||
);
|
||||
|
||||
export default Video;
|
||||
Reference in New Issue
Block a user