mcpField
S
stimulus

stimulus

github.com/smnandre開発18292 回インストール20 週間前に更新
リポジトリ

stimulus について

Stimulus の利用方法を扱うスキルです。data 属性で既存の HTML に動作を追加するフレームワークで、HTML を基準に、コントローラーの接続、型付き値、アクション、outlet、遅延読み込みを説明します。

主な機能

  1. 01data 属性によるコントローラー接続
  2. 02イベントとコントローラーアクションの紐付け
  3. 03型付き値とターゲットの利用
  4. 04outlet によるコントローラー間連携
  5. 05コントローラー依存関係の遅延読み込み
  6. 06Symfony と Twig との統合

活用シーン

  1. 01サーバー描画 HTML への動作追加
  2. 02ボタン、フォーム、入力イベントの処理
  3. 03関連するコントローラーインスタンスの連携
  4. 04要素が表示されたときの重い依存関係の読み込み

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/smnandre/symfony-ux-skills --skill stimulus

インストール後、Claude Code で/stimulusを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
api.md
gotchas.md
patterns.md

詳細

Stimulus

JavaScript オブジェクトをデータ属性を介して HTML に接続する、軽量な JavaScript フレームワークです。Stimulus は HTML をレンダリングするのではなく、サーバーでレンダリングされた HTML に動作を追加します。

基本的な考え方は、HTML が信頼できる唯一の情報源であり、JavaScript コントローラーが要素に接続され、データ属性がその配線を担うというものです。AssetMapper を使えば、ビルド手順は必要ありません。

クイックリファレンス

data-controller="name"              attach controller to element
data-name-target="item"             mark element as a target
data-action="event->name#method"    bind event to controller method
data-name-key-value="..."           pass typed data to controller
data-name-key-class="..."           configure CSS class names
data-name-other-outlet=".selector"  reference another controller instance

コントローラーのひな形

// assets/controllers/example_controller.js
import { Controller } from '@hotwired/stimulus';

export default class extends Controller {
    static targets = ['input', 'output'];
    static values = { url: String, delay: { type: Number, default: 300 } };
    static classes = ['loading'];
    static outlets = ['other'];

    connect() {
        // Called when controller connects to DOM
    }

    disconnect() {
        // Called when controller disconnects -- clean up here
    }

    submit(event) {
        // Action method
    }
}

ファイルの命名規則:hello_controller.js は data-controller="hello" に対応します。サブディレクトリでは区切り文字として -- を使います:components/modal_controller.js は data-controller="components--modal" に対応します。

HTML の接続例

基本的なコントローラー
<div data-controller="hello">
    <input data-hello-target="name" type="text">
    <button data-action="click->hello#greet">Greet</button>
    <span data-hello-target="output"></span>
</div>
サーバーからの値(Twig)

値属性を介してサーバーのデータをコントローラーに渡します。値は型付けされ、自動的に解析されます。

<div data-controller="map"
     data-map-latitude-value="{{ place.lat }}"
     data-map-longitude-value="{{ place.lng }}"
     data-map-zoom-value="12">
</div>

使用できる型:String、Number、Boolean、Array、Object。値が変更されると、{name}ValueChanged() コールバックが呼び出されます。

アクション

形式は event->controller#method です。要素の種類ごとにデフォルトのイベント(ボタンは click、入力欄は input、フォームは submit)があるため、イベントは省略できます。

