ion-modal
Modalは、アプリのコンテンツの上に表示されるダイアログであり、インタラクションを再開する前にはアプリによって消されなければならない。選択できるオプションが多い場合や、リスト内の項目をフィルタする場合、およびその他の多くのユースケースで、Selectコンポーネントとして役立ちます。
インラインモーダル(推奨)
テンプレートに直接コンポーネントを記述することで、 ion-modal
を使用することができます。これにより、モーダルを表示するために必要なハンドラの数を減らすことができます。
Angular、React、Vue で ion-modal
を使用する場合、渡されたコンポーネントはモーダルが解除されると破棄されます。この機能は JavaScript フレームワークによって提供されるので、JavaScript フレームワークなしで ion-modal
を使用しても、渡されたコンポーネントは破棄されません。この機能が必要な場合は、代わりに modalController
を使用することをお勧めします。
- src/app/example.component.html
- src/app/example.component.ts
<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-modal
の isOpen
プロパティを使用すると、開発者がアプリケーションの状態からモーダルの表示状態を制御することができます。つまり、 isOpen
を true
に設定するとモーダルが表示され、 isOpen
を false
に設定するとモーダルが解除されます。
isOpen
は一方向のデータバインディングを使用します。つまり、モーダルが解除されたときに自動的に false
にセットされることはありません。開発者は ionModalDidDismiss
または didDismiss
イベントを監視して、 isOpen
を false
に設定する必要があります。この理由は、ion-modal
の内部がアプリケーションの状態と密に結合するのを防ぐためである。一方通行のデータバインディングでは、モーダルはリアクティブ変数が提供するboolean値だけを気にすればいいです。双方向のデータバインディングでは、モーダルはboolean値とリアクティブ変数の存在の両方を考慮する必要があります。これは、非決定的な動作につながり、アプリケーションのデバッグを困難にします。
- src/app/example.component.html
- src/app/example.component.ts
<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
を表示させることができます。開発者は、モーダルの表示と非表示を完全に制御することができます。
- src/app/example.component.html
- src/app/example.component.ts
- src/app/modal-example.component.html
- src/app/modal-example.component.ts
- src/app/app.module.ts
<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-modal
の canDismiss
プロパティは、モーダルをいつ終了させるかを開発者がコントロールできるようにします。
canDismiss`プロパティの使用方法には、boolean値の設定とコールバック関数の設定の2種類があります。
note
Note: シートモーダルでは、0
ブレークポイントが設定されていない場合、スワイプ時に canDismiss
はチェックされません。しかし、Esc
やハードウェアのバックボタンを押すと、チェックされます。
boolean値の設定
開発者は canDismiss
にboolean値を設定することができます。 canDismiss
が true
の場合、ユーザーがモーダルを閉じようとすると、モーダルは閉じます。 canDismiss
が false
の場合、ユーザーがモーダルを閉じようとしても、モーダルは閉じません。
boolean値を設定するのは、モーダルが終了する前に特定のアクションを実行する必要がある場合に使用する必要があります。たとえば、開発者がモーダルを閉じる前に "利用規約" チェックボックスをチェックすることを要求したい場合、最初は canDismiss
を false
に設定し、チェックボックスがチェックされたら true
に更新することが可能です。
- src/app/example.component.html
- src/app/example.component.ts
<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
を関数として設定することができます。この関数は、 true
か false
のどちらかに解決する Promise
を返さなければなりません。もし、約束が true
に解決されたら、モーダルは解除されます。もし、プロミスが false
に解決された場合、モーダルは解除されません。
コールバック関数を設定するのは、モーダルを終了する前に確認ダイアログを表示するなど、終了条件が複雑な場合に使用する必要があります。ユーザーがこのダイアログで選択したオプションは、モーダルの終了を続行するかどうかの判断に使用されます。
コールバック関数を設定すると、カードまたはシートモーダルの使用時にスワイプジェスチャが中断されることに注意してください。これは、Ionicが、あなたのコールバック関数が何を解決するか事前に知らないためです。
- src/app/example.component.html
- src/app/example.component.ts
<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
にコールバック関数を設定し、role
が gesture
でないかチェックすることで実現できます。
- src/app/example.component.html
- src/app/example.component.ts
<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
コールバックを変更できるかを示す簡単な例です:
- src/app/example.component.html
- src/app/example.component.ts
- src/app/child.component.html
- src/app/child.component.ts
- src/app/app.module.ts
<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-modal
に presentingElement
プロパティを設定する必要があります。
開発者は、アプリのメインコンテンツの上にカードが積み重なったように表示されるカードモーダル効果を作成することができます。カードモーダルを作成するには、開発者は ion-modal
に presentingElement
プロパティと swipeToClose
プロパティを設定する必要があります。
canDismiss
プロパティを使用して、カードモーダルをスワイプして閉じることができるかどうかを制御することができます。
note
The card display style is only available on iOS.
- src/app/example.component.html
- src/app/example.component.ts
<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-modal
に breakpoints
と initialBreakpoint
プロパティを設定する必要があります。
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.25
は breakpoints
配列に存在しないので、 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>
背景コンテンツとのインタラクション
- src/app/example.component.html
- src/app/example.component.ts
- src/app/example.component.css
<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>
自動の高さのシート
- src/app/example.component.html
- src/app/example.component.css
<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);
}
- src/app/example.component.html
- src/global.css
<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>
アニメーション
アニメーションビルダーを使用し、enterAnimation
と leaveAnimation
にアニメーションを割り当てることで、表示時、非表示時のアニメーションをカスタマイズすることができます。
- src/app/example.component.html
- src/app/example.component.ts
<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-alertやion-loadingなどのコンポーネントが提供するものより複雑なインターフェースを必要とする開発者に便利です。
- src/app/example.component.html
- src/global.css
<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
Key | Function |
---|---|
Esc | Dismisses the modal |
ラベル
モーダルには dialog
という役割があります。そのため、開発者はモーダルに適切なラベル付けを行う必要があります。モーダルが ion-title
を使用している場合、 ion-modal
で aria-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
Description | true の場合、モーダルはアニメーションを行います。 |
Attribute | animated |
Type | boolean |
Default | true |
backdropBreakpoint
Description | シートモーダル使用時に背景がフェードインし始めるポイントを示す0~1の10進数値です。それ以前は、背景は非表示で、シートの下のコンテンツは操作可能です。この値は排他的で、指定された値の後に背景がアクティブになることを意味します。 |
Attribute | backdrop-breakpoint |
Type | number |
Default | 0 |
backdropDismiss
Description | true の場合、バックドロップがクリックされるとモーダルは解除されます。 |
Attribute | backdrop-dismiss |
Type | boolean |
Default | true |
breakpoints
Description | シート モーダルを作成するときに使用するブレークポイントです。配列の各値は 0 から 1 の間の 10 進数でなければならず、0 はモーダルが完全に閉じていることを、1 はモーダルが完全に開いていることを示しています。値は、画面の高さではなく、モーダルの高さに対する相対値です。この配列の値の1つは、initialBreakpoint プロパティの値でなければなりません。例えば[0, .25, .5, 1] |
Attribute | undefined |
Type | number[] | undefined |
Default | undefined |
canDismiss
Description | モーダルが dismiss メソッドを呼び出したときに、終了できるかどうかを決定します。 値が true または値の関数が true を返す場合、モーダルは終了しようとするときに閉じます。値が false または値の関数が false を返す場合、モーダルは終了しようとしたときに閉じません。 |
Attribute | can-dismiss |
Type | ((data?: any, role?: string | undefined) => Promise<boolean>) | boolean |
Default | true |
enterAnimation
Description | モーダルが表示されたときに使用するアニメーション。 |
Attribute | undefined |
Type | ((baseEl: any, opts?: any) => Animation) | undefined |
Default | undefined |
handle
Description | シートモーダルの上部に表示される水平線です。 breakpoints とinitialBreakpoint プロパティを設定すると、デフォルトでtrue になります。 |
Attribute | handle |
Type | boolean | undefined |
Default | undefined |
handleBehavior
Description | ハンドルが押されたときのシートモーダルのインタラクション動作です。 デフォルトは "none" で、ハンドルが押されてもモーダルはサイズも位置も変わりません。cycle" に設定すると、押されたときにモーダルが利用可能なブレークポイント間を循環するようになります。 ハンドルの動作は、 handleプロパティが falseに設定されている場合、または breakpoints` プロパティが設定されていない場合(フルスクリーンまたはカード モーダルを使用している場合)には、利用できません。 |
Attribute | handle-behavior |
Type | "cycle" | "none" | undefined |
Default | 'none' |
htmlAttributes
Description | モーダルに渡す追加属性。 |
Attribute | undefined |
Type | undefined | { [key: string]: any; } |
Default | undefined |
initialBreakpoint
Description | シートモーダル作成時にモーダルが開く初期点を示す 0 から 1 までの 10 進値。この値は breakpoints 配列にも記載されている必要があります。 |
Attribute | initial-breakpoint |
Type | number | undefined |
Default | undefined |
isOpen
Description | true の場合、モーダルは開かれます。 false の場合、モーダルは閉じます。それ以外の場合は、modalController または trigger プロパティを使用してください。注意: isOpen は、モーダルが終了しても自動的に false に戻されません。あなたのコードでそれを行う必要があります。 |
Attribute | is-open |
Type | boolean |
Default | false |
keepContentsMounted
Description | true の場合、モーダルの作成時に ion-modal に渡されたコンポーネントが自動的にマウントされます。このコンポーネントは、モーダルが終了してもマウントされたままです。しかし、モーダルが破棄されると、コンポーネントは破棄されます。このプロパティはリアクティブではないので、モーダルを最初に作成するときにのみ使用する必要があります。 注意:この機能は、Angular、React、Vue などの JavaScript フレームワークのインライン モーダルにのみ適用されます。 |
Attribute | keep-contents-mounted |
Type | boolean |
Default | false |
keyboardClose
Description | true の場合、オーバーレイが表示されたときにキーボードが自動的に解除されます。 |
Attribute | keyboard-close |
Type | boolean |
Default | true |
leaveAnimation
Description | モーダルが解除されたときに使用するアニメーションです。 |
Attribute | undefined |
Type | ((baseEl: any, opts?: any) => Animation) | undefined |
Default | undefined |
mode
Description | modeは、どのプラットフォームのスタイルを使用するかを決定します。 |
Attribute | mode |
Type | "ios" | "md" |
Default | undefined |
presentingElement
Description | モーダルを提示した要素です。カード提示効果や、複数のモーダルを重ねる場合に使用します。iOS modeでのみ適用されます。 |
Attribute | undefined |
Type | HTMLElement | undefined |
Default | undefined |
showBackdrop
Description | true の場合、モーダルの後ろに背景が表示されます。このプロパティは、モーダルが表示されたときに背景が画面を暗くするかどうかを制御します。このプロパティは、背景がアクティブであるかどうか、または DOM に存在するかどうかを制御するものではありません。 |
Attribute | show-backdrop |
Type | boolean |
Default | true |
trigger
Description | クリックされたときにモーダルを開かせるトリガー要素に対応するIDです。 |
Attribute | trigger |
Type | string | undefined |
Default | undefined |
イベント
Name | Description |
---|---|
didDismiss | モーダルが解散した後に発行されます。ionModalDidDismiss の略記です。 |
didPresent | モーダルが提示された後に発行されます。ionModalDidPresent の略記です。 |
ionBreakpointDidChange | モーダルブレークポイントが変更された後に発行されます。 |
ionModalDidDismiss | モーダルが終了した後に発行されます。 |
ionModalDidPresent | モーダルが提示された後に発行されます。 |
ionModalWillDismiss | モーダルが解散する前に発行されます。 |
ionModalWillPresent | モーダルが提示される前に発行されます。 |
willDismiss | モーダルが解散する前に発行されます。ionModalWillDismiss の略記です。 |
willPresent | モーダルが提示される前に発行されます。ionModalWillPresent の略記です。 |
メソッド
dismiss
Description | モーダルオーバーレイが表示された後、それを解除します。 |
Signature | dismiss(data?: any, role?: string) => Promise<boolean> |
getCurrentBreakpoint
Description | シートスタイルモーダルの現在のブレークポイントを返します。 |
Signature | getCurrentBreakpoint() => Promise<number | undefined> |
onDidDismiss
Description | モーダルが解除されたときに解決するPromiseを返します。 |
Signature | onDidDismiss<T = any>() => Promise<OverlayEventDetail<T>> |
onWillDismiss
Description | モーダルがいつ解散するかを解決するPromiseを返します。 |
Signature | onWillDismiss<T = any>() => Promise<OverlayEventDetail<T>> |
present
Description | モーダルオーバーレイを作成した後に提示します。 |
Signature | present() => Promise<void> |
setCurrentBreakpoint
Description | シートスタイルモーダルを特定のブレークポイントに移動します。ブレークポイントの値は、 breakpoints 配列で定義された値でなければなりません。 |
Signature | setCurrentBreakpoint(breakpoint: number) => Promise<void> |
CSS Shadow Parts
Name | Description |
---|---|
backdrop | ion-backdrop`要素です。 |
content | デフォルトslotのラッパー要素です。 |
handle | handle="true"`のときにシートモーダルの上部に表示されるハンドルです。 |
CSSカスタムプロパティ
Name | Description |
---|---|
--backdrop-opacity | 背景の不透明度 |
--background | モーダルコンテンツの背景 |
--border-color | モーダルコンテンツのボーダーカラー |
--border-radius | モーダルコンテンツのボーダー半径 |
--border-style | モーダルコンテンツのボーダースタイル |
--border-width | モーダルコンテンツのボーダー幅 |
--height | モーダルの高さ |
--max-height | モーダルの最大の高さ |
--max-width | モーダルの最大幅 |
--min-height | モーダルの最小高さ |
--min-width | モーダルの最小幅 |
--width | モーダルの幅 |
Slots
Name | Description |
---|---|
`` | コンテンツは .modal-content 要素の内側に配置されます。 |