Skip to main content
Version: v7

ion-modal

shadow

Modalは、アプリのコンテンツの上に表示されるダイアログであり、インタラクションを再開する前にはアプリによって消されなければならない。選択できるオプションが多い場合や、リスト内の項目をフィルタする場合、およびその他の多くのユースケースで、Selectコンポーネントとして役立ちます。

インラインモーダル(推奨)

テンプレートに直接コンポーネントを記述することで、 ion-modal を使用することができます。これにより、モーダルを表示するために必要なハンドラの数を減らすことができます。

Angular、React、Vue で ion-modal を使用する場合、渡されたコンポーネントはモーダルが解除されると破棄されます。この機能は JavaScript フレームワークによって提供されるので、JavaScript フレームワークなしで ion-modal を使用しても、渡されたコンポーネントは破棄されません。この機能が必要な場合は、代わりに modalController を使用することをお勧めします。

<ion-header>
<ion-toolbar>
<ion-title>Inline Modal</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-button id="open-modal" expand="block">Open</ion-button>
<p>{{ message }}</p>
<ion-modal trigger="open-modal" (willDismiss)="onWillDismiss($event)">
<ng-template>
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-button (click)="cancel()">Cancel</ion-button>
</ion-buttons>
<ion-title>Welcome</ion-title>
<ion-buttons slot="end">
<ion-button (click)="confirm()" [strong]="true">Confirm</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-item>
<ion-input
label="Enter your name"
labelPlacement="stacked"
type="text"
placeholder="Your name"
[(ngModel)]="name"
></ion-input>
</ion-item>
</ion-content>
</ng-template>
</ion-modal>
</ion-content>

isOpen の使用

ion-modalisOpen プロパティを使用すると、開発者がアプリケーションの状態からモーダルの表示状態を制御することができます。つまり、 isOpentrue に設定するとモーダルが表示され、 isOpenfalse に設定するとモーダルが解除されます。

isOpen は一方向のデータバインディングを使用します。つまり、モーダルが解除されたときに自動的に false にセットされることはありません。開発者は ionModalDidDismiss または didDismiss イベントを監視して、 isOpenfalse に設定する必要があります。この理由は、ion-modal の内部がアプリケーションの状態と密に結合するのを防ぐためである。一方通行のデータバインディングでは、モーダルはリアクティブ変数が提供するboolean値だけを気にすればいいです。双方向のデータバインディングでは、モーダルはboolean値とリアクティブ変数の存在の両方を考慮する必要があります。これは、非決定的な動作につながり、アプリケーションのデバッグを困難にします。

<ion-header>
<ion-toolbar>
<ion-title>Inline Modal</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-button expand="block" (click)="setOpen(true)">Open</ion-button>
<ion-modal [isOpen]="isModalOpen">
<ng-template>
<ion-header>
<ion-toolbar>
<ion-title>Modal</ion-title>
<ion-buttons slot="end">
<ion-button (click)="setOpen(false)">Close</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Magni illum quidem recusandae ducimus quos
reprehenderit. Veniam, molestias quos, dolorum consequuntur nisi deserunt omnis id illo sit cum qui. Eaque,
dicta.
</p>
</ion-content>
</ng-template>
</ion-modal>
</ion-content>

モーダルコントローラ

ModalController を使用すると、開発者はプログラムによって ion-modal を表示させることができます。開発者は、モーダルの表示と非表示を完全に制御することができます。

<ion-header>
<ion-toolbar>
<ion-title>Controller Modal</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-button expand="block" (click)="openModal()">Open</ion-button>
<p>{{ message }}</p>
</ion-content>

モーダルの終了を防止する

モーダルにデータを入力しているとき、誤ってデータが失われないようにする方法があると便利です。 ion-modalcanDismiss プロパティは、モーダルをいつ終了させるかを開発者がコントロールできるようにします。

canDismiss`プロパティの使用方法には、boolean値の設定とコールバック関数の設定の2種類があります。

note

Note: シートモーダルでは、0 ブレークポイントが設定されていない場合、スワイプ時に canDismiss はチェックされません。しかし、Esc やハードウェアのバックボタンを押すと、チェックされます。

boolean値の設定

開発者は canDismiss にboolean値を設定することができます。 canDismisstrue の場合、ユーザーがモーダルを閉じようとすると、モーダルは閉じます。 canDismissfalse の場合、ユーザーがモーダルを閉じようとしても、モーダルは閉じません。

boolean値を設定するのは、モーダルが終了する前に特定のアクションを実行する必要がある場合に使用する必要があります。たとえば、開発者がモーダルを閉じる前に "利用規約" チェックボックスをチェックすることを要求したい場合、最初は canDismissfalse に設定し、チェックボックスがチェックされたら true に更新することが可能です。

<div class="ion-page">
<ion-header>
<ion-toolbar>
<ion-title>App</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-button id="open-modal" expand="block">Open</ion-button>
<ion-modal #modal trigger="open-modal" [canDismiss]="canDismiss" [presentingElement]="presentingElement">
<ng-template>
<ion-header>
<ion-toolbar>
<ion-title>Modal</ion-title>
<ion-buttons slot="end">
<ion-button (click)="modal.dismiss()">Close</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content>
<p class="ion-padding-horizontal">You must accept the terms and conditions to close this modal.</p>
<ion-item>
<ion-checkbox id="terms" (ionChange)="onTermsChanged($event)" [checked]="canDismiss">
<div class="ion-text-wrap">Do you accept the terms and conditions?</div>
</ion-checkbox>
</ion-item>
</ion-content>
</ng-template>
</ion-modal>
</ion-content>
</div>

コールバック関数を設定する

開発者は canDismiss を関数として設定することができます。この関数は、 truefalse のどちらかに解決する Promise を返さなければなりません。もし、約束が true に解決されたら、モーダルは解除されます。もし、プロミスが false に解決された場合、モーダルは解除されません。

コールバック関数を設定するのは、モーダルを終了する前に確認ダイアログを表示するなど、終了条件が複雑な場合に使用する必要があります。ユーザーがこのダイアログで選択したオプションは、モーダルの終了を続行するかどうかの判断に使用されます。

コールバック関数を設定すると、カードまたはシートモーダルの使用時にスワイプジェスチャが中断されることに注意してください。これは、Ionicが、あなたのコールバック関数が何を解決するか事前に知らないためです。

<div class="ion-page">
<ion-header>
<ion-toolbar>
<ion-title>App</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-button id="open-modal" expand="block">Open</ion-button>
<ion-modal #modal trigger="open-modal" [canDismiss]="canDismiss" [presentingElement]="presentingElement">
<ng-template>
<ion-header>
<ion-toolbar>
<ion-title>Modal</ion-title>
<ion-buttons slot="end">
<ion-button (click)="modal.dismiss()">Close</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<p>You will be prompted when closing this modal.</p>
</ion-content>
</ng-template>
</ion-modal>
</ion-content>
</div>

スワイプで閉じないようにする

開発者は、ユーザがスワイプしてカードやシートのモーダルを閉じないようにしたい場合があります。これは canDismiss にコールバック関数を設定し、rolegesture でないかチェックすることで実現できます。

<div class="ion-page" #page>
<ion-header>
<ion-toolbar>
<ion-title>App</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-button id="open-modal" expand="block">Open</ion-button>
<ion-modal #modal trigger="open-modal" [canDismiss]="canDismiss" [presentingElement]="page">
<ng-template>
<ion-header>
<ion-toolbar>
<ion-title>Modal</ion-title>
<ion-buttons slot="end">
<ion-button (click)="modal.dismiss()">Close</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<p>
To close this modal, please use the "Close" button provided. Note that swiping the modal will not dismiss
it.
</p>
</ion-content>
</ng-template>
</ion-modal>
</ion-content>
</div>

子コンポーネントでのdismiss動作の変更

あるシナリオでは、開発者は提示されたモーダルの状態に基づいて canDismiss コールバックの動作をカスタマイズする必要があるかもしれません。このカスタマイズは、たとえば、モーダル内のフォームが無効な場合にモーダルが却下されないようにしたい場合に特に便利です。

このカスタマイズを実現するために、子コンポーネントは、親コンポーネントと通信して canDismiss コールバックを管理する条件を更新するために、関数コールバック、イベントエミッション、その他のリアクティビティメカニズムなどのさまざまなテクニックを使用できます。

以下は、子コンポーネントが親コンポーネントとどのように通信して canDismiss コールバックを変更できるかを示す簡単な例です:

<div class="ion-page">
<ion-header>
<ion-toolbar>
<ion-title>App</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-button id="open-modal" expand="block">Open</ion-button>
<ion-modal
#modal
trigger="open-modal"
[canDismiss]="canDismiss"
[presentingElement]="presentingElement"
(willPresent)="onWillPresent()"
>
<ng-template>
<app-child [modal]="modal" (dismissChange)="onDismissChange($event)"></app-child>
</ng-template>
</ion-modal>
</ion-content>
</div>

モーダルの種類

Card Modal

開発者は、アプリのメインコンテンツの上にカードが積み重なったようにモーダルが表示されるカードモーダルエフェクトを作成できます。カードモーダルを作成するには、開発者は ion-modalpresentingElement プロパティを設定する必要があります。

開発者は、アプリのメインコンテンツの上にカードが積み重なったように表示されるカードモーダル効果を作成することができます。カードモーダルを作成するには、開発者は ion-modalpresentingElement プロパティと swipeToClose プロパティを設定する必要があります。

canDismiss プロパティを使用して、カードモーダルをスワイプして閉じることができるかどうかを制御することができます。

note

The card display style is only available on iOS.

<div class="ion-page">
<ion-header>
<ion-toolbar>
<ion-title>App</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-button id="open-modal" expand="block">Open Card Modal</ion-button>

<ion-modal #modal trigger="open-modal" [presentingElement]="presentingElement">
<ng-template>
<ion-header>
<ion-toolbar>
<ion-title>Modal</ion-title>
<ion-buttons slot="end">
<ion-button (click)="modal.dismiss()">Close</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<ion-item>
<ion-avatar slot="start">
<ion-img src="https://i.pravatar.cc/300?u=b"></ion-img>
</ion-avatar>
<ion-label>
<h2>Connor Smith</h2>
<p>Sales Rep</p>
</ion-label>
</ion-item>
<ion-item>
<ion-avatar slot="start">
<ion-img src="https://i.pravatar.cc/300?u=a"></ion-img>
</ion-avatar>
<ion-label>
<h2>Daniel Smith</h2>
<p>Product Designer</p>
</ion-label>
</ion-item>
<ion-item>
<ion-avatar slot="start">
<ion-img src="https://i.pravatar.cc/300?u=d"></ion-img>
</ion-avatar>
<ion-label>
<h2>Greg Smith</h2>
<p>Director of Operations</p>
</ion-label>
</ion-item>
<ion-item>
<ion-avatar slot="start">
<ion-img src="https://i.pravatar.cc/300?u=e"></ion-img>
</ion-avatar>
<ion-label>
<h2>Zoey Smith</h2>
<p>CEO</p>
</ion-label>
</ion-item>
</ion-list>
</ion-content>
</ng-template>
</ion-modal>
</ion-content>
</div>

シートモーダル

マップアプリのドロワーコンポーネントに似たシートモーダルエフェクトを作成します。シートモーダルを作成するには、ion-modalbreakpointsinitialBreakpoint プロパティを設定する必要があります。

breakpointsプロパティには、スワイプしたときにシートがスナップすることができる各ブレークポイントを示す配列が渡されます。 breakpoints プロパティが [0, 0.5, 1] の場合、シートをスワイプすると、モーダルの 0%、50%、100%を表示することができることを示します。モーダルが0%にスワイプされると、モーダルは自動的にディスクローズされます。 0 ブレークポイントが含まれていない場合、スワイプ時にモーダルを解除することはできませんが、Esc またはハードウェアの戻るボタンを押すことで解除することができることに注意してください。

initialBreakpoint プロパティは、シート モーダルが表示されるときに、どのブレークポイントから開始するかを知るために必要なものです。 initialBreakpoint の値は、 breakpoints 配列にも存在する必要があります。例えば、 breakpoints の値が [0, 0.5, 1] である場合、 initialBreakpoint の値が 0.5 であれば、 breakpoints 配列に 0.5 が存在するため有効であると考えられます。 0.25breakpoints 配列に存在しないので、 initialBreakpoint の値は無効になります。

backdropBreakpoint プロパティは、 ion-backdrop がフェードインし始めるポイントをカスタマイズするために使用することができます。これは、シートの下にインタラクティブなコンテンツがあるようなインタフェースを作成する際に便利です。よくある使用例としては、シートが完全に展開されるまでマップがインタラクティブになるような、マップをオーバーレイするシートモーダルです。

<ion-header>
<ion-toolbar>
<ion-title>App</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-button id="open-modal" expand="block">Open Sheet Modal</ion-button>

<ion-modal #modal trigger="open-modal" [initialBreakpoint]="0.25" [breakpoints]="[0, 0.25, 0.5, 0.75]">
<ng-template>
<ion-content>
<ion-searchbar placeholder="Search" (click)="modal.setCurrentBreakpoint(0.75)"></ion-searchbar>
<ion-list>
<ion-item>
<ion-avatar slot="start">
<ion-img src="https://i.pravatar.cc/300?u=b"></ion-img>
</ion-avatar>
<ion-label>
<h2>Connor Smith</h2>
<p>Sales Rep</p>
</ion-label>
</ion-item>
<ion-item>
<ion-avatar slot="start">
<ion-img src="https://i.pravatar.cc/300?u=a"></ion-img>
</ion-avatar>
<ion-label>
<h2>Daniel Smith</h2>
<p>Product Designer</p>
</ion-label>
</ion-item>
<ion-item>
<ion-avatar slot="start">
<ion-img src="https://i.pravatar.cc/300?u=d"></ion-img>
</ion-avatar>
<ion-label>
<h2>Greg Smith</h2>
<p>Director of Operations</p>
</ion-label>
</ion-item>
<ion-item>
<ion-avatar slot="start">
<ion-img src="https://i.pravatar.cc/300?u=e"></ion-img>
</ion-avatar>
<ion-label>
<h2>Zoey Smith</h2>
<p>CEO</p>
</ion-label>
</ion-item>
</ion-list>
</ion-content>
</ng-template>
</ion-modal>
</ion-content>

背景コンテンツとのインタラクション

<div class="ion-page">
<ion-header>
<ion-toolbar>
<ion-title>App</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<p>You can interact with the +/- buttons until the sheet is fully expanded.</p>

<div class="counter__section">
<ion-button (click)="decrement()">-</ion-button>
<p>{{count }}</p>
<ion-button (click)="increment()">+</ion-button>
</div>

<ion-modal
#modal
trigger="open-modal"
[isOpen]="true"
[initialBreakpoint]="0.25"
[breakpoints]="[0.25, 0.5, 0.75]"
[backdropDismiss]="false"
[backdropBreakpoint]="0.5"
>
<ng-template>
<ion-content class="ion-padding">
<ion-searchbar placeholder="Search" (click)="modal.setCurrentBreakpoint(0.75)"></ion-searchbar>
<ion-list>
<ion-item>
<ion-avatar slot="start">
<ion-img src="https://i.pravatar.cc/300?u=b"></ion-img>
</ion-avatar>
<ion-label>
<h2>Connor Smith</h2>
<p>Sales Rep</p>
</ion-label>
</ion-item>
<ion-item>
<ion-avatar slot="start">
<ion-img src="https://i.pravatar.cc/300?u=a"></ion-img>
</ion-avatar>
<ion-label>
<h2>Daniel Smith</h2>
<p>Product Designer</p>
</ion-label>
</ion-item>
<ion-item>
<ion-avatar slot="start">
<ion-img src="https://i.pravatar.cc/300?u=d"></ion-img>
</ion-avatar>
<ion-label>
<h2>Greg Smith</h2>
<p>Director of Operations</p>
</ion-label>
</ion-item>
<ion-item>
<ion-avatar slot="start">
<ion-img src="https://i.pravatar.cc/300?u=e"></ion-img>
</ion-avatar>
<ion-label>
<h2>Zoey Smith</h2>
<p>CEO</p>
</ion-label>
</ion-item>
</ion-list>
</ion-content>
</ng-template>
</ion-modal>
</ion-content>
</div>

自動の高さのシート

<ion-header>
<ion-toolbar>
<ion-title>App</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-button id="open-modal" expand="block">Open Sheet Modal</ion-button>

<ion-modal trigger="open-modal" [initialBreakpoint]="1" [breakpoints]="[0, 1]">
<ng-template>
<div class="block">Block of Content</div>
</ng-template>
</ion-modal>
</ion-content>

ハンドルの動作

シートモーダルでは、ブレークポイント間でシートをドラッグするために使用されるハンドルインジケータをオプションでレンダリングすることができます。 handleBehavior プロパティは、ハンドルがユーザーによってアクティブにされたときの振る舞いを設定するために使用されます。

<ion-header>
<ion-toolbar>
<ion-title>App</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-button id="open-modal" expand="block">Open Sheet Modal</ion-button>

<ion-modal
trigger="open-modal"
[initialBreakpoint]="0.25"
[breakpoints]="[0, 0.25, 0.5, 0.75]"
handleBehavior="cycle"
>
<ng-template>
<ion-content class="ion-padding">
<div class="ion-margin-top">
<ion-label>Click the handle above to advance to the next breakpoint.</ion-label>
</div>
</ion-content>
</ng-template>
</ion-modal>
</ion-content>

スタイリング

モーダルはアプリケーションのルートで表示されるので、アプリ全体を覆うように表示されます。この動作は、インライン モーダルおよびコントローラから表示されるモーダルの両方に適用されます。その結果、カスタムのモーダルスタイルを特定のコンポーネントにスコープすることはできず、モーダルには適用されません。代わりに、スタイルはグローバルに適用する必要があります。ほとんどの開発者は、カスタムスタイルを global.css に配置すれば十分です。

note

IonicのAngularアプリを構築する場合、スタイルはグローバルなスタイルシートファイルに追加する必要があります。詳しくは、以下のAngularセクションの Style Placement をお読みください。

note

ion-modal は、積み重ねられたモーダルは同じサイズであるという前提で動作します。その結果、後続の各モーダルはボックスシャドウを持たず、背景の不透明度は 0 になります。これは、モーダルが追加されるたびに影や背景が濃くなるのを避けるためです。これは、CSS 変数 --box-shadow--backdrop-opacity を設定することで変更することができます。

ion-modal.stack-modal {
--box-shadow: 0 28px 48px rgba(0, 0, 0, 0.4);
--backdrop-opacity: var(--ion-backdrop-opacity, 0.32);
}
<ion-header>
<ion-toolbar>
<ion-title>App</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-button id="open-modal" expand="block">Open Modal</ion-button>

<ion-modal #modal trigger="open-modal">
<ng-template>
<ion-content>
<ion-toolbar>
<ion-title>Modal</ion-title>
<ion-buttons slot="end">
<ion-button color="light" (click)="modal.dismiss()">Close</ion-button>
</ion-buttons>
</ion-toolbar>
<ion-list>
<ion-item>
<ion-avatar slot="start">
<ion-img src="https://i.pravatar.cc/300?u=b"></ion-img>
</ion-avatar>
<ion-label>
<h2>Connor Smith</h2>
<p>Sales Rep</p>
</ion-label>
</ion-item>
<ion-item>
<ion-avatar slot="start">
<ion-img src="https://i.pravatar.cc/300?u=a"></ion-img>
</ion-avatar>
<ion-label>
<h2>Daniel Smith</h2>
<p>Product Designer</p>
</ion-label>
</ion-item>
<ion-item>
<ion-avatar slot="start">
<ion-img src="https://i.pravatar.cc/300?u=d"></ion-img>
</ion-avatar>
<ion-label>
<h2>Greg Smith</h2>
<p>Director of Operations</p>
</ion-label>
</ion-item>
<ion-item>
<ion-avatar slot="start">
<ion-img src="https://i.pravatar.cc/300?u=e"></ion-img>
</ion-avatar>
<ion-label>
<h2>Zoey Smith</h2>
<p>CEO</p>
</ion-label>
</ion-item>
</ion-list>
</ion-content>
</ng-template>
</ion-modal>
</ion-content>

アニメーション

アニメーションビルダーを使用し、enterAnimationleaveAnimation にアニメーションを割り当てることで、表示時、非表示時のアニメーションをカスタマイズすることができます。

<ion-header>
<ion-toolbar>
<ion-title>App</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-button id="open-modal" expand="block">Open Modal</ion-button>

<ion-modal #modal trigger="open-modal" [enterAnimation]="enterAnimation" [leaveAnimation]="leaveAnimation">
<ng-template>
<ion-header>
<ion-toolbar>
<ion-title>Modal</ion-title>
<ion-buttons slot="end">
<ion-button (click)="modal.dismiss()">Close</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<ion-item>
<ion-avatar slot="start">
<ion-img src="https://i.pravatar.cc/300?u=b"></ion-img>
</ion-avatar>
<ion-label>
<h2>Connor Smith</h2>
<p>Sales Rep</p>
</ion-label>
</ion-item>
<ion-item>
<ion-avatar slot="start">
<ion-img src="https://i.pravatar.cc/300?u=a"></ion-img>
</ion-avatar>
<ion-label>
<h2>Daniel Smith</h2>
<p>Product Designer</p>
</ion-label>
</ion-item>
<ion-item>
<ion-avatar slot="start">
<ion-img src="https://i.pravatar.cc/300?u=d"></ion-img>
</ion-avatar>
<ion-label>
<h2>Greg Smith</h2>
<p>Director of Operations</p>
</ion-label>
</ion-item>
<ion-item>
<ion-avatar slot="start">
<ion-img src="https://i.pravatar.cc/300?u=e"></ion-img>
</ion-avatar>
<ion-label>
<h2>Zoey Smith</h2>
<p>CEO</p>
</ion-label>
</ion-item>
</ion-list>
</ion-content>
</ng-template>
</ion-modal>
</ion-content>

Custom Dialogs

ion-modalは、フルページビュー、カード、シートに使用されることが多いですが、カスタムダイアログに使用することも可能です。これは、ion-alertion-loadingなどのコンポーネントが提供するものより複雑なインターフェースを必要とする開発者に便利です。

<ion-header>
<ion-toolbar>
<ion-title>App</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-button id="open-custom-dialog" expand="block">Open Custom Dialog</ion-button>

<ion-modal id="example-modal" #modal trigger="open-custom-dialog">
<ng-template>
<div class="wrapper">
<h1>Dialog header</h1>

<ion-list lines="none">
<ion-item button="true" detail="false" (click)="modal.dismiss()">
<ion-icon name="person-circle"></ion-icon>
<ion-label>Item 1</ion-label>
</ion-item>
<ion-item button="true" detail="false" (click)="modal.dismiss()">
<ion-icon name="person-circle"></ion-icon>
<ion-label>Item 2</ion-label>
</ion-item>
<ion-item button="true" detail="false" (click)="modal.dismiss()">
<ion-icon name="person-circle"></ion-icon>
<ion-label>Item 3</ion-label>
</ion-item>
</ion-list>
</div>
</ng-template>
</ion-modal>
</ion-content>

カスタムダイアログを作成する際に注意すべき点がいくつかあります。

  • ion-content は、フルページモダル、カード、シートで使用することを意図しています。カスタムダイアログのサイズが動的であったり、不明であったりする場合は、 ion-content を使用するべきではありません。
  • カスタムダイアログを作成することは、デフォルトのモーダルエクスペリエンスから逃れる方法を提供します。そのため、カスタムダイアログは、カードやシートのモーダルでは使用しないでください。

Interfaces

ModalOptions

下記は modalController を使用する際に利用できるすべてのオプションです。これらのオプションは、 modalController.create() を呼び出す際に指定します。

interface ModalOptions {
component: any;
componentProps?: { [key: string]: any };
presentingElement?: HTMLElement;
showBackdrop?: boolean;
backdropDismiss?: boolean;
cssClass?: string | string[];
animated?: boolean;
canDismiss?: boolean | ((data?: any, role?: string) => Promise<boolean>);

mode?: 'ios' | 'md';
keyboardClose?: boolean;
id?: string;
htmlAttributes?: { [key: string]: any };

enterAnimation?: AnimationBuilder;
leaveAnimation?: AnimationBuilder;

breakpoints?: number[];
initialBreakpoint?: number;
backdropBreakpoint?: number;
handle?: boolean;
}

ModalCustomEvent

必須ではありませんが、このコンポーネントから発行される Ionic イベントでより強く型付けを行うために、CustomEvent インターフェースの代わりにこのインターフェースを使用することが可能です。

interface ModalCustomEvent extends CustomEvent {
target: HTMLIonModalElement;
}

アクセシビリティ

Keyboard Navigation

KeyFunction
EscDismisses the modal

ラベル

モーダルには dialog という役割があります。そのため、開発者はモーダルに適切なラベル付けを行う必要があります。モーダルが ion-title を使用している場合、 ion-modalaria-labelledby を設定すると、内部のテキストをモーダル自体のラベルに使用することができます。モーダルに追加の説明テキストが含まれている場合、このテキストは aria-describedby を使ってモーダルと関連付けることができます。

スクリーンリーダー

モーダルには aria-modal 属性が適用されています。この属性は、支援技術によるナビゲーションをモーダル要素のコンテンツに制限させることがあります。その結果、次や前の項目に移動するジェスチャを使用しても、モーダルの外側の要素にフォーカスが当たらない場合があります。これは、backdropBreakpoint プロパティを使用して、シート モーダルでバックドロップを無効にした場合にも当てはまります。

開発者が手動でフォーカスを移動しても、アシストはモーダル要素のコンテンツへのナビゲーションを制限しません。ただし、Ionic では、フォーカスのトラッピングが有効になっているモーダルに対して、モーダルの外側に手動でフォーカスを移動することはサポートされていません。

See https://w3c.github.io/aria/#aria-modal for more information.

フォーカスのトラッピング

モーダルが表示されると、フォーカスは表示されたモーダルの内側に閉じ込められます。ユーザーは、モーダル内の他のインタラクティブ要素にフォーカスを合わせることができますが、モーダルが表示されている間は、モーダルの外側のインタラクティブ要素にフォーカスを合わせることができません。複数のスタック モーダルを表示するアプリケーションでは、最後に表示されたモーダルにフォーカスが移動します。

backdropBreakpoint プロパティによって背景が無効にされたシート モーダルは、フォーカスのトラッピングの対象にはなりません。

シートモーダル

シートモーダルでは、backdropBreakpoint プロパティが使用されているとき、ユーザがモーダルの後ろのコンテンツとインタラクトできるようにします。バックドロップは、指定された backdropBreakpoint までは無効になり、それ以降は有効になります。

バックドロップが無効になると、ユーザーはポインタやキーボードを使用して、シートモーダルの外側の要素を操作することができるようになります。入力支援は、aria-modal の使用により、デフォルトではシートモーダルの外側にフォーカスを当てないかもしれません。オートフォーカスなどの機能は、ユーザーに警告することなく、支援技術が 2つのインタラクティブなコンテキスト間をジャンプする原因となるため、ここでは避けることをお勧めします。

パフォーマンス

インナー コンテンツのマウント

インラインの ion-modal のコンテンツは、閉じられるとアンマウントされます。このコンテンツがレンダリングに時間がかかる場合、開発者は keepContentsMounted プロパティを使用して、モーダルがマウントされると同時にコンテンツをマウントすることができます。これにより、モーダルが開かれたときにインナー コンテンツがすでにマウントされているので、アプリケーションの応答性を最適化することができます。

<ion-header>
<ion-toolbar>
<ion-title>Example</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-button id="open-modal" expand="block">Open Modal</ion-button>
<ion-modal [keepContentsMounted]="true" trigger="open-modal" #modal>
<ng-template>
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-button (click)="modal.dismiss()">Cancel</ion-button>
</ion-buttons>
<ion-title>Modal</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding"> This content was mounted as soon as the modal was created. </ion-content>
</ng-template>
</ion-modal>
</ion-content>

開発者は keepContentsMounted を使用する際に、以下の点に注意する必要があります。

  • この機能は、既存のパフォーマンスの問題に対処するための最後の手段として使用すべきです。この機能を使用する前に、パフォーマンスのボトルネックを特定し、解決するように努めてください。さらに、パフォーマンスの問題を予測するためにこの機能を使用しないでください。

  • この機能は、JavaScriptフレームワークを使用している場合にのみ必要です。フレームワークを使用していない開発者は、レンダリングするコンテンツをモーダルに渡すことができ、コンテンツは自動的にレンダリングされます。

  • この機能はインラインモーダルでのみ動作します。 modalController で作成されたモーダルは先に作成されないので、インナーコンテンツも作成されません。

  • インナー コンポーネントの JavaScript Framework ライフサイクル フックはすべて、モーダルが表示されたときではなく、モーダルがマウントされたときに実行されます。

プロパティ

animated

Descriptiontrueの場合、モーダルはアニメーションを行います。
Attributeanimated
Typeboolean
Defaulttrue

backdropBreakpoint

Descriptionシートモーダル使用時に背景がフェードインし始めるポイントを示す0~1の10進数値です。それ以前は、背景は非表示で、シートの下のコンテンツは操作可能です。この値は排他的で、指定された値の後に背景がアクティブになることを意味します。
Attributebackdrop-breakpoint
Typenumber
Default0

backdropDismiss

Descriptiontrueの場合、バックドロップがクリックされるとモーダルは解除されます。
Attributebackdrop-dismiss
Typeboolean
Defaulttrue

breakpoints

Descriptionシート モーダルを作成するときに使用するブレークポイントです。配列の各値は 0 から 1 の間の 10 進数でなければならず、0 はモーダルが完全に閉じていることを、1 はモーダルが完全に開いていることを示しています。値は、画面の高さではなく、モーダルの高さに対する相対値です。この配列の値の1つは、initialBreakpoint プロパティの値でなければなりません。例えば[0, .25, .5, 1]
Attributeundefined
Typenumber[] | undefined
Defaultundefined

canDismiss

Descriptionモーダルが dismiss メソッドを呼び出したときに、終了できるかどうかを決定します。 値が true または値の関数が true を返す場合、モーダルは終了しようとするときに閉じます。値が false または値の関数が false を返す場合、モーダルは終了しようとしたときに閉じません。
Attributecan-dismiss
Type((data?: any, role?: string | undefined) => Promise<boolean>) | boolean
Defaulttrue

enterAnimation

Descriptionモーダルが表示されたときに使用するアニメーション。
Attributeundefined
Type((baseEl: any, opts?: any) => Animation) | undefined
Defaultundefined

handle

Descriptionシートモーダルの上部に表示される水平線です。 breakpointsinitialBreakpointプロパティを設定すると、デフォルトでtrueになります。
Attributehandle
Typeboolean | undefined
Defaultundefined

handleBehavior

Descriptionハンドルが押されたときのシートモーダルのインタラクション動作です。 デフォルトは "none" で、ハンドルが押されてもモーダルはサイズも位置も変わりません。cycle" に設定すると、押されたときにモーダルが利用可能なブレークポイント間を循環するようになります。 ハンドルの動作は、handleプロパティがfalseに設定されている場合、またはbreakpoints` プロパティが設定されていない場合(フルスクリーンまたはカード モーダルを使用している場合)には、利用できません。
Attributehandle-behavior
Type"cycle" | "none" | undefined
Default'none'

