イケてるUIを手早く、必要な分だけ、しっかり作れるのがshadcn


# 要約

- shadcnとはTailwind CSSを利用した**シンプルでイケてるデザイン例**のことである
- 各画面要素（ボタンや表など）単位で個別に入手し、即利用できる。要らない部分は入手しなくてもよい
- あくまで例なので、変えたい部分は**自由に手を加えること**も出来る（加えなくてもいい）
- 「機能は作れるけど、見栄えの方は……」という人の強い味方である 

# 本文

## 1. 経緯
　先日、[AIの力におんぶにだっこ](https://qiita.com/Anest_Doi/items/8cf6ca156b701db892e1)して、何とかNext.jsでWebサイトを作ることに成功した。
　意気揚々と社内公開してみたところ、このような意見が寄せられた。

---

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2352782/15b43205-5847-21c8-8caf-62b29e4a53e8.png" width="25">
「デザインがイケていない、<b>ネット黎明期の個人サイト</b>みたいな感じがする」

---
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2352782/a6607934-71e2-ef48-e3d3-440e9f10a679.png" width="25">
「ダークモード／ライトモードの切り替えを <b>【ダークモード】とべた書きで書いてある</b>ラジオボタンでやらせるのは、ちょっと」

---
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2352782/15b43205-5847-21c8-8caf-62b29e4a53e8.png" width="25">
「ソースが<b>ごちゃごちゃ</b>している」

---

「そこまで言わなくても良くない…？」と思った。

　出来ることなら、こういうのを作りたいよ？

**イメージ図**
![iketeru.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2352782/eeb78931-2472-5637-a5e0-d2441cb97f42.png)


　でもどうやって作るのか、わからないのよ。

「こういう機能のサイトを作りたい」は大体イメージつくし、AIにも相談できるけど、UIになると途端に語彙がなくなる自分がいる。

　行にカーソルを当てたらそこがちょっと暗くなる、とかなら何とかなるかもしれない。
 
　入力したら絞り込みが出来るとか、
 
　列クリックしたら昇順（降順）ソートするとか、
  
　クリックしたらピロっとメニューが出てくる形式のボタンとかは、

　**無理**。
 
---

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2352782/15b43205-5847-21c8-8caf-62b29e4a53e8.png" width="25">「え、でもやってるサイトはちゃんとやってますよね？」

---

　そりゃデザインの天才がやってるんでしょ、と思っていた。

　痛烈な指摘をしていただいた彼から、**shadcn**なるものを教えていただくまでは……


## 2. shadcnとは

「シャドシーエヌ」と読むらしい。

　QiitaやZennでも記事が見受けられたが、公式のサンプルコードを見て実際に触ってみるのが速い。

https://ui.shadcn.com/

　shadcnをざっくりと表現するなら以下のようになる。
 
**「Tailwindは扱える人が扱えば無限のポテンシャルがあるけど難しいです。だったら、とても扱える人達が作ったテンプレートを要素ごとにソース付きで提供します。どうぞ好きなように使ってください」**

### 2-1. 手早い

　上記サイトページに書いてある文言の通りである。
 「Beautifully designed components that you can copy and paste into your apps.」

　美しいデザインのコンポーネントをコピペして入れられる。

#### 導入～使ってみる

**前準備：作りたてのNext.jsプロジェクトを用意する**
![npx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2352782/f86d7d76-a118-d796-f874-2539d4c4dc55.png)

**1. 中身を極限まで削る**

```page.tsx
export default function Home() {
  return (
    <div>
      Hello, world!
    </div>
  );
}
```

```globals.css
/* すべて消す */
```

![result1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2352782/c36bff70-e4ad-7078-2cbf-877d36d45398.png)

**2. shadcnを初期化**

```
　npx shadcn-ui@latest init
```
　いつもやる「npm install ～」じゃないのね。

　その後、いろいろ聞かれるがglobals.cssの場所以外は全部デフォルトにする。

![init.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2352782/b23f61e6-9afc-8aa6-b383-49c2d8d38692.png)


**3. 必要な要素を追加する**

　ボタンを追加したくなったとする。

https://ui.shadcn.com/docs/components/button

　上記の手順に従ってみる。
 
```
　npx shadcn-ui@latest add button
```

　components/uiの配下にbuttonが生成された。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2352782/71e5e624-9b72-0b4f-093f-46b6f58b135d.png)

　ボタンの定義を利用する。
```page.tsx
import {Button} from "@/components/ui/button";

export default function Home() {
  return (
    <div>
      Hello, world!
      <div>
        <Button variant="outline">search</Button>
      </div>
      <div>
        <Button variant="default">submit</Button>
      </div>
      <div>
        <Button variant="destructive">ALLDelete</Button>
      </div>
    </div>
  );
}
```

　出来上がり。
 
![result2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2352782/f555212d-b928-c837-2507-49cb1a98062e.png)


　こんな形で要素を手軽に取り込むことが出来る。
　取り扱っている要素も、ダイアログやページネーション、メニューバーなど、サイトを作る上で肝心な要素は網羅されている。（**しかも全部カッコいい**）

