次へのテーマの追加.スタイルのコンポーネント、mobx、およびタイプスクリプトと
7651 ワード
ダークモード対ライトモード?
あなたのユーザーを決定しましょう.オプションを
styled-components
とmobx
との間でシームレスに切り替えるオプションを提供します.始める
の永続的なデータモービルストアを作成する
StyleProvider を作成する
テーマ
インストール
yarn add styled-components mobx mobx-react
yarn add -D @types/styled-components
2 .テーマ定数のファイルを作成する
themes.constants.ts
このファイルでは、テーマやその他のリレーショナル定数を定義します.const COLOURS = {
black: '#000000',
white: '#FFFFFF'
}
const DARK_THEME = {
name: 'dark',
background: COLOURS.black,
textPrimary: COLOURS.white
}
const LIGHT_THEME = {
name: 'light',
background: COLOURS.white,
textPrimary: COLOURS.black
}
export const DEFAULT_THEME = 'dark'
export const THEMES = {
dark: DARK_THEME,
light: LIGHT_THEME,
}
3 .次のスタイルコンポーネントを追加します。設定。jsファイル
NextConfigオブジェクトで、キーペア値を追加します.
compiler: {
styledComponents: true,
},
4 . ServerStylesheetをCountドキュメントに追加します。TSX
getInitialProps
メソッドを下に示すMyDocument
クラスに追加します.あなたが
_document.tsx
をすでに作成していないならば、あなたのpages
フォルダにそれを加えてください.ペーストします.import Document, {
Html,
Head,
Main,
NextScript,
DocumentContext,
} from 'next/document';
import { ServerStyleSheet } from 'styled-components';
class MyDocument extends Document {
static async getInitialProps(ctx: DocumentContext) {
const sheet = new ServerStyleSheet();
const originalRenderPage = ctx.renderPage;
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) =>
sheet.collectStyles(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
styles: [
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>,
],
};
} finally {
sheet.seal();
}
}
render() {
return (
<Html>
<Head>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default MyDocument;
localstorageで永続的なデータを許可するユーティリティ関数を作成する
utils.ts
export const setStorage = (key: string, value: unknown) => {
window.localStorage.setItem(key, JSON.stringify(value));
};
export const getStorage = (key: string) => {
const value = window.localStorage.getItem(key);
if (value) {
return JSON.parse(value);
}
};
MOVXでUIストアを作成する
uiStore.ts
import { action, makeAutoObservable, observable } from 'mobx';
import { setStorage } from './utils';
type Themes = 'dark' | 'light';
class UiStore {
@observable
private _theme: Themes = 'light';
@observable
private _initializing: boolean = true;
constructor() {
makeAutoObservable(this);
}
get theme() {
return this._theme;
}
get initializing() {
return this._initializing;
}
@action
toggleTheme() {
this._theme = this._theme === 'light' ? 'dark' : 'light';
setStorage('theme', this._theme);
}
@action
changeTheme(nameOfTheme: Themes) {
this._theme = nameOfTheme;
}
@action
finishInitializing() {
this._initializing = false;
}
}
export const uiStore = new UiStore();
スタイルコンポーネントを使用したグローバルスタイルの作成
スタイリングコンポーネントのテーマには次のようにアクセスできます.
global-styles.ts
export const GlobalStyle = createGlobalStyle`
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
background: ${({ theme }) => theme.colors.body};
}
`;
StyleProviderの作成
style-provider.tsx
import { observer } from 'mobx-react';
import { useEffect, ReactNode } from 'react';
import { ThemeProvider } from 'styled-components';
import { uiStore } from './uiStore';
import { DEFAULT_THEME, THEMES } from './theme.constants';
import { GlobalStyle } from './global-styles`
import { getStorage, setStorage } from './utils';
interface OnlyChildren {
children: ReactNode
}
const StyleProviderComponent = (props: OnlyChildren) => {
const { children } = props;
const { theme } = uiStore;
useEffect(() => {
if (!getStorage('theme')) {
setStorage('theme', DEFAULT_THEME);
}
const storageThemeName = getStorage('theme');
uiStore.changeTheme(storageThemeName);
uiStore.finishInitializing();
}, []);
return (
<ThemeProvider theme={THEMES[theme]}>
<GlobalStyle />
{children}
</ThemeProvider>
);
};
export const StyleProvider = observer(StyleProviderComponent);
9 .テーマを入力する
default-theme.d.ts
import 'styled-components';
declare module 'styled-components' {
export interface DefaultTheme {
name: string;
colors: {
primary: string;
textPrimary: string;
};
}
}
10 .ページを提供します。TSX
import type { AppProps } from 'next/app';
import { StyleProvider } from './style-provider';
function MyApp({ Component, pageProps }: AppProps) {
return (
<StyleProvider>
<Component {...pageProps} />
</StyleProvider>
);
}
export default MyApp;
ページ/インデックスで動作することをテストします。TSX
import type { NextPage } from 'next';
import Head from 'next/head';
import { uiStore } from './uiStore';
const Home: NextPage = () => {
const { initializing } = uiStore;
if (!initializing) {
return <h1>Loading...</h1>;
}
return (
<>
<Head>
<title>
Adding themes to Next.js with styled-components, mobx, and typescript
</title>
<meta name='description' content='Tutorial by Zach Nugent' />
<link rel='icon' href='/favicon.ico' />
</Head>
<button onClick={() => uiStore.toggleTheme()}>Switch theme</button>
</>
)
}
export default Home
スタイルのコンポーネントのテーマにアクセスすることができますバックコールの間にコールバック機能(EX : ${({ theme }) => theme.colors.textPrimary}
)を追加します.例:
const Button = styled.button`
background: ${({ theme }) => theme.colors.body};
border: 1px solid ${({ theme }) => theme.colors.accent};
color: ${({ theme }) => theme.colors.textPrimary};
`
読書ありがとう🙂Reference
この問題について(次へのテーマの追加.スタイルのコンポーネント、mobx、およびタイプスクリプトと), 我々は、より多くの情報をここで見つけました https://dev.to/mrzachnugent/adding-themes-to-nextjs-with-styled-components-mobx-and-typescript-2cd3テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol