1
mirror of https://github.com/jakejarvis/jarv.is.git synced 2025-09-15 05:45:33 -04:00

responsive style adjustments

This commit is contained in:
2021-12-31 12:46:39 -05:00
parent 1bbee816c2
commit d0e00b197c
13 changed files with 73 additions and 108 deletions

View File

@@ -1,6 +1,4 @@
.home { .home {
font-size: 1em;
h1 { h1 {
margin: 0 0 0.3em -0.03em; // TODO: why is this indented slightly? margin: 0 0 0.3em -0.03em; // TODO: why is this indented slightly?
font-size: 1.8em; font-size: 1.8em;
@@ -35,10 +33,10 @@
} }
} }
sup { .pgp_key {
letter-spacing: normal; margin: 0 0.15em;
position: relative; font-size: 0.65em;
margin-left: 0.2em; word-spacing: -0.3em;
a { a {
background: none; background: none;
@@ -46,13 +44,7 @@
} }
} }
.pgp { .quiet {
font-size: 0.875em;
word-spacing: -0.3em;
margin-right: 0.075em;
}
.light {
color: var(--medium-light); color: var(--medium-light);
} }

View File

@@ -133,7 +133,7 @@ export default function Home() {
> >
the Tooth Fairy the Tooth Fairy
</Link> </Link>
. <span className={styles.light}>I've improved a bit since then, I think...</span> . <span className={styles.quiet}>I've improved a bit since then, I think...</span>
</p> </p>
<p> <p>
@@ -220,11 +220,9 @@ export default function Home() {
<Link href="/contact/" title="Send an email" lightColor="#de0c0c" darkColor="#ff5050"> <Link href="/contact/" title="Send an email" lightColor="#de0c0c" darkColor="#ff5050">
email email
</Link>{" "} </Link>{" "}
<sup className="monospace"> <sup className={`monospace ${styles.pgp_key}`}>
<Link href="/pubkey.asc" title="My Public Key" lightColor="#757575" darkColor="#959595" external={true}> <Link href="/pubkey.asc" title="My Public Key" lightColor="#757575" darkColor="#959595" external={true}>
<span className={styles.pgp}> <LockIcon className="icon" /> 2B0C 9CF2 51E6 9A39
<LockIcon alt="PGP Key" /> 2B0C 9CF2 51E6 9A39
</span>
</Link> </Link>
</sup> </sup>
,{" "} ,{" "}

View File

@@ -23,14 +23,8 @@
} }
} }
.meta_icon { .icon {
margin-right: 0.6em; margin-right: 0.6em;
user-select: none;
.icon_svg {
vertical-align: -0.2em;
cursor: inherit;
}
} }
.date, .date,

View File

