シートモーダル
Sheet ModalはPicker/Calendarのオーバーレイに似た特別なオーバーレイ・タイプです。このようなモーダルでは、カスタムコンテンツを含むカスタムオーバーレイを作成することができます。
シートレイアウト
シートのレイアウトはとてもシンプルです。
<body>
...
<!-- シートモーダルコンテナ -->
<div class="sheet-modal">
<!-- シートモーダルのツールバー(オプション -->
<div class="toolbar">
<div class="toolbar-inner">
<div class="left"></div>
<div class="right">
<a href="#" class="link sheet-close">Done</a>
</div>
</div>
</div>
<!-- シートモーダルインナー -->
<div class="sheet-modal-inner">
<!-- シートモーダルコンテンツ -->
<div class="block">
<p>Integer mollis nulla id nibh elementum finibus...</p>
</div>
</div>
</div>
</body>
シートのトップレイアウト
デフォルトでは、シートモーダルは画面の下側から開きます。しかし、画面の上部から開くことも可能です。この場合、sheet 要素に sheet-modal-top
クラスを追加する必要があります。また、この場合はボトムツールバーを使用することをお勧めします。
<!-- 上から開くための「sheet-modal-top」クラスの追加 -->
<div class="sheet-modal sheet-modal-top">
<!-- トップシート用のボトムツールバー -->
<div class="toolbar toolbar-bottom">
<div class="toolbar-inner">
<div class="left"></div>
<div class="right">
<a href="#" class="link sheet-close">Done</a>
</div>
</div>
</div>
<!-- シートモーダルインナー -->
<div class="sheet-modal-inner">
<!-- シートモーダルコンテンツ -->
<div class="block">
<p>Integer mollis nulla id nibh elementum finibus...</p>
</div>
</div>
</div>
シートアプリのメソッド
Sheetに関連するアプリのメソッドを見てみましょう。
app.sheet.create(parameters)- Sheetのインスタンスを作成する
- parameters - object. シートのパラメータを持つオブジェクト
作成されたSheetのインスタンスを返すメソッド
app.sheet.destroy(el)- Sheetのインスタンスの破棄
- el - HTMLElementまたはstring(CSSセレクタ付き)またはobject。破壊するSheet要素またはSheetインスタンスを指定します。
app.sheet.get(el)- HTML要素によるSheetインスタンスの取得
- el - HTMLElement または string (CSSセレクタを使用)。Sheetの要素を指定します。
メソッドは、Sheetのインスタンスを返します。
app.sheet.open(el, animate)- シートを開く
- el - HTMLElement または string (CSSセレクタ付き)。開くSheetの要素です。
- animate - booleanを指定します。アニメーションでシートを開きます。
Sheetのインスタンスを返します。
app.sheet.close(el, animate)- シートを閉じる
- el - HTMLElementまたはstring (CSSセレクタ付き)を指定します。閉じるSheet要素。
- animate - boolean。アニメーションでSheetを閉じます。
メソッドはSheetのインスタンスを返します。
app.sheet.stepOpen(el)- Sheetのスワイプステップの開閉
- el - HTMLElementまたはstring(CSSセレクタ付き)。スワイプステップを開くためのSheet要素です。
メソッドはSheetのインスタンスを返します。
app.sheet.stepClose(el)- スワイプステップを閉じる/折りたたむ
- el - HTMLElementまたはstring(CSSセレクタ付き)。スワイプステップを閉じるためのSheet要素。
メソッドはSheetのインスタンスを返します。
app.sheet.stepToggle(el)- Sheetのスワイプステップをトグル(開閉)する
- el - HTMLElementまたはstring(CSSセレクタを使用)。スワイプステップを切り替えるためのSheet要素。
Sheetのインスタンスを返します。
Sheetのパラメータ
ここでは、Sheetを作成するために必要なパラメータの一覧を見てみましょう。
Parameter | Type | Default | Description |
---|---|---|---|
el | HTMLElement | Sheet要素。既にHTML内にSheet要素があり、この要素を使って新しいインスタンスを作成したい場合に便利です。 | |
content | string | Full Sheet HTML layout string. Sheet要素を動的に作成したい場合に便利です。 | |
backdrop | boolean | Sheet Backdrop (背後の暗い半透明のレイヤー)を有効にします。デフォルトでは、MD と Aurora テーマでは true 、iOS テーマでは false です。 | |
backdropEl | HTMLElement string | HTML 要素または文字列 カスタム背景要素の CSS セレクタ | |
scrollToEl | HTMLElement string | HTML要素または文字列(CSSセレクタ付き)の要素です。指定された場合、シートは開いたときにこの要素にページコンテンツをスクロールしようとします。 | |
closeByBackdropClick | boolean | true | 有効な場合は,背景のクリックで閉じられる |
closeByOutsideClick | boolean | false | 有効にすると,背景の外側をクリックしたときに閉じられます |
closeOnEscape | boolean | false | ESCキーを押したときに閉じられるかどうか |
animate | boolean | true | シートの開閉をアニメーションで行うかどうかを指定します。.open()と .close()`メソッドで上書きすることができます。 |
swipeToClose | boolean | false | スワイプジェスチャーでシートを閉じることができるかどうか |
swipeToStep | boolean | false | 有効にすると、開いたシートを、スワイプで操作できるように、部分的に開いた状態と完全に開いた状態の2つに分けることができます。 |
swipeHandler | HTMLElement string | 渡さない場合は、シート全体をスワイプして閉じることができます。ここでは、スワイプターゲットとして使われるカスタム要素のHTML要素または文字列のCSSセレクタを渡すことができます。(swipeToClose または swipeToStep も有効にする必要があります) | |
push | boolean | false | 有効にすると、オープン時にビューを後ろに押します。トップセーフエリアが設定されている場合のみ動作します。また、Sheet要素に sheet-modal-push クラスを追加することでも、この機能を有効にすることができます。 |
on | object | イベントハンドラーを持つオブジェクトです。例えば、以下のようになります。
|
なお、以下のすべてのパラメータは、グローバルアプリのパラメータとして、sheet
プロパティで使用することで、すべてのシートのデフォルト値を設定することができます。例えば、以下のようなものがあります。
var app = new Framework7({
sheet: {
closeByBackdropClick: false,
}
});
自動初期化されたシートモーダルを使用する場合(例:app.sheet.create
で作成しない)、利用可能なすべてのシートパラメータをdata-
属性で渡すことができます。例えば、以下のようになります。
<!-- パラメータをkebab-caseのdata属性で渡す -->
<div class="sheet-modal" data-close-on-escape="true" data-swipe-to-close="true">
...
</div>
シートのメソッドとプロパティ
シートを作成するためには、Sheet.Createを呼び出す必要があります。
var sheet = app.sheet.create({ /* parameters */ })
その後、便利なメソッドとプロパティを持つ初期化されたインスタンス(上記の例では sheet
という変数)が作成されます。
Properties | |
---|---|
sheet.app | グローバルアプリのインスタンスへのリンク |
sheet.el | Sheet HTML要素 |
sheet.$el | シートのHTML要素を持つDom7インスタンス |
sheet.backdropEl | 背景のHTML要素 |
sheet.$backdropEl | 背景のHTML要素を持つDom7のインスタンス |
sheet.params | シートパラメータ |
sheet.opened | シートを開くかどうかを示すブール値のプロップ |
Methods | |
sheet.open(animate) | シートを開く。ここでは
|
sheet.close(animate) | シートを閉じる。シートを閉じる
|
sheet.stepOpen() | 開く/シートを広げる スワイプステップ |
sheet.stepClose() | シートを閉じる/折りたたむ スワイプステップ |
sheet.stepToggle() | シートスワイプステップのトグル(開く/閉じる) |
sheet.setSwipeStep() | ステップの位置を更新します。シートモダールが開かれたときに、手動で内容が変更された後に呼び出す必要があります。 |
sheet.destroy() | シートの破棄 |
sheet.on(event, handler) | イベントハンドラの追加 |
sheet.once(event, handler) | 発射後に削除されるイベントハンドラの追加 |
sheet.off(event, handler) | イベントハンドラの削除 |
sheet.off(event) | 指定されたイベントのハンドラをすべて削除する |
sheet.emit(event, ...args) | インスタンスでイベントを発生させる |
リンクによるシートの制御
リンクの特別なクラスとデータ属性を使って、(DOMにシートがある場合)必要なシートを開いたり閉じたりすることができます。
シートを開くには、"sheet-open"クラスを任意のHTML要素に追加する必要があります(リンクが望ましい)。
シートを閉じるには、任意の HTML 要素に "sheet-close" クラスを追加する必要があります (リンクが好ましい)。
もしDOM内に複数のシートがある場合は、このHTML要素にdata-sheet=".my-sheet"属性を追加して、適切なシートを指定する必要があります。
上記のメモによると
<!-- data-sheet属性では、開くべきシートのCSSセレクタを指定しています。 -->
<p><a href="#" data-sheet=".my-sheet" class="sheet-open">Open Sheet</a></p>
<!-- また、DOMのどこかに -->
<div class="sheet-modal my-sheet">
<div class="sheet-modal-inner">
<!-- シートを閉じるためのリンク -->
<a class="link sheet-close">Close</a>
</div>
</div>
スワイプステップ
swipeToStep`パラメータを渡すと、シートは部分的に開かれ、スワイプすることでさらに拡大することができます。この機能を実現するためには、シートのHTMLに最初のステップを定義する必要があります。そうすることで、Framework7はシートをどの程度開くべきかを知ることができます。
これを実現するためには、シートの初期コンテンツを
要素で囲み、そのシートモーダルに
height:auto`を設定する必要があります。<div class="sheet-modal" style="height: auto">
<div class="sheet-modal-inner">
<!-- 初期のシートモーダルコンテンツ -->
<div class="sheet-modal-swipe-step">
...
</div>
<!-- スワイプしたときに表示される残りのコンテンツ -->
...
</div>
</div>
上部に配置されたSheetモーダルの場合、このスワイプステップは下部に配置する必要があります。
<div class="sheet-modal sheet-modal-top" style="height: auto">
<div class="sheet-modal-inner">
<!-- 余分なスワイプで開かれるコンテンツの残りの部分 -->
...
<!-- 初期シートモーダルコンテンツ -->
<div class="sheet-modal-swipe-step">
...
</div>
</div>
</div>
シートのイベント
Sheetでは、Sheet要素のDOMイベント、アプリとSheetインスタンスのイベントが発生します。
DOMイベント
Event | Target | Description |
---|---|---|
sheet:open | Sheet Element<div class="sheet"> | シートがオープニングアニメーションを開始すると、イベントが発生します。 |
sheet:opened | Sheet Element<div class="sheet"> | イベントは、Sheet がオープニングアニメーションを完了した後に発生します。 |
sheet:close | Sheet Element<div class="sheet"> | イベントは、Sheet が閉じるアニメーションを開始したときに発生します。 |
sheet:closed | Sheet Element<div class="sheet"> | イベントは、Sheetが閉じたアニメーションを完了した後に発生します。 |
sheet:stepopen | Sheet Element<div class="sheet"> | シートのスワイプステップのオープン/エクスパンションでイベントが発生 |
sheet:stepclose | Sheet Element<div class="sheet"> | イベントはシートのスワイプステップのクローズ/コラプスでトリガされます。 |
sheet:stepprogress | Sheet Element<div class="sheet"> | シートのスワイプステップが開いた状態と閉じた状態の間でイベントが発生します。event.detailとして、ステップオープンのプログレス番号( 0から 1`まで)を受け取ります。 |
sheet:beforedestroy | Sheet Element<div class="sheet"> | イベントは、Sheetインスタンスが破棄される直前に発生します。 |
アプリとシートインスタンスのイベント
Sheet インスタンスは self インスタンスと app インスタンスの両方でイベントを発行します。アプリインスタンスのイベントは、同じ名前でプレフィックスとして popup
が付きます。
Event | Arguments | Target | Description |
---|---|---|---|
open | sheet | sheet | イベントはSheetがオープニングアニメーションを開始したときにトリガーされます。イベントハンドラは引数として、Sheet インスタンスを受け取ります。 |
sheetOpen | sheet | app | |
opened | sheet | sheet | イベントは、Sheet がオープニングアニメーションを完了した後に発生します。As an argument event handler receives sheet instance |
sheetOpened | sheet | app | |
close | sheet | sheet | イベントはSheetが閉じるアニメーションを開始するときに発生します。As an argument event handler receive sheet instance |
sheetClose | sheet | app | |
closed | sheet | sheet | イベントはSheetが閉じるアニメーションを完了した後に実行されます。As an argument event handler receive sheet instance |
sheetClosed | sheet | app | |
beforeDestroy | sheet | sheet | イベントはSheetインスタンスが破壊される直前に発生します。As an argument event handler receive sheet instance |
sheetBeforeDestroy | sheet | app | |
stepOpen | sheet | sheet | シートのスワイプステップ開閉時にイベントが発生する |
sheetStepOpen | sheet | app | |
stepClose | sheet | sheet | イベントはシートスワイプステップのクローズ/コラプスでトリガされます。 |
sheetStepClose | sheet | app | |
stepProgress | sheet,progress | sheet | シートスワイプのステップが開いた状態と閉じた状態の間でイベントが発生します。progressとして、ステップオープンのプログレス番号を受け取ります( 0から 1`まで)。 |
sheetStepProgress | sheet,progress | app |
CSS Variables
Below is the list of related CSS variables (CSS custom properties).
:root {
--f7-sheet-height: 260px;
--f7-sheet-border-color: transparent;
--f7-sheet-transition-duration: 300ms;
--f7-sheet-push-border-radius: 10px;
--f7-sheet-push-offset: var(--f7-safe-area-top);
--f7-sheet-bg-color: #fff;
}
:root .theme-dark,
:root.theme-dark {
--f7-sheet-bg-color: #202020;
}
.ios {
--f7-sheet-border-color: var(--f7-bars-border-color);
}
Examples
<template>
<div class="page">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<!-- In data-sheet attribute we specify CSS selector of sheet we need to open-->
<div class="title">Sheet Modal</div>
<div class="right"><a class="link sheet-open" href="#" data-sheet=".my-sheet">Open Sheet</a></div>
</div>
</div>
<div class="page-content">
<div class="block block-strong">
<!-- In data-sheet attribute we specify CSS selector of sheet we need to open-->
<p><a class="button button-fill sheet-open" href="#" data-sheet=".my-sheet">Open Sheet</a></p>
<!-- Link to close sheet-->
<p><a class="button button-fill sheet-close" href="#" data-sheet=".my-sheet">Close Sheet</a></p>
<p><a class="button button-fill dynamic-sheet" href="#">Create Dynamic Sheet</a></p>
<p><a class="button button-fill sheet-open" href="#" data-sheet=".my-sheet-top">Open Top Sheet</a></p>
<p><a class="button button-fill sheet-open" href="#" data-sheet=".my-sheet-swipe-to-close">Swipe To
Close</a></p>
<p><a class="button button-fill sheet-open" href="#" data-sheet=".my-sheet-swipe-to-step">Swipe To Step</a>
</p>
<p><a class="button button-fill sheet-open" href="#" data-sheet=".my-sheet-push">Sheet Push</a></p>
</div>
</div>
</div>
<div class="sheet-modal my-sheet">
<div class="toolbar">
<div class="toolbar-inner">
<div class="left"></div>
<div class="right"><a class="link sheet-close" href="#">Done</a></div>
</div>
</div>
<div class="sheet-modal-inner">
<div class="block">
<h4>Info</h4>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque ac diam ac quam euismod porta vel a
nunc. Quisque sodales scelerisque est, at porta justo cursus ac.</p>
</div>
</div>
</div>
<div class="sheet-modal sheet-modal-top my-sheet-top">
<div class="toolbar toolbar-bottom">
<div class="toolbar-inner">
<div class="left"></div>
<div class="right"><a class="link sheet-close" href="#">Done</a></div>
</div>
</div>
<div class="sheet-modal-inner">
<div class="block">
<h4>Info</h4>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque ac diam ac quam euismod porta vel a
nunc. Quisque sodales scelerisque est, at porta justo cursus ac.</p>
</div>
</div>
</div>
<div class="sheet-modal my-sheet-swipe-to-close" style="height:auto; --f7-sheet-bg-color: #fff;">
<div class="sheet-modal-inner">
<div class="page-content">
<div class="block-title block-title-large">Hello!</div>
<div class="block">
<p><b>Swipe me down to close</b></p>
<p>Eaque maiores ducimus, impedit unde culpa qui, explicabo accusamus, non vero corporis voluptatibus
similique odit ab. Quaerat quasi consectetur quidem libero? Repudiandae adipisci vel voluptatum, autem
libero minus dignissimos repellat.</p>
</div>
</div>
</div>
</div>
<div class="sheet-modal my-sheet-swipe-to-step" style="height:auto; --f7-sheet-bg-color: #fff;">
<div class="sheet-modal-inner">
<div class="sheet-modal-swipe-step">
<div class="display-flex padding justify-content-space-between align-items-center">
<div style="font-size: 18px"><b>Total:</b></div>
<div style="font-size: 22px"><b>$500</b></div>
</div>
<div class="padding-horizontal padding-bottom">
<a class="button button-large button-fill">Make Payment</a>
<div class="margin-top text-align-center">Swipe up for more details</div>
</div>
</div>
<div class="block-title block-title-medium margin-top">Your order:</div>
<div class="list no-hairlines">
<ul>
<li class="item-content">
<div class="item-inner">
<div class="item-title">Item 1</div>
<div class="item-after text-color-black"><b>$200</b></div>
</div>
</li>
<li class="item-content">
<div class="item-inner">
<div class="item-title">Item 2</div>
<div class="item-after text-color-black"><b>$180</b></div>
</div>
</li>
<li class="item-content">
<div class="item-inner">
<div class="item-title">Delivery</div>
<div class="item-after text-color-black"><b>$120</b></div>
</div>
</li>
</ul>
</div>
</div>
</div>
<div class="sheet-modal sheet-modal-push my-sheet-push">
<div class="toolbar">
<div class="toolbar-inner">
<div class="left"></div>
<div class="right">
<a class="link sheet-close">Close</a>
</div>
</div>
</div>
<div class="sheet-modal-inner">
<div class="page-content">
<div class="block">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quae ducimus dolorum ipsa aliquid accusamus
perferendis laboriosam delectus numquam minima animi, libero illo in tempora harum sequi corporis alias
ex adipisci.</p>
<p>Sunt magni enim saepe quasi aspernatur delectus consectetur fugiat necessitatibus qui sed, similique
quis facere tempora, laudantium quae expedita ea, aperiam dolores. Aut deserunt soluta alias magnam.
Consequatur, nisi, enim.</p>
<p>Eaque maiores ducimus, impedit unde culpa qui, explicabo accusamus, non vero corporis voluptatibus
similique odit ab. Quaerat quasi consectetur quidem libero? Repudiandae adipisci vel voluptatum, autem
libero minus dignissimos repellat.</p>
<p>Iusto, est corrupti! Totam minus voluptas natus esse possimus nobis, delectus veniam expedita sapiente
ut cum reprehenderit aliquid odio amet praesentium vero temporibus obcaecati beatae aspernatur incidunt,
perferendis voluptates doloribus?</p>
<p>Illum id laborum tempore, doloribus culpa labore ex iusto odit. Quibusdam consequuntur totam nam
obcaecati, enim cumque nobis, accusamus, quos voluptates, voluptatibus sapiente repellendus nesciunt
praesentium velit ipsa illo iusto.</p>
</div>
</div>
</div>
</div>
</template>
<script>
export default (props, { $on, $, $f7 }) => {
$on('pageInit', () => {
// DOM events for my-sheet sheet
$('.my-sheet').on('sheet:open', function (e) {
console.log('my-sheet open');
});
$('.my-sheet').on('sheet:opened', function (e) {
console.log('my-sheet opened');
});
// Create dynamic Sheet
var dynamicSheet = app.sheet.create({
content: `
<div class="sheet-modal">
<div class="toolbar">
<div class="toolbar-inner">
<div class="left"></div>
<div class="right">
<a class="link sheet-close">Done</a>
</div>
</div>
</div>
<div class="sheet-modal-inner">
<div class="block">
<p>Sheet created dynamically.</p>
<p><a href="#" class="link sheet-close">Close me</a></p>
</div>
</div>
</div>
`,
// Events
on: {
open: function (sheet) {
console.log('Sheet open');
},
opened: function (sheet) {
console.log('Sheet opened');
},
}
});
// Events also can be assigned on instance later
dynamicSheet.on('close', function (sheet) {
console.log('Sheet close');
});
dynamicSheet.on('closed', function (sheet) {
console.log('Sheet closed');
});
// Open dynamic sheet
$('.dynamic-sheet').on('click', function () {
// Close inline sheet before
app.sheet.close('.my-sheet');
// Open dynamic sheet
dynamicSheet.open();
});
// Create swipe-to-close Sheet
app.sheet.create({
el: '.my-sheet-swipe-to-close',
swipeToClose: true,
backdrop: true,
});
// Create swipe-to-step Sheet
app.sheet.create({
el: '.my-sheet-swipe-to-step',
swipeToClose: true,
swipeToStep: true,
backdrop: true,
});
})
return $render;
}
</script>