htmlAttributes

Descriptionモーダルに渡す追加属性。
Attributeundefined
Typeundefined | { [key: string]: any; }
Defaultundefined

initialBreakpoint

Descriptionシートモーダル作成時にモーダルが開く初期点を示す 0 から 1 までの 10 進値。この値は breakpoints 配列にも記載されている必要があります。
Attributeinitial-breakpoint
Typenumber | undefined
Defaultundefined

isOpen

Descriptiontrueの場合、モーダルは開かれます。 falseの場合、モーダルは閉じます。それ以外の場合は、modalController または trigger プロパティを使用してください。注意: isOpen は、モーダルが終了しても自動的に false に戻されません。あなたのコードでそれを行う必要があります。
Attributeis-open
Typeboolean
Defaultfalse

keepContentsMounted

Descriptiontrueの場合、モーダルの作成時に ion-modal に渡されたコンポーネントが自動的にマウントされます。このコンポーネントは、モーダルが終了してもマウントされたままです。しかし、モーダルが破棄されると、コンポーネントは破棄されます。このプロパティはリアクティブではないので、モーダルを最初に作成するときにのみ使用する必要があります。 注意:この機能は、Angular、React、Vue などの JavaScript フレームワークのインライン モーダルにのみ適用されます。
Attributekeep-contents-mounted
Typeboolean
Defaultfalse