{# Explicit event #}
<button data-action="click->hello#greet">Greet</button>

{# Default event (click for button) #}
<button data-action="hello#greet">Greet</button>

{# Multiple actions on same element #}
<input type="text"
       data-action="focus->field#highlight blur->field#normalize input->field#validate">

{# Prevent default #}
<form data-action="submit->form#validate:prevent">

{# Keyboard shortcuts #}
<div data-action="keydown.esc@window->modal#close">
<input data-action="keydown.enter->modal#submit keydown.ctrl+s->modal#save">

{# Global events (window/document) #}
<div data-action="resize@window->sidebar#adjust click@document->sidebar#closeOutside">
CSS クラス

CSS クラス名を外部化して、コントローラーを汎用的なものに保ちます。

<button data-controller="button"
        data-button-loading-class="opacity-50 cursor-wait"
        data-button-active-class="bg-blue-600"
        data-action="click->button#submit">
    Submit
</button>
// In controller
this.element.classList.add(...this.loadingClasses);
複数のコントローラー

要素には複数のコントローラーを設定できます。

<div data-controller="dropdown tooltip"
     data-action="mouseenter->tooltip#show mouseleave->tooltip#hide">
    <button data-action="click->dropdown#toggle">Menu</button>
    <ul data-dropdown-target="menu" hidden>...</ul>
</div>
アウトレット(コントローラー間の通信)

CSS セレクターを使って、ほかのコントローラーのインスタンスを参照します。

<div data-controller="player"
     data-player-playlist-outlet="#playlist">
    <button data-action="click->player#playNext">Next</button>
</div>

<ul id="playlist" data-controller="playlist">
    <li data-playlist-target="track">Song 1</li>
    <li data-playlist-target="track">Song 2</li>
</ul>
// In player controller
static outlets = ['playlist'];

playNext() {
    const tracks = this.playlistOutlet.trackTargets;
    // ...
}
遅延読み込み(重い依存関係)

要素がビューポートに表示されたときにのみ、コントローラーの JS を読み込みます。チャートライブラリ、エディター、マップなど、重い依存関係を持つコントローラーに使用します。

/* stimulusFetch: 'lazy' */
import { Controller } from '@hotwired/stimulus';
import Chart from 'chart.js';

export default class extends Controller {
    connect() {
        // Chart.js is only loaded when this element enters the viewport
    }
}

/* stimulusFetch: 'lazy' */ コメントは、ファイルの先頭行に記述する必要があります。

Symfony / Twig との統合

生のデータ属性を使う方法を推奨します。どこでも使えて読みやすく、特別なヘルパーも必要ありません。

{# Raw attributes (preferred) #}
<div data-controller="search"
     data-search-url-value="{{ path('api_search') }}">

複雑なケースや、属性をプログラムで生成する場合には Twig ヘルパーを利用できます。

{# Twig helper #}
<div {{ stimulus_controller('search', { url: path('api_search') }) }}>

{# Chaining multiple controllers #}
<div {{ stimulus_controller('a')|stimulus_controller('b') }}>

{# Target and action helpers #}
<input {{ stimulus_target('search', 'query') }}>
<button {{ stimulus_action('search', 'submit') }}>

主な原則

HTML が主導し、JS が応答します。 コントローラーはマークアップを作成するのではなく、既存の HTML に動作を追加します。コントローラー内で DOM を生成している場合は、TwigComponent または LiveComponent のほうが適していないか検討してください。

1 つのコントローラーにつき、1 つの役割にします。 ドロップダウンコントローラーはドロップダウンを、ツールチップコントローラーはツールチップを扱います。巨大なコントローラーを作るのではなく、同じ要素に複数のコントローラーを組み合わせてください。

disconnect() でクリーンアップします。 connect() でイベントリスナー、タイマー、サードパーティーライブラリのインスタンスを追加する場合は、disconnect() で必ず削除してください。ページが切り替わると、Turbo ナビゲーションによってコントローラーは切断され、再接続されます。

データ属性より値を使います。 コントローラーが読み取る、または監視する必要があるデータには、生の data-* 属性ではなく、Stimulus の値(型付きで、変更コールバックを備えています)を使ってください。

参考資料

  • 完全な API(ライフサイクル、ターゲット、値、アクション、クラス、アウトレット):references/api.md
  • パターン(デバウンス、fetch、モーダル、フォームなど):references/patterns.md
  • 注意点(よくある間違い、デバッグ、Turbo との互換性):references/gotchas.md

関連項目

  • UX Map は、マップコンテナー要素で Stimulus 互換のイベント(ux:map:connect、ux:map:marker:after-create など)をディスパッチします。カスタム Stimulus コントローラーを使って、マップの動作を拡張できます。
  • UX Icons は SVG のみで構成されているため Stimulus との統合は不要ですが、値の変更を介して Stimulus でアイコン名を動的に切り替えることができます。

コメント