mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2025-07-03 12:06:39 -04:00
27
components/notes/List.module.scss
Normal file
27
components/notes/List.module.scss
Normal file
@ -0,0 +1,27 @@
|
||||
.section {
|
||||
margin: 1.5em 0;
|
||||
|
||||
.year {
|
||||
font-size: 2.1em;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.4em;
|
||||
}
|
||||
|
||||
.list {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
li:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:first-of-type {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
22
components/notes/List.tsx
Normal file
22
components/notes/List.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import ListItem from "./ListItem";
|
||||
|
||||
import styles from "./List.module.scss";
|
||||
|
||||
export default function List({ allNotes }) {
|
||||
const sections = [];
|
||||
|
||||
Object.entries(allNotes).forEach(([year, notes]: [string, any]) => {
|
||||
sections.push(
|
||||
<section key={year} className={styles.section}>
|
||||
<h2 className={styles.year}>{year}</h2>
|
||||
<ul className={styles.list}>
|
||||
{notes.map((note) => (
|
||||
<ListItem key={note.slug} title={note.title} date={note.date} slug={note.slug} />
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
);
|
||||
});
|
||||
|
||||
return <>{sections.reverse()}</>;
|
||||
}
|
12
components/notes/ListItem.module.scss
Normal file
12
components/notes/ListItem.module.scss
Normal file
@ -0,0 +1,12 @@
|
||||
.row {
|
||||
display: flex;
|
||||
letter-spacing: -0.008em;
|
||||
line-height: 1.75;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.date {
|
||||
width: 5.25em;
|
||||
flex-shrink: 0;
|
||||
color: var(--medium);
|
||||
}
|
23
components/notes/ListItem.tsx
Normal file
23
components/notes/ListItem.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
import Link from "next/link";
|
||||
import { format, parseISO } from "date-fns";
|
||||
|
||||
import styles from "./ListItem.module.scss";
|
||||
|
||||
export type Props = {
|
||||
title: string;
|
||||
date: string;
|
||||
slug: string;
|
||||
};
|
||||
|
||||
export default function ListItem({ title, date, slug }: Props) {
|
||||
return (
|
||||
<li className={styles.row}>
|
||||
<span className={styles.date}>{format(parseISO(date), "MMM d")}</span>
|
||||
<span>
|
||||
<Link href={`/notes/${slug}/`} prefetch={false}>
|
||||
<a>{title}</a>
|
||||
</Link>
|
||||
</span>
|
||||
</li>
|
||||
);
|
||||
}
|
77
components/notes/Meta.module.scss
Normal file
77
components/notes/Meta.module.scss
Normal file
@ -0,0 +1,77 @@
|
||||
.meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
font-size: 0.825em;
|
||||
line-height: 2.3;
|
||||
letter-spacing: 0.04em;
|
||||
color: var(--medium);
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
background: none;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
> div {
|
||||
display: inline-flex;
|
||||
margin-right: 1.6em;
|
||||
white-space: nowrap;
|
||||
|
||||
&:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.meta_icon {
|
||||
margin-right: 0.6em;
|
||||
user-select: none;
|
||||
|
||||
.icon_svg {
|
||||
vertical-align: -0.2em;
|
||||
cursor: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.date,
|
||||
.edit {
|
||||
a {
|
||||
display: inline-flex;
|
||||
}
|
||||
}
|
||||
|
||||
.tags {
|
||||
white-space: normal;
|
||||
display: inline-flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.tag {
|
||||
text-transform: lowercase;
|
||||
white-space: nowrap;
|
||||
margin-right: 0.75em;
|
||||
|
||||
&::before {
|
||||
content: "#"; // cosmetically hashtagify tags
|
||||
padding-right: 0.125em;
|
||||
color: var(--light);
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 0.3em 0 0.5em -0.03em; // TODO: why is this indented slightly?
|
||||
font-size: 2.1em;
|
||||
line-height: 1.3;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.006em;
|
||||
|
||||
a {
|
||||
background: none;
|
||||
padding-bottom: 0;
|
||||
color: inherit;
|
||||
}
|
||||
}
|
68
components/notes/Meta.tsx
Normal file
68
components/notes/Meta.tsx
Normal file
@ -0,0 +1,68 @@
|
||||
import Link from "next/link";
|
||||
import { format, parseISO } from "date-fns";
|
||||
import Hits from "../hits/Hits";
|
||||
import { DateIcon, TagIcon, EditIcon, ViewsIcon } from "../icons";
|
||||
import * as config from "../../lib/config";
|
||||
|
||||
import styles from "./Meta.module.scss";
|
||||
|
||||
export type Props = {
|
||||
title: string;
|
||||
date: string;
|
||||
slug: string;
|
||||
tags?: string[];
|
||||
};
|
||||
|
||||
export default function Meta({ title, date, slug, tags = [] }: Props) {
|
||||
return (
|
||||
<>
|
||||
<div className={styles.meta}>
|
||||
<div className={styles.date}>
|
||||
<span className={styles.meta_icon}>
|
||||
<DateIcon className={`icon ${styles.icon_svg}`} />
|
||||
</span>
|
||||
<span title={format(parseISO(date), "PPppp")}>{format(parseISO(date), "MMMM d, yyyy")}</span>
|
||||
</div>
|
||||
{tags.length > 0 && (
|
||||
<div className={styles.tags}>
|
||||
<span className={styles.meta_icon}>
|
||||
<TagIcon className={`icon ${styles.icon_svg}`} />
|
||||
</span>
|
||||
{tags.map((tag) => (
|
||||
<span key={tag} className={styles.tag}>
|
||||
{tag}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<div>
|
||||
<span className={styles.meta_icon}>
|
||||
<EditIcon className={`icon ${styles.icon_svg}`} />
|
||||
</span>
|
||||
<span>
|
||||
<a
|
||||
href={`https://github.com/${config.githubRepo}/blob/main/notes/${slug}.mdx`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
title={`Edit "${title}" on GitHub`}
|
||||
>
|
||||
Improve This Post
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className={styles.meta_icon}>
|
||||
<ViewsIcon className={`icon ${styles.icon_svg}`} />
|
||||
</span>
|
||||
<Hits slug={`notes/${slug}`} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1 className={styles.title}>
|
||||
<Link href={`/notes/${slug}/`}>
|
||||
<a>{title}</a>
|
||||
</Link>
|
||||
</h1>
|
||||
</>
|
||||
);
|
||||
}
|
Reference in New Issue
Block a user