keyboardClose

Descriptiontrueの場合、オーバーレイが表示されたときにキーボードが自動的に解除されます。
Attributekeyboard-close
Typeboolean
Defaulttrue

leaveAnimation

Descriptionモーダルが解除されたときに使用するアニメーションです。
Attributeundefined
Type((baseEl: any, opts?: any) => Animation) | undefined
Defaultundefined

mode

Descriptionmodeは、どのプラットフォームのスタイルを使用するかを決定します。
Attributemode
Type"ios" | "md"
Defaultundefined

presentingElement

Descriptionモーダルを提示した要素です。カード提示効果や、複数のモーダルを重ねる場合に使用します。iOS modeでのみ適用されます。
Attributeundefined
TypeHTMLElement | undefined
Defaultundefined

showBackdrop

Descriptiontrueの場合、モーダルの後ろに背景が表示されます。このプロパティは、モーダルが表示されたときに背景が画面を暗くするかどうかを制御します。このプロパティは、背景がアクティブであるかどうか、または DOM に存在するかどうかを制御するものではありません。
Attributeshow-backdrop
Typeboolean
Defaulttrue

trigger

Descriptionクリックされたときにモーダルを開かせるトリガー要素に対応するIDです。
Attributetrigger
Typestring | undefined
Defaultundefined

