1
mirror of https://github.com/jakejarvis/jarv.is.git synced 2025-09-14 01:55:31 -04:00

clean up global styles

This commit is contained in:
2022-01-10 16:15:17 -05:00
parent 18e04bdd5f
commit 3864d18ba3
11 changed files with 103 additions and 93 deletions

View File

@@ -16,31 +16,43 @@
margin-top: 1em; margin-top: 1em;
margin-bottom: 0.5em; margin-bottom: 0.5em;
line-height: 1.5; line-height: 1.5;
/* offset (approximately) with sticky header so jumped-to content isn't hiding behind it */
scroll-margin-top: 4em;
} }
/* special bottom border for H2s */ /* special bottom border for <h2>s */
.content h2 { .content h2 {
padding-bottom: 0.25em; padding-bottom: 0.25em;
border-bottom: 1px solid var(--kinda-light); border-bottom: 1px solid var(--kinda-light);
} }
.content figure { .content h3,
.content h4 {
scroll-margin-top: 5em;
}
/* default to centering all images */
.content figure,
.content :global(.image_wrapper) {
margin: 1em auto; margin: 1em auto;
text-align: center; text-align: center;
} }
.content figure img { .content figure :global(.image_wrapper) {
height: auto; margin-bottom: 0;
max-width: 100%;
} }
.content figure figcaption { .content figure figcaption {
font-size: 0.9em; font-size: 0.9em;
line-height: 1.5; line-height: 1.5;
margin-top: 0.3em;
color: var(--medium); color: var(--medium);
} }
.content figure figcaption p {
margin-top: 0.3em;
}
.content ul, .content ul,
.content ol { .content ol {
margin-left: 1.5em; margin-left: 1.5em;
@@ -58,9 +70,42 @@
background-color: var(--light); background-color: var(--light);
} }
/* sub-heading anchor styles */
.content :global(.h-anchor) {
margin: 0 0.25em;
padding: 0 0.25em;
color: var(--medium-light);
background: none;
font-weight: 300;
opacity: 0; /* overridden on hover */
user-select: none;
}
.content :global(.h-anchor::before) {
content: "\0023"; /* pound sign `#`, done here to keep content DOM cleaner */
}
.content :global(.h-anchor:hover) {
color: var(--link);
}
/* make anchor `#` link show up on hover over the corresponding heading */
.content h2:hover :global(.h-anchor),
.content h3:hover :global(.h-anchor),
.content h4:hover :global(.h-anchor) {
opacity: 1;
}
@media screen and (max-width: 768px) { @media screen and (max-width: 768px) {
.content { .content {
font-size: 0.925em; font-size: 0.925em;
line-height: 1.85; line-height: 1.85;
} }
.content h2 {
scroll-margin-top: 5em;
}
.content h3,
.content h4 {
scroll-margin-top: 6em;
}
} }

View File

