feat: reader mode

This commit is contained in:
Jacky Zhao
2025-04-17 19:45:17 -07:00
parent bfd72347cf
commit b34d521293
8 changed files with 139 additions and 1 deletions

View File

@ -0,0 +1,32 @@
// @ts-ignore
import readerModeScript from "./scripts/readermode.inline"
import styles from "./styles/readermode.scss"
import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types"
import { classNames } from "../util/lang"
const ReaderMode: QuartzComponent = ({ displayClass }: QuartzComponentProps) => {
return (
<button class={classNames(displayClass, "readermode")}>
<svg
xmlns="http://www.w3.org/2000/svg"
class="readerIcon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<rect x="6" y="4" width="12" height="16" rx="1"></rect>
<line x1="9" y1="8" x2="15" y2="8"></line>
<line x1="9" y1="12" x2="15" y2="12"></line>
<line x1="9" y1="16" x2="13" y2="16"></line>
</svg>
</button>
)
}
ReaderMode.beforeDOMLoaded = readerModeScript
ReaderMode.css = styles
export default (() => ReaderMode) satisfies QuartzComponentConstructor

View File

@ -4,6 +4,7 @@ import FolderContent from "./pages/FolderContent"
import NotFound from "./pages/404"
import ArticleTitle from "./ArticleTitle"
import Darkmode from "./Darkmode"
import ReaderMode from "./ReaderMode"
import Head from "./Head"
import PageTitle from "./PageTitle"
import ContentMeta from "./ContentMeta"
@ -29,6 +30,7 @@ export {
TagContent,
FolderContent,
Darkmode,
ReaderMode,
Head,
PageTitle,
ContentMeta,

View File

@ -0,0 +1,25 @@
let isReaderMode = false
const emitReaderModeChangeEvent = (mode: "on" | "off") => {
const event: CustomEventMap["readermodechange"] = new CustomEvent("readermodechange", {
detail: { mode },
})
document.dispatchEvent(event)
}
document.addEventListener("nav", () => {
const switchReaderMode = () => {
isReaderMode = !isReaderMode
const newMode = isReaderMode ? "on" : "off"
document.documentElement.setAttribute("reader-mode", newMode)
emitReaderModeChangeEvent(newMode)
}
for (const readerModeButton of document.getElementsByClassName("readermode")) {
readerModeButton.addEventListener("click", switchReaderMode)
window.addCleanup(() => readerModeButton.removeEventListener("click", switchReaderMode))
}
// Set initial state
document.documentElement.setAttribute("reader-mode", isReaderMode ? "on" : "off")
})

View File

@ -6,7 +6,7 @@
border: none;
width: 20px;
height: 20px;
margin: 0 10px;
margin: 0;
text-align: inherit;
flex-shrink: 0;

View File

@ -0,0 +1,33 @@
.readermode {
cursor: pointer;
padding: 0;
position: relative;
background: none;
border: none;
width: 20px;
height: 20px;
margin: 0;
text-align: inherit;
flex-shrink: 0;
& svg {
position: absolute;
width: 20px;
height: 20px;
top: calc(50% - 10px);
stroke: var(--darkgray);
transition: opacity 0.1s ease;
}
}
:root[reader-mode="on"] {
& .sidebar.left,
& .sidebar.right {
opacity: 0;
transition: opacity 0.2s ease;
&:hover {
opacity: 1;
}
}
}