ReactJS에 색상 테마를 추가하는 방법은 무엇입니까?

27651 단어 reactnextjsdark
짙은 색 모드를 제외하고react 사이트에 임의의 색 테마를 추가할 수 있습니다.
TL;DR은 작은 react 갈고리와 CSS 사용자 정의 속성을 사용하여react 프로그램에 임의의 색 테마를 추가합니다.여기서 보기: use-color-theme
지난 몇 주 동안 나는 내 사이트를 업그레이드하고 어둠의 패턴의 기능을 포함하여 완전히 새롭게 설계해 왔다.어두운 모드/조명을 추가할 수 있는 좋은 자원을 찾았어요.
- 모드 전환이지만 적절한 주제와 두 개 이상의 주제에 대한 정보는 거의 없습니다.
이것이 바로 내가 나의 사이트를 위해 새로운 기능을 구축하기로 결정한 이유이다. use-color-theme.
간단한 반응 연결로 light-theme, dark-theme 및 기타 전환 가능body 표시에서 초기화합니다.갈고리는 CSS custom
properties
과 함께 작동하며prefers-color-scheme 및 사용자와 일치하는 엔진 덮개 아래의 로컬 스토리지
항상
색상 테마화.
현재 새로운 색 테마를 추가하려면 몇 단계만 필요합니다.제목에 있는 테마 아이콘을 클릭하여 나의 site을 보십시오.

초기 설정


여러 테마를 추가하는 것은 여태껏 이렇게 간단하지 않았다.간단한 절차에 따라 웹 사이트에 테마를 추가할 수 있습니다.
이 절차를 완료하기 위해 예시 페이지를 만들거나 click here을 만들어서'페이지에 추가'부분으로 바로 이동합니다.
우선, 우리는 새로운 디렉터리를 만들고 기초 지식을 설치합니다.
mkdir colorful && cd colorful
yarn init -y
yarn add react react-dom next
다음은 pages에 필요한 NextJs 폴더를 만들고 두 개의 파일을 만듭니다. _app.jsindex.js입니다.
우리도 그것을 예뻐 보일 수 있도록 기초 지식을 첨가합시다.
_ 응용 프로그램.js:
export const _App = ({ pageProps, Component }) => {

  return (
    <>
      <style jsx global>{`
        html,
        body {
          padding: 0;
          margin: 0;
          font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto,
          Ubuntu, Cantarell, Fira Sans, Helvetica Neue, sans-serif;
        }

        body {
          background-color: #fff;
        }

        a {
          color: inherit;
          text-decoration: none;
        }

        * {
          box-sizing: border-box;
        }

        header {
          height: 100px;
          position: sticky;
          top: 0;
          margin-top: 32px;
          background-color: #fff
        }

        nav {
          max-width: 760px;
          padding: 32px;
          display: flex;
          justify-content: flex-end;
          align-items: center;
          margin: 0 auto;
        }

        button {
          border: 0;
          border-radius: 4px;
          height: 40px;
          min-width: 40px;
          padding: 0 8px;
          display: flex;
          justify-content: center;
          align-items: center;
          background-color: #e2e8f0;
          cursor: pointer;
          color: #fff;
          margin-left: 16px;
        }

        button:hover, button:focus, button:active {
          background-color: var(--button-bg-hover);
          outline: none;
        }
      `}</style>
      <header>
        <nav>
          <button>Toggle</button>
        </nav>
      </header>
      <Component {...pageProps} />
    </>
  );
};

export default _App;
지수회사 명
export default function Index() {
  return <>
    <style jsx>{`
      .wrapper {
        max-width: 760px;
        padding: 0 32px;
        margin: 0 auto;
      }
    `}</style>
    <main className="page">
      <div className="wrapper">
        <h1 className="intro">Hello World!</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Adipisci
          animi consectetur delectus dolore eligendi id illo impedit iusto,
          laudantium nam nisi nulla quas, qui quisquam voluptatum? Illo nostrum
          odit optio.
        </p>
      </div>

    </main>
  </>;
}

CSS 변수


