From 8ea444c131da24a3698616f42cfccf0a9e7b42ce Mon Sep 17 00:00:00 2001 From: Jonah Scheinerman Date: Tue, 9 Feb 2021 08:44:18 -0500 Subject: [PATCH] Add dark mode for docs --- docsgen/index.tsx | 2 +- docsgen/markdown.tsx | 40 +++++++++++++++++++++++++++------------- docsgen/page.tsx | 25 ++++++++++++++++++------- docsgen/pageModel.ts | 2 +- docsgen/sidebar.tsx | 42 ++++++++++++++++++++++++++++++++++++------ docsgen/style.ts | 12 ++++++++++++ 6 files changed, 95 insertions(+), 28 deletions(-) diff --git a/docsgen/index.tsx b/docsgen/index.tsx index 6250523..1573c8c 100644 --- a/docsgen/index.tsx +++ b/docsgen/index.tsx @@ -46,7 +46,7 @@ const pages = readdirSync("docs") const orderPath = join("docs", "order.txt"); let order: string[] = []; if (existsSync(orderPath) && !statSync(orderPath).isDirectory()) { - order = readFileSync(orderPath, "UTF8").split("\n"); + order = readFileSync(orderPath, { encoding: "utf8" }).split("\n"); } function orderBy(order: string[]): (a: PageModel, b: PageModel) => number { diff --git a/docsgen/markdown.tsx b/docsgen/markdown.tsx index 658c836..6fddf0a 100644 --- a/docsgen/markdown.tsx +++ b/docsgen/markdown.tsx @@ -2,7 +2,7 @@ import { Node } from "commonmark"; import { highlight } from "highlight.js"; import * as React from "react"; import { createNodeId, getNodeText } from "./markdownUtils"; -import { component } from "./style"; +import { component, darkMode } from "./style"; interface MarkdownProps { root: Node; @@ -146,18 +146,32 @@ const CodeBlock = component("code-block", "code", { }, }); -const CodeInline = component("code-inline", "code", { - color: "#6272a4", - fontSize: 18, -}); +const CodeInline = component( + "code-inline", + "code", + { + color: "#6272a4", + fontSize: 18, + }, + darkMode({ + color: "#919dc0", + }), +); -export const Link = component("link", "a", { - color: "#008075", - textDecoration: "none", - $nest: { - "&:hover": { - color: "#00B3A4", - textDecoration: "underline", +export const Link = component( + "link", + "a", + { + color: "#008075", + textDecoration: "none", + $nest: { + "&:hover": { + color: "#00B3A4", + textDecoration: "underline", + }, }, }, -}); + darkMode({ + color: "#2EE6D6", + }), +); diff --git a/docsgen/page.tsx b/docsgen/page.tsx index dbf8276..153ed1f 100644 --- a/docsgen/page.tsx +++ b/docsgen/page.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import { Link, Markdown } from "./markdown"; import { PageModel } from "./pageModel"; import { Sidebar } from "./sidebar"; -import { component, mobile } from "./style"; +import { component, darkMode, mobile } from "./style"; interface PageProps { pages: PageModel[]; @@ -59,6 +59,10 @@ const Contents = component( background: "#EBF1F5", boxShadow: "inset 15px 0 30px -30px #182026", }, + darkMode({ + background: "#323543", + color: "#F5F8FA", + }), mobile({ overflow: "visible", boxShadow: "inset 0 15px 30px -30px #182026" }), ); @@ -80,9 +84,16 @@ const EndMatter = component("end-matter", "div", { fontSize: 14, }); -const License = component("license", "div", { - marginTop: 20, - color: "#738694", - textShadow: "0 1px 0 white", - fontSize: 12, -}); +const License = component( + "license", + "div", + { + marginTop: 20, + color: "#738694", + textShadow: "0 1px 0 white", + fontSize: 12, + }, + darkMode({ + textShadow: "0 1px 0 black", + }), +); diff --git a/docsgen/pageModel.ts b/docsgen/pageModel.ts index 58c60ee..d19b9a8 100644 --- a/docsgen/pageModel.ts +++ b/docsgen/pageModel.ts @@ -14,7 +14,7 @@ export interface PageSection { export class PageModel { public static from(path: string): PageModel { const name = basename(path, ".md"); - const source = readFileSync(path, "UTF8"); + const source = readFileSync(path, { encoding: "utf8" }); const root = parser.parse(source); return new PageModel(name, root, getTitle(root), getSections(root)); } diff --git a/docsgen/sidebar.tsx b/docsgen/sidebar.tsx index eec69c8..db7508b 100644 --- a/docsgen/sidebar.tsx +++ b/docsgen/sidebar.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import { classes, style } from "typestyle"; import { MarkdownChildren } from "./markdown"; import { PageModel } from "./pageModel"; -import { component, mobile, styles } from "./style"; +import { component, darkMode, mobile, styles } from "./style"; interface SidebarProps { pages: PageModel[]; @@ -36,7 +36,12 @@ export const Sidebar: React.FunctionComponent = ({ pages, selected return ( {links} - + View on GitHub @@ -54,6 +59,9 @@ const Container = component( fontSize: 14, overflow: "auto", }, + darkMode({ + background: "#272a35", + }), mobile({ overflow: "visible" }), ); @@ -80,18 +88,30 @@ const PageLink = component( }, }, }, + darkMode({ + color: "#E1E8ED", + background: "#1C1E26", + $nest: { + "&:hover": { + background: "#323643", + }, + }, + }), mobile({ display: "block" }), ); -const homeLink = style({ - color: HOME_COLOR, -}); +const homeLink = style( + { + color: HOME_COLOR, + }, + darkMode({ color: "#919dc0" }), +); const pageLink = style({ color: LINK_COLOR, }); -const selectedPage = style({ +const selectedPageStyles = styles({ color: "#F5F8FA", background: HOME_COLOR, $nest: { @@ -102,6 +122,8 @@ const selectedPage = style({ }, }); +const selectedPage = style(selectedPageStyles, darkMode(selectedPageStyles)); + const SectionLink = component( "section-link", "a", @@ -114,6 +136,14 @@ const SectionLink = component( }, }, }, + darkMode({ + color: "#E1E8ED", + $nest: { + "&:hover": { + background: HOME_COLOR, + }, + }, + }), mobile({ display: "none" }), ); diff --git a/docsgen/style.ts b/docsgen/style.ts index c0c0cae..736db64 100644 --- a/docsgen/style.ts +++ b/docsgen/style.ts @@ -26,6 +26,14 @@ export function mobile(...styles: CSSProps[]): CSSProps { return media({ maxWidth: 700 }, ...styles); } +export function darkMode(styles: CSSProps): CSSProps { + return { + $nest: { + "@media (prefers-color-scheme: dark)": styles, + }, + }; +} + cssRule("body", { fontFamily: `"Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif`, fontSize: 16, @@ -59,5 +67,9 @@ cssRule( paddingTop: 25, marginLeft: -20, }, + darkMode({ + color: "#919dc0", + textShadow: "1px 1px 2px #1c1e26", + }), mobile({ marginLeft: 0 }), );