テーマをカスタマイズする
すべてのYamada UIのコンポーネントは、テーマからスタイルやトークンを継承します。シナリオによっては、プロジェクトに合わせたカラー
などをカスタマイズする必要がある場合があります。
テーマをカスタマイズする場合は、extendTheme
を使用することをオススメします。これは、デフォルトのテーマを継承したテーマを作成します。extendTheme
を使用しない場合は、デフォルトのテーマを継承せず全く新しいテーマになります。
テーマの運用
テーマをカスタマイズした場合、型補完をすることをオススメします。型補完は、CLIを使用します。
CLI
を使用する場合は、ファイルのデフォルトでエクスポートされているテーマを参照するので、テーマのファイルを作成する必要があります。
開発中にテーマのトークンやスタイルが追加・変更することを考えて、テーマをフォルダにしておくことをオススメします。
./theme├ components # 各コンポーネントのスタイルを定義するフォルダ├ tokens # 各トークンを定義するフォルダ├ styles # グローバルスタイルやリセットスタイルを定義するフォルダ├ config.ts # コンフィグを設定するファイル└ index.ts # テーマをデフォルトでエクスポートするファイル
./theme/index.ts
import { extendTheme, UsageTheme } from "@yamada-ui/react"// import { styles } from './styles'// import { components } from './components'// import { tokens } from './tokens'const customTheme: UsageTheme = {// styles,// components,// ...tokens,}export const theme = extendTheme(customTheme)()
extendTheme
を使用して、テーマをデフォルトでエクスポートしています。
テーマの適用
テーマを適用する場合は、UIProvider
のtheme
に渡します。
Create React Appの場合
index.tsx
import { createRoot } from "react-dom/client"import { App } from "./app"import { UIProvider } from "@yamada-ui/react"import { theme } from "theme"const container = document.getElementById("app")const root = createRoot(container!)root.render(<UIProvider theme={theme}><App /></UIProvider>,)
Next.jsの場合
_app.tsx
import type { AppProps } from "next/app"import { UIProvider } from "@yamada-ui/react"import { theme } from "theme"const App = ({ Component, pageProps }: AppProps) => {return (<UIProvider theme={theme}><Component {...pageProps} /></UIProvider>)}export default App
Viteの場合
.main.tsx
import React from "react"import ReactDOM from "react-dom/client"import App from "./App.tsx"import { UIProvider } from "@yamada-ui/react"import { theme } from "theme"ReactDOM.createRoot(document.getElementById("root")!).render(<React.StrictMode><UIProvider theme={theme}><App /></UIProvider></React.StrictMode>,)
トークンを変更する
今回は、colors
に新しいトークンと既存のトークンを変更してみましょう。
tokens
の配下にcolors.ts
を作成します。
./theme/tokens/colors.ts
import { ThemeTokens } from "@yamada-ui/react"export const colors: ThemeTokens = {banner: "#9d38a0",black: ["#1F2123", "#101112"],}
colors
に新しくbanner
を追加し、black
を変更しています。また、配列を定義することで、カラーモードに対応できます。
index.ts
を作成し、先ほど作成したcolors
をエクスポートします。
./theme/tokens/index.ts
import { colors } from "./colors"export const tokens = { colors }
customTheme
にtokens
を含めます。
./theme/index.ts
import { extendTheme, UsageTheme } from "@yamada-ui/react"// import { styles } from "./styles"// import { components } from "./components"import { tokens } from "./tokens"const customTheme: UsageTheme = {// styles,// components,...tokens,}export const theme = extendTheme(customTheme)()
もし、デフォルトのテーマからcolors
だけ継承したくない場合は、extendTheme
にomit
を渡します。
./theme/index.ts
import { extendTheme, UsageTheme } from "@yamada-ui/react"// import { styles } from "./styles"// import { components } from "./components"import { tokens } from "./tokens"const customTheme: UsageTheme = {// styles,// components,...tokens,}export const theme = extendTheme(customTheme)({ omit: ["colors"] })
トークンにレスポンシブオブジェクトを設定する
テーマのトークンは、デフォルトではレスポンシブオブジェクトに対応していません。もし、テーマのトークンにレスポンシブオブジェクトを対応させたい場合は、config.theme.responsive
をtrue
に設定します。
./theme/config.ts
import { extendConfig } from "@yamada-ui/react"export const config = extendConfig({theme: {responsive: true,},})
もっとコンフィグをカスタマイズしたい場合は、こちらをご覧ください。
テーマのトークンにレスポンシブオブジェクトを設定します。
./theme/tokens/spaces.ts
import type { ThemeTokens } from "@yamada-ui/react"export const spaces: ThemeTokens = {1: { base: "0.25rem", md: "0.125rem" },2: { base: "0.5rem", md: "0.25rem" },3: { base: "0.75rem", md: "0.375rem" },4: { base: "1rem", md: "0.5rem" },}
レスポンシブオブジェクトをもっと学びたい場合は、こちらをご覧ください。
レスポンシブオブジェクトには、必ずbase
を設定してください。また、レスポンシブオブジェクトではないテーマのトークンにbase
を設定しないてください。理由は、base
を持つオブジェクトは、レスポンシブオブジェクトと判定されるためです。
あとは、トークンを変更すると同様に./theme/index.ts
のtokens
にspaces
を含めます。
セマンティックトークンを変更する
セマンティックトークンの中に、各コンポーネントで使用されるカラースキーマが設定されています。
実際に設定されている値はこちらです。
export const semantics: ThemeSemantics = {colors: {primary: "blue.500",secondary: "violet.500",info: "blue.500",success: "green.500",warning: "orange.500",danger: "red.500",link: "blue.500",},colorSchemes: {primary: "blue",secondary: "violet",info: "blue",success: "green",warning: "orange",danger: "red",link: "blue",},spaces: {xs: "1",sm: "2",md: "4",normal: "6",lg: "8",xl: "12","2xl": "16","3xl": "24","4xl": "32",},}
今回は、デフォルトのカラースキーマを変更してみましょう。
theme
の配下にsemantics.ts
を作成します。
./theme/semantics.ts
import { ThemeSemantics } from "@yamada-ui/react"export const semantics: ThemeSemantics = {colors: {primary: "pink.500",},colorSchemes: {primary: "pink",},}
customTheme
にsemantics
を含めます。
./theme/index.ts
import { extendTheme, UsageTheme } from "@yamada-ui/react"// import { styles } from "./styles"// import { components } from "./components"import { tokens } from "./tokens"import { semantics } from "./semantics"const customTheme: UsageTheme = {// styles,// components,semantics,...tokens,}export const theme = extendTheme(customTheme)()
セマンティックトークンをもっと学びたい場合は、こちらをご覧ください。
スタイルを変更する
styles
にはglobalStyle・resetStyle・layerStyles・textStylesなどを設定できます。
今回は、body
のスタイルなどを設定するglobalStyle
を変更してみましょう。
styles
の配下にglobal-style.ts
を作成します。
./theme/styles/global-style.ts
import { UIStyle } from "@yamada-ui/react"export const globalStyle: UIStyle = {body: {bg: ["black", "white"],},}
body
の背景を変更しています。また、配列を定義することで、カラーモードに対応できます。
index.ts
を作成し、先ほど作成したglobalStyle
をエクスポートします。
./theme/styles/index.ts
import { globalStyle } from "./global-style"export const styles = { globalStyle }
customTheme
にstyles
を含めます。
./theme/index.ts
import { extendTheme, UsageTheme } from "@yamada-ui/react"import { styles } from "./styles"// import { components } from "./components"import { tokens } from "./tokens"import { semantics } from "./semantics"const customTheme: UsageTheme = {styles,// components,semantics,...tokens,}export const theme = extendTheme(customTheme)()
もし、デフォルトのテーマからstyles
だけ継承したくない場合は、extendTheme
にomit
を渡します。
./theme/index.ts
import { extendTheme, UsageTheme } from "@yamada-ui/react"import { styles } from "./styles"// import { components } from "./components"import { tokens } from "./tokens"import { semantics } from "./semantics"const customTheme: UsageTheme = {styles,// components,semantics,...tokens,}export const theme = extendTheme(customTheme)({ omit: ["styles"] })
テキストとレイヤースタイルを学びたい場合は、こちらをご覧ください。
コンポーネントのスタイルを変更する
プロジェクトによって、Yamada UIのコンポーネントのスタイルを変更したい場合があります。Yamada UIのコンポーネントは、テーマのスタイルを参照しているので簡単にコンポーネントのスタイルを変更することができます。
コンポーネントのスタイルは、コンポーネントの基本スタイル(baseStyle
)、さまざまなサイズのスタイル(sizes
)、さまざまなビジュアルのスタイル(variants
)、デフォルトのprops
(defaultProps
)で構成されています。
すべてのコンポーネントは、size
やvariant
があるわけではありません。どのコンポーネントが対応しているかを確認するには、コンポーネントのページのprops
を参照してください。
Yamada UIは、コンポーネントにスタイルのprops
を設定することでスタイリングすることができます。しかし、大規模なプロジェクトは開発者が多く、個々でスタイルを設定するとデザインの一貫性を担保できなくなります。その場合、共通しているスタイルをテーマのコンポーネントのスタイルに設定することで回避することができます。
今回は、コンポーネントのContainer
を変更してみましょう。
components
の配下にcontainer.ts
を作成します。
./theme/components/container.ts
import { ComponentStyle } from "@yamada-ui/react"export const Container: ComponentStyle = {baseStyle: {bg: "green.100",},sizes: {sm: { p: "sm", fontSize: "sm" },md: { p: "md", fontSize: "md" },lg: { p: "lg", fontSize: "lg" },},variants: {"with-border-solid": {borderWidth: "1px",},"with-border-dotted": {borderWidth: "1px",borderStyle: "dotted",},},defaultProps: {size: "md",variant: "with-border-solid",},}
背景色を変更し、sizes
で各サイズを、variants
で各バリアントを定義しています。defaultProps
は、初期値を設定しています。
index.ts
を作成し、先ほど作成したContainer
をエクスポートします。
./theme/components/index.ts
import { Container } from "./container"export const components = { Container }
customTheme
にcomponents
を含めます。
./theme/index.ts
import { extendTheme, UsageTheme } from "@yamada-ui/react"import { styles } from "./styles"import { components } from "./components"import { tokens } from "./tokens"import { semantics } from "./semantics"const customTheme: UsageTheme = {styles,components,semantics,...tokens,}export const theme = extendTheme(customTheme)()
これで、Container
の背景色は変更され、size
またはvariant
を渡すことでスタイルが変更されます。
import { Container } from "@yamada-ui/react"const Demo = () => {return (<Container size="sm" variant="with-border-dotted">This is Container</Container>)}
今回変更したContainer
は、単一の要素で構成されるコンポーネントです。また、複数の要素で構成されるコンポーネント(Accordion
など)があります。複数の要素で構成されるコンポーネントを変更する場合、型定義はComponentMultiStyle
になります。
各コンポーネントのテーマのスタイルを確認するには、コンポーネントのページのテーマ
を参照してください。
Yamada UIが提供するコンポーネントに限らず、独自のカスタムコンポーネントのスタイルを作成することができます。詳しくは、こちらをご覧ください。
ユーティリティ
Yamada UIは、テーマのユーティリティを多く提供しています。
extendTheme
を使う
デフォルトのテーマを継承して、新しいテーマを作成します。複数のオブジェクトを渡すことも可能です。また、オプションを指定することも可能です。
複数のテーマをマージする
./theme/index.ts
import { extendTheme, UsageTheme } from "@yamada-ui/react"const firstTheme: UsageTheme = {}const secondTheme: UsageTheme = {}export const theme = extendTheme(firstTheme, secondTheme)()
デフォルトのテーマを継承しない
./theme/index.ts
import { extendTheme, UsageTheme } from "@yamada-ui/react"const firstTheme: UsageTheme = {}const secondTheme: UsageTheme = {}export const theme = extendTheme(firstTheme, secondTheme)({ merge: false })
デフォルトテーマから特定のトークンを除外して継承する
./theme/index.ts
import { extendTheme, UsageTheme } from "@yamada-ui/react"const customTheme: UsageTheme = {}export const theme = extendTheme(customTheme)({ omit: ["colors"] })
デフォルトテーマから特定のトークンだけ継承する
./theme/index.ts
import { extendTheme, UsageTheme } from "@yamada-ui/react"const customTheme: UsageTheme = {}export const theme = extendTheme(customTheme)({ pick: ["spaces"] })
extendBaseTheme
を使う
デフォルトのテーマのグローバルスタイルやカラーなどのトークンのみを継承して、新しいテーマを作成します。複数のオブジェクトを渡すことも可能です。また、オプションを指定することも可能です。
./theme/index.ts
import { extendBaseTheme, UsageTheme } from "@yamada-ui/react"import { styles } from "./styles"import { tokens } from "./tokens"const customTheme: UsageTheme = {styles,...tokens,}export const theme = extendTheme(customTheme)()
extendBaseTheme
は、内部的にbaseTheme
を使用しています。baseTheme
は、グローバルスタイルやカラーなどのトークンは定義されていますが、コンポーネントのスタイルが定義されていません。
extendStyle
を使う
globalStyle
やresetStyle
を継承して、新しいスタイルを作成します。
import { extendStyle, UIStyle } from "@yamada-ui/react"const globalStyle: UIStyle = extendStyle("globalStyle", {/*** 追加のスタイルを定義する*/})
extendToken
を使う
特定のトークンを継承して、新しいトークンを作成します。
import { extendToken, ThemeTokens } from "@yamada-ui/react"const colors: ThemeTokens = extendToken("colors", {/*** 追加のトークンを定義する*/})
extendComponent
を使う
特定のコンポーネントのスタイルを継承して、新しいコンポーネントのスタイルを作成します。
import { extendComponent, ComponentStyle } from "@yamada-ui/react"const Button: ComponentStyle = extendComponent("Button", {/*** 追加の`baseStyle`や`sizes`を定義する*/})
extendComponentSize
を使う
特定のコンポーネントのサイズを継承して、新しいコンポーネントのサイズを作成します。
import { extendComponentSize, ComponentStyle } from "@yamada-ui/react"const Tag: ComponentStyle = {baseStyle: {/*** 新しいスタイルを定義する*/},sizes: extendComponentSize("Tag", {/*** 追加のサイズを定義する*/}),}
この関数は、baseStyle
やvariants
は継承したくないが、sizes
だけ継承したいケースに使えます。
extendComponentVariant
を使う
特定のコンポーネントのバリアントを継承して、新しいコンポーネントのバリアントを作成します。
import { extendComponentVariant, ComponentStyle } from "@yamada-ui/react"const Tag: ComponentStyle = {baseStyle: {/*** 新しいスタイルを定義する*/},variants: extendComponentVariant("Tag", {/*** 追加のバリアントを定義する*/}),}
この関数は、baseStyle
やsizes
は継承したくないが、variants
だけ継承したいケースに使えます。
extendComponentDefaultProps
を使う
特定のコンポーネントのprops
を継承して、新しいコンポーネントのprops
を作成します。
import { extendComponentDefaultProps, ComponentStyle } from "@yamada-ui/react"const Tag: ComponentStyle = {baseStyle: {/*** 新しいスタイルを定義する*/},defaultProps: extendComponentDefaultProps("Tag", {/*** 追加のpropsを定義する*/}),}
この関数は、baseStyle
やsizes
は継承したくないが、defaultProps
だけ継承したいケースに使えます。
withDefaultSize
を使う
すべて
または一部
のコンポーネントのデフォルトのサイズを変更します。
./theme/index.ts
import { extendTheme, withDefaultSize } from "@yamada-ui/react"/*** 省略*/export const theme = extendTheme(customTheme,withDefaultSize({size: "lg",components: ["Badge", "Tag", "Button"], // もし、空の配列を渡した場合は、すべてのコンポーネントに設定されます。}),)()
withDefaultVariant
を使う
すべて
または一部
のコンポーネントのデフォルトのバリアントを変更します。
./theme/index.ts
import { extendTheme, withDefaultVariant } from "@yamada-ui/react"/*** 省略*/export const theme = extendTheme(customTheme,withDefaultVariant({variant: "solid",components: ["Badge", "Tag", "Button"], // もし、空の配列を渡した場合は、すべてのコンポーネントに設定されます。}),)()
withDefaultColorScheme
を使う
すべて
または一部
のコンポーネントのデフォルトのカラースキーマを変更します。
./theme/index.ts
import { extendTheme, withDefaultColorScheme } from "@yamada-ui/react"/*** 省略*/export const theme = extendTheme(customTheme,withDefaultColorScheme({colorScheme: "primary",components: ["Badge", "Tag", "Button"], // もし、空の配列を渡した場合は、すべてのコンポーネントに設定されます。}),)()
withDefaultProps
を使う
すべて
または一部
のコンポーネントのデフォルトのprops
を一括で変更します。
./theme/index.ts
import { extendTheme, withDefaultProps } from "@yamada-ui/react"/*** 省略*/export const theme = extendTheme(customTheme,withDefaultProps({defaultProps: {size: "lg",variant: "solid",colorScheme: "primary",},components: ["Badge", "Tag", "Button"], // もし、空の配列を渡した場合は、すべてのコンポーネントに設定されます。}),)()
generate
を使う
generate
は、テーマのトークンをカスタマイズしたり、生成する便利なユーティリティです。
余白をカスタマイズする
デフォルトのテーマのspaces
に指定された数値を乗算して、新しいspaces
を生成します。
./theme/index.ts
import { extendTheme, withDefaultProps, generate } from "@yamada-ui/react"export const theme = extendTheme({spaces: generate.spaces(2),})()
これで、アプリケーション全体の余白が2倍になりました。
カラーのトーンを生成する
colorScheme
に使用するトーン(50から950)
を生成されます。
./theme/index.ts
import { extendTheme, withDefaultProps, generate } from "@yamada-ui/react"export const theme = extendTheme({colors: {red: generate.tones("#e82e34"),},})()
GitHubでこのページを編集する