ionic-team / ionic-framework

A powerful cross-platform UI toolkit for building native-quality iOS, Android, and Progressive Web Apps with HTML, CSS, and JavaScript.
https://ionicframework.com
MIT License
51.08k stars 13.51k forks source link

bug: Accordion doesn't apply IonSlides/Swiper options #24044

Closed jongbonga closed 3 years ago

jongbonga commented 3 years ago

Prerequisites

Ionic Framework Version

Current Behavior

options for IonSlides/Swiper are not being applied when inside an accordion initially closed.

Expected Behavior

Accordion to respect components inside its content visual options. Or expose an onToggle event from accordion to deal with such scenarios

Steps to Reproduce

  <ion-accordion-group>
    <ion-accordion value="blog">
      <ion-item slot="header">
        <ion-label>Blog</ion-label>
      </ion-item>
      <div slot="content">
        <swiper [slidesPerView]="1.5">
          <ng-template swiperSlide *ngFor="let blog of blogs">

          </ng-template>
        </swiper>
      </div>
    </ion-accordion>
  </ion-accordion-group>

Code Reproduction URL

No response

Ionic Info

Ionic:

   Ionic CLI                     : 6.17.1 (/Users/jonathan/.nvm/versions/node/v16.4.2/lib/node_modules/@ionic/cli)
   Ionic Framework               : @ionic/angular 6.0.0-rc.0
   @angular-devkit/build-angular : 12.1.4
   @angular-devkit/schematics    : 12.2.1
   @angular/cli                  : 12.1.4
   @ionic/angular-toolkit        : 4.0.0

Additional Information

No response

ionitron-bot[bot] commented 3 years ago

Thanks for the issue! This issue has been labeled as needs reproduction. This label is added to issues that need a code reproduction.

Please reproduce this issue in an Ionic starter application and provide a way for us to access it (GitHub repo, StackBlitz, etc). Without a reliable code reproduction, it is unlikely we will be able to resolve the issue, leading to it being closed.

If you have already provided a code snippet and are seeing this message, it is likely that the code snippet was not enough for our team to reproduce the issue.

For a guide on how to create a good reproduction, see our Contributing Guide.

jongbonga commented 3 years ago

Please see reproduction https://codesandbox.io/s/summer-wood-679qz?file=/src/app/home/home.page.html https://github.com/jongbonga/accordion

liamdebeasi commented 3 years ago

Thanks! The issue here is that Swiper is getting initialized when it is hidden, so all of its dimensions are going to be 0px.

To work around this, you can call the update method on ion-slides when ionChange fires from ion-accordion-group:

import { IonSlides, AccordionGroupCustomEvent } from '@ionic/angular';

...

@ViewChild('slides', { static: true }) slides: IonSlides;

...

onChange(ev: AccordionGroupCustomEvent) {
  const { value } = ev.detail;
  if (value === 'blog') {
    this.slides.update();
  }
}
<ion-accordion-group (ionChange)="onChange($event)">
  ...
   <ion-slides [options]="slideOpts" #slides>
    ...
  </ion-slides>
</ion-accordion-group>

Can you try the above code and let me know if it resolves the issue?

jongbonga commented 3 years ago

Thanks for the workaround. however it only works if I do set a timeout like setTimeout(() => this.slides.update(), 1000);

liamdebeasi commented 3 years ago

Does using a requestAnimationFrame work instead of the setTimeout? Currently we do not consider this an Ionic bug since the issue is with how Swiper initializes itself, but it would be good to figure out a reliable workaround since this issue can occur even outside of Ionic apps.

jongbonga commented 3 years ago

No, requestAnimationFrame doesn't do the trick, unless I'm not using it properly

  onChange(ev: any) {
    const { value } = ev.detail;

    if (value === 'blog') {
      requestAnimationFrame(() => this.slides.update());
    } 
  }
liamdebeasi commented 3 years ago

Does it work if you do 2 requestAnimationFrame calls?

requestAnimationFrame(() => {
  requestAnimationFrame(() => {
    this.slides.update();
  });
});

What I am trying to do is get the slides to update in the next rendering frame, which is likely when the slider component will have dimensions.

ionitron-bot[bot] commented 3 years ago

Thanks for the issue! This issue is being closed due to the lack of a reply. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.

Thank you for using Ionic!