またしても AI に使わせてみた — カルーセル、そして "氷山の一角" の話(やってみた #3)
/carousel375px のビューポートで撮影。縦長のページはフレーム内をスクロールします。
解説記事
またしても AI に使わせてみた — カルーセル、そして "氷山の一角" の話(やってみた #3)
やってみたシリーズ: 自作のデザインシステム
@gunjo/ui(群青)を、群青を一度も見たことのない AI に、毎回「実際のアプリでよく出てくる UI」を作らせる連載。各回が「群青でこう作る」というハウツーにもなる。#1 設定画面 / #2 モーダル告知 に続いて、今回は カルーセル。
条件は毎回同じ。予備知識ゼロの AI に、公開済みの npm @gunjo/ui(alpha.2)と gunjo.jp の docs だけを渡す。ソースは見せない。まっさらな Next.js(React 19 / Tailwind v4)で npm run build が通るまで自力で。
お題
LP やメディア一覧で頻出のカルーセル。複数スライド(画像+見出し)を、前後ボタンと位置インジケータ(ドット)で送る。通すカテゴリは Display(Carousel / Card / Img / Badge)。
結果 — 動いた(4/5)
npm run build 成功、/carousel は static prerender、コンソールエラー0(実機確認済み)。autoPlay・loop・ドット・「Slide N of N」カウンタ・キーボード矢印まで動いた。
効いたのは今回も コンポーネントが1か所に型つきでそろっていること。Carousel を一発で発見し、controls={{ navigation: true, dots: true }} だけで前後ボタンとドットが出る組み合わせ型のコンポーネントの作りが良かった、と。さらに Img(aspectRatio・objectFit・skeleton・画像エラー時の穏やかな代替表示を内蔵)が刺さったらしい。
<Carousel className="w-full" opts={{ loop: true }} autoPlay
controls={{ navigation: true, dots: true }} setApi={setApi}>
<CarouselContent>
{slides.map((s) => (
<CarouselItem key={s.title}>
<Card className="overflow-hidden">
<Img src={s.poster} aspectRatio="video" objectFit="cover" />
<CardContent>…</CardContent>
</Card>
</CarouselItem>
))}
</CarouselContent>
</Carousel>
そして、ここからが本題 — "氷山の一角" だった
AI は build を一度落とした。エラーは——見覚えがありすぎた。
Error: `Tooltip` must be used within `TooltipProvider`
#2 で Banner が出したのと同じ、サーバー側の事前描画(SSR)でのクラッシュ。Carousel の前後ボタン(TooltipButton)とドット(Tooltip)が、必要な TooltipProvider を自分の内側に持っていない。#2 のあと #49 で Banner は直した。直したつもりだった。
念のため、ソース全体で「Tooltip を使うのに TooltipProvider を持たない」コンポーネントを棚卸ししたら——28個あった。Carousel、TooltipButton、Calendar、DatePicker、Combobox、Command、DataTable、Accordion、Avatar… provider を持っていたのは Banner と Toast だけ。
#49 は氷山の一角だった。 バグを1個直しただけで、根っこ(同じパターン)が残っていた。
これは、予備知識ゼロの AI に作らせるテストがバグ1個じゃなくパターンを見つけた瞬間です。一個ずつ叩いていたら何ヶ月も気づかなかった、全体に共通する欠陥を、3回目の素朴な「カルーセル作って」が炙り出した。直し方も1個ずつじゃなく、群青の Tooltip ラッパー自体を単体で完結させて28個まとめて直す、という設計判断に変わる(#52)。
ほかにも正直な粗さ:
- docs のコード例が fetch に映らない(#2 の #50・まだ未デプロイ)— AI は結局 TS 型から composition を再構築した
controlsにオブジェクトを渡すと既定が全部 off に反転する非直感(docs 記載なし)Carouselの既定がw-[640px]固定、Imgもh-[256px] w-[256px]固定 — 初期状態で幅いっぱいに広がらず、上書きが必要(#47 と同系統)
学び — だから "担保できる" は、テストしてから言う
AI に使わせる → 粗さが出る → 大元(SSOT)で一貫して直す → また使わせる
#3 で一番大きいのは、gunjo がまだ "難しい2割" を完全には担保できていないと、自分のテストで分かったこと。28個の潜在クラッシュを抱えたまま「担保できる」と書いていたら、それは嘘になっていた。やってみたシリーズは、その嘘を書く前に潰すためにある。盛らない、隠さない。出た不備は全部 issue にして直す。
次回予告(やってみた #4)
- ダッシュボード(Charts / Stat / Table)— 群青の Charts は HTML/CSS の基本的なコンポーネントでできている。任意のデータで崩れないかを予備知識ゼロの AI に通す、差別化の本丸。
試す
- gunjo.jp / npm
@gunjo/ui/ GitHub - 前回: #1 設定画面 / #2 モーダル告知
- まとめ記事: 群青(@gunjo/ui) / なぜ要るのか: AI 時代のデザインシステム論
- GunjoUI by UIXHERO
まだ alpha、粗削りな青。粗さが出るたび直します。Issue 歓迎。
この連載は、作者が AI(Claude と Codex)と協働で制作しています。実験・検証の設計、判断、公開前の事実確認は人間が行い、実作業と下書き執筆は AI が担っています。
使用した @gunjo/ui コンポーネント
この画面のソースが直接 import しているコンポーネントです。
cold AI が組み上げた実コード
ファイル名をクリックでソースを展開できます。