테마 스타일에 CSS 사용자 정의 속성을 추가합니다.
지수회사 명
...
<style jsx>{`
 ...

  h1 {
    color: var(--headings);
  }

  p {
    color: var(--text)
  }
`}</style>
...
응용 프로그램에서js 파일, 그리고 우리는 서로 다른 색을 가진 전역 CSS 변수를 추가할 수 있습니다.CSS 속성을 js의 다른 CSS와 함께 추가할 수도 있습니다
프레임워크나 일반 css 파일, 클래스만 일치하면
제목에 사용할 색상을 교환하여 CSS 속성을 전체적으로 사용합니다.
_ 응용 프로그램.회사 명
...
 <style jsx global>{`
  ...
  body {
    background-color: var(--background);
  }

  header {
    height: 100px;
    position: sticky;
    top: 0;
    margin-top: 32px;
    background-color: var(--background);
    backdrop-filter: blur(10px);
  }

  nav {
    max-width: 760px;
    padding: 32px;
    display: flex;
    justify-content: flex-end;
    align-items: center;
    margin: 0 auto;
  }

  button {
    border: 0;
    border-radius: 4px;
    height: 40px;
    width: 40px;
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: var(--button-bg);
    transition: background-color 0.2s ease-in;
    cursor: pointer;
    color: var(--headings)
  }

  button:hover, button:focus, button:active {
    background-color: var(--button-bg-hover);
    outline: none;
  }

  body {
    --button-bg: #e2e8f0;
    --button-bg-hover: #cdd7e5;
    --background: #fff;
    --headings: #000;
    --text: #38393e;
  }
`}</style>

useColorTheme 추가


터미널에서 yarn add use-color-theme을 실행하여 사용자 정의 갈고리를 추가하고 응용 프로그램에서 실행합니다.js 파일.이것은 테마가 모든 페이지에서 전체적으로 사용할 수 있는지 확인합니다.
_ 응용 프로그램.회사 명
import useColorTheme from "use-color-theme";

export const _App = ({ pageProps, Component }) => {
  const colorTheme = useColorTheme('light-theme', {
    classNames: ['light-theme', 'dark-theme', 'funky']
  });
  return (
    <>
      <style jsx global>{`
        ...

        .light-theme {
          --button-bg: #e2e8f0;
          --button-bg-hover: #cdd7e5;
          --background: #fff;
          --headings: #000;
          --text: #38393e;
        }

        .dark-theme {
          --button-bg: rgb(255 255 255 / 0.08);
          --button-bg-hover: rgb(255 255 255 / 0.16);
          --background: #171923;
          --headings: #f9fafa;
          --text: #a0aec0;
        }

        .funky {
          --button-bg: #1f2833;
          --button-bg-hover: #425069;
          --background: #0b0c10;
          --headings: #66fcf1;
          --text: #e647ff;
        }
    `}</style>
      <header>
        <nav>
          <button onClick={colorTheme.toggle}>Toggle</button>
        </nav>
      </header>
      ...
    </>
  );
};

export default _App;

상세히


