フロントエンド開発の先端を突っ走るNext.js
next.js アプリの初期化( npx create-next-app@latest <アプリ名> ) または yarn create next-app <アプリ名> または bun create next-app <アプリ名> )

Next.js AppRouter で emotionを使う方法

● Next.js AppRouter で emotionを使う方法

新たに作成するアプリの場合は emotionのかわりに goober を使うという手もあります。
https://github.com/cristianbote/goober

・ next.jsアプリの初期化

npx create-next-app@latest

( app router を選択してアプリを新規作成します )

● emotion のインストール

・1. npm から emotion をインストール

npm install @emotion/react

・ 2. tsconfig の設定

{
  "compilerOptions": {

    // emotion
    "jsx": "preserve",
    "jsxImportSource": "@emotion/react",

・3. next.config.mjs の設定

/** @type {import('next').NextConfig} */
const nextConfig = {
  compiler: {
    emotion: true,
  },
};

export default nextConfig;

・4. サーバーコンポーネントの先頭に pragma をつける

  • src/app/layout.tsx
  • src/app/page.tsx

いずれも先頭に以下を追加

/* @jsxImportSource react */

・5. クライアントコンポーネントの先頭に 'use client'; をつける

クライアントコンポーネントの先頭に以下を追加

'use client';

以上で動作します!

npm run dev

・ emotion を 使ったCSSスタイリングの例 (1. tsx に直接記述)

components/SampleCss.tsx

'use client';

import { css } from '@emotion/react';
import { FC } from 'react';

export const SampleCss: FC = () => {
  return (
    <div
      css={css`
        color: green;
        font-size: 48px;
        font-weight: bold;
      `}
    >
      SampleCss
    </div>
  );
};

・ emotion を 使ったCSSスタイリングの例 (2. 変数を2つ定義して配列でマージする)

import { css } from '@emotion/react';

const fontLarge = css`
  font-size: 48px;
`;

const colorGreen = css`
  color: green;
`;

export default function Home() {
  return (
    <>
      <div css={[fontLarge, colorGreen]}>home</div>
    </>
  );
}

・ emotion を 使ったCSSスタイリングの例 (変数定義時に他のスタイルを取り込む)

import { css } from '@emotion/react';

const fontLarge = css`
  font-size: 48px;
`;

const myFont = css`
  ${fontLarge}
  color: blue;
`;

export default function Home() {
  return (
    <>
      <div css={myFont}>home</div>
    </>
  );
}

・ emotion を 使ったCSSスタイリングの例 (グローバルスタイルを 設定する)

import type { AppProps } from 'next/app';
import { css, Global } from '@emotion/react';

const globalStyle = css`
  body {
    font-family: 'Helvetica Neue', Arial, 'Hiragino Kaku Gothic ProN',
      'Hiragino Sans', Meiryo, sans-serif;
  }
`;

export default function App({ Component, pageProps }: AppProps) {
  return (
    <>
      <Global styles={globalStyle}></Global>
      <Component {...pageProps} />
    </>
  );
}

・ emotion を 使ったCSSスタイリングの例 (動的スタイル conditional style)

src/pages/index.tsx

import { useState } from 'react';
import { css } from '@emotion/react';

type MyFont = {
    colored:boolean
}

export default function Home() {
  const [colored, setColored] = useState<boolean>(false);

  const myFont = ({ colored }:MyFont) => css`
    border: solid 1px black;
    border-radius: 10px;
    padding: 16px;
    cursor: pointer;
    ${colored &&
    `
    background-color: #413F42;
    color: white;
  `}
  `;

  return (
    <>
      <button
        onClick={() => {
          setColored(!colored);
        }}
      >
        色変更
      </button>
      <div css={myFont({ colored: colored })}>home</div>
    </>
  );
}

・ emotion を 使ったCSSスタイリングの例 (styled-components のように設定する)

npm install @emotion/styled

こちらで css から js object に 変換します

https://transform.tools/css-to-js

1. SampleStyled.tsx(styled.div記法)

'use client';

import styled from '@emotion/styled';

const MyTitle = styled.div`
  border: 10px solid blue;
  padding: 2rem;
  font-size: 3.5rem;
  margin: 0px;
  color: blue;
`;

export function SampleStyled() {
  return <MyTitle as={'button'}>home</MyTitle>;
}

as={'button'} で 出力時にタグを div から button に変更しています

2. SampleStyled.tsx(className渡し記法)

import styled from '@emotion/styled';
import { FC, ComponentProps } from 'react';

type StylableFC = FC<ComponentProps<'div'>>;

const SampleStyled: StylableFC = ({ className }) => {
  return <div className={className}>コンポーネントサンプル</div>;
};

export default styled(SampleStyled)`
  margin: 16px 0;
  background-color: #f6f6f6;
  color: green;
  padding: 20px;
  border-radius: 8px;
  font-size: 64px;
  font-weight: bold;
`;

● react17 + emotion で知っておくと良いこと

react17 で emotionを動かすには

1. tsconfig.json

    "jsx": "preserve",
    "jsxImportSource": "@emotion/react",

2. コンポーネントファイルの先頭に jsxプラグマを追加

/** @jsxImportSource @emotion/react */

3. コンポーネントファイルの先頭に jsxプラグマを追加したくない場合はこちら

react-app-rewired を使用する場合

https://harryhedger.medium.com/quick-how-to-use-the-emotion-css-prop-with-create-react-app-5f6aa0f0c5c5

@craco/craco を使用する場合

https://qiita.com/y-suzu/items/2d3fcf5414f7b418f05a

https://emotion.sh/docs/@emotion/babel-preset-css-prop

http://tinyurl.com/24mbeogl

https://qiita.com/xrxoxcxox/items/17e0762d8e69c1ef208f

● その他リンク

@emotion/reactでのスタイル指定方法 - Qiita

https://qiita.com/282Haniwa/items/7248bed02a1b5b66579f

【React】propsでemotionのスタイルを受け取る際の型定義 #React - Qiita

No.2319
08/27 20:58

edit