Home > Software engineering >  Is there a way to make an ion-modal-sheet to snap the header in Ionic V6
Is there a way to make an ion-modal-sheet to snap the header in Ionic V6

Time:08-08

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 ?

uber eats modal sheet exemple

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.

  • Related