Yamada UI:多機能かつ柔軟なUIコンポーネントライブラリを触ってみた

## はじめに
みなさんは、どのReactのUIコンポーネントライブラリを使っていますか？
Material-UI（MUI）、Chakra UI、Boostrap等々、様々だと思います。

今回はYamada UIという多機能かつ柔軟性が高いUIコンポーネントライブラリを紹介します。


https://github.com/hirotomoyamada/yamada-ui

https://yamada-ui.vercel.app/

## Yamada UIとは
公式の説明を日本語訳したものを以下に載せます。

>Yamada UIは、最先端のWebアプリケーションやWebサイトの開発を効率化するReact UIコンポーネントライブラリです。他のReact UIコンポーネントライブラリでは一般的にサポートされていないカラーモードやアニメーションなどの様々な機能を取り入れ、複雑なユーザーインターフェイスを構築するために簡単に組み合わせることができる多様なコンポーネントを提供しています。

「かゆいところに手の届く多機能性」と「カスタマイズが容易であるという柔軟性」の二つを兼ね備えたライブラリであるという所感です。



## Yamada UIの使い方
使い方はChakura UIなどのコンポーネントライブラリと同様です。
まずパッケージを追加します。

```bash
$ pnpm add @yamada-ui/react
# or
$ yarn add @yamada-ui/react
# or
$ npm install @yamada-ui/react
```

そして`UIProvider`という高位コンポーネント（Higher-Order Component、HOC）を設定すれば、使えるようになります。

```javascript
import { UIProvider } from "@yamada-ui/react"

const App = ({ children }) => {
  return <UIProvider>{children}</UIProvider>
}

export default App
```

## Yamada UIの詳細
全ては紹介できないので、基本的な使い方と特に印象的だった部分をかいつまんで紹介します

### テーマ
`UIProvider`の`theme`でテーマを設定できます。

```javascript
import { UIProvider, extendTheme } from "@yamada-ui/react"

const customTheme = extendTheme({
  spaces: {
    xs: "1rem",
    sm: "1.25rem",
    md: "1.5rem",
    normal: "2rem",
    lg: "2.5rem",
    xl: "3rem",
  },
})()

const App = () => {
  return (
    <UIProvider theme={customTheme}>
      <YourApplication />
    </UIProvider>
    )
}
```

### ローディング
ローディングは、スクリーンローディング(2)ページローディング(3)バックエンドローディングの3つがサポートされています。

```javascript
const { screen, page, background } = useLoading()

//isLoading、start、update、finishメソッドがある。使い方：screen.start()とscreen.finish()
```

### 通知
通知はボタンと組み合わせて以下のように使います。

```typescript
const notice = useNotice()


return (
  <Button
    onClick={() =>
      notice({
        title: "Notification",
        description: "This is description.",
      })
    }
  >
    Show notification
  </Button>
)
```

### コンポーネント
`variant`, `size`, `colorScheme`で以下のようにカスタマイズできます。

![ 2023-12-05 11.27.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487820/c765b57b-311c-07a6-d8a3-756dc011a715.png)

### レスポンシブ
`breakpoints`が設定されているため、レスポンシブを簡単に実装できます。
ここでは`bg`の色がレスポンシブに応じて変わります。

```javascript
<Box
  bg={{ base: "primary", "2xl": "secondary", xl: "warning", lg: "danger" }}
>
  This is Box
</Box>
```

```javascript
export const breakpoints = {
  sm: "30em", // 480px
  md: "48em", // 768px
  lg: "61em", // 976px
  xl: "80em", // 1280px
  "2xl": "90em", // 1440px
}
```
### カラーモード
カラーモードは`changeColorMode`で変更できます。
現在のカラーモードは`colorMode`で確認でき、`toggleColorMode`で変更できます。

```javascript
const { colorMode, changeColorMode, toggleColorMode } = useColorMode()

return (
    <Wrap/>
        <Button onClick={() => changeColorMode("light")}>Light Mode</Button>
        <Button onClick={toggleColorMode}>
          Switch to {colorMode === "light" ? "Dark" : "Light"} Mode
        </Button>
    </Wrap>
)
```


### カレンダー
カレンダーは以下のように使います。
```bash
$ pnpm add @yamada-ui/calendar
```
```javascript
import { Calendar } from "@yamada-ui/calendar"

<Calendar />
```
![ 2023-12-05 11.40.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487820/8c14a0ec-f33e-41fd-615e-7b012e36698d.png)