디테일을 봐라, 무슨 일이 일어났는지 봐라.
  • useColorTheme을 가져오고 모든 것을 사용합니다
    기타 반응 훅:
  •     const colorTheme = useColorTheme('light-theme', {
          classNames: ['light-theme', 'dark-theme', 'funky']
        });
    
    첫 번째 매개 변수는 초기 클래스입니다. 다른 매개 변수를 선택하지 않으면 이 클래스를 사용합니다.두 번째 매개 변수는
    configuration은 연결에 사용됩니다.원하는 방식으로 클래스를 명명할 수 있지만, 의미 이름을 사용하는 것을 권장합니다
  • , .light-theme, .dark-theme, .funky에 클래스를 추가했습니다.
    다른 색 변수.
  • 우리는 colorTheme.toggle
  • 을 사용하여 단추에 onClick 기능을 추가했다

    특정 주제 설정


    그런데 만약에 제가 특정한 주제로 바꾸고 싶다면?
    간단한 해결 방안이 하나 더 있다.구현 방법을 살펴보겠습니다.
    _ 응용 프로그램.회사 명
    ...
    <nav>
      <button onClick={() => colorTheme.set('light-theme')}>Light</button>
      <button onClick={() => colorTheme.set('dark-theme')}>Dark</button>
      <button onClick={() => colorTheme.set('funky')}>Funky</button>
      <button onClick={() => colorTheme.toggle()}>Toggle</button>
    </nav>
    ...
    
    이제 우리는 모두 준비가 되었으니 마음대로 주제를 바꿀 수 있다.그런데 우리가 페이지를 새로 고칠 때 무슨 일이 일어날까요?이리 와봐.

    플래시


    보시다시피 페이지를 새로 고칠 때 테마는 이전과 같지만 순식간에 흰색 섬광이 나타납니다.이것은 사용자가 저장을 선호하기 때문이다
    로컬 저장소,react 수합 기간에만 접근합니다.다행히도 해결 방안이 하나 더 있다.
    다른 작업을 수행하기 전에 불러오는 코드 차단 스크립트를 설정할 수 있습니다.스크립트 mkdir public && cd public에 파일을 만들고 touch colorTheme.js으로 파일을 만들고 다음 코드를 복사합니다.
    색상 테마.js:
    // Insert this script in your index.html right after the <body> tag.
    // This will help to prevent a flash if dark mode is the default.
    
    (function() {
      // Change these if you use something different in your hook.
      var storageKey = 'colorTheme';
      var classNames = ['light-theme', 'dark-theme', 'funky'];
    
      function setClassOnDocumentBody(colorTheme) {
        var theme = 'light-theme';
        if (typeof colorTheme === 'string') {
          theme = colorTheme;
        }
        for (var i = 0; i < classNames.length; i++) {
          document.body.classList.remove(classNames[i]);
        }
        document.body.classList.add(theme);
      }
    
      var preferDarkQuery = '(prefers-color-scheme: dark)';
      var mql = window.matchMedia(preferDarkQuery);
      var supportsColorSchemeQuery = mql.media === preferDarkQuery;
      var localStorageTheme = null;
      try {
        localStorageTheme = localStorage.getItem(storageKey);
      } catch (err) {}
      var localStorageExists = localStorageTheme !== null;
      if (localStorageExists) {
        localStorageTheme = JSON.parse(localStorageTheme);
      }
      // Determine the source of truth
      if (localStorageExists) {
        // source of truth from localStorage
        setClassOnDocumentBody(localStorageTheme);
      } else if (supportsColorSchemeQuery) {
        // source of truth from system
        setClassOnDocumentBody(mql.matches ? classNames[1] : classNames[0]);
        localStorage.setItem(storageKey, JSON.stringify('dark-theme'));
      } else {
        // source of truth from document.body
        var iscolorTheme = document.body.classList.contains('dark-theme');
        localStorage.setItem(storageKey, iscolorTheme ? JSON.stringify('dark-theme') : JSON.stringify('light-theme'));
      }
    }());
    
    이 스크립트는 다음과 같은 작업을 수행합니다.
  • localStorage을 사용하여 colorTheme 찾기
  • 그리고 prefers-color-scheme CSS 미디어 조회를 찾아 짙은 색으로 설정되었는지 확인합니다. 이것은 사용자가 짙은 색 모드를 사용하는 시스템을 불러오는 사이트로 전환됩니다.
  • , 로컬 스토리지에 모드가 설정되어 있지 않은 경우
    그러나 사용자의 시스템은 암흑 모드를 사용합니다. 클래스 dark-theme
    주요 문서의 본문.
  • 로컬 저장소에 설정이 없으면 아무것도 하지 않습니다.
    마지막으로 우리 사이트의 기본 테마를 불러옵니다.
  • 그렇지 않으면 로컬 모드 집합과 관련된 클래스를 추가합니다
    파일
  • 의 본문 저장소
    그리고 우리가 해야 할 마지막 일은 페이지를 불러오는 동안 스크립트를 불러오는 것입니다.우리는 스크립트가 메타 태그를 불러오기 전에, 페이지 내용을 불러오기 전에 실행되는지 확인하기를 희망합니다.다음 페이지에서저희가 사용할 수 있어요._document.js 파일, 기본 컨텐트 이전 및 이후에 스크립트 로드<head></head>(자세한 내용은 docs 참조).
    _ 파일.회사 명
    import Document, { Head, Html, Main, NextScript } from 'next/document';
    
    class _Document extends Document {
      render() {
        return (
          <Html>
            <Head>
            </Head>
            <body>
              <script src="./colorTheme.js" />
              <Main />
              <NextScript />
            </body>
          </Html>
        );
      }
    }
    
    export default _Document;
    
    

    결과


    다른 내용을 불러오기 전에 스크립트를 body에 추가함으로써 플래시를 피하는 데 성공했습니다.코드 here을 찾을 수 있습니다.
    당신의 생각을 알고 자신의 색깔 테마를 만들어 보세요.

    좋은 웹페이지 즐겨찾기