feat: reader mode
This commit is contained in:
		
							
								
								
									
										32
									
								
								quartz/components/ReaderMode.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								quartz/components/ReaderMode.tsx
									
									
									
									
									
										Normal 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
 | 
			
		||||
@@ -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,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										25
									
								
								quartz/components/scripts/readermode.inline.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								quartz/components/scripts/readermode.inline.ts
									
									
									
									
									
										Normal 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")
 | 
			
		||||
})
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
  border: none;
 | 
			
		||||
  width: 20px;
 | 
			
		||||
  height: 20px;
 | 
			
		||||
  margin: 0 10px;
 | 
			
		||||
  margin: 0;
 | 
			
		||||
  text-align: inherit;
 | 
			
		||||
  flex-shrink: 0;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										33
									
								
								quartz/components/styles/readermode.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								quartz/components/styles/readermode.scss
									
									
									
									
									
										Normal 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;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user