### カルーセル
スライドを埋め込みたい場合は、以下のように`Carousel`を使います。

```javascript
<Carousel>
  <CarouselSlide as={Center} bg="primary">
    1
  </CarouselSlide>
  <CarouselSlide as={Center} bg="secondary">
    2
  </CarouselSlide>
  <CarouselSlide as={Center} bg="warning">
    3
  </CarouselSlide>
  <CarouselSlide as={Center} bg="danger">
    4
  </CarouselSlide>
</Carousel>
```
![ 2023-12-05 11.43.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487820/9dd8ee74-919d-9f0e-0241-4752971a39de.png)


### テーブル
テーブルは`NativeTable`と`PagingTable`があります。
以下のようなソート機能付き&ページ機能付きの表を簡単に作ることができます。

```javascript
const columns = useMemo<Column<Data>[]>(
  () => [
    {
      header: "First Name",
      accessorKey: "firstName",
    },
    {
      header: "Last Name",
      accessorKey: "lastName",
    },
    {
      header: "Age",
      accessorKey: "age",
    },
    {
      header: "Email",
      accessorKey: "email",
    },
  ],
  [],
)
return <PagingTable columns={columns} data={data} />
```

![ 2023-12-05 11.46.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487820/6c8deb40-1ee8-8a51-03a6-4e3b86ea3baa.png)

### リオーダー
順番変更可能な要素を簡単に作ることができます。

```javascript
import { Reorder, ReorderItem} from "@yamada-ui/react"

<Reorder>
  <ReorderItem label="ギニュー">ギニュー</ReorderItem>
  <ReorderItem label="リクーム">リクーム</ReorderItem>
  <ReorderItem label="バータ">バータ</ReorderItem>
</Reorder>
```

### スクロール
スクロールについては`ScrollArea`を使えば簡単に実装できます。

```javascript
<ScrollArea h="xs" innerProps={{ as: VStack, gap: "md" }}>
  <Text>
    セルゲームより約7年後、高校生に成長した悟飯が天下一武道会に出場することを知った悟空は、自らも出場するために占いババの力によって1日だけこの世に戻る。天下一武道会の最中、悟空たちは界王よりもさらに高位の存在である界王神から、恐ろしい力を持つ魔人ブウの封印が解かれようとしていることを知らされる。復活した魔人ブウにより悟飯やベジータが倒され、悟空はあの世に帰ったため、地球の命運は悟空の次男・孫悟天と少年トランクスの幼い二人に託される。
    一方、魔人ブウは様々な人間との出会いからより邪悪で強力な魔人へと変貌。悟天とトランクスが「フュージョン（融合）」して誕生した戦士・ゴテンクスや、潜在能力を解放し、パワーアップを遂げて帰ってきた悟飯らが応戦するが、戦士たちを次々と吸収し姿を変えていく魔人ブウに苦戦を強いられる。危機に陥った悟飯らを救うため現世に舞い戻った悟空とベジータは、界王神界で真の姿となった魔人ブウとの最終決戦に臨む。ドラゴンボールの協力もあり、地球・ナメック星・あの世の人々のエネルギーによって作り上げられた超特大の元気玉によって魔人ブウは完全に消滅する。
    それから10年後、悟空は孫のパンと共に天下一武道会に久しぶりに出場し、魔人ブウの生まれ変わりである少年・ウーブと出会う。悟空はウーブと共に見果てぬ強さを追い求めて修行に旅立ち、物語は幕を閉じる。
  </Text>
</ScrollArea>
```
さらにスクロールの制御も以下のように簡単に実装できます。

```javascript
const ref = useRef<HTMLDivElement>(null)

const scrollToTop = () => {
  if (!ref.current) return

  ref.current.scrollTo({ top: 0, behavior: "smooth" })
}

//スクロールのトップに移動
<Button onClick={scrollToTop}>Scroll to top</Button>
```


## おわりに
いかがだったでしょうか。まだまだ全て紹介できていないですが、便利さは伝わったと思います。

Yamada UIは参考記事は少ないというデメリットはあるものの、ドキュメントがわかりやすいので、導入しやすいと思います。個人開発で使ってみてはいかがでしょうか。



最後にGitHubのリンクのcodesandboxを添付して、記事を締めくくります。

https://github.com/hirotomoyamada/yamada-ui#codesandbox