mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2025-07-03 17:46:39 -04:00
pre-render optimizations
This commit is contained in:
@ -13,7 +13,7 @@
|
||||
tab-size: 2px;
|
||||
background-color: var(--colors-codeBackground);
|
||||
border: 1px solid var(--colors-kindaLight);
|
||||
border-radius: var(--radii-corner);
|
||||
border-radius: 0.6em;
|
||||
}
|
||||
|
||||
.codeBlock :global(.line-number)::before {
|
||||
@ -106,8 +106,8 @@
|
||||
width: 3em;
|
||||
color: var(--colors-mediumDark);
|
||||
border: 1px solid var(--colors-kindaLight);
|
||||
border-top-right-radius: var(--radii-corner);
|
||||
border-bottom-left-radius: var(--radii-corner);
|
||||
border-top-right-radius: 0.6em;
|
||||
border-bottom-left-radius: 0.6em;
|
||||
background-color: var(--colors-backgroundHeader);
|
||||
backdrop-filter: saturate(180%) blur(5px);
|
||||
}
|
||||
|
@ -4,5 +4,5 @@
|
||||
page-break-inside: avoid;
|
||||
background-color: var(--colors-codeBackground);
|
||||
border: 1px solid var(--colors-kindaLight);
|
||||
border-radius: var(--radii-corner);
|
||||
border-radius: 0.6em;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import Giscus from "@giscus/react";
|
||||
import config from "../../lib/config";
|
||||
import * as config from "../../lib/config";
|
||||
import type { GiscusProps } from "@giscus/react";
|
||||
|
||||
export type CommentsProps = {
|
||||
|
@ -10,7 +10,6 @@
|
||||
.row {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
max-width: var(--sizes-maxLayoutWidth);
|
||||
margin: 0 auto;
|
||||
justify-content: space-between;
|
||||
font-size: 0.8em;
|
||||
|
@ -1,7 +1,8 @@
|
||||
import clsx from "clsx";
|
||||
import { HeartIcon } from "lucide-react";
|
||||
import Link from "../Link";
|
||||
import config from "../../lib/config";
|
||||
import * as config from "../../lib/config";
|
||||
import { MAX_WIDTH } from "../../lib/config/constants";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
import styles from "./Footer.module.css";
|
||||
@ -11,7 +12,7 @@ export type FooterProps = ComponentPropsWithoutRef<"footer">;
|
||||
const Footer = ({ className, ...rest }: FooterProps) => {
|
||||
return (
|
||||
<footer className={clsx(styles.footer, className)} {...rest}>
|
||||
<div className={styles.row}>
|
||||
<div className={styles.row} style={{ maxWidth: MAX_WIDTH }}>
|
||||
<div>
|
||||
Content{" "}
|
||||
<Link href="/license" title={config.license} plain className={styles.link}>
|
||||
|
@ -14,22 +14,22 @@
|
||||
backdrop-filter: saturate(180%) blur(5px);
|
||||
}
|
||||
|
||||
.selfieImage {
|
||||
.homeImage {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border: 1px solid var(--colors-light);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.selfieLink {
|
||||
.homeLink {
|
||||
display: inline-flex;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
color: var(--colors-mediumDark) !important;
|
||||
}
|
||||
|
||||
.selfieLink:hover,
|
||||
.selfieLink:focus-visible {
|
||||
.homeLink:hover,
|
||||
.homeLink:focus-visible {
|
||||
color: var(--colors-link) !important;
|
||||
}
|
||||
|
||||
@ -46,7 +46,6 @@
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
max-width: var(--sizes-maxLayoutWidth);
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
@ -56,14 +55,14 @@
|
||||
height: 5.9em;
|
||||
}
|
||||
|
||||
.selfieImage {
|
||||
.homeImage {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.selfieLink:hover .selfieImage,
|
||||
.selfieLink:focus-visible .selfieImage {
|
||||
.homeLink:hover .homeImage,
|
||||
.homeLink:focus-visible .homeImage {
|
||||
border-color: var(--colors-linkUnderline);
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,8 @@ import clsx from "clsx";
|
||||
import Link from "../Link";
|
||||
import Image from "../Image";
|
||||
import Menu from "../Menu";
|
||||
import config from "../../lib/config";
|
||||
import * as config from "../../lib/config";
|
||||
import { MAX_WIDTH } from "../../lib/config/constants";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
import styles from "./Header.module.css";
|
||||
@ -14,12 +15,12 @@ export type HeaderProps = ComponentPropsWithoutRef<"header">;
|
||||
const Header = ({ className, ...rest }: HeaderProps) => {
|
||||
return (
|
||||
<header className={clsx(styles.header, className)} {...rest}>
|
||||
<nav className={styles.nav}>
|
||||
<Link href="/" rel="author" title={config.authorName} plain className={styles.selfieLink}>
|
||||
<nav className={styles.nav} style={{ maxWidth: MAX_WIDTH }}>
|
||||
<Link href="/" rel="author" title={config.authorName} plain className={styles.homeLink}>
|
||||
<Image
|
||||
src={selfieJpg}
|
||||
alt={`Photo of ${config.authorName}`}
|
||||
className={styles.selfieImage}
|
||||
className={styles.homeImage}
|
||||
width={70}
|
||||
height={70}
|
||||
quality={60}
|
||||
|
@ -9,7 +9,7 @@ export type HeadingAnchorProps = Omit<ComponentPropsWithoutRef<typeof Link>, "hr
|
||||
|
||||
const HeadingAnchor = ({ id, title, ...rest }: HeadingAnchorProps) => {
|
||||
return (
|
||||
<Link href={`#${id}`} title={`Jump to "${title}"`} aria-hidden plain {...rest}>
|
||||
<Link href={`#${id}`} title={`Jump to "${title}"`} plain {...rest}>
|
||||
<LinkIcon size="0.8em" />
|
||||
</Link>
|
||||
);
|
||||
|
@ -1,5 +0,0 @@
|
||||
.image {
|
||||
height: auto;
|
||||
max-width: 100%;
|
||||
border-radius: var(--radii-corner);
|
||||
}
|
@ -1,15 +1,11 @@
|
||||
import NextImage from "next/image";
|
||||
import clsx from "clsx";
|
||||
import { MAX_WIDTH } from "../../lib/config/constants";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
import type { StaticImageData } from "next/image";
|
||||
|
||||
import styles from "./Image.module.css";
|
||||
|
||||
const MAX_WIDTH = 865;
|
||||
|
||||
export type ImageProps = ComponentPropsWithoutRef<typeof NextImage>;
|
||||
|
||||
const Image = ({ src, height, width, quality, placeholder, className, ...rest }: ImageProps) => {
|
||||
const Image = ({ src, height, width, quality, placeholder, style, ...rest }: ImageProps) => {
|
||||
const constrainWidth = (width?: number | `${number}`) => {
|
||||
if (!width) return MAX_WIDTH;
|
||||
|
||||
@ -22,10 +18,14 @@ const Image = ({ src, height, width, quality, placeholder, className, ...rest }:
|
||||
width: constrainWidth(width || (src as StaticImageData).width),
|
||||
quality: quality || 75,
|
||||
placeholder: placeholder || (typeof src === "string" ? "empty" : "blur"),
|
||||
style: {
|
||||
height: "auto",
|
||||
...style,
|
||||
},
|
||||
...rest,
|
||||
};
|
||||
|
||||
return <NextImage className={clsx(styles.image, className)} {...imageProps} />;
|
||||
return <NextImage {...imageProps} />;
|
||||
};
|
||||
|
||||
export default Image;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import NextLink from "next/link";
|
||||
import clsx from "clsx";
|
||||
import objStr from "obj-str";
|
||||
import config from "../../lib/config";
|
||||
import { BASE_URL } from "../../lib/config/constants";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
import styles from "./Link.module.css";
|
||||
@ -14,7 +14,7 @@ export type LinkProps = ComponentPropsWithoutRef<typeof NextLink> & {
|
||||
const Link = ({ href, rel, target, prefetch = false, plain, openInNewTab, className, ...rest }: LinkProps) => {
|
||||
// This component auto-detects whether or not this link should open in the same window (the default for internal
|
||||
// links) or a new tab (the default for external links). Defaults can be overridden with `openInNewTab={true}`.
|
||||
const isExternal = typeof href === "string" && !(["/", "#"].includes(href[0]) || href.startsWith(config.baseUrl));
|
||||
const isExternal = typeof href === "string" && !(["/", "#"].includes(href[0]) || href.startsWith(BASE_URL));
|
||||
|
||||
if (openInNewTab || isExternal) {
|
||||
return (
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* accessible invisibility stuff pulled from @reach/skip-nav:
|
||||
https://github.com/reach/reach-ui/blob/main/packages/skip-nav/styles.css */
|
||||
|
||||
.hiddenLink {
|
||||
.skipNav {
|
||||
border: 0;
|
||||
clip: rect(0 0 0 0);
|
||||
height: 1px;
|
||||
@ -12,7 +12,7 @@ https://github.com/reach/reach-ui/blob/main/packages/skip-nav/styles.css */
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.hiddenLink:focus {
|
||||
.skipNav:focus {
|
||||
padding: 1rem;
|
||||
position: fixed;
|
||||
top: 10px;
|
||||
@ -24,6 +24,5 @@ https://github.com/reach/reach-ui/blob/main/packages/skip-nav/styles.css */
|
||||
background: var(--colors-superDuperLight);
|
||||
color: var(--colors-link);
|
||||
border: 2px solid var(--colors-kindaLight);
|
||||
border-radius: var(--radii-corner);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ const skipNavId = "skip-nav";
|
||||
|
||||
export const SkipToContentLink = () => {
|
||||
return (
|
||||
<a href={`#${skipNavId}`} tabIndex={0} className={styles.hiddenLink}>
|
||||
<a href={`#${skipNavId}`} tabIndex={0} className={styles.skipNav}>
|
||||
Skip to content
|
||||
</a>
|
||||
);
|
||||
|
@ -11,3 +11,15 @@
|
||||
.toggle:focus-visible {
|
||||
color: var(--colors-warning);
|
||||
}
|
||||
|
||||
/* hacky way to avoid flashing icon for a few milliseconds on initial render */
|
||||
.toggle > .sun,
|
||||
[data-theme="dark"] .toggle > .moon {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* stylelint-disable-next-line no-descending-specificity */
|
||||
.toggle > .moon,
|
||||
[data-theme="dark"] .toggle > .sun {
|
||||
display: none;
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import { useHasMounted, useTheme } from "../../hooks";
|
||||
import { EllipsisIcon, MoonIcon, SunIcon } from "lucide-react";
|
||||
import clsx from "clsx";
|
||||
import { MoonIcon, SunIcon } from "lucide-react";
|
||||
import { useTheme } from "../../hooks";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
import type { LucideIcon } from "lucide-react";
|
||||
|
||||
@ -9,27 +10,17 @@ import styles from "./ThemeToggle.module.css";
|
||||
|
||||
export type ThemeToggleProps = ComponentPropsWithoutRef<LucideIcon>;
|
||||
|
||||
const ThemeToggle = ({ ...rest }: ThemeToggleProps) => {
|
||||
const hasMounted = useHasMounted();
|
||||
const ThemeToggle = ({ className, ...rest }: ThemeToggleProps) => {
|
||||
const { theme, setTheme } = useTheme();
|
||||
|
||||
// render a placeholder icon to avoid layout shifting until we're fully mounted and self-aware
|
||||
if (!hasMounted) {
|
||||
return (
|
||||
<div className={styles.toggle}>
|
||||
<EllipsisIcon style={{ stroke: "var(--colors-mediumLight)" }} {...rest} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={() => setTheme(theme === "light" ? "dark" : "light")}
|
||||
aria-label="Toggle Theme"
|
||||
className={styles.toggle}
|
||||
title={theme === "light" ? "Toggle Dark Mode" : "Toggle Light Mode"}
|
||||
aria-label={theme === "light" ? "Toggle Dark Mode" : "Toggle Light Mode"}
|
||||
>
|
||||
{theme === "light" ? <SunIcon {...rest} /> : <MoonIcon {...rest} />}
|
||||
<SunIcon className={clsx(styles.sun, className)} {...rest} />
|
||||
<MoonIcon className={clsx(styles.moon, className)} {...rest} />
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
@ -2,10 +2,6 @@
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.player video {
|
||||
border-radius: var(--radii-corner);
|
||||
}
|
||||
|
||||
.wrapper.responsive {
|
||||
position: relative;
|
||||
padding-top: 56.25%; /* ratio of 1280x720 */
|
||||
|
Reference in New Issue
Block a user