어둠 모드로는 부족해!여기 대안이 하나 있는데...
현재 대부분의 사이트에는 어둠의 모드를 바꾸는 옵션이 있는데, 만약 당신이 그것을 발견하지 못한다면, 당신은 비명을 질렀을 것이다. "네가 어떻게 감히 나의 망막을 태울 수 있니!"만약 내가 원하는 것이 옅은 색과 짙은 색이 아니라 회색 모드, 크리스마스 모드 또는 내가 가장 좋아하는 영화/비디오 게임 모드를 선택할 수 있다면 어떻게 해야 합니까?
https://www.infoxicator.com/es/dark-mode-no-es-suficiente-esta-es-una-alternativa
TL;박사 01 명
테마 전환 개츠비 플러그인👉
Nextjs의 주제 스위치 종속성👉 https://www.npmjs.com/package/gatsby-plugin-theme-switcher
https://www.npmjs.com/package/use-theme-switcher
React를 사용하여 다중 테마 전환 프로그램 만들기
다음은 제가 찾고 있는 기능입니다.
Next.js
을 포함하는 표준 Tailwind
블로그 템플릿부터 시작하겠습니다. 그러나 이 솔루션은 styled-components
과 CSS Modules
을 포함한 모든 스타일 라이브러리에 적용되어야 합니다.npx create-next-app --example blog-starter blog-starter-app
플러그 인 테마 색상 추가
저희는 을 사용하여 저희 사이트에 색을 추가하고 글로벌 CSS 클래스를 사용하여 저희 테마를 설정할 것입니다.
추가할 각 주제에 새 클래스를 추가하는
index.css
파일을 엽니다. 예를 들면 다음과 같습니다..theme-twitter {
--color-bg-primary: #15202B;
--color-bg-primary-light: #172D3F;
--color-bg-accent: #1B91DA;
--color-bg-accent-light: #1B91DA;
--color-bg-secondary: #657786;
--color-text-link: #1B91DA;
--color-bg-compliment: #112b48;
--color-bg-default: #192734;
--color-bg-inverse: #1B91DA;
--color-text-primary: #fff;
--color-text-secondary: #f2f2f2;
--color-text-default: #e9e9e9;
--color-text-default-soft: #6a6a6a;
--color-text-inverse: #1B91DA;
--color-text-inverse-soft: #1B91DA;
}
.theme-midnightgreen {
--color-bg-primary: #004953;
--color-bg-primary-light: #E7FDFF;
--color-bg-accent: #DE7421;
--color-bg-accent-light: #DE7421;
--color-bg-secondary: #E7FDFF;
--color-text-link: #008ca0;
--color-bg-compliment: #f5f5ff;
--color-bg-default: #f5f5f5;
--color-bg-inverse: #d77d4d;
--color-text-primary: #f5f5f5;
--color-text-secondary: #004953;
--color-text-default: #303030;
--color-text-default-soft: #484848;
--color-text-inverse: #008ca0;
--color-text-inverse-soft: #ffffffb3;
}
.theme-my-favourite-colors {
...
}
tailwind.config.js
파일을 열고 마지막으로 만든 CSS 변수로 색상 클래스를 확장합니다.예:module.exports = {
purge: ['./components/**/*.js', './pages/**/*.js'],
theme: {
extend: {
colors: {
'accent-1': 'var(--color-bg-primary)',
'accent-2': 'var(--color-bg-secondary)',
'accent-7': 'var(--color-bg-accent)',
success: '#0070f3',
cyan: '#79FFE1',
},
textColor: {
white: "var(--color-text-primary)",
grey: "var(--color-text-link)",
black: "var(--color-text-secondary)",
},
},
},
}
Note: If you are not using Tailwind, you can configure your styling solution using the same CSS variables, the rest of the steps in this tutorial should remain the same.
CSS 클래스를 문서 바디 태그에 지정하여 사용자 정의 스타일을 적용합니다.당신의 문서를 엽니다.js 파일과 하드 코드를 추가합니다. 기본 테마입니다.
<body className="theme-twitter">
<Main />
<NextScript />
</body>
페이지를 새로 고치면 선택한 수업의 주제 색을 볼 수 있습니다.CSS 변수 주제 상태
테마를 전 세계에서 모든 구성 요소에 사용할 수 있도록 관리하고 서로 다른 테마 사이를 전환한다.우리는 을 사용하여 주제 상하문과 공급자를 만들 것입니다.
context/theme-context.js
에 새 파일 생성import React from "react";
import useLocalStorage from "./context/use-local-storage";
const ThemeContext = React.createContext();
export const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useLocalStorage("theme", null);
const switchTheme = (newTheme) => {
// eslint-disable-next-line no-undef
const root = document.body;
root.classList.remove(theme);
root.classList.add(newTheme);
setTheme(newTheme);
};
return (
<ThemeContext.Provider value={{ theme, switchTheme }}>
{children}
</ThemeContext.Provider>
);
};
export default ThemeContext;
useLocalStorage
갈고리를 사용하여 테마 값을 "theme"키 아래에 오래 저장하고 있습니다.이 갈고리의 원본 코드는 여기에서 찾을 수 있습니다: React Context API로컬 저장소가 비어 있으면 초기값은null이며, 나중에 자세한 설명이 있을 것입니다.
switchTheme
갈고리는 이 함수에 전달된 새로운 값으로 주체에 추가된 CSS 클래스의 값을 대체하고 이 값을 로컬 저장소에 저장합니다._app.js
에 신규 공급자 추가import '../styles/index.css'
import { ThemeProvider } from '../context/theme-context';
export default function MyApp({ Component, pageProps }) {
return <ThemeProvider>
<Component {...pageProps} />
</ThemeProvider>
}
https://github.com/infoxicator/use-theme-switcher/blob/master/src/use-local-storage.js 테마 선택기
사용 가능한 테마 사이를 전환할 수 있는 아주 기본적인 테마 선택기 구성 요소를 만듭니다.
import React from "react";
const myThemes = [
{
id: "theme-midnightgreen",
name: "Midnight Green",
},
{
id: "theme-spacegray",
name: "Space Gray",
},
{
id: "theme-twitter",
name: "Twitter Dark",
}
]
const ThemePicker = ({ theme, setTheme }) => {
if (theme) {
return (
<div>
{myThemes.map((item, index) => {
const nextTheme = myThemes.length -1 === index ? myThemes[0].id : myThemes[index+1].id;
return item.id === theme ? (
<div key={item.id} className={item.id}>
<button
aria-label={`Theme ${item.name}`}
onClick={() => setTheme(nextTheme)}
>
{item.name}
</button>
</div>
) : null;
}
)}
</div>
);
}
return null;
};
export default ThemePicker;
이 구성 요소는 사용 가능한 테마 그룹을 가져오고, 이 단추를 보여 줍니다. 이 단추를 누르면 다음 사용 가능한 테마를 설정합니다.이것은 테마 교환기 구성 요소의 매우 기본적인 구현이지만, 예를 들어 아래 목록에서 목록을 선택하거나 보여주는 사용자 정의 논리와 디자인을 추가할 수 있습니다.사이트 상단에
ThemeSwitcher
구성 요소를 렌더링합니다.layout.js
을 열고 다음을 추가합니다.import ThemePicker from './theme-picker';
import React, { useContext } from "react"
import ThemeContext from '../context/theme-context';
export default function Layout({ preview, children }) {
const { theme, switchTheme } = useContext(ThemeContext);
return (
<>
<Meta />
<div className="min-h-screen bg-accent-1 text-white">
<Alert preview={preview} />
<ThemePicker theme={theme ? theme : 'theme-midnightgreen'} setTheme={switchTheme} />
<main>{children}</main>
</div>
<Footer />
</>
)
}
사용자가 사용자 정의 테마를 선택하지 않았을 때 테마 값은 처음으로 null
이므로 기본 테마 값을 ThemePicker
구성 요소에 전달합니다.죽음의 백광을 극복하다
누가 이런 간단한 버그가 이렇게 복잡하고 사이트를 보여주는 다른 방식(서버 사이드 디스플레이, 정적 사이트 생성, 클라이언트 디스플레이)과 이렇게 깊은 관계를 가진다고 생각했겠는가?요컨대 플래시는 초기 HTML을 보여주는 시간에 의해 만들어진다.SSR이나 SSG를
next.js
또는 gatsby
등의 도구와 함께 사용할 때 HTML은 클라이언트에 도착하기 전에 미리 나타납니다. 따라서 로컬에서 저장된 초기 테마 값은 서버에서 나타나는 값과 다르고 정확한 테마를 적용하는 동시에 작은'flash'를 생성합니다.이 문제를 해결하는 관건은 사이트 내용을 DOM에 보여주기 전에 정확한 CSS 클래스를 설정하는'render Blocking'스크립트를 사용하는 것이다.
theme-script.js
이라는 새 파일 만들기import React from "react";
function setColorsByTheme(
defaultDarkTheme,
defaultLightTheme,
themeStorageKey
) {
var mql = window.matchMedia("(prefers-color-scheme: dark)");
var prefersDarkFromMQ = mql.matches;
var persistedPreference = localStorage.getItem(themeStorageKey);
var root = document.body;
var colorMode = "";
var hasUsedToggle = typeof persistedPreference === "string";
if (hasUsedToggle) {
colorMode = JSON.parse(persistedPreference);
} else {
colorMode = prefersDarkFromMQ ? defaultDarkTheme : defaultLightTheme;
localStorage.setItem(themeStorageKey, JSON.stringify(colorMode));
}
root.classList.add(colorMode);
}
const ThemeScriptTag = () => {
const themeScript = `(${setColorsByTheme})(
'theme-twitter',
'theme-midnightgreen',
'theme',
)`;
// eslint-disable-next-line react/no-danger
return <script dangerouslySetInnerHTML={{ __html: themeScript }} />;
};
export default ThemeScriptTag;
만약 당신이 이 문제와 이 해결 방안을 깊이 연구하고 싶다면Josh W.Comau는 우수한
을 창조하여 한 걸음 한 걸음 이 문제를 분석하고 이 해결 방안을 제시했다.블로그 게시물 결론
이게 다야!지금, 나는 당신에게 도전합니다. 당신이 가장 좋아하는 영화나 비디오 게임 테마를 선택하여 당신의 사이트에 적용할 수 있습니다. 만약 창의적이라고 생각한다면, 당신은 자신의 사용자 정의 테마 전환 구성 요소를 만들 수 있습니다. 예를 들어 그의 사이트 에 추가된 구성 요소, 이 구성 요소는 잠금 해제 가능한 테마를 가지고 있으며, 이 사이트를 통해서만 활성화할 수 있습니다. 그러니 부활절 달걀을 찾아보세요!😉
Reference
이 문제에 관하여(어둠 모드로는 부족해!여기 대안이 하나 있는데...), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/infoxicator/dark-mode-is-not-enough-here-is-an-alternative-nj1텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)