Discourse 3.1.0.beta6 は、まったく新しいコンポーネントベースの <DModal> API を搭載しています。DModal は UI キット の一部であり、discourse/ui-kit/d-modal からインポートされます。
これは旧来のコントローラーベースの API を置き換えます。旧 API は現在非推奨です。旧 API を使用して既存のモーダルがある場合は、こちらのマイグレーションガイドを確認してください。
モーダルのレンダリング
モーダルは、handlebars テンプレートに <DModal> コンポーネントを含めることでレンダリングされます。適切なテンプレートを持っていない場合は、Using Plugin Outlet Connectors from a Theme or Plugin を確認してください。
シンプルなモーダルは次のようになります。
<DButton
@translatedLabel="Show Modal"
@action={{fn (mut this.modalIsVisible) true}}
/>
{{#if this.modalIsVisible}}
<DModal @title="My Modal" @closeModal={{fn (mut this.modalIsVisible) false}}>
Hello world, this is some content in a modal
</DModal>
{{/if}}
ここでは
mutヘルパー が、hbs のみで値を設定する方法として使用されています。modalIsVisibleは他の標準的な Ember メソッドでも設定できます。
この例は、次のようなシンプルなモーダルを作成します。
コンポーネントでのラップ
さらに複雑さを加える前に、新しいモーダルを独自のコンポーネント定義にラップするのが通常は最善です。<DModal> の部分を新しい <MyModal /> コンポーネント内に移動しましょう。
// components/my-modal.gjs
<template>
<DModal @title="My Modal" @closeModal={{@closeModal}}>
Hello world, this is some content in a modal
</DModal>
</template>
この .gjs ファイルをクラスベースのコンポーネントにアップグレードすることで、より複雑なロジックや状態を導入できます。
新しいコンポーネントを利用するには、呼び出し箇所を参照するように更新し、@closeModal 引数を渡すことを忘れないでください。
<DButton
@translatedLabel="Show Modal"
@action={{fn (mut this.modalIsVisible) true}}
/>
{{#if this.modalIsVisible}}
<MyModal @closeModal={{fn (mut this.modalIsVisible) false}} />
{{/if}}
フッターの追加
多くのモーダルには、何らかのコールトゥアクション(CTA)があります。Discourse では、これらは通常モーダルの下部に配置されます。これを可能にするため、DModal には、その中にコンテンツをレンダリングできる複数の「名前付きブロック」があります。ここでは、フッターに 2 つのボタン(そのうちの 1 つは標準の DModalCancel ボタン)を含むように例を更新しました。
<DModal @title="My Modal" @closeModal={{@closeModal}}>
<:body>
Hello world, this is some content in a modal
</:body>
<:footer>
<DButton class="btn-primary" @translatedLabel="Submit" />
<DModalCancel @close={{@closeModal}} />
</:footer>
</DModal>
非 hbs コンテキストからのモーダルレンダリング
理想적으로는、上記で示した宣言的なテクニックを使用して、Ember テンプレート内で <DModal> インスタンスをレンダリングすべきです。それが使用ケースに合わない場合は、modal サービスを注入して modal.show() を呼び出すことで実行できます。
上記で説明したように、モーダルを独自のコンポーネントにラップしていることを確認してください。その後、コンポーネントクラスの参照を showModal に渡してモーダルをトリガーします。
import MyModal from "discourse/components/my-modal";
// (関連する場所に modal サービスを注入)
// モーダルを開きたいときにこの呼び出しを追加します。
// `@closeModal` 引数は自動的にコンポーネントに渡されます。
this.modal.show(MyModal);
// 任意で '`model`' パラメータを渡します。`@model` としてコンポーネントに渡されます。
// これはデータや、モーダルが使用するアクション/コールバックを含むことができます。
this.modal.show(MyModal, {
model: { topic: this.topic, someAction: this.someAction },
});
// `modal.show()` はプロミスを返すため、クローズを待つことができます。
// `@closeModal` アクションに渡されたデータで解決されます。
const result = await this.modal.show(MyModal);
さらにカスタマイズ可能に!
<DModal> には、複数の名前付きブロックと引数があります。
引数
| 引数 | 目的 |
|---|---|
@closeModal |
閉じる UI が表示されるために必須です。 |
@title |
<h1 id="discourse-modal-title"> をレンダリングし、aria-labelledby を接続します。 |
@subtitle |
タイトルの下の小さなテキスト。 |
@flash / @flashType |
モーダルの上部のインラインアラート(DFlashMessage)。 |
@hideHeader, @hideFooter |
領域全体を非表示にします。 |
@headerClass, @bodyClass |
ヘッダー/ボディーのラッパーに追加するクラス。 |
@dismissable |
@closeModal が設定されている場合、デフォルトで true です。Esc / バックドロップクリック / X を無効にします。 |
@autofocus |
デフォルトで true です。dTrapTab を介して最初のフォーカス可能な要素に自動フォーカスします。 |
@submitOnEnter |
デフォルトで true です。フォーカスがフォーム / テキストエリア / select-kit にない限り、Enter キーで .d-modal__footer .btn-primary をクリックします。 |
@beforeClose |
async ({ initiatedBy }) => boolean。クローズをキャンセルするには false を返します(例:未保存フォームの確認)。 |
@hidden |
キーボード処理を一時停止します。ネストされたモーダルが上部にある場合に使用されます。 |
@tagName |
"div"(デフォルト)または "form"。ネイティブの送信が動作するようにフォームには "form" を使用します。 |
ブロック
| ブロック | 位置 | 使用場面 |
|---|---|---|
default / :body |
メインコンテンツエリア | デフォルトの領域 |
:aboveHeader |
最上部、ヘッダーの前 | まれに必要;タイトルバーの上(例:バナー)に配置しなければならないコンテンツ用。 |
:headerAboveTitle |
ヘッダー内、タイトル前 | 存在するが未使用。まれに必要。 |
:belowModalTitle |
.d-modal__title 内、<h1> の後 |
補足的なメタ情報のための優れた位置。 |
:headerBelowTitle |
ヘッダー内、タイトルブロック後 | ヘッダーの一部であるタブ、サブナビ、または検索入力。 |
:headerPrimaryAction |
ヘッダーの右側(モバイルのみ) | X クローズボタンをプライマリアクション(例:“保存”)に置き換えます。また、左側に"キャンセル"ボタンを自動レンダリングし、ヘッダーに .--has-primary-action を追加します。 |
:belowHeader |
ヘッダーとボディーの間 | スクロール可能なボディーの外側にある永続的なサブヘッダーコンテンツ(例:検索)で、スティッキー表示のために使用。 |
:aboveFooter |
ボディーとフッターの間 | @hideFooter が設定されている場合に抑制されます。フッターに関連するが外側のコンテンツに使用。またまれです。 |
:footer |
下部アクションバー | プライマリ + セカンダリボタン。ここでの最初の .btn-primary は Enter キーでトリガーされるものです。 |
:belowFooter |
フッターの後 | まれに必要;@hideFooter を無視します。境界付きフッター領域の外側のステータステキストに有用。 |
ソース:引数についてはインタラクティブスタイルガイド、名前付きブロックについては d-modal テンプレート実装 を参照してください。
CSS
.d-modal クラスをアンカーとして使用してコアをオーバーライドし、レガシーの .modal セレクタを避けてください。
利用可能な 4 つの修飾子:
- .
--largeは 最大幅 を 800px に設定します(デスクトップのみ) - .
--maxは 最大幅 を 90vw に設定します(デスクトップのみ) - .
has-searchは 固定高さ(80vh)を設定します:検索/フィルタシステムを持つモーダルで、結果の長さに基づく高さの変化を避けるために意図されています(デスクトップのみ) .--stackedはフッターのボタンをスタッキングに設定します(モバイルのみ)
このドキュメントはバージョン管理されています - 変更を github で提案してください。

