Slide 1

Slide 1 text

なぜコピペで使う コンポーネント集を利用するのか? フロントエンドカンファレンス沖縄2023 @mottox2

Slide 2

Slide 2 text

@mottox2 UIデザインとウェブフロントエンド

Slide 3

Slide 3 text

コンポーネント集、 どうしていますか? 既存のものを使っていますか?

Slide 4

Slide 4 text

本セッションの対象者 小規模チーム シングルプロダクト マルチプロダクト 大規模 マルチプロダクトであるとか、 サービスが成熟期な人にはNot for meと感じられるかもしれません

Slide 5

Slide 5 text

コンポーネント集の歴史を振り返る 1. Bootstrap時代 2. React/Vueコンポーネント時代 3. Unstyledコンポーネント⁨時代

Slide 6

Slide 6 text

Bootstrap時代 € CSSフレームワークとも呼ばれていた、 SPA普及以前によ く使われていたもG € でかいCSSを読み込んで使う、 グローバ' € カスタマイズはできた! € CSS本体をいじってしまうと、 1万行ぐらいあったりする ので、 どこをいじったか分かりにくくなることがあった

Slide 7

Slide 7 text

React/Vueコンポーネント時代 T MUI、 Chakra等コンポーネントライブラリと言ったら、 多く の人が思い浮かべるものF T npmで配布されるコンポーネントを読み込んで利用するF T テーマ的な概念はあるが、 細かいカスタマイズは難しいF T 自作コンポーネントとのインタフェースを揃えにくいF T スタイリングライブラリを強制されがち。

Slide 8

Slide 8 text

コンポーネントライブラリ固有の 知識が多すぎない? スタイルはブラックボックスの中 MUIのサンプル // スタイルはブラックボックスの中、原則props経由で見た目を変更する /* 何も考えずにコンポーネントを作ると、sxPropsが使えない */ import from import from import from const = => = = = = = Card ; CardContent ; ArticleCard () ( < > < {{ mt: }}> < > < {{ fontSize: }} >Okinawa > > > { } < /> > ); '@mui/material/Card' '@mui/material/CardContent' '@/components/ArticleCard' "text.secondary" "" "margin-top: 16px;" Page sx sx color article style div div Card 4 CardContent Typography 14 Typography CardContent Card ArticleCard

Slide 9

Slide 9 text

Unstyledコンポーネント時代 • スタイルがなく、 機能だけを提供す‡ • アクセシビリティを担保しながら作る観点もあ‡ • その分、 自分たちで書く量も多8 • 自作コンポーネントライブラリの基礎にもなりう‡ • Headless UI, Ark UI, Radix Primitivesなど

Slide 10

Slide 10 text

Radix Primitivesのサンプルコード import from import as from import const = => = = = = = = = = React ; Tabs ; ; () ( < > < > < > Account > < > Password > > > ) 'react' '@radix-ui/react-tabs' './styles.css' "TabsRoot" "tab1" "TabsList" "Manage your account" "TabsTrigger" "tab1" "TabsTrigger" "tab2" * Tabs.Root Tabs.List Tabs.Trigger Tabs.Trigger Tabs.Trigger Tabs.Trigger Tabs.List Tabs.Root Demo className defaultValue className aria-label className value className value

Slide 11

Slide 11 text

Radix Primitivesのサンプルコード .TabsRoot .TabsList .TabsTrigger { : ; : ; : ; : ( ); } { : ; : ; : ( ); } { : ; : ; : ; : ; display flex flex-direction column width 300 box-shadow 0 2 10 var flex-shrink 0 display flex border-bottom 1 solid var font-family inherit background-color white padding 0 20 height 45 px px px px px px --black-a4 --mauve-6 サンプルコードが提供されてるとはいえ このテンションでやるのは大変

Slide 12

Slide 12 text

楽な状態と自由な状態のトレードオフ ‚ unstyledなライブラリは自由ではあるが、 あまりにも手 数がかかりすぎp ‚ MUI系はカスタマイズがしにくい上に、 流儀に沿わないと ポテンシャルを活かせな9 ‚ headless系との噛み合わせも ‚ 自作コンポーネントに思想を組み込むのも漏れがち

Slide 13

Slide 13 text

自由と楽さ、 どちらが欲しいですか?

Slide 14

Slide 14 text

両取りできる!?コピペで導入するコンポーネント集 r コンポーネント集のサイトからコードをプロジェクトにコ ピペして利用するもE r Unstyledなライブラリにスタイルを当てたものが用意さ れている

Slide 15

Slide 15 text

コピペで導入するとは何? “ コピペで導入でき、 コードがプロジェクト上に露出すf “ 今までprops経由やthemeで変更を行う必要があった部 分が露出し、 カスタマイズ可能v “ ライブラリ特有の部分が少なく、 挙動も把握しやす “ ライブラリ自体を離脱する選択が取りやすいので、 採用し やすい

Slide 16

Slide 16 text

両取りできる!?コピペで導入するコンポーネント集 t 有名どころは3X t radix primitiveにスタイルを当てたshadcn/uS t ArkUIにスタイルを当てたParkU3 t Tailwind Labsが開発中のCatalyst (現在未公開)

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

shadcn/ui r Radix Primitiveに対し てTailwindのスタ イ ルを当てたコ ンポーネン ト集x r イ ン ス トール用のCLIが用意されてい て、 以下のよ うなコ マン ド で依存関係も含めて導入でき るx r `npx shadcn-ui@latest add button r Tailwindのテーマを利用した実装にな っ ている。

Slide 19

Slide 19 text

shadcn/ui export interface extends typeof ?: const = = ... => const = ? : return < = = ... /> . < >, < buttonVariants> { } React. < , >( ({ , , , , }, ) { asChild Slot ( className { ( ({ , , }))} ref {ref} { } ) ButtonProps React ButtonHTMLAttributes HTMLButtonElement VariantProps forwardRef HTMLButtonElement ButtonProps cn asChild className variant size asChild props ref Comp buttonVariants variant size className props boolean Button false Comp "button"

Slide 20

Slide 20 text

À

Slide 21

Slide 21 text

À Park UI À Ark UIをベースにスタイルを当てたコンポーネント集i À PandaCSS (React、 Vue、 Solid) とTailwindを対象にし ているi À(おそらく、 自作コンポーネントライブラリを作るのに向い ている。 )

Slide 22

Slide 22 text

Next.jsのプロジェクトにshadcn/uiのボタンを追加しま Q `npx shadcn-ui@latest init EQ `npx shadcn-ui@latest add button ÇQ 作成されたButtonを読み込む 時間があればデモ

Slide 23

Slide 23 text

À 余談: 雰囲気がニュートラルであること À 良い意味で 「らしさ」 がないスタイル、 UIデザインのスター ト地点にしやすv À ニュートラルな理6 À スタイルが自由にいじれるから好き勝手変更でき9 À ダークモードなどを考えると自ずとニュートラルにな りがち

Slide 24

Slide 24 text

使いたいという理由もありましたが 状況にフィットしたので 実プロジェクトでshadcn/uiを採用しています

Slide 25

Slide 25 text

なぜ採用したのか? - そもそもの前提条件 ‡ 組織的にReact + TailwindCSSを使うことが多f ‡ ロックインすることは許容していE ‡ 人数は多くないのでUIだけにコストはかけずらf ‡ 対象となるアプリケーションはユーザー向けフロントエン ドと内部向けフロントエンドが存在するサービス

Slide 26

Slide 26 text

一般ユーザー向け 編集者向け ウェブサイト寄り フロントエンド ウェブアプリ寄り フロントエンド Tailwind製 何を使おう? なぜ採用したのか? - スタイリング方法の統一

Slide 27

Slide 27 text

編集者向け ウェブアプリ寄り フロントエンド x 同じチームで触るとしたら MUIやChakraは避けたF x TailwindとCSS in JSの スイッチングコストは結構 でかい (主観) → スタイリングのライブラリ を統一したい

Slide 28

Slide 28 text

このプロジェクトの行き来はしんどい const = => return = = = () { < > < > < >Hello Okinawa > < >Hello Okinawa > > > } ChakraPage fontSize mt color Card CardBody Text Text Text Text CardBody Card 'xl' "4" "gray.500" const = => return = = () { < > < > < >Hello Okinawa > < >Hello Okinawa > > > } TailwindPage className className Card Card.Body Card.Body Card p p p p "text- xl" "mt-4 text- gray-500"

Slide 29

Slide 29 text

` カスタマイズが入るコンポーネントの見込みがあっ1 ` ちょっと凝ったFileUplod、 SelectBo ` 外部ライブラリと連携するRichEditoÈ ` CSS in JS系のを入れたくなかった なぜ採用したのか? - 外部ライブラリとの連携

Slide 30

Slide 30 text

使ってみてどうか? x 総評としては入れて良かったと感じているI x Tailwindを使いつつUIパーツが速攻で用意できてよいI x TailwindのconfigやVariantのレールが引けて良いI x 気に入らないことがあったらすぐ変更できる安心感I x 離脱しやすいので導入の心理的コストが低い。

Slide 31

Slide 31 text

どんな懸念がある? † コピペで導入する方法が枯れてないことによる負債化X † 共有コンポーネントが触りやすすぎることによる負債化。 → やはり気を使ってメンテナンスしていく必要はありそう   離脱しても単なるTailwindプロジェクトになるので一定   の安心感はある

Slide 32

Slide 32 text

まとめ u セッションタイトル→自由と便利さを両どりするためP u コンポーネント集にも新時代が訪れつつあるP u その中でも妥協点になりうるコピペで使うコンポーネン ト集が現れてきているP u 今回の選択はあくまで一例、 自分のプロジェクトにあった ものを選ぼう。

Slide 33

Slide 33 text

Thank you!