　ダークモードも勿論入っており、もう**ダサダサべた書き【ダークモード】ラジオボタン**とはお別れだ。

https://ui.shadcn.com/docs/dark-mode


### 2-2. 必要な分だけ

　上記の例で見て分かる通り、使わない要素以外の定義は含まれない。

　さらにチェックボックス、表、カレンダーといった定義も必要な分だけを取得して利用することが出来る。

　その内容はcomponents/ui配下に配置されることになる。
 
```page.tsx
import {Button} from "@/components/ui/button";
import {Checkbox} from "@/components/ui/checkbox";
import {Calendar} from "@/components/ui/calendar";

export default function Home() {
  return (
        // 中略
      <div>
        <Checkbox/>承知しました。
      </div>
      <div>
        <Calendar />
      </div>
    </div>
  );
}
```
![result3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2352782/cd56fee2-da32-8f6f-2d41-04842b9bc1d1.png)

### 2-3. しっかり作れる

これだけでもイケてるが、components/uiに配置された各コンポーネントの定義は、自由に編集が可能である。

ボタンのvariantsの定義にemergencyを追加。
背景を黄色、文字色を赤、ホバー時に黒くするように定義し、画面内で呼び出すようにした。

```button.tsx
    variants: {
      variant: {
        // 中略
        emergency: "bg-yellow-300 text-red-400 hover:bg-slate-900/90",
      },
```

```page.tsx
      <div>
        <Button variant="emergency">emergency</Button>
      </div>
```

実行してみる。下部にemergencyのボタンが設置されていることが確認できる。
（左が非ホバー時、右がホバー時）
![result4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2352782/952535cb-a36f-44f9-e4e1-daa9cd649040.png)![result5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2352782/d0eca525-3522-a000-c3b6-74de4757d2c1.png)

定義に触れるということは、引数を渡してボタンサイズを可変にしたり（やるかは別として）、他の資材と組み合わせて独自の要素を作り込むことも出来る。

機能としての部分と、画面表示としての部分がきちんと役割分担されるため、ソースがごちゃごちゃになることもなくなる。

## 3. 感想

### 3-1. 便利さもそうだけど、コンセプトがすごい

　shadcnに触れてみて思ったのは「これ、**やりたかったけど出来なかったこと**だわ」ということである。
　画面表示のコンポーネントはそれ用のフォルダにまとまっていて、適宜参照することで画面構築を行う。必要のない要素には触らないでいたい。
　ただ、こだわれるときは好きにこだわれるようにしたい……

　白と黒のイケてる表示もそうだが、人・組織ごとにジャストフィットするようなコンセプトが非常に優れていると思った。
 
　人気が出るのも頷ける内容だった。

### 3-2. 無知が流石に罪になってきた
　AIに触った時でも感じたことだが「**そもそも知らない**」という状態は、今の時代、相当に大きなハンデを背負うことになるのだなと思った。

　ちまちま試行錯誤するのはどんな分野であれ通る道だが、人によって「試行錯誤」する段階が違うというか、「えっ、**そんなところ**で？」と感じる度合いがますます高まってきそうだった。
　そういった事態を防ぐためにもエバンジェリスト（伝道者）が必要になるのだろう。

「VUCA」と聞くだけで蕁麻疹が出来る虚弱体質ではあるものの、そんなことはIT界隈には関係のない話。

**「先行き不透明だったらなおさら先をきちんとチェックせよ」** という当たり前の教訓を、社会人11年目に得たのであった。

### 3-3. 恵まれてるけど怖い

　今の状態で十全に開発が出来るというのは間違いなく恵まれている。（以前の参画プロジェクトではそもそも外部ネットワークにアクセスできなかった）

　とは言え、恵まれているからこその贅沢な悩みも出ている。

　技術の可能性に触れるだけ、**言い訳の余地**が消えていくのだ。
 
「**才能が……**」「**時間が……**」という定番の文句が言えなくなっている。

「そんなの無理だよ」という弱音が吐けなくなってくる。

　徐々に価値観のアップデートをせよ、ということなのだろう。「**無理ってほどでもない**」と前向きに捉えられるように。
 
# 余談

## Chakraと比較するとどうなのか？

　UIと言えば「チャクラ」も有名らしい。

https://v2.chakra-ui.com/

　内容を確認してみる限り、
 
　元々の目標だった**イケてるデザイン**を達成するだけなら、どちらでも実現できると思われた。

　両者の意見はこんなところだろう。

---

**shadcn**「OK、さっさと終わらせよう。イケてるボタンだけでいいなら、ボタンだけ取ってくればいい。動くようにはしといてある。こだわりたければ、オレのを参考に好きなだけ加工すればいい。他のが欲しくなったら、その時に考えよう」

---

**Chakra**「本業でもないUI部分でいちいち悩みたくないでしょう？　必要な部品はすべてあります。サイトを作るのに必要そうなパラメータも全部決めています。悩む要素はすべて消しておきました。あなたはその中で好きなものを選ぶだけでよいのです……」

---

　両方とも魅力的な提案である。
　先にChakraに出会っていたら、今頃はChakraの記事を書いていただろう。

　それぞれ求めているスタイルが違うので、自分に適している方を採用するのが良いだろう。