import Layout from 'lib/components/layout'

export const meta = {
  title: 'Themes',
  group: 'Customization',
  index: 25,
}

## Themes

**Geist UI** now supports a variety of themes, and it is very easy to create or inherit modifications, no third-party styles or configs.
As a basic option, there are two themes available, `light` and `dark`.

### Switch themes

To switch in the default themes you only need to set the value of `themeType`, you can follow the steps below:

1. Make sure `GeistProvider` and `CssBaseline` are already on the root component.

2. Update the value of `themeType`, and the theme of all components will follow automatically.

```jsx
// NAME:src/app.js
import { CssBaseline, GeistProvider } from '@geist-ui/core'

const App = () => {
  const [themeType, setThemeType] = useState('light')
  const switchThemes = () => {
    setThemeType(last => (last === 'dark' ? 'light' : 'dark'))
  }
  return (
    <GeistProvider themeType={themeType}>
      <CssBaseline />
      <YourComponent onClick={switchThemes} />
    </GeistProvider>
  )
}
```

### Customizing theme

Customizing a theme is very simple in Geist UI, you just need to provide a new theme `Object`,
and all the components will change automatically.
Here is a complete [sample](https://github.com/geist-org/geist-ui/tree/master/examples/custom-themes) for reference.

```jsx
import { CssBaseline, GeistProvider, Themes } from '@geist-ui/core'

const myTheme1 = Themes.createFromLight({
  type: 'coolTheme',
  palette: {
    success: '#000',
  },
})

const App = () => (
  <GeistProvider themes={[myTheme1]} themeType="coolTheme">
    <CssBaseline />
    <YourAppComponent onClick={switchThemes} />
  </GeistProvider>
)
```

Function `Themes.createFromLight` allows you to fork a new theme based on Light Theme,
Of course, you can also create a new theme based on the dark style: `Themes.createFromDark`,
Or create a theme based on your own theme:

```jsx
const myBaseTheme = { ... }
const myTheme2 = Themes.create(myBaseTheme, {
  type: 'myTheme2',
  palette: {
    success: '#000',
  },
})
```

### Get types

When you need to know the detailed type definition when modifying the theme,
you can refer to the existing [type file](https://github.com/geist-org/geist-ui/blob/master/components/themes/presets/index.ts),
which corresponds to project that support TypeScript, you can refer to the type directly in the package：

```ts
import {
  GeistUIThemes,
  GeistUIThemesFont,
  GeistUIThemesPalette,
  GeistUIThemesExpressiveness,
  GeistUIThemesLayout,
} from '@geist-ui/core'

// usage:
const myStyles: GeistUIThemes = {
  /* ... */
}
const myPalette: Partial<GeistUIThemesPalette> = {
  /* ... */
}
```

### Customizer

#### ClassName

You can override the style by defining a `className` on the component.

```jsx
import { Button, Row } from '@geist-ui/core'

const MyPage = () => (
  <Row>
    <Button className="page-button">Click me!</Button>
  </Row>
)

// in css file:
.page-button {
  padding: 0;
}
```

#### Inline styles

Defining an inline style will also correctly override the component.

```jsx
const MyPage = () => (
  <Row>
    <Button style={{ margin: '20px' }}>Click me!</Button>
  </Row>
)
```

### Build components

You can use the Geist preset Hooks to get the theme states to create your own components.
For more information, please refer to [useTheme](/en-us/hooks/use-theme) documentation.

```jsx
import { useTheme } from '@geist-ui/core'

const MyComponent = () => {
  const theme = useTheme()
  return (
    <div style={{ color: theme.palette.success }}>
      <span>hello world!</span>
    </div>
  )
}
```

### Themes APIs

`Themes` contains some static methods that are useful when working with custom themes:

- `Themes.create` - create a new theme object.
- `Themes.createFromDark` - create a new theme object based on Dark Theme.
- `Themes.createFromLight` - create a new theme object based on Light Theme.
- `Themes.isPresetTheme` - Check if a theme is the base of Geist UI.
- `Themes.isAvailableThemeType` - Check if the name of the theme is available.
- `Themes.hasUserCustomTheme` - Check if a list of themes has a custom.
- `Themes.getPresets` - Get a default list of themes.
- `Themes.getPresetStaticTheme` - Get the theme loaded by Geist UI default.

export default ({ children }) => <Layout meta={meta}>{children}</Layout>
