gpui-kit について
gpui-kitは、Rustのgpui-kit crateを使ったアプリケーション開発をコーディングエージェントに案内するスキルです。設計・コーディングガイドの参照を必須とし、フォーム、フィードバック、オーバーレイ、ナビゲーション、データ表示のコンポーネントを紹介します。
主な機能
- 01crateのレイヤーと状態所有のガイド
- 02設計・コーディングガイドの参照
- 03UIコンポーネント一覧
- 04ステートフル/ステートレスな部品のパターン
- 05テーマ、オーバーレイ、レイアウトの指針
活用シーン
- 01UIタスクに適したコンポーネントの選択
- 02フォームや操作コントロールの実装
- 03オーバーレイとナビゲーションを備えた画面の構築
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ longbridge/ gpui-kit --skill gpui-kitインストール後、Claude Code で/gpui-kitを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/coding-guides.mdconventions.mdrecipes.mdusage.mdreferences/gpui/action.mdasync.mdcontext.mdelement-advanced.mdelement-api.mdelement-best-practices.mdelement-examples.mdelement-id.mdelement-patterns.mdelement.mdentity-advanced.mdentity-api.mdentity-best-practices.mdentity-patterns.mdentity.mdevent.mdfocus-handle.mdglobal.mdlayout-style.mdtest-examples.mdtest-reference.mdtest.md詳細
GPUI Kit
アプリケーションは単一のクレート gpui-kit に依存します。GPUI は use gpui_kit::*; で利用でき、各レイヤーには名前を指定してアクセスできます。gpui_kit::component(スタイル付きコンポーネント)、gpui_kit::base(スタイルなしの動作)、gpui_kit::assets(デフォルトのアイコン)、gpui_kit::platform です。
タスクに適したコンストラクター、状態の所有者、イベント、レイアウトの契約を選ぶには、まずコンポーネントファミリーの規約を確認してください。ファミリーの仕組みを把握したうえで、対象のコンポーネントが必要な機能に対応していることを確認します。
状態の保持、サブスクリプション、オーバーレイレイヤーを含む、コンパイル済みの完全なビューについては、テスト済みアプリケーションのレシピをお読みください。
まずガイドを読む
このスキルが前提とするルールは、2 つのガイドに記載されています。これらは必須要件であり、参考資料ではありません。このページや、コードベース内の類似ファイル、トレーニングデータをもとに回答せず、ガイドファイル自体をお読みください。
| ガイド | 読むタイミング |
|---|---|
Design Guides、スキル gpui-kit-design-guides | コンポーネント、レイアウト、間隔、階層、色、密度、インタラクション状態、オーバーレイ、モーション、インターフェース文言を選ぶ前 |
| コーディングガイド | クレートのレイヤー構造、RenderOnce と Entity<T> の使い分け、状態の所有者、ElementId、イベント、フォーカス、非同期処理、公開 API、命名、テストを扱う前 |
変更が画面に表示される部分に関わる場合は、まず Design Guides をお読みください。コード構造はプロダクトの意図を保つものであり、その代わりになるものではありません。デザインスキルがインストールされていない場合は、https://gpui-kit.com/docs/design-guides.md を取得してください。コーディングガイドは https://gpui-kit.com/docs/coding-guides.md の完全なコピーです。そのため、ガイド内の ./design-guides.md と ./getting-started.md へのリンクは、それぞれデザインスキルと https://gpui-kit.com/docs/getting-started.md を指します。
コーディングガイドのセクション一覧
新しいクレート、モジュール、機能に取り組む場合は、ガイド全体を読んでください。変更範囲が限定的な場合は、まず「アーキテクチャの概要」と「コーディングエージェント向けルール」を読み、次に変更に該当するセクションを読んでください(grep -n '^## ' references/coding-guides.md)。
| セクション | 読むタイミング |
|---|---|
| アーキテクチャの概要 | 常に。クレートのレイヤー構成、所有権の境界を確認するとき |
| ブートストラップとルートの所有権 | main、init、Root、ウィンドウの作成、アプリケーションレベルの状態を扱うとき |
| GPUI のフェーズとコンテキストを理解する | App、Window、Context<T>、レンダリングと更新の区別に関わるものを扱うとき |
| 適切な単位を選ぶ | RenderOnce、Entity<T>、カスタム Element のどれを使うか決めるとき |
| 状態の所有権 | 状態の保存場所、変更する主体、Entity<State> のハンドルを確認するとき |
| 安定した識別子 | ElementId、リスト、繰り返し要素、キー付き状態を扱うとき |
| レンダリングと合成 | render、ビルダーチェーン、when/map、子要素の合成を扱うとき |
| 振る舞いと表示の境界 | gpui-base、gpui-component、アプリケーションコードのどこに実装するか決めるとき |
| テーマとスタイル | cx.theme()、トークン、Styled、サイズ、バリアントを扱うとき |
| イベント、アクション、フォーカス | cx.emit、subscribe、actions!、キーバインド、FocusHandle を扱うとき |
| 非同期処理と副作用 | cx.spawn、background_spawn、Task、I/O、タイマーを扱うとき |
| レイアウト、測定、スクロール | フレックスレイアウト、サイズ指定、overflow、スクロールハンドル、測定を扱うとき |
| リスト、テーブル、大量のデータ | VirtualList、List、DataTable、デリゲート、大規模なコレクションを扱うとき |
| パブリック API の設計 | pub を使うものすべて。ビルダー、非公開フィールド、セッターとリーダーの命名を確認するとき |
| プラットフォームと機能の境界 | macOS/Windows/Linux/wasm の違い、フィーチャーゲートを扱うとき |
| ファイルと命名規則 | 新しいファイル、モジュール、型とメソッドの名前、Kind サフィックス、Context を扱うとき |
| テスト戦略 | 何をテストするか、#[gpui_kit::test]、TestAppContext を扱うとき |
| パフォーマンスルール | レンダリングコスト、アロケーション、再レンダリングのトリガーを確認するとき |
| よくある失敗 | 作業を終える前に確認。存在しない API の創作、レンダリング中の状態変更、インデックス ID など |
| コーディングエージェント向けルール | エージェントがコードを書く場合は常に読むこと |
| 実装チェックリスト | 作業を終える前に確認。作業内容に照らして各項目を確認すること |
必ず守ること
ガイドの代わりではなく、最低限守るべき事項です。
- API を決して創作しないでください。 現在のソースコードを検索して、実際のシグネチャを確認してください。 React、CSS、または古い GPUI の例を類推して書き換えないでください。 もっともらしく見えても実在しないメソッドを使うことが、最もよくある失敗です。
- 依存関係は 1 つだけです。 アプリケーションが依存するのは
gpui-kitのみです。GPUI はuse gpui_kit::*;で使用します。各レイヤーはgpui_kit::component、gpui_kit::base、gpui_kit::assets、gpui_kit::platformです。 - 振る舞いはフレームワーク、表示はアプリケーションが担います。
gpui-baseに色、サイズ指定、 レイアウトを含めないでください。アプリケーションのスタイル設定コードにインタラクションの振る舞いを含めないでください。 - 安定した識別子を使ってください。 繰り返し表示する要素には、リストのインデックスではなく、
ドメインに基づく
ElementIdが必要です。 - 境界を越えて
pubフィールドを公開しないでください。 パブリックなデータ型には、ビルダーと読み取り用メソッドを使ってください。 Contextは省略せずに書いてください。cxは GPUI のものです。それ以外の名前は、保持する内容に基づけてください。
ドキュメント
- タスク/コンポーネントのページを探す:
https://gpui-kit.com/llms.txtを使用し、該当する Markdown ページを読み込みます。 - 完全なリファレンス:広範なリファレンスが実際に必要な場合は、
https://gpui-kit.com/llms-full.txtを利用できます - コンポーネントごとの API:
https://gpui-kit.com/component/{name}.mdを取得します。 例:button.md、input.md、select.md、dialog.md、data-table.md - サイト内の任意のページは、URL の末尾に
.mdを追加することで Markdown として取得できます
クイックリファレンス
セットアップと例:references/usage.md。
use gpui_kit::*;
gpui_kit::application()
.with_assets(gpui_kit::assets::Assets)
.run(|cx| {
gpui_kit::init(cx); // first, before anything else
gpui_kit::open_window(options, cx, |window, cx| {
cx.new(|cx| AppView::new(window, cx))
})
.expect("failed to open window");
});
- ステートレス(
RenderOnce):render内で構築します:Button::new("save").primary().label("Save").on_click(|_, _, _| {}) - ステートフル:ビュー内で
Entity<State>を保持し、renderで参照を渡します:let input = cx.new(|cx| InputState::new(window, cx));の後にInput::new(&self.input) - サイズ:
.xsmall().small().medium()(デフォルト).large() - テーマ:
cx.theme().primary·.background·.foreground·.border·.muted - オーバーレイ:
gpui_kit::component::WindowExtを介してwindow.open_dialog(...)、open_sheet(...)、push_notification(...)
コンポーネントカタログ
インポートパスは gpui_kit::component:: からの相対パスです。そのため、input::{Input, InputState}
は use gpui_kit::component::input::{Input, InputState}; を意味します。完全な API については、
コンポーネントの .md ドキュメントを取得してください。
入力とフォーム
| Component | Import | Notes |
|---|---|---|
Input | input::{Input, InputState} | ステートフル。テキスト、パスワード、マスク、検証 |
Textarea | input::{Textarea, TextareaState} | ステートフル。複数行テキスト |
Editor | input::{Editor, EditorState} | ステートフル。コードエディター、tree-sitter 機能 |
NumberInput | input::{NumberInput, NumberInputEvent} | ステートフル。ステップ付きの数値入力 |
OtpInput | input::OtpInput | ステートフル。ワンタイムパスワード |
SpeechButton | speech::{SpeechButton, SpeechState} | ステートフル。音声入力、speech 機能 |
Select | select::{Select, SelectState} | ステートフル。ドロップダウン式の選択 |
Combobox | combobox::{Combobox, ComboboxState} | ステートフル。検索可能な選択 |
Checkbox | checkbox::Checkbox | ステートレス。on_click は &bool を受け取ります |
Switch | switch::Switch | ステートレス。切り替え |
Radio | radio::{Radio, RadioGroup} | ステートレス。 |
Slider | slider::{Slider, SliderState} | ステートフル。 |
Toggle | button::Toggle | ステートレス。 |
Rating | rating::Rating | ステートレス。 |
Stepper | stepper::Stepper | ステートレス。複数ステップの進捗表示 |
ColorPicker | color_picker::{ColorPicker, ColorPickerState} | ステートフル。 |
DatePicker | date_picker::{DatePicker, DatePickerState} | ステートフル。 |
TimeField | time_field::{TimeField, TimeFieldState} | ステートフル。時刻、24 時間/12 時間形式 |
Calendar | calendar::{Calendar, CalendarState} | ステートフル。インラインの月表示 |
Form | form::{v_form, h_form, field} | フォームフィールド用のレイアウトコンテナー |
表示とフィードバック
| コンポーネント | インポート | 備考 |
|---|---|---|
Button | button::{Button, ButtonGroup} | ステートレス。主要な UI 操作 |
Icon | {Icon, IconName} | ステートレス。Lucide アイコン |
Badge | badge::Badge | ステートレス。 |
Tag | tag::Tag | ステートレス。閉じられるタグ |
Avatar | avatar::Avatar | ステートレス。 |
Label | label::Label | ステートレス。フォームラベル |
Kbd | kbd::Kbd | ステートレス。キーボードキーの表示 |
Alert | alert::Alert | ステートレス。情報/成功/警告/エラー |
Spinner | spinner::Spinner | ステートレス。読み込みインジケーター |
Skeleton | skeleton::Skeleton | ステートレス。読み込み用プレースホルダー |
Shimmer | shimmer::{ShimmerText, ShimmerStyle} | ステートレス。ストリーミングテキストのシマー |
Marker | marker::{Marker, MarkerVariant} | ステートレス。インラインのステータスマーカー |
Progress | progress::{Progress, ProgressCircle} | ステートレス。 |
Tooltip | tooltip::Tooltip | 要素に対する .tooltip() 経由 |
HoverCard | hover_card::{HoverCard, HoverCardState} | ステートフル。 |
Clipboard | clipboard::Clipboard | ステートレス。コピーボタン |
TextView | text::TextView | TextView::markdown(id, text)。HTML にも対応 |
| 画像 | gpui_kit::{img, ImageSource, ObjectFit} | GPUI の img() 要素 |
オーバーレイとポップアップ
| コンポーネント | インポート | 備考 |
|---|---|---|
Dialog | dialog::Dialog + WindowExt | window.open_dialog(...) 経由 |
AlertDialog | WindowExt | window.open_alert_dialog(...) 経由 |
Sheet | sheet::Sheet + WindowExt | サイドパネル。window.open_sheet(...) 経由 |
Notification | notification::Notification + WindowExt | window.push_notification(...) 経由 |
Popover | popover::Popover | フローティングオーバーレイ |
Menu | menu::{PopupMenu, DropdownMenu} | コンテキストメニュー |
DropdownButton | button::DropdownButton | ドロップダウンメニュー付きボタン |
Command | command::{Command, CommandState, CommandGroup} | ステートフル。コマンドパレット |
| フォーカストラップ | FocusTrapElement | コンテナーに対する .focus_trap(id, &handle)。Dialog と Sheet には組み込み済み |
ナビゲーションとレイアウト
| コンポーネント | インポート | 備考 |
|---|---|---|
Tabs / TabBar | tab::{Tab, TabBar} | タブ付きインターフェース |
Sidebar | sidebar::{Sidebar, SidebarMenu, ...} | アプリのナビゲーションパネル |
TitleBar | TitleBar | ウィンドウのタイトルバー |
StatusBar | status_bar::StatusBar | ウィンドウのステータスバー |
Breadcrumb | breadcrumb::Breadcrumb | ナビゲーション用パンくずリスト |
Pagination | pagination::Pagination | ページナビゲーション |
Accordion | accordion::Accordion | 折りたたみ可能なセクション |
Collapsible | collapsible::Collapsible | 単一の折りたたみ可能な項目 |
GroupBox | group_box::GroupBox | ラベル付きコンテナー |
Resizable | resizable::{h_resizable, v_resizable, resizable_panel, ResizableState} | ドラッグ可能な分割ペイン |
ResizeHandle | resizable::{resize_handle, HandleEdge} | 単独のサイズ変更用エッジ |
Scrollbar | scroll::Scrollbar | カスタムスクロールバー |
データ表示
| コンポーネント | インポート | 備考 |
|---|---|---|
DataTable | table::{DataTable, TableState, TableDelegate} | 状態を保持します。多機能なテーブル |
Diff | diff::{Diff, DiffState, DiffFile} | 状態を保持する RenderOnce 要素です。1 つ以上のファイル、マージコンフリクト、ソースファイルの読み取り専用の統合/Git 差分表示で、パッチはアプリケーションが提供します |
Table | table::{Table, ...} | シンプルなテーブル |
VirtualList | {v_virtual_list, h_virtual_list} | 大規模なリスト向けの高性能表示 |
List | list::{List, ListState, ListDelegate} | 状態を保持します。検索可能なリスト |
Tree | tree::{Tree, TreeState, TreeItem, TreeEntry} | 状態を保持します。階層構造 |
DescriptionList | description_list::DescriptionList | キーと値のペア |
Settings | setting::Settings | 設定パネル |
チャットとメッセージング
| コンポーネント | インポート | 備考 |
|---|---|---|
Message | message::{Message, MessageContent, MessageAlignment} | 状態を保持しません。チャットメッセージの行 |
Bubble | bubble::{Bubble, BubbleContent, BubbleVariant} | 状態を保持しません。メッセージバブル |
Attachment | attachment::{Attachment, AttachmentContent, ...} | 状態を保持しません。ファイル/メディアの添付カード |
MessageScroller | message_scroller::{MessageScroller, MessageScrollerState} | 状態を保持します。自動スクロールするメッセージリスト |
チャート
| コンポーネント | インポート | 備考 |
|---|---|---|
Chart | chart::{AreaChart, BarChart, LineChart, PieChart, RadarChart} | 棒グラフ、折れ線グラフ、面グラフ、円グラフ |
Plot | plot::Plot | データには #[derive(IntoPlot)] を使用します |
テスト
UI 統合テストとは、ヘッドレスウィンドウで実際のコンポーネントをレンダリングし、
入力をシミュレートして、状態、フォーカス、レイアウト、オーナーのコールバックを確認することです。テストの実行には
#[gpui_kit::test] を、UI の操作と検査には gpui_kit::test を使用します。
コンポーネントの操作テストを追加するよう求められた場合は、UI 統合テストとして説明してください。
ユニットテスト、GPUI コンテキストテスト、UI 統合テストについては、 テストを参照してください。依存関係のセットアップ、実行可能な完全な UI フロー、 スコープ付きネイティブ操作、フレームと非同期処理の扱い、アクセシビリティとジオメトリに関するアサーションの制限が含まれています。本番環境のビューを使用し、 通常の Rust アサーションでアクションの結果を検証してください。
GPUI リファレンス
タスクで扱う仕組みに対応するファイルを読み込んでください。各ファイルは目次の行から始まります。
| トピック | ファイル | 読み込むタイミング |
|---|---|---|
| アクションとキーバインド | action.md | actions!、bind_keys、on_action、key_context を使う場合 |
| 非同期処理とバックグラウンドタスク | async.md | cx.spawn、background_spawn、Task、非同期 I/O を使う場合 |
| コンテキスト管理 | context.md | App、Window、Context<T>、AsyncApp を使う場合 |
| カスタム要素(低レベル) | element.md | Element トレイト、request_layout、prepaint、paint を使う場合 |
| エンティティの状態 | entity.md | Entity<T>、WeakEntity、状態管理を使う場合 |
| イベントとサブスクリプション | event.md | cx.emit、cx.subscribe、cx.observe を使う場合 |
| フォーカスとキーボード操作 | focus-handle.md | FocusHandle、track_focus、Tab キーによる移動を使う場合 |
| グローバル状態 | global.md | Global トレイト、cx.set_global、アプリ全体の設定を使う場合 |
| レイアウトとスタイル | layout-style.md | div()、h_flex()、v_flex()、フレックスボックス、オーバーフロー、配置を使う場合 |
| ElementId | element-id.md | ElementId、.id()、一意性のルール、状態を持つ要素を使う場合 |
| テスト | test.md | #[gpui_kit::test]、TestAppContext、VisualTestContext を使う場合 |
トピックのファイルだけでは不十分な場合は、詳しい解説を参照してください。
- Element トレイト:element-api.md(完全な API、ヒットボックス、イベント) · element-patterns.md(テキスト、インタラクティブ要素、コンテナ、複合要素) · element-examples.md(完全な例) · element-best-practices.md(パフォーマンス、状態、注意点) · element-advanced.md(カスタムレイアウト、非同期更新、仮想リスト)
- エンティティ:entity-api.md(完全な API、ライフサイクル) · entity-patterns.md(モデルとビュー、エンティティ間連携、オブザーバー) · entity-best-practices.md(メモリ、パフォーマンス) · entity-advanced.md(コレクション、レジストリ、デバウンス、状態機械)
- テスト:test-examples.md(構成、セットアップ、アサーション、テストの実行) · test-reference.md(再入可能性、プロパティテスト、モック)