どのようにreactjsで色のテーマを追加するには?


ちょうど暗いモードよりも、あなたの反応サイトに色のテーマの任意の数を追加します.
TLあなたは小さな反応フックとCSSのカスタムプロパティを使用して、あなたの反応アプリに好きなように博士の多くの色のテーマとして追加します.ここでチェックしてください.use-color-theme
ここ数週間、私はダークモード機能を含む完全な再設計で私のウェブサイトをアップグレードしました.私は、暗いモード/光を加える若干の良い資源を見つけました
-モードスイッチャ、しかし、わずか2つ以上のテーマで適切なテーマを行うにはほとんど少し情報.
そういうわけで、私は私のサイトのために新しい機能を構築することに決めました:use-color-theme .
単純な反応フックをトグルlight-theme , dark-theme その他
クラス・オンbody タグ.フックはCSSで動作するcustom
properties
用途prefers-color-scheme そして、ユーザーと一致するフードの下のlocalstorage
好みと頻繁に関連付けられているフラッシュの問題を排除する
色のテーマ.
今、新しい色のテーマを追加するだけでいくつかの手順で発生します.それをチェックしてくださいsite ヘッダーのテーマアイコンを押すことによって.

初期設定


複数のテーマを追加することが容易になりました.ちょうど簡単な手順に従って、あなたのサイトにテーマを追加することができます.
手順を実行するページを作成しますclick here まっすぐにページパーツにそれを追加するにジャンプします.
まず、新しいディレクトリを作成し、基本をインストールします.
mkdir colorful && cd colorful
yarn init -y
yarn add react react-dom next
次に、我々はpages 必要なフォルダNextJs つのファイルを作成します._app.js and index.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;
インデックス.js
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カスタムプロパティをテーマのスタイルを追加しましょう.
インデックス.js
...
<style jsx>{`
 ...

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

  p {
    color: var(--text)
  }
`}</style>
...
は、アプリでは.JSファイルは、グローバルなCSS変数を異なる色で追加できます.他のCSSとのCSSプロパティを追加することもできます
フレームワークまたはプレーンCSSファイル
また、ヘッダーに使われる色を交換しましょう.
アプリ.js
...
 <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ファイル.これは、テーマが各ページにグローバルに利用可能であることを確認します.
アプリ.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を輸入し、それは私たちが使用するのと同じ方法をimiment
    その他のフック
  •     const colorTheme = useColorTheme('light-theme', {
          classNames: ['light-theme', 'dark-theme', 'funky']
        });
    
    1番目のパラメータは初期クラスです.番目のパラメータは
    configuration フック用.クラスの名前を任意の方法で名前を付けることができますが、意味の名前をお勧めします
  • クラスを追加しました.light-theme , .dark-theme and .funky with
    異なる色変数.
  • 我々は、ボタンをクリックして機能を追加しましたcolorTheme.toggle
  • 設定詳細テーマ


    しかし、私は特定のテーマにそれを変更する場合はどうですか?
    簡単な解決策もあります.どのように実装できるかを見てみましょう.
    アプリ.js
    ...
    <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>
    ...
    
    今、我々はすべて設定され、簡単に我々は好きなようにテーマを変更することができます.しかし、我々がページをリフレッシュするとき、何が起こりますか?チェックアウト.

    フラッシュ


    ご存知のように、ページをリフレッシュするとき、テーマは以前と同じままですが、白いフラッシュのスプリット秒があります.ユーザーの好みが格納されているためです
    LocalStorageとのみ反応水和中にアクセスします.幸いにも、それに解決策があります.
    他の何かを実行する前に読み込みを完了するコードをブロックするスクリプトを設定できます.スクリプトのファイルを作成しましょう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のメディアクエリは、ダークモードを使用してシステムを持っているユーザーをロードするユーザーに変換する、そのダークに設定するかどうかを確認します.
  • localstorageにモードが設定されていない場合
    しかし、ユーザーのシステムはダークモードを使用して、我々はクラスを追加しますdark-theme
    本文の本文.
  • LocalStorageに設定されている何もないならば、我々は何もしません
    私たちのサイトのデフォルトのテーマを読み込みます.
  • さもなければ、ローカルでモードセットに関連したクラスを加えます
    文書の本文への保管
  • 最後に我々がしなければならないことは、ページロード中にスクリプトを読み込むことです.スクリプトがロードされた後にスクリプトが実行されることを確認したいが、ページの内容が読み込まれる前に.次に.私たちは_document.js メインコンテンツの前にスクリプトをロードする<head></head> チェックアウトdocs を参照).
    KHIドキュメントjs
    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 .
    私はあなたがそれを何を考え、自分の色のテーマを作成してください知ってみましょう.