Yamada UIにスターをあげる

スター
Yamada UIYamada UIv1.7.2

テーマをカスタマイズする

すべてのYamada UIのコンポーネントは、テーマからスタイルやトークンを継承します。シナリオによっては、プロジェクトに合わせたカラーなどをカスタマイズする必要がある場合があります。

テーマの運用

テーマをカスタマイズした場合、型補完をすることをオススメします。型補完は、CLIを使用します。

開発中にテーマのトークンやスタイルが追加・変更することを考えて、テーマをフォルダにしておくことをオススメします。

./theme
├ components # 各コンポーネントのスタイルを定義するフォルダ
├ tokens # 各トークンを定義するフォルダ
├ styles # グローバルスタイルやリセットスタイルを定義するフォルダ
├ config.ts # コンフィグを設定するファイル
└ index.ts # テーマをデフォルトでエクスポートするファイル
Copied!

./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)()
Copied!

テーマの適用

テーマを適用する場合は、UIProviderthemeに渡します。

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>,
)
Copied!

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
Copied!

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>,
)
Copied!

トークンを変更する

今回は、colorsに新しいトークンと既存のトークンを変更してみましょう。

tokensの配下にcolors.tsを作成します。

./theme/tokens/colors.ts

import { ThemeTokens } from "@yamada-ui/react"
export const colors: ThemeTokens = {
banner: "#9d38a0",
black: ["#1F2123", "#101112"],
}
Copied!

index.tsを作成し、先ほど作成したcolorsをエクスポートします。

./theme/tokens/index.ts

import { colors } from "./colors"
export const tokens = { colors }
Copied!

customThemetokensを含めます。

./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)()
Copied!

もし、デフォルトのテーマからcolorsだけ継承したくない場合は、extendThemeomitを渡します。

./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"] })
Copied!

トークンにレスポンシブオブジェクトを設定する

テーマのトークンは、デフォルトではレスポンシブオブジェクトに対応していません。もし、テーマのトークンにレスポンシブオブジェクトを対応させたい場合は、config.theme.responsivetrueに設定します。

./theme/config.ts

import { extendConfig } from "@yamada-ui/react"
export const config = extendConfig({
theme: {
responsive: true,
},
})
Copied!

テーマのトークンにレスポンシブオブジェクトを設定します。

./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" },
}
Copied!

あとは、トークンを変更すると同様に./theme/index.tstokensspacesを含めます。

セマンティックトークンを変更する

セマンティックトークンの中に、各コンポーネントで使用されるカラースキーマが設定されています。

実際に設定されている値はこちらです。

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",
},
}
Copied!

今回は、デフォルトのカラースキーマを変更してみましょう。

themeの配下にsemantics.tsを作成します。

./theme/semantics.ts

import { ThemeSemantics } from "@yamada-ui/react"
export const semantics: ThemeSemantics = {
colors: {
primary: "pink.500",
},
colorSchemes: {
primary: "pink",
},
}
Copied!

customThemesemanticsを含めます。

./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)()
Copied!

スタイルを変更する

stylesにはglobalStyleresetStylelayerStylestextStylesなどを設定できます。

今回は、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"],
},
}
Copied!

index.tsを作成し、先ほど作成したglobalStyleをエクスポートします。

./theme/styles/index.ts

import { globalStyle } from "./global-style"
export const styles = { globalStyle }
Copied!

customThemestylesを含めます。

./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)()
Copied!

もし、デフォルトのテーマからstylesだけ継承したくない場合は、extendThemeomitを渡します。

./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"] })
Copied!

コンポーネントのスタイルを変更する

プロジェクトによって、Yamada UIのコンポーネントのスタイルを変更したい場合があります。Yamada UIのコンポーネントは、テーマのスタイルを参照しているので簡単にコンポーネントのスタイルを変更することができます。

コンポーネントのスタイルは、コンポーネントの基本スタイル(baseStyle)、さまざまなサイズのスタイル(sizes)、さまざまなビジュアルのスタイル(variants)、デフォルトのprops(defaultProps)で構成されています。

今回は、コンポーネントの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",
},
}
Copied!

index.tsを作成し、先ほど作成したContainerをエクスポートします。

./theme/components/index.ts

import { Container } from "./container"
export const components = { Container }
Copied!

customThemecomponentsを含めます。

./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)()
Copied!

これで、Containerの背景色は変更され、sizeまたはvariantを渡すことでスタイルが変更されます。

import { Container } from "@yamada-ui/react"
const Demo = () => {
return (
<Container size="sm" variant="with-border-dotted">
This is Container
</Container>
)
}
Copied!

ユーティリティ

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)()
Copied!

デフォルトのテーマを継承しない

./theme/index.ts

import { extendTheme, UsageTheme } from "@yamada-ui/react"
const firstTheme: UsageTheme = {}
const secondTheme: UsageTheme = {}
export const theme = extendTheme(firstTheme, secondTheme)({ merge: false })
Copied!

デフォルトテーマから特定のトークンを除外して継承する

./theme/index.ts

import { extendTheme, UsageTheme } from "@yamada-ui/react"
const customTheme: UsageTheme = {}
export const theme = extendTheme(customTheme)({ omit: ["colors"] })
Copied!

デフォルトテーマから特定のトークンだけ継承する

./theme/index.ts

import { extendTheme, UsageTheme } from "@yamada-ui/react"
const customTheme: UsageTheme = {}
export const theme = extendTheme(customTheme)({ pick: ["spaces"] })
Copied!

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 = extendBaseTheme(customTheme)()
Copied!

extendStyleを使う

globalStyleresetStyleを継承して、新しいスタイルを作成します。

import { extendStyle, UIStyle } from "@yamada-ui/react"
const globalStyle: UIStyle = extendStyle("globalStyle", {
/**
* 追加のスタイルを定義する
*/
})
Copied!

extendTokenを使う

特定のトークンを継承して、新しいトークンを作成します。

import { extendToken, ThemeTokens } from "@yamada-ui/react"
const colors: ThemeTokens = extendToken("colors", {
/**
* 追加のトークンを定義する
*/
})
Copied!

extendComponentを使う

特定のコンポーネントのスタイルを継承して、新しいコンポーネントのスタイルを作成します。

import { extendComponent, ComponentStyle } from "@yamada-ui/react"
const Button: ComponentStyle = extendComponent("Button", {
/**
* 追加の`baseStyle`や`sizes`を定義する
*/
})
Copied!

extendComponentSizeを使う

特定のコンポーネントのサイズを継承して、新しいコンポーネントのサイズを作成します。

import { extendComponentSize, ComponentStyle } from "@yamada-ui/react"
const Tag: ComponentStyle = {
baseStyle: {
/**
* 新しいスタイルを定義する
*/
},
sizes: extendComponentSize("Tag", {
/**
* 追加のサイズを定義する
*/
}),
}
Copied!

extendComponentVariantを使う

特定のコンポーネントのバリアントを継承して、新しいコンポーネントのバリアントを作成します。

import { extendComponentVariant, ComponentStyle } from "@yamada-ui/react"
const Tag: ComponentStyle = {
baseStyle: {
/**
* 新しいスタイルを定義する
*/
},
variants: extendComponentVariant("Tag", {
/**
* 追加のバリアントを定義する
*/
}),
}
Copied!

extendComponentDefaultPropsを使う

特定のコンポーネントのpropsを継承して、新しいコンポーネントのpropsを作成します。

import { extendComponentDefaultProps, ComponentStyle } from "@yamada-ui/react"
const Tag: ComponentStyle = {
baseStyle: {
/**
* 新しいスタイルを定義する
*/
},
defaultProps: extendComponentDefaultProps("Tag", {
/**
* 追加のpropsを定義する
*/
}),
}
Copied!

withDefaultSizeを使う

すべてまたは一部のコンポーネントのデフォルトのサイズを変更します。

./theme/index.ts

import { extendTheme, withDefaultSize } from "@yamada-ui/react"
/**
* 省略
*/
export const theme = extendTheme(
customTheme,
withDefaultSize({
size: "lg",
components: ["Badge", "Tag", "Button"], // もし、空の配列を渡した場合は、すべてのコンポーネントに設定されます。
}),
)()
Copied!

withDefaultVariantを使う

すべてまたは一部のコンポーネントのデフォルトのバリアントを変更します。

./theme/index.ts

import { extendTheme, withDefaultVariant } from "@yamada-ui/react"
/**
* 省略
*/
export const theme = extendTheme(
customTheme,
withDefaultVariant({
variant: "solid",
components: ["Badge", "Tag", "Button"], // もし、空の配列を渡した場合は、すべてのコンポーネントに設定されます。
}),
)()
Copied!

withDefaultColorSchemeを使う

すべてまたは一部のコンポーネントのデフォルトのカラースキーマを変更します。

./theme/index.ts

import { extendTheme, withDefaultColorScheme } from "@yamada-ui/react"
/**
* 省略
*/
export const theme = extendTheme(
customTheme,
withDefaultColorScheme({
colorScheme: "primary",
components: ["Badge", "Tag", "Button"], // もし、空の配列を渡した場合は、すべてのコンポーネントに設定されます。
}),
)()
Copied!

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"], // もし、空の配列を渡した場合は、すべてのコンポーネントに設定されます。
}),
)()
Copied!

generateを使う

generateは、テーマのトークンをカスタマイズしたり、生成する便利なユーティリティです。

余白をカスタマイズする

デフォルトのテーマのspacesに指定された数値を乗算して、新しいspacesを生成します。

./theme/index.ts

import { extendTheme, withDefaultProps, generate } from "@yamada-ui/react"
export const theme = extendTheme({
spaces: generate.spaces(2),
})()
Copied!

これで、アプリケーション全体の余白が2倍になりました。

カラーのトーンを生成する

colorSchemeに使用するトーン(50から950)を生成されます。

./theme/index.ts

import { extendTheme, withDefaultProps, generate } from "@yamada-ui/react"
export const theme = extendTheme({
colors: {
red: generate.tones("#e82e34"),
},
})()
Copied!

GitHubでこのページを編集する

デフォルトのテーマコンポーネントのスタイル