イベント

NameDescription
didDismissモーダルが解散した後に発行されます。ionModalDidDismiss の略記です。
didPresentモーダルが提示された後に発行されます。ionModalDidPresent の略記です。
ionBreakpointDidChangeモーダルブレークポイントが変更された後に発行されます。
ionModalDidDismissモーダルが終了した後に発行されます。
ionModalDidPresentモーダルが提示された後に発行されます。
ionModalWillDismissモーダルが解散する前に発行されます。
ionModalWillPresentモーダルが提示される前に発行されます。
willDismissモーダルが解散する前に発行されます。ionModalWillDismiss の略記です。
willPresentモーダルが提示される前に発行されます。ionModalWillPresent の略記です。

メソッド

dismiss

Descriptionモーダルオーバーレイが表示された後、それを解除します。
Signaturedismiss(data?: any, role?: string) => Promise<boolean>

getCurrentBreakpoint

Descriptionシートスタイルモーダルの現在のブレークポイントを返します。
SignaturegetCurrentBreakpoint() => Promise<number | undefined>

onDidDismiss

Descriptionモーダルが解除されたときに解決するPromiseを返します。
SignatureonDidDismiss<T = any>() => Promise<OverlayEventDetail<T>>

onWillDismiss

Descriptionモーダルがいつ解散するかを解決するPromiseを返します。
SignatureonWillDismiss<T = any>() => Promise<OverlayEventDetail<T>>

present

Descriptionモーダルオーバーレイを作成した後に提示します。
Signaturepresent() => Promise<void>

setCurrentBreakpoint

Descriptionシートスタイルモーダルを特定のブレークポイントに移動します。ブレークポイントの値は、 breakpoints 配列で定義された値でなければなりません。
SignaturesetCurrentBreakpoint(breakpoint: number) => Promise<void>

CSS Shadow Parts

NameDescription
backdropion-backdrop`要素です。
contentデフォルトslotのラッパー要素です。
handlehandle="true"`のときにシートモーダルの上部に表示されるハンドルです。

CSSカスタムプロパティ

NameDescription
--backdrop-opacity背景の不透明度
--backgroundモーダルコンテンツの背景
--border-colorモーダルコンテンツのボーダーカラー
--border-radiusモーダルコンテンツのボーダー半径
--border-styleモーダルコンテンツのボーダースタイル
--border-widthモーダルコンテンツのボーダー幅
--heightモーダルの高さ
--max-heightモーダルの最大の高さ
--max-widthモーダルの最大幅
--min-heightモーダルの最小高さ
--min-widthモーダルの最小幅
--widthモーダルの幅

Slots

NameDescription
``コンテンツは .modal-content 要素の内側に配置されます。