Skip to content

Commit 3bd16bc

Browse files
authored
docs(modal): playground example to prevent swipe to dismiss (#2820)
1 parent 95c4f23 commit 3bd16bc

File tree

16 files changed

+556
-2
lines changed

16 files changed

+556
-2
lines changed

docs/api/modal.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ import ControllerExample from '@site/static/usage/v7/modal/controller/index.md';
5151

5252
When entering data into a modal, it is often desirable to have a way of preventing accidental data loss. The `canDismiss` property on `ion-modal` gives developers control over when a modal is allowed to dismiss.
5353

54-
There are two different ways of using the `canDismiss` property.
54+
There are two different ways of using the `canDismiss` property: setting a boolean value or setting a callback function.
5555

5656
:::note
5757
Note: When using a sheet modal, `canDismiss` will not be checked on swipe if there is no `0` breakpoint set. However, it will still be checked when pressing `Esc` or the hardware back button.
@@ -79,6 +79,14 @@ import CanDismissFunctionExample from '@site/static/usage/v7/modal/can-dismiss/f
7979

8080
<CanDismissFunctionExample />
8181

82+
### Prevent swipe to close
83+
84+
Developers may want to prevent users from swiping to close a modal. This can be done by setting a callback function for `canDismiss` and checking if the `role` is not `gesture`.
85+
86+
import CanDismissPreventSwipeToCloseExample from '@site/static/usage/v7/modal/can-dismiss/prevent-swipe-to-close/index.md';
87+
88+
<CanDismissPreventSwipeToCloseExample />
89+
8290
## Types of modals
8391

8492
### Card Modal
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
```html
2+
<div class="ion-page" #page>
3+
<ion-header>
4+
<ion-toolbar>
5+
<ion-title>App</ion-title>
6+
</ion-toolbar>
7+
</ion-header>
8+
<ion-content class="ion-padding">
9+
<ion-button id="open-modal" expand="block">Open</ion-button>
10+
<ion-modal #modal trigger="open-modal" [canDismiss]="canDismiss" [presentingElement]="page">
11+
<ng-template>
12+
<ion-header>
13+
<ion-toolbar>
14+
<ion-title>Modal</ion-title>
15+
<ion-buttons slot="end">
16+
<ion-button (click)="modal.dismiss()">Close</ion-button>
17+
</ion-buttons>
18+
</ion-toolbar>
19+
</ion-header>
20+
<ion-content class="ion-padding">
21+
<p>
22+
To close this modal, please use the "Close" button provided. Note that swiping the modal will not dismiss
23+
it.
24+
</p>
25+
</ion-content>
26+
</ng-template>
27+
</ion-modal>
28+
</ion-content>
29+
</div>
30+
```
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
```ts
2+
import { Component } from '@angular/core';
3+
4+
@Component({
5+
selector: 'app-example',
6+
templateUrl: 'example.component.html',
7+
})
8+
export class ExampleComponent {
9+
async canDismiss(data?: any, role?: string) {
10+
return role !== 'gesture';
11+
}
12+
}
13+
```
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Modal | Can Dismiss</title>
8+
<link rel="stylesheet" href="../../../../common.css" />
9+
<script src="../../../../common.js"></script>
10+
<script type="module" src="https://cdn.jsdelivr.net/npm/@ionic/core@6/dist/ionic/ionic.esm.js"></script>
11+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core@6/css/ionic.bundle.css" />
12+
13+
</head>
14+
15+
<body>
16+
<ion-app>
17+
<div class="ion-page">
18+
<ion-header>
19+
<ion-toolbar>
20+
<ion-title>App</ion-title>
21+
</ion-toolbar>
22+
</ion-header>
23+
<ion-content class="ion-padding">
24+
<ion-button id="open-modal" expand="block">Open</ion-button>
25+
26+
<ion-modal trigger="open-modal">
27+
<ion-header>
28+
<ion-toolbar>
29+
<ion-title>Modal</ion-title>
30+
<ion-buttons slot="end">
31+
<ion-button onclick="dismiss()">Close</ion-button>
32+
</ion-buttons>
33+
</ion-toolbar>
34+
</ion-header>
35+
<ion-content class="ion-padding">
36+
<p>To close this modal, please use the "Close" button provided. Note that swiping the modal will not dismiss
37+
it.</p>
38+
</ion-content>
39+
</ion-modal>
40+
</ion-content>
41+
</div>
42+
</ion-app>
43+
44+
<script>
45+
const modal = document.querySelector('ion-modal');
46+
47+
modal.canDismiss = (data, role) => role !== 'gesture';
48+
modal.presentingElement = document.querySelector('.ion-page');
49+
50+
function dismiss() {
51+
modal.dismiss();
52+
}
53+
54+
</script>
55+
</body>
56+
57+
</html>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import Playground from '@site/src/components/global/Playground';
2+
3+
import javascript from './javascript.md';
4+
import vue from './vue.md';
5+
6+
import react from './react.md';
7+
8+
import angular_example_component_html from './angular/example_component_html.md';
9+
import angular_example_component_ts from './angular/example_component_ts.md';
10+
11+
<Playground
12+
version="6"
13+
code={{
14+
javascript,
15+
react,
16+
vue,
17+
angular: {
18+
files: {
19+
'src/app/example.component.html': angular_example_component_html,
20+
'src/app/example.component.ts': angular_example_component_ts,
21+
},
22+
},
23+
}}
24+
src="usage/v6/modal/can-dismiss/prevent-swipe-to-close/demo.html"
25+
devicePreview
26+
mode="ios"
27+
/>
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
```html
2+
<div class="ion-page">
3+
<ion-header>
4+
<ion-toolbar>
5+
<ion-title>App</ion-title>
6+
</ion-toolbar>
7+
</ion-header>
8+
<ion-content class="ion-padding">
9+
<ion-button id="open-modal" expand="block">Open</ion-button>
10+
11+
<ion-modal trigger="open-modal">
12+
<ion-header>
13+
<ion-toolbar>
14+
<ion-title>Modal</ion-title>
15+
<ion-buttons slot="end">
16+
<ion-button onclick="dismiss()">Close</ion-button>
17+
</ion-buttons>
18+
</ion-toolbar>
19+
</ion-header>
20+
<ion-content class="ion-padding">
21+
<p>
22+
To close this modal, please use the "Close" button provided. Note that swiping the modal will not dismiss it.
23+
</p>
24+
</ion-content>
25+
</ion-modal>
26+
</ion-content>
27+
</div>
28+
29+
<script>
30+
var modal = document.querySelector('ion-modal');
31+
32+
modal.canDismiss = (data, role) => role !== 'gesture';
33+
modal.presentingElement = document.querySelector('.ion-page');
34+
35+
function dismiss() {
36+
modal.dismiss();
37+
}
38+
</script>
39+
```
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
```tsx
2+
import React, { useState, useRef, useEffect } from 'react';
3+
import { IonButtons, IonButton, IonModal, IonHeader, IonContent, IonToolbar, IonTitle, IonPage } from '@ionic/react';
4+
5+
function Example() {
6+
const modal = useRef<HTMLIonModalElement>(null);
7+
const page = useRef(null);
8+
9+
const [presentingElement, setPresentingElement] = useState<HTMLElement | null>(null);
10+
11+
useEffect(() => {
12+
setPresentingElement(page.current);
13+
}, []);
14+
15+
function dismiss() {
16+
modal.current?.dismiss();
17+
}
18+
19+
async function canDismiss(data?: any, role?: string) {
20+
return role !== 'gesture';
21+
}
22+
23+
return (
24+
<IonPage ref={page}>
25+
<IonHeader>
26+
<IonToolbar>
27+
<IonTitle>App</IonTitle>
28+
</IonToolbar>
29+
</IonHeader>
30+
<IonContent className="ion-padding">
31+
<IonButton id="open-modal" expand="block">
32+
Open
33+
</IonButton>
34+
<IonModal ref={modal} trigger="open-modal" canDismiss={canDismiss} presentingElement={presentingElement!}>
35+
<IonHeader>
36+
<IonToolbar>
37+
<IonTitle>Modal</IonTitle>
38+
<IonButtons slot="end">
39+
<IonButton onClick={() => dismiss()}>Close</IonButton>
40+
</IonButtons>
41+
</IonToolbar>
42+
</IonHeader>
43+
<IonContent className="ion-padding">
44+
<p>
45+
To close this modal, please use the "Close" button provided. Note that swiping the modal will not dismiss
46+
it.
47+
</p>
48+
</IonContent>
49+
</IonModal>
50+
</IonContent>
51+
</IonPage>
52+
);
53+
}
54+
55+
export default Example;
56+
```
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
```html
2+
<template>
3+
<ion-page ref="page">
4+
<ion-header>
5+
<ion-toolbar>
6+
<ion-title>App</ion-title>
7+
</ion-toolbar>
8+
</ion-header>
9+
<ion-content class="ion-padding">
10+
<ion-button id="open-modal" expand="block">Open</ion-button>
11+
12+
<ion-modal ref="modal" trigger="open-modal" :can-dismiss="canDismiss" :presenting-element="page?.$el">
13+
<ion-header>
14+
<ion-toolbar>
15+
<ion-title>Modal</ion-title>
16+
<ion-buttons slot="end">
17+
<ion-button @click="dismiss">Close</ion-button>
18+
</ion-buttons>
19+
</ion-toolbar>
20+
</ion-header>
21+
<ion-content class="ion-padding">
22+
<p>
23+
To close this modal, please use the "Close" button provided. Note that swiping the modal will not dismiss
24+
it.
25+
</p>
26+
</ion-content>
27+
</ion-modal>
28+
</ion-content>
29+
</ion-page>
30+
</template>
31+
32+
<script setup lang="ts">
33+
import { IonButtons, IonButton, IonModal, IonHeader, IonContent, IonToolbar, IonTitle, IonPage } from '@ionic/vue';
34+
import { ref } from 'vue';
35+
36+
const page = ref(null);
37+
const modal = ref(null);
38+
39+
function dismiss() {
40+
modal.value.$el.dismiss();
41+
}
42+
43+
async function canDismiss(data?: any, role?: string) {
44+
return role !== 'gesture';
45+
}
46+
</script>
47+
```
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
```html
2+
<div class="ion-page" #page>
3+
<ion-header>
4+
<ion-toolbar>
5+
<ion-title>App</ion-title>
6+
</ion-toolbar>
7+
</ion-header>
8+
<ion-content class="ion-padding">
9+
<ion-button id="open-modal" expand="block">Open</ion-button>
10+
<ion-modal #modal trigger="open-modal" [canDismiss]="canDismiss" [presentingElement]="page">
11+
<ng-template>
12+
<ion-header>
13+
<ion-toolbar>
14+
<ion-title>Modal</ion-title>
15+
<ion-buttons slot="end">
16+
<ion-button (click)="modal.dismiss()">Close</ion-button>
17+
</ion-buttons>
18+
</ion-toolbar>
19+
</ion-header>
20+
<ion-content class="ion-padding">
21+
<p>
22+
To close this modal, please use the "Close" button provided. Note that swiping the modal will not dismiss
23+
it.
24+
</p>
25+
</ion-content>
26+
</ng-template>
27+
</ion-modal>
28+
</ion-content>
29+
</div>
30+
```
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
```ts
2+
import { Component } from '@angular/core';
3+
4+
@Component({
5+
selector: 'app-example',
6+
templateUrl: 'example.component.html',
7+
})
8+
export class ExampleComponent {
9+
async canDismiss(data?: any, role?: string) {
10+
return role !== 'gesture';
11+
}
12+
}
13+
```

0 commit comments

Comments
 (0)