@@ -18,15 +18,17 @@ export default function Meta({ title, date, slug, tags = [] }: Props) {
<> <>
<div className={styles.meta}> <div className={styles.meta}>
<div className={styles.date}> <div className={styles.date}>
<span className={styles.meta_icon}> <span>
<DateIcon className={`icon ${styles.icon_svg}`} /> <DateIcon className={`icon ${styles.icon}`} />
</span>
<span title={format(parseISO(date), "PPppp")}>
<Link href={`/notes/${slug}/`}>{format(parseISO(date), "MMMM d, yyyy")}</Link>
</span> </span>
<span title={format(parseISO(date), "PPppp")}>{format(parseISO(date), "MMMM d, yyyy")}</span>
</div> </div>
{tags.length > 0 && ( {tags.length > 0 && (
<div className={styles.tags}> <div className={styles.tags}>
<span className={styles.meta_icon}> <span>
<TagIcon className={`icon ${styles.icon_svg}`} /> <TagIcon className={`icon ${styles.icon}`} />
</span> </span>
{tags.map((tag) => ( {tags.map((tag) => (
<span key={tag} className={styles.tag}> <span key={tag} className={styles.tag}>
@@ -36,8 +38,8 @@ export default function Meta({ title, date, slug, tags = [] }: Props) {
</div> </div>
)} )}
<div> <div>
<span className={styles.meta_icon}> <span>
<EditIcon className={`icon ${styles.icon_svg}`} /> <EditIcon className={`icon ${styles.icon}`} />
</span> </span>
<span> <span>
<a <a
@@ -51,8 +53,8 @@ export default function Meta({ title, date, slug, tags = [] }: Props) {
</span> </span>
</div> </div>
<div> <div>
<span className={styles.meta_icon}> <span>
<ViewsIcon className={`icon ${styles.icon_svg}`} /> <ViewsIcon className={`icon ${styles.icon}`} />
</span> </span>
<Hits slug={`notes/${slug}`} /> <Hits slug={`notes/${slug}`} />
</div> </div>

View File

@@ -12,10 +12,30 @@
align-items: center; align-items: center;
line-height: 1; line-height: 1;
svg { .link {
display: inline-flex;
align-items: center;
color: var(--medium-dark);
background: none;
padding-bottom: 0;
&:hover {
color: var(--link);
}
}
.icon {
width: 1.6em; width: 1.6em;
height: 1.6em; height: 1.6em;
} }
.text {
font-size: 0.95em;
font-weight: 500;
margin-top: 0.125em;
margin-left: 0.75em;
line-height: 1;
}
} }
.theme_toggle { .theme_toggle {
@@ -24,15 +44,20 @@
@media screen and (max-width: 800px) { @media screen and (max-width: 800px) {
.item { .item {
margin-left: 2em; margin-left: 1.75em;
svg { .icon {
width: 1.75em; width: 1.75em;
height: 1.75em; height: 1.75em;
} }
// hide text next to emojis on mobile
.text {
display: none;
}
} }
.theme_toggle { .theme_toggle {
margin-left: 1.6em; margin-left: 1.4em;
} }
} }

View File

@@ -1,27 +1,27 @@
import dynamic from "next/dynamic"; import dynamic from "next/dynamic";
import MenuItem from "./MenuItem"; import Link from "next/link";
import { HomeIcon, NotesIcon, ProjectsIcon, ContactIcon } from "../icons"; import { HomeIcon, NotesIcon, ProjectsIcon, ContactIcon } from "../icons";
import styles from "./Menu.module.scss"; import styles from "./Menu.module.scss";
const menuItems = [ const menuItems = [
{ {
icon: <HomeIcon />, icon: <HomeIcon className={`icon ${styles.icon}`} />,
text: "Home", text: "Home",
href: "/", href: "/",
}, },
{ {
icon: <NotesIcon />, icon: <NotesIcon className={`icon ${styles.icon}`} />,
text: "Notes", text: "Notes",
href: "/notes/", href: "/notes/",
}, },
{ {
icon: <ProjectsIcon />, icon: <ProjectsIcon className={`icon ${styles.icon}`} />,
text: "Projects", text: "Projects",
href: "/projects/", href: "/projects/",
}, },
{ {
icon: <ContactIcon />, icon: <ContactIcon className={`icon ${styles.icon}`} />,
text: "Contact", text: "Contact",
href: "/contact/", href: "/contact/",
}, },
@@ -35,11 +35,15 @@ export default function Menu() {
<ul className={styles.menu}> <ul className={styles.menu}>
{menuItems.map((item, index) => ( {menuItems.map((item, index) => (
<li key={index} className={styles.item}> <li key={index} className={styles.item}>
<MenuItem {...item} /> <Link href={item.href} prefetch={false}>
<a className={styles.link}>
{item.icon} <span className={styles.text}>{item.text}</span>
</a>
</Link>
</li> </li>
))} ))}
<li className={`${styles.item} ${styles.theme_toggle}`}> <li className={`${styles.item} ${styles.theme_toggle}`}>
<ThemeToggle /> <ThemeToggle className={styles.icon} />
</li> </li>
</ul> </ul>
); );

View File

@@ -1,30 +0,0 @@
.item_link {
display: inline-flex;
align-items: center;
color: var(--medium-dark);
background: none;
padding-bottom: 0;
&:hover {
color: var(--link);
}
}
.item_icon {
user-select: none;
}
.item_text {
font-size: 0.95em;
font-weight: 500;
margin-top: 0.05em;
margin-left: 0.75em;
line-height: 1;
}
@media screen and (max-width: 800px) {
// hide text next to emojis on mobile
.item_text {
display: none;
}
}

View File

@@ -1,20 +0,0 @@
import Link from "next/link";
import styles from "./MenuItem.module.scss";
type Props = {
href: URL | string;
icon: any;
text: string;
};
export default function MenuItem({ href, icon, text }: Props) {
return (
<Link href={href} prefetch={false}>
<a className={styles.item_link}>
<span className={styles.item_icon}>{icon}</span>
<span className={styles.item_text}>{text}</span>
</a>
</Link>
);
}

View File

@@ -8,19 +8,20 @@ const storageKey = "dark_mode";
export const getDarkPref = () => localStorage.getItem(storageKey); export const getDarkPref = () => localStorage.getItem(storageKey);
export const setDarkPref = (pref: boolean) => localStorage.setItem(storageKey, pref as unknown as string); export const setDarkPref = (pref: boolean) => localStorage.setItem(storageKey, pref as unknown as string);
// use the `<html class="...">` as a hint to what the theme was set to outside of the button component // use the `<html data-theme="...">` as a hint to what the theme was set to outside of the button component
// there's probably (definitely) a cleaner way to do this..? // TODO: there's probably (definitely) a cleaner way to do this, maybe with react hooks..?
export const isDark = () => document.documentElement.getAttribute("data-theme") === "dark"; export const isDark = () => document.documentElement.getAttribute("data-theme") === "dark";
// sets appropriate `<html data-theme="...">` CSS property // sets appropriate `<html data-theme="...">` and color-scheme CSS properties
export const updateDOM = (dark: boolean) => { export const updateDOM = (dark: boolean) => {
const root = document.documentElement; const root = document.documentElement;
const theme = dark ? "dark" : "light";
// set `<html data-theme="...">` root.setAttribute("data-theme", theme);
root.setAttribute("data-theme", dark ? "dark" : "light"); root.style.colorScheme = theme;
}; };
export default function ThemeToggle() { export default function ThemeToggle({ className = "" }) {
// sync button up with theme and preference states after initialization // sync button up with theme and preference states after initialization
const [dark, setDark] = useState(isDark()); const [dark, setDark] = useState(isDark());
const [saved, setSaved] = useState(!!getDarkPref()); const [saved, setSaved] = useState(!!getDarkPref());
@@ -61,7 +62,7 @@ export default function ThemeToggle() {
title={dark ? "Toggle Light Mode" : "Toggle Dark Mode"} title={dark ? "Toggle Light Mode" : "Toggle Dark Mode"}
aria-label={dark ? "Toggle Light Mode" : "Toggle Dark Mode"} aria-label={dark ? "Toggle Light Mode" : "Toggle Dark Mode"}
> >
{dark ? <BulbOffIcon /> : <BulbOnIcon />} {dark ? <BulbOffIcon className={`icon ${className}`} /> : <BulbOnIcon className={`icon ${className}`} />}
</button> </button>
); );
} }

View File

@@ -10,6 +10,7 @@ export default function RepositoryGrid({ repos }) {
<RepositoryCard key={repo.name} {...repo} /> <RepositoryCard key={repo.name} {...repo} />
))} ))}
</div> </div>
<p className={styles.view_more}> <p className={styles.view_more}>
<a href="https://github.com/jakejarvis?tab=repositories" target="_blank" rel="noopener noreferrer"> <a href="https://github.com/jakejarvis?tab=repositories" target="_blank" rel="noopener noreferrer">
View more on GitHub... View more on GitHub...

View File

@@ -3,7 +3,7 @@ import type { ReactPlayerProps } from "react-player";
import styles from "./FullPageVideo.module.scss"; import styles from "./FullPageVideo.module.scss";
export default function Video(props: ReactPlayerProps) { export default function FullPageVideo(props: ReactPlayerProps) {
return ( return (
<div className={styles.wrapper}> <div className={styles.wrapper}>
<ReactPlayer className={styles.react_player} width="100%" height="100%" {...props} /> <ReactPlayer className={styles.react_player} width="100%" height="100%" {...props} />

View File

@@ -31,6 +31,7 @@ module.exports = withBundleAnalyzer({
{ {
loader: "@svgr/webpack", loader: "@svgr/webpack",
options: { options: {
icon: true,
typescript: true, typescript: true,
svgProps: { svgProps: {
className: "icon", className: "icon",

View File

@@ -1,7 +1,7 @@
@use "reset"; @use "reset";
@use "typography"; @use "typography";
@use "colors";
@use "syntax"; @use "syntax";
@use "colors";
// Global Styles // Global Styles
body { body {
@@ -89,10 +89,7 @@ a {
display: inline-block; display: inline-block;
height: 1.2em; height: 1.2em;
width: 1.2em; width: 1.2em;
margin: 0 0.05em; vertical-align: -0.2em;
vertical-align: -0.22em;
border: 0;
cursor: inherit;
} }
// all code // all code