iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Modals

A modal is a full-screen overlay used for focused tasks. Ionic ships ion-modal with iOS-native presentation gestures (swipe-down to dismiss) and Android-native animation.

Imperative + declarative + sheets

EXAMPLE
import { modalController } from '@ionic/core';
import { useState } from 'react';
import { IonModal, IonHeader, IonToolbar, IonTitle,
         IonContent, IonButton, IonButtons, IonItem, IonInput } from '@ionic/react';

// === 1) DECLARATIVE — React/Vue/Angular component pattern ===
function EditProfile({ open, onDismiss, user }) {
    const [name, setName] = useState(user.name);

    return (
        <IonModal
            isOpen={open}
            onDidDismiss={(ev) => onDismiss(ev.detail.data, ev.detail.role)}
            breakpoints={[0, 0.5, 0.9]}    // bottom-sheet positions
            initialBreakpoint={0.5}
        >
            <IonHeader>
                <IonToolbar>
                    <IonTitle>Edit profile</IonTitle>
                    <IonButtons slot="end">
                        <IonButton onClick={() => onDismiss(null, 'cancel')}>Cancel</IonButton>
                        <IonButton onClick={() => onDismiss({ name }, 'save')} strong>Save</IonButton>
                    </IonButtons>
                </IonToolbar>
            </IonHeader>
            <IonContent className="ion-padding">
                <IonItem>
                    <IonInput value={name} onIonInput={(e) => setName(e.detail.value)} label="Name" />
                </IonItem>
            </IonContent>
        </IonModal>
    );
}

// === 2) IMPERATIVE — modalController, returns a result ===
async function showEditModal(user) {
    const modal = await modalController.create({
        component: 'edit-profile-modal',
        componentProps: { user },
        backdropDismiss: false,        // require explicit close
        cssClass: 'large-modal',
    });

    await modal.present();
    const { data, role } = await modal.onWillDismiss();

    if (role === 'save') {
        await api.updateProfile(data);
    }
}

// === 3) CARD modal — iOS 13+ stacked look ===
<IonModal isOpen={open} presentingElement={page}>
    {/* page = the IonPage ref */}
</IonModal>

// === 4) BOTTOM sheet — like Apple Maps / Spotify's mini-player ===
<IonModal
    isOpen={open}
    breakpoints={[0, 0.25, 0.5, 0.9]}
    initialBreakpoint={0.25}
    backdropBreakpoint={0.5}
    handle={true}
>
    ...
</IonModal>

Why it matters

breakpoints + initialBreakpoint turn a modal into a draggable bottom sheet for free — the same animation Apple and Google ship.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
// Angular
const modal = await this.modalCtrl.create({ component: ProfileModal });
await modal.present();
const { data } = await modal.onWillDismiss();
Try it Yourself »

Discussion

Loading…