@@ -1,28 +1,35 @@
import dynamic from "next/dynamic"; import dynamic from "next/dynamic";
import type { ReactNode } from "react"; import type { ReactNode } from "react";
type Props = { type CustomCodeProps = {
className?: string; className?: string;
children: ReactNode; children: ReactNode;
}; };
const CustomCode = (props: Props) => { const CustomCode = (props: CustomCodeProps) => {
if (props.className?.split(" ").includes("hljs")) { if (props.className?.split(" ").includes("hljs")) {
const CopyButton = dynamic(() => import("../clipboard/CopyButton")); const CopyButton = dynamic(() => import("../clipboard/CopyButton"));
// full multi-line code blocks with highlight.js and copy-to-clipboard button // full multi-line code blocks with highlight.js and copy-to-clipboard button
return ( return (
<div className="code_block"> <div>
<CopyButton source={props.children} /> <CopyButton source={props.children} />
<code {...props}>{props.children}</code> <code {...props}>{props.children}</code>
<style jsx>{` <style jsx>{`
.code_block { div {
position: relative; position: relative;
max-width: 100%; max-width: 100%;
overflow-x: scroll; overflow-x: scroll;
margin: 1em 0; margin: 1em 0;
} }
div > code {
display: block;
overflow-x: auto;
padding: 1em;
tab-size: 2;
}
`}</style> `}</style>
<style jsx global>{` <style jsx global>{`

View File

@@ -1,14 +1,17 @@
import Image from "next/image"; import Image from "next/image";
import type { ImageProps } from "next/image"; import type { ImageProps } from "next/image";
import type { CSSProperties } from "react";
// TODO: infer ratio when given zero/one dimensions // TODO: infer ratio when given zero/one dimensions
// TODO: fold figure/figcaption tags into this component // TODO: fold figure/figcaption tags into this component
const CustomImg = (props: ImageProps) => { type CustomImageProps = ImageProps & {
style?: CSSProperties;
};
const CustomImage = (props: CustomImageProps) => {
return ( return (
// the required height and width are part of the props, so they get automatically passed here with {...props} <div className="image_wrapper" style={props.style}>
<div style={{ margin: "1em auto", textAlign: "center" }}>
<Image <Image
src={props.src} src={props.src}
layout="intrinsic" layout="intrinsic"
@@ -23,4 +26,4 @@ const CustomImg = (props: ImageProps) => {
); );
}; };
export default CustomImg; export default CustomImage;

View File

@@ -1,5 +1,4 @@
import Link from "next/link"; import Link from "next/link";
import type { LinkProps } from "next/link"; import type { LinkProps } from "next/link";
type CustomLinkProps = LinkProps & { type CustomLinkProps = LinkProps & {
@@ -7,10 +6,12 @@ type CustomLinkProps = LinkProps & {
rel?: string; rel?: string;
className?: string; className?: string;
children?: unknown; children?: unknown;
rest?: unknown;
}; };
const CustomLink = ({ href, target, rel, className, children }: CustomLinkProps) => (
const CustomLink = ({ href, target, rel, className, children, ...rest }: CustomLinkProps) => (
<Link href={href} passHref={true}> <Link href={href} passHref={true}>
<a className={className} target={target} rel={rel}> <a className={className} target={target} rel={rel} {...rest}>
{children} {children}
</a> </a>
</Link> </Link>

View File

@@ -1,4 +1,5 @@
import ReactPlayer, { ReactPlayerProps } from "react-player/lazy"; import ReactPlayer from "react-player/lazy";
import type { ReactPlayerProps } from "react-player";
const Video = (props: ReactPlayerProps) => ( const Video = (props: ReactPlayerProps) => (
<div style={{ position: "relative", paddingTop: "56.25%" }}> <div style={{ position: "relative", paddingTop: "56.25%" }}>

View File

@@ -39,7 +39,7 @@
} }
@media screen and (max-width: 768px) { @media screen and (max-width: 768px) {
.section .year { .year {
font-size: 2em; font-size: 2em;
} }
} }

View File

@@ -1,22 +1,10 @@
import { intlFormat, formatDistanceToNowStrict } from "date-fns"; import { intlFormat, formatDistanceToNowStrict } from "date-fns";
import { StarOcticon, ForkOcticon } from "../icons/octicons"; import { StarOcticon, ForkOcticon } from "../icons/octicons";
import { RepoType } from "../../types";
import styles from "./RepoCard.module.css"; import styles from "./RepoCard.module.css";
type Props = { const RepoCard = (props: RepoType) => (
name: string;
url: string;
description?: string;
language?: {
name: string;
color?: string;
};
stars?: number;
forks?: number;
updatedAt: string;
};
const RepoCard = (props: Props) => (
<div className={styles.card}> <div className={styles.card}>
<a className={styles.name} href={props.url} target="_blank" rel="noopener noreferrer"> <a className={styles.name} href={props.url} target="_blank" rel="noopener noreferrer">
{props.name} {props.name}

View File

@@ -53,7 +53,6 @@ export const getNote = async (slug: string): Promise<NoteType> => {
const { code: mdxSource } = await bundleMDX({ const { code: mdxSource } = await bundleMDX({
source: content, source: content,
cwd: process.cwd(), cwd: process.cwd(),
// cwd: path.join("/Users/jake/source/jarv.is", "components"),
xdmOptions: (options) => { xdmOptions: (options) => {
options.remarkPlugins = [...(options.remarkPlugins ?? []), [remarkGfm, { singleTilde: false }]]; options.remarkPlugins = [...(options.remarkPlugins ?? []), [remarkGfm, { singleTilde: false }]];
options.rehypePlugins = [ options.rehypePlugins = [
@@ -62,7 +61,12 @@ export const getNote = async (slug: string): Promise<NoteType> => {
[rehypeSlug, {}], [rehypeSlug, {}],
[ [
rehypeAutolinkHeadings, rehypeAutolinkHeadings,
{ behavior: "append", properties: { className: "h-anchor" }, content: [], test: ["h2", "h3"] }, {
behavior: "append",
properties: { className: "h-anchor", ariaHidden: true, tabIndex: -1 },
content: [],
test: ["h2", "h3"],
},
], ],
[rehypeHighlight, {}], [rehypeHighlight, {}],
]; ];

View File

@@ -4,8 +4,9 @@ import PageTitle from "../components/page/PageTitle";
import RepoCard from "../components/projects/RepoCard"; import RepoCard from "../components/projects/RepoCard";
import { ProjectsIcon } from "../components/icons"; import { ProjectsIcon } from "../components/icons";
import type { GetStaticProps } from "next"; import type { GetStaticProps } from "next";
import { RepoType } from "../types";
const Projects = ({ repos }) => ( const Projects = (props: { repos: RepoType[] }) => (
<> <>
<NextSeo <NextSeo
title="Projects" title="Projects"
@@ -23,7 +24,7 @@ const Projects = ({ repos }) => (
/> />
<div> <div>
{repos.map((repo) => ( {props.repos.map((repo: RepoType) => (
<div key={repo.name} className="repo_card"> <div key={repo.name} className="repo_card">
<RepoCard {...repo} /> <RepoCard {...repo} />
</div> </div>
@@ -103,7 +104,7 @@ export const getStaticProps: GetStaticProps = async () => {
} }
); );
const repos = user.repositories.edges.map(({ node: repo }) => ({ const repos: RepoType[] = user.repositories.edges.map(({ node: repo }) => ({
name: repo.name, name: repo.name,
url: repo.url, url: repo.url,
description: repo.description, description: repo.description,

View File

@@ -20,7 +20,7 @@ a:hover {
background-size: 100% 2px; background-size: 100% 2px;
} }
/* set an anchor's class to `no-underline` to disable all of this */ /* set an anchor's class to `no-underline` to disable all of the above */
.no-underline { .no-underline {
background: none !important; background: none !important;
padding-bottom: 0; padding-bottom: 0;
@@ -49,59 +49,6 @@ code {
padding: 0.1em 0.25em; padding: 0.1em 0.25em;
} }
/* code blocks */
pre code {
display: block;
overflow-x: auto;
padding: 1em;
tab-size: 2;
}
/* sub-heading anchor styles */
.h-anchor {
margin: 0 0.25em;
padding: 0 0.25em;
color: var(--medium-light);
background: none;
font-weight: 300;
opacity: 0; /* overridden on hover */
user-select: none;
}
.h-anchor::before {
content: "\0023"; /* pound sign `#`, done here to keep content DOM cleaner */
}
.h-anchor:hover {
color: var(--link);
}
/* make anchor `#` link show up on hover over the corresponding heading */
h2:hover .h-anchor,
h3:hover .h-anchor,
h4:hover .h-anchor {
opacity: 1;
}
/* offset (approximately) with sticky header so jumped-to content isn't hiding behind it */
h2 {
scroll-margin-top: 4em;
}
h3,
h4 {
scroll-margin-top: 5em;
}
@media screen and (max-width: 768px) {
h2 {
scroll-margin-top: 5em;
}
h3,
h4 {
scroll-margin-top: 6em;
}
}
/* https://web.dev/prefers-reduced-motion/#(bonus)-forcing-reduced-motion-on-all-websites */ /* https://web.dev/prefers-reduced-motion/#(bonus)-forcing-reduced-motion-on-all-websites */
@media (prefers-reduced-motion: reduce) { @media (prefers-reduced-motion: reduce) {
*, *,

13
types/index.d.ts vendored
View File

@@ -15,3 +15,16 @@ export type NoteType = {
frontMatter: NoteMetaType; frontMatter: NoteMetaType;
mdxSource: string; mdxSource: string;
}; };
export type RepoType = {
name: string;
url: string;
description?: string;
language?: {
name: string;
color?: string;
};
stars?: number;
forks?: number;
updatedAt: string;
};