import React, { useState, useEffect } from "react"
import "./themetog.css"
const Toggle = () => {
const websiteTheme = typeof window != `undefined` ? window.__theme : null
const [ theme, setTheme ] = useState(websiteTheme)
useEffect(() => {
setTheme(window.__theme)
window.__onThemeChange = () => {
setTheme(window.__theme)
}
}, [])
const ThemeToggle = () => {
window.__setPreferredTheme(websiteTheme === 'dark' ? 'light' : 'dark')
}
return (
<>
<button onClick={ThemeToggle} id="tog"/>
<label className="toggleback" htmlFor="tog">
<div className="togglecon"/>
</label>
</>
)
}
export default Toggle
내가 기반으로 사용중인 gatsby-blog-starter는 html.js가 없는데, .cache/default-html.js 파일을 src폴더로 가져와서 html.js로 바꿔주면 된다.
그 다음 body태그에 'light'과 같은 기본 테마를 className
으로 지정해주고
dangerouslySetInnerHtml
사용하여 다음 스크립트를 삽입.
https://overreacted.io 를 참고함
<script dangerouslySetInnerHTML={{
__html: `
(function() {
window.__onThemeChange = function() {};
function setTheme(newTheme) {
window.__theme = newTheme;
preferredTheme = newTheme;
document.body.className = newTheme;
window.__onThemeChange(newTheme);
}
var preferredTheme;
try {
preferredTheme = localStorage.getItem('theme');
} catch (err) { }
window.__setPreferredTheme = function(newTheme) {
setTheme(newTheme);
try {
localStorage.setItem('theme', newTheme);
} catch (err) {}
}
var darkQuery = window.matchMedia('(prefers-color-scheme: dark)');
darkQuery.addListener(function(e) {
window.__setPreferredTheme(e.matches ? 'dark' : 'light')
});
setTheme(preferredTheme || (darkQuery.matches ? 'dark' : 'light'));
})();
`,
}}
/>
.light {
--color-text: black;
--color-text-sub: var(--black-90);
--color-line: rgba(10,10,10,0.2);
}
.dark {
--color-text: white;
--color-text-sub: var(--black-10);
--color-line: rgba(240,240,240,0.2);
}
이런 식으로 변수를 만들어주면 된다.
스크롤을 내리면 사라지고 올리면 나타난다.
https://lxieyang.github.io/blogs/tech-2018-08-18-reactstrap-gatsby-auto-hiding-navbar-trick/
https://www.gatsbyjs.com/plugins/gatsby-remark-autolink-headers/
npm install --save gatsby-remark-autolink-headers
각 제목들에 링크를 달아주는 역할을 함. 설치 후 gatsby-config에서
gatsby-transformer-remark
아래 plugin에 추가해준다.
export const pageQuery = graphql`
query BlogPostBySlug(
$id: String!
$previousPostId: String
$nextPostId: String
) {
site {
siteMetadata {
title
}
}
markdownRemark(id: { eq: $id }) {
id
excerpt(pruneLength: 160)
html
tableOfContents
}
blog-post.js
의 일부이다. tableOfContents를 알아서 잘 불러와준다. html태그형태로 불러와지니 dangerouslySetInnerHTML
로 밀어넣어주면 된다.
문제는 toc에서 각 제목으로 클릭해서 이동하면 제목이 위에 딱 붙는 식으로 스크롤이 되어버려서 네비바에 가려진다는 것..
css의 scroll-margin-top
을 사용하면 약간의 여백을 만들어서 쉽게 해결할 수 있다.
gatsby-remark-autolink-headers
에 offsetY
라는 속성이 이 역할을 한다고는 나와있는데 뭘 잘못했는지 작동을 안했다.