Astrojs 및 tailwindCSS로 테마 토글 버튼 빌드
16256 단어 astrowebdevtailwindcssjavascript
Next.js 사용
Next.js 위에 구축된 내 블로그에서 어두운 모드를 전환하는 ThemeContext를 작성했습니다. ThemeContext는 앱을 마운트할 때 루트 HTML에
class="dark"
를 추가합니다. 이런 식으로 TailwindCSS는 현재 테마가 무엇인지 인식할 수 있습니다. 1// The code I am using in my blog built with Next.js
import { useEffect, useState, createContext } from "react";
const defaultState = {
theme: "light",
toggleDark: () => {},
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q0bxxcx8cz7eea9bmoem.jpg)
};
export const ThemeContext = createContext(defaultState);
export const ThemeProvider = ({ initialTheme, children }) => {
const [theme, setTheme] = useState("light");
const rawSetTheme = (rawTheme) => {
const root = window.document.documentElement;
const isDark = rawTheme === "dark";
root.classList.remove(isDark ? "light" : "dark");
root.classList.add(rawTheme);
};
if (initialTheme) {
rawSetTheme(initialTheme);
}
React.useEffect(() => {
rawSetTheme(theme);
}, [theme]);
return (
<ThemeContext.Provider value={[ theme, setTheme ]}>
{children}
</ThemeContext.Provider>
);
};
Astro.js 사용
그러나 Context API의 사용을 유지하려면 아래와 같이 작성해야 할 수 있습니다.
// mainPage.astro
---
import ContextWrapperedComponent from "./ContextWrapperedComponent"
---
<ContextWrapperedComponent client:load />
// ContextWrapperedComponent
export const ContextWrapperedComponent = () => {
// logic for context and components
return (
<div>
// bunch of components that rely on context
</div>
)
}
Astro.js - Partial Hydration 2 아이디어를 기반으로 전체
ContextWrapperedComponent
를 client:load
또는 client:only
로 레이블을 지정하여 수화시키고 HTML에 Javascript로 주입해야 합니다. 그러나 이런 식으로 주입되어 우리가 원하는 것이 아닌 전체 번들 크기를 늘리는 불필요한 스크립트가 많이 있습니다.그래서 어두운 모드 상태의 저장소를 Context에서 localStorage로 전환하기로 결정했습니다.
언뜻 보기에 이 구현은 간단해 보이지만 여전히 많은 주의 사항이 있습니다.
주의 사항 1 - 깜박이는 페이지
Astro의 렌더링 프로세스는 먼저 HTML과 CSS를 클라이언트에 보내고 수화된 템플릿 문자열을 마운트하고 이벤트를 수신하여 스크립트를 주입하는 것입니다. 이 동작은 원하지 않는 결과를 초래할 수 있습니다.
// This code will update the page's theme upon the finsish
// of the first time painting, but that is not what we want.
useEffect(() => {
let theme: "light" | "dark";
if (typeof localStorage !== "undefined" && localStorage.getItem("theme")) {
theme = localStorage.getItem("theme") as "light" | "dark";
} else if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
theme = "dark";
} else {
theme = "light";
}
if (theme === "light") {
setTheme("light");
} else {
setTheme("dark");
}
}, []);
예를 들어 기본 테마가 어두운 모드이지만 localStorage에 저장된 항목이 밝은 모드인 경우. HTML은 먼저 다크 모드를 표시하고 클라이언트 측이 마운트되면 이벤트가 수화된 스크립트 주입을 트리거하고 페이지가 라이트 모드로 업데이트되며 이 프로세스는 사용자가 페이지를 변경할 때마다 계속 작동합니다. 결과적으로 페이지가 계속 깜박입니다.
깜박임 문제를 해결하려면 브라우저의 첫 번째 그림을 그리기 전에 테마를 업데이트해야 합니다.
고맙게도 Astro.js는 이미 우리를 돌보고 있습니다. 그들의 API에서 특수 속성
is:inline
3 을 사용하여 있는 그대로 HTML 및 CSS로 클라이언트에 스크립트를 보낼 수 있습니다. Astro는 이 스크립트를 수화하지 않고 어떤 종류의 최적화도 연습하지 않습니다. 진지하게 말하자면 이것은 Astro의 철학에서 환영받지 못하지만 우리의 응용 프로그램에 필요합니다. 그 외에도 Astro.js의 공식 문서도 이 접근 방식을 채택했습니다. 4// With this code, we can update the page's theme before the first-time painting.
// You should put the code into <script is:inline>
const html = document.querySelector("html");
const theme = (() => {
if (
typeof localStorage !== "undefined" &&
localStorage.getItem("theme")
) {
return localStorage.getItem("theme");
}
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
return "dark";
}
return "light";
})();
if (theme === "light") {
html.classList.remove("dark");
} else {
html.classList.add("dark");
}
주의 사항 2 - 토글 버튼의 전환
원래 내 어두운 모드 전환 버튼은 어두운 모드 아래에 있어 태양 아이콘을 표시하고 밝은 모드 아래에 달 아이콘을 표시합니다. 이 디자인의 문제는 경고 1에 가깝습니다. 깜박임 문제가 있습니다. 처음에는 위의 솔루션으로 했던 것처럼 아이콘을 업데이트할 수 있다고 생각했지만 나중에 이것이 작동하지 않는다는 것을 발견했고 그 이유는 매우 간단합니다.
상호 작용하려면 토글 버튼이 필요하기 때문에 Astro.js가 이 스크립트를 수화함을 나타내기 위해 접두사
client:load
를 붙여야 합니다. 그러나 첫 번째 페인팅 시 하이드레이트된 스크립트가 아직 주입되지 않았으므로 is:inline
스크립트가 아이콘을 업데이트할 대상 버튼을 찾을 수 없습니다. 버튼은 첫 번째 페인팅이 완료된 후에만 나타납니다.이 문제를 해결하려면 토글 버튼의 디자인을 변경해야 합니다. 이제 태양과 달 아이콘이 동시에 표시되지만 어느 것이 현재 테마인지 나타내기 위해 희미하게 전환됩니다.
결론
Astro.js를 사용한 코딩은 새로운 여정이며 발견할 가능성이 많습니다. 탐색 중에 발견한 내용을 계속 업데이트할 것입니다.
TailwindCSS - dark mode ↩
Astro - Partial Hydration ↩
Astro - is:inline ↩
withAstro - docs - GItHub ↩
Reference
이 문제에 관하여(Astrojs 및 tailwindCSS로 테마 토글 버튼 빌드), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/summerbud/build-the-theme-toggle-button-with-astrojs-and-tailwindcss-mmp텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)