Customize Theme
All components of Yamada UI inherit styles and tokens from the theme. Depending on the scenario, you may need to customize things like color
to match your project.
When customizing the theme, it is recommended to use extendTheme
. This creates a theme that inherits from the Default Theme. If you do not use extendTheme
, it will become a completely new theme that does not inherit from the Default Theme.
Theme Usage
If you customize the theme, it is recommended to use type completion. Type completion uses the CLI.
When using the CLI
, you need to create a theme file because it refers to the theme that is exported by default in the file.
Considering that the theme's tokens and styles may be added or changed during development, it is recommended to keep the theme in a folder.
./theme├ components # Folder to define the styles of each component├ tokens # Folder to define each token├ styles # Folder to define global styles and reset styles├ config.ts # File to set the config└ index.ts # File to export the theme by default
./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)()
The theme is being exported by default using extendTheme
.
Applying Theme
To apply a theme, pass it to theme
of UIProvider
.
In the case of 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>,)
In the case of 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
In the case of 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>,)
Changing Tokens
This time, let's try changing new and existing tokens in colors
.
Create colors.ts
under tokens
.
./theme/tokens/colors.ts
import { ThemeTokens } from "@yamada-ui/react"export const colors: ThemeTokens = {banner: "#9d38a0",black: ["#1F2123", "#101112"],}
We have added a new banner
to colors
and changed black
. Also, by defining an array, you can support color modes.
Create index.ts
and export the colors
you created earlier.
./theme/tokens/index.ts
import { colors } from "./colors"export const tokens = { colors }
Include tokens
in customTheme
.
./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)()
If you don't want to inherit only colors
from the default theme, pass omit
to extendTheme
.
./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"] })
Setting Responsive Objects to Tokens
By default, theme tokens do not support responsive objects. If you want to enable responsive objects for theme tokens, set config.theme.responsive
to true
.
./theme/config.ts
import { extendConfig } from "@yamada-ui/react"export const config = extendConfig({theme: {responsive: true,},})
If you want to learn more about customizing the config, please check here.
Set responsive objects to theme tokens.
./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" },}
If you want to learn more about responsive objects, please check here.
Make sure to set base
for responsive objects. Also, do not set base
for theme tokens that are not responsive objects. The reason is that objects with base
are considered responsive objects.
Next, include spaces
in the tokens
in ./theme/index.ts
as you did in Changing Tokens.
Changing Semantic Tokens
Within the semantic tokens, a color scheme used in each component is set.
Here are the actual values that are set.
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",},}
This time, let's try changing the default color scheme.
Create semantics.ts
under theme
.
./theme/semantics.ts
import { ThemeSemantics } from "@yamada-ui/react"export const semantics: ThemeSemantics = {colors: {primary: "pink.500",},colorSchemes: {primary: "pink",},}
Include semantics
in customTheme
.
./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)()
If you want to learn more about semantic tokens, please check here.
Changing Styles
You can set globalStyle, resetStyle, layerStyles, textStyles, etc. in styles
.
This time, let's try changing the globalStyle
that sets the style of body
.
Create global-style.ts
under styles
.
./theme/styles/global-style.ts
import { UIStyle } from "@yamada-ui/react"export const globalStyle: UIStyle = {body: {bg: ["black", "white"],},}
The background of body
is being changed. Also, by defining an array, you can support color modes.
Create index.ts
and export the globalStyle
you just created.
./theme/styles/index.ts
import { globalStyle } from "./global-style"export const styles = { globalStyle }
Include styles
in customTheme
.
./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)()
If you don't want to inherit only styles
from the default theme, pass omit
to extendTheme
.
./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"] })
If you want to learn about text and layer styles, please check here.
Changing the Style of Components
Depending on the project, you may want to change the style of Yamada UI's components. Since Yamada UI's components refer to the style of the theme, you can easily change the style of the components.
The style of a component is composed of the basic style of the component (baseStyle
), styles of various sizes (sizes
), styles of various visuals (variants
), and default props
(defaultProps
).
Not all components have size
or variant
. To check which components are compatible, please refer to the props
on the component's page.
Yamada UI can style components by setting style props
on them. However, large projects have many developers, and setting styles individually can compromise design consistency. In that case, you can avoid this by setting common styles in the style of the theme's components.
This time, let's change the Container
component.
Create container.ts
under components
.
./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",},}
The background color is changed, each size is defined in sizes
, and each variant is defined in variants
. defaultProps
sets the default values.
Create index.ts
and export the Container
you just created.
./theme/components/index.ts
import { Container } from "./container"export const components = { Container }
Include components
in customTheme
.
./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)()
Now, the background color of Container
is changed, and the style is changed by passing size
or variant
.
import { Container } from "@yamada-ui/react"const Demo = () => {return (<Container size="sm" variant="with-border-dotted">This is Container</Container>)}
The Container
we changed this time is a component composed of a single element. There are also components composed of multiple elements (such as Accordion
). When changing a component composed of multiple elements, the type definition becomes ComponentMultiStyle
.
To check the theme style of each component, please refer to the Theming
on the component's page.
You can create styles for custom components, not just the components provided by Yamada UI. For more details, please check here.
Utility
Yamada UI provides many theme utilities.
Using extendTheme
Create a new theme by inheriting the default theme. It is also possible to pass multiple objects and specify options.
Merging multiple themes
./theme/index.ts
import { extendTheme, UsageTheme } from "@yamada-ui/react"const firstTheme: UsageTheme = {}const secondTheme: UsageTheme = {}export const theme = extendTheme(firstTheme, secondTheme)()
Not inheriting the default theme
./theme/index.ts
import { extendTheme, UsageTheme } from "@yamada-ui/react"const firstTheme: UsageTheme = {}const secondTheme: UsageTheme = {}export const theme = extendTheme(firstTheme, secondTheme)({ merge: false })
Inheriting from the default theme excluding specific tokens
./theme/index.ts
import { extendTheme, UsageTheme } from "@yamada-ui/react"const customTheme: UsageTheme = {}export const theme = extendTheme(customTheme)({ omit: ["colors"] })
Inheriting only specific tokens from the default theme
./theme/index.ts
import { extendTheme, UsageTheme } from "@yamada-ui/react"const customTheme: UsageTheme = {}export const theme = extendTheme(customTheme)({ pick: ["spaces"] })
Using extendBaseTheme
This creates a new theme that inherits only the tokens such as global styles and colors of the default theme. It is also possible to pass multiple objects and specify options.
./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)()
extendBaseTheme
internally uses baseTheme
. baseTheme
has defined tokens such as global styles and colors, but the styles of the components are not defined.
Using extendStyle
Create a new style by inheriting globalStyle
or resetStyle
.
import { extendStyle, UIStyle } from "@yamada-ui/react"const globalStyle: UIStyle = extendStyle("globalStyle", {/*** Define additional styles*/})
Using extendToken
This creates a new token by inheriting a specific token.
import { extendToken, ThemeTokens } from "@yamada-ui/react"const colors: ThemeTokens = extendToken("colors", {/*** Define additional tokens*/})
Using extendComponent
This creates the style of a new component by inheriting the style of a specific component.
import { extendComponent, ComponentStyle } from "@yamada-ui/react"const Button: ComponentStyle = extendComponent("Button", {/*** Define additional `baseStyle` and `sizes`*/})
Using extendComponentSize
This creates the size of a new component by inheriting the size of a specific component.
import { extendComponentSize, ComponentStyle } from "@yamada-ui/react"const Tag: ComponentStyle = {baseStyle: {/*** Define a new style*/},sizes: extendComponentSize("Tag", {/*** Define additional sizes*/}),}
You can use this function when you only want to inherit sizes
, but not baseStyle
or variants
.
Using extendComponentVariant
This creates a new component variant by inheriting a specific component's variant.
import { extendComponentVariant, ComponentStyle } from "@yamada-ui/react"const Tag: ComponentStyle = {baseStyle: {/*** Define new style*/},variants: extendComponentVariant("Tag", {/*** Define additional variants*/}),}
You can use this function when you only want to inherit variants
, but not baseStyle
or sizes
.
Using extendComponentDefaultProps
This creates the props
of a new component by inheriting the props
of a specific component.
import { extendComponentDefaultProps, ComponentStyle } from "@yamada-ui/react"const Tag: ComponentStyle = {baseStyle: {/*** Define new style*/},defaultProps: extendComponentDefaultProps("Tag", {/*** Define additional props*/}),}
You can use this function when you don't want to inherit baseStyle
or sizes
, but only want to inherit defaultProps
.
Usage of withDefaultSize
It changes the default size of all
or some
components.
./theme/index.ts
import { extendTheme, withDefaultSize } from "@yamada-ui/react"/*** omitted*/export const theme = extendTheme(customTheme,withDefaultSize({size: "lg",components: ["Badge", "Tag", "Button"], // If you pass an empty array, it will be set for all components.}),)()
Using withDefaultVariant
Changes the default variant of all
or some
components.
./theme/index.ts
import { extendTheme, withDefaultVariant } from "@yamada-ui/react"/*** omitted*/export const theme = extendTheme(customTheme,withDefaultVariant({variant: "solid",components: ["Badge", "Tag", "Button"], // If you pass an empty array, it will be set for all components.}),)()
Using withDefaultColorScheme
Changes the default color scheme of all
or some
components.
./theme/index.ts
import { extendTheme, withDefaultColorScheme } from "@yamada-ui/react"/*** omitted*/export const theme = extendTheme(customTheme,withDefaultColorScheme({colorScheme: "primary",components: ["Badge", "Tag", "Button"], // If you pass an empty array, it will be set for all components.}),)()
Usage of withDefaultProps
It changes all or part of the default props
of the components at once.
./theme/index.ts
import { extendTheme, withDefaultProps } from "@yamada-ui/react"/*** omitted*/export const theme = extendTheme(customTheme,withDefaultProps({defaultProps: {size: "lg",variant: "solid",colorScheme: "primary",},components: ["Badge", "Tag", "Button"], // If you pass an empty array, it will be set for all components.}),)()
Using generate
generate
is a useful utility for customizing or generating theme tokens.
Customizing spacing
It generates new spaces
by multiplying the specified number with the spaces
in the default theme.
./theme/index.ts
import { extendTheme, withDefaultProps, generate } from "@yamada-ui/react"export const theme = extendTheme({spaces: generate.spaces(2),})()
This makes the spacing of the entire application twice as large.
Generating color tones
It generates tones
(50 to 950) used in colorScheme
.
./theme/index.ts
import { extendTheme, withDefaultProps, generate } from "@yamada-ui/react"export const theme = extendTheme({colors: {red: generate.tones("#e82e34"),},})()
Edit this page on GitHub