Skip to content

Commit

Permalink
docs(modal): playground example to prevent swipe to dismiss (#2820)
Browse files Browse the repository at this point in the history
  • Loading branch information
sean-perkins authored Mar 24, 2023
1 parent 95c4f23 commit 3bd16bc
Show file tree
Hide file tree
Showing 16 changed files with 556 additions and 2 deletions.
10 changes: 9 additions & 1 deletion docs/api/modal.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import ControllerExample from '@site/static/usage/v7/modal/controller/index.md';

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.

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

:::note
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.
Expand Down Expand Up @@ -79,6 +79,14 @@ import CanDismissFunctionExample from '@site/static/usage/v7/modal/can-dismiss/f

<CanDismissFunctionExample />

### Prevent swipe to close

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`.

import CanDismissPreventSwipeToCloseExample from '@site/static/usage/v7/modal/can-dismiss/prevent-swipe-to-close/index.md';

<CanDismissPreventSwipeToCloseExample />

## Types of modals

### Card Modal
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
```html
<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>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
```ts
import { Component } from '@angular/core';

@Component({
selector: 'app-example',
templateUrl: 'example.component.html',
})
export class ExampleComponent {
async canDismiss(data?: any, role?: string) {
return role !== 'gesture';
}
}
```
57 changes: 57 additions & 0 deletions static/usage/v6/modal/can-dismiss/prevent-swipe-to-close/demo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Modal | Can Dismiss</title>
<link rel="stylesheet" href="../../../../common.css" />
<script src="../../../../common.js"></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/@ionic/core@6/dist/ionic/ionic.esm.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core@6/css/ionic.bundle.css" />

</head>

<body>
<ion-app>
<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 trigger="open-modal">
<ion-header>
<ion-toolbar>
<ion-title>Modal</ion-title>
<ion-buttons slot="end">
<ion-button onclick="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>
</ion-modal>
</ion-content>
</div>
</ion-app>

<script>
const modal = document.querySelector('ion-modal');

modal.canDismiss = (data, role) => role !== 'gesture';
modal.presentingElement = document.querySelector('.ion-page');

function dismiss() {
modal.dismiss();
}

</script>
</body>

</html>
27 changes: 27 additions & 0 deletions static/usage/v6/modal/can-dismiss/prevent-swipe-to-close/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Playground from '@site/src/components/global/Playground';

import javascript from './javascript.md';
import vue from './vue.md';

import react from './react.md';

import angular_example_component_html from './angular/example_component_html.md';
import angular_example_component_ts from './angular/example_component_ts.md';

<Playground
version="6"
code={{
javascript,
react,
vue,
angular: {
files: {
'src/app/example.component.html': angular_example_component_html,
'src/app/example.component.ts': angular_example_component_ts,
},
},
}}
src="usage/v6/modal/can-dismiss/prevent-swipe-to-close/demo.html"
devicePreview
mode="ios"
/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
```html
<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 trigger="open-modal">
<ion-header>
<ion-toolbar>
<ion-title>Modal</ion-title>
<ion-buttons slot="end">
<ion-button onclick="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>
</ion-modal>
</ion-content>
</div>

<script>
var modal = document.querySelector('ion-modal');
modal.canDismiss = (data, role) => role !== 'gesture';
modal.presentingElement = document.querySelector('.ion-page');
function dismiss() {
modal.dismiss();
}
</script>
```
56 changes: 56 additions & 0 deletions static/usage/v6/modal/can-dismiss/prevent-swipe-to-close/react.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
```tsx
import React, { useState, useRef, useEffect } from 'react';
import { IonButtons, IonButton, IonModal, IonHeader, IonContent, IonToolbar, IonTitle, IonPage } from '@ionic/react';

function Example() {
const modal = useRef<HTMLIonModalElement>(null);
const page = useRef(null);

const [presentingElement, setPresentingElement] = useState<HTMLElement | null>(null);

useEffect(() => {
setPresentingElement(page.current);
}, []);

function dismiss() {
modal.current?.dismiss();
}

async function canDismiss(data?: any, role?: string) {
return role !== 'gesture';
}

return (
<IonPage ref={page}>
<IonHeader>
<IonToolbar>
<IonTitle>App</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent className="ion-padding">
<IonButton id="open-modal" expand="block">
Open
</IonButton>
<IonModal ref={modal} trigger="open-modal" canDismiss={canDismiss} presentingElement={presentingElement!}>
<IonHeader>
<IonToolbar>
<IonTitle>Modal</IonTitle>
<IonButtons slot="end">
<IonButton onClick={() => dismiss()}>Close</IonButton>
</IonButtons>
</IonToolbar>
</IonHeader>
<IonContent className="ion-padding">
<p>
To close this modal, please use the "Close" button provided. Note that swiping the modal will not dismiss
it.
</p>
</IonContent>
</IonModal>
</IonContent>
</IonPage>
);
}

export default Example;
```
47 changes: 47 additions & 0 deletions static/usage/v6/modal/can-dismiss/prevent-swipe-to-close/vue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
```html
<template>
<ion-page ref="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 ref="modal" trigger="open-modal" :can-dismiss="canDismiss" :presenting-element="page?.$el">
<ion-header>
<ion-toolbar>
<ion-title>Modal</ion-title>
<ion-buttons slot="end">
<ion-button @click="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>
</ion-modal>
</ion-content>
</ion-page>
</template>

<script setup lang="ts">
import { IonButtons, IonButton, IonModal, IonHeader, IonContent, IonToolbar, IonTitle, IonPage } from '@ionic/vue';
import { ref } from 'vue';
const page = ref(null);
const modal = ref(null);
function dismiss() {
modal.value.$el.dismiss();
}
async function canDismiss(data?: any, role?: string) {
return role !== 'gesture';
}
</script>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
```html
<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>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
```ts
import { Component } from '@angular/core';

@Component({
selector: 'app-example',
templateUrl: 'example.component.html',
})
export class ExampleComponent {
async canDismiss(data?: any, role?: string) {
return role !== 'gesture';
}
}
```
Loading

1 comment on commit 3bd16bc

@vercel
Copy link

@vercel vercel bot commented on 3bd16bc Mar 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

ionic-docs – ./

ionic-docs-ionic1.vercel.app
ionic-docs-gqykycf8t.vercel.app
ionic-docs-git-main-ionic1.vercel.app

Please sign in to comment.