Cubic Bezier Input | 501A

Works

Cubic Bezier Input

スタイルが適用されておらず、高い composability を備えたキュービックベジェ入力コンポーネント。

概要

cubic-bezier-input は、スタイルを持たないヘッドレスな React コンポーネントです。Radix や shadcn/ui などのライブラリで広まった composable なコンポーネントパターンに従い、開発者がベジェ曲線エディタのルックアンドフィールを完全に制御できるようにします。

課題

既存のベジェ曲線入力にはいくつかの制限がありました:

Tailwind でスタイルを適用でき、Radix のような composability を持つものが欲しいと思いました。そうすれば、他人のデザイン決定と戦うことなく、どんなプロジェクトにも統合できます。

解決策

コンポーネント構造は compound component パターンに従います:

<CubicBezier.Root>
  <CubicBezier.Grid />
  <CubicBezier.Controller index={1}>
    <CubicBezier.Line />
    <CubicBezier.Thumb />
  </CubicBezier.Controller>
  <CubicBezier.Controller index={2}>
    <CubicBezier.Line />
    <CubicBezier.Thumb />
  </CubicBezier.Controller>
  <CubicBezier.Curve>
    <CubicBezier.End />
  </CubicBezier.Curve>
</CubicBezier.Root>

すべてのコンポーネントは className プロパティを受け付け、ゼロスタイルで出荷されるため、Tailwind や他の CSS アプローチを使って簡単にスタイルを適用できます。曲線とグリッドは SVG で描画されるため、fill-*stroke-* などのユーティリティクラスを使って外観をカスタマイズできます。

開発と実装

このコンポーネントは、Vercel の AI コーディングツールである v0 を使って構築しました。まず API サーフェスを設計し、コンポーネント階層、公開するプロパティ、各パーツが受け付けるべきもの、そしてコンテキストを通じて状態をどのように流すかを検討しました。それらの設計が固まったら、v0 に内容を伝えてコードを生成させました。

API は Radix を参考にモデリングしました。状態管理は制御された(controlled)パターンと制御されていない(uncontrolled)パターンの両方をサポートし、onValueChange でリアルタイム更新、onValueCommit でユーザーの操作完了をハンドリングします。minYmaxY のような制約は、ベジェ値が特定の範囲内に収まる必要があるケースをサポートするために追加しました。

最後に

API を設計し、その仕様に基づいてエージェントに構築させるのがこれほど簡単になったことはありません。また、コードをどのように構造化してほしいかを具体的に指定することの重要性も増していると感じます。エージェントはコードを生成できますが、あなたが導かなければ良い設計判断を下すことはできません。

サードパーティのライブラリの設計決定に依存せずに、ミニライブラリや内部コンポーネントを素早く構築することは、エージェントの優れた活用方法です。自分のニーズに正確に合ったものを作れます。このアプローチは今後ますます使っていきたいと考えています。