I'm currently developing an app using Ionic V6 and i'm figured out if it was possible to make an ion-modal-sheet snap the header when it fully swiped like the Uber eats application ?
Thanks in advance for your answers and have a nice day !
CodePudding user response:
For those who wondering how to do it, here's how i managed to get something similar:
first of all i've added an id to my header (my ion-header is wrapped inside a component called header) if your header is always in the same page of where you're creating the modal, use a template reference variable instead of an id:
<header
id="getHeight"
[title]="'Solutions disponibles'"
[displayGoBack]="true"></header>
then i've created a helper to:
- Get the height of the header (can be different between iOS and Android)
- Get the body height
- Use the body height and the header height to return the height my modal should have in px and in %
export const getContentHeight = (): any => {
const header = document.querySelector('#getHeight');
const body = document.querySelector('body');
if (body && header) {
const percent = (100 - (header.clientHeight * 100 / body.clientHeight));
return {
height: body.clientHeight - header.clientHeight,
percent: percent
}
}
}
After that i've created another helper to change the visual aspect of my modal when breakpoint reach 0.9:
export const setModalSheetContentHeight = (modal: HTMLIonModalElement, breakpoint: number, expand: boolean): any => {
if (breakpoint >= 0.9 && !expand) {
modal.classList.add('no-radius');
modal.setCurrentBreakpoint(1);
expand = true;
} else if (breakpoint <= 0.9 && expand) {
modal.classList.remove('no-radius');
expand = false;
}
return expand;
}
The boolean "expand" avoid the helper to always set the modal breakpoint to 1.
Then i've created a method that add some listeners on the modal:
initModalListener(): void {
let expand = false;
// Define if the modal is fully expand
const content = getContentHeight();
// Return an object with content height in px and in %
addEventListener('ionModalWillPresent', () => {
this.modal.setAttribute('style', `--height: ${content.height}px`);
// Set the modal height before it shown to avoid visual bug
});
addEventListener('ionBreakpointDidChange', (e: any) => {
const breakpoint = e.detail.breakpoint;
expand = setModalSheetContentHeight(this.modal, breakpoint, expand);
});
}
And after all of that i call this method inside of the method that create my modal:
private async presentModal(): Promise<void> {
this.modal = await this.modalCtrl.create({
component: YourModalComponent,
breakpoints: [0.3, 0.65, 1],
initialBreakpoint: 0.3,
backdropBreakpoint: 1,
showBackdrop: false,
canDismiss: false,
keyboardClose: true,
id: 'modalSheet',
}
});
this.initModalListener();
await this.modal.present();
}
This is a first shot so i'm sure that there is plenty of thing to adjust but for now, it work pretty well with Ionic 6.