From 761d06f1682ae9f3eebec0523c971898e7e519f4 Mon Sep 17 00:00:00 2001 From: ShaneK Date: Thu, 16 Oct 2025 13:29:58 +0100 Subject: [PATCH] fix(accordion-group): fixing animation in react --- .../accordion-group/accordion-group.tsx | 18 +++++++-- .../accordion/test/accordion.spec.ts | 37 +++++++++++++++++++ 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/core/src/components/accordion-group/accordion-group.tsx b/core/src/components/accordion-group/accordion-group.tsx index 00d40d33fc..7c4e780d06 100644 --- a/core/src/components/accordion-group/accordion-group.tsx +++ b/core/src/components/accordion-group/accordion-group.tsx @@ -73,6 +73,8 @@ export class AccordionGroup implements ComponentInterface { */ @Event() ionValueChange!: EventEmitter; + private hasEmittedInitialValue = false; + @Watch('value') valueChanged() { this.emitValueChange(false); @@ -163,7 +165,9 @@ export class AccordionGroup implements ComponentInterface { * We work around this by manually emitting a value change when the component * has loaded and the watcher is configured. */ - this.emitValueChange(true); + if (!this.hasEmittedInitialValue) { + this.emitValueChange(true); + } } /** @@ -273,10 +277,16 @@ export class AccordionGroup implements ComponentInterface { } /** - * Do not use `value` here as that will not account - * for the adjustment we make above. + * Track if this is the initial value update so accordions + * can skip transition animations when they first render. */ - this.ionValueChange.emit({ value: this.value, initial }); + const shouldMarkInitial = initial || (!this.hasEmittedInitialValue && value !== undefined); + + this.ionValueChange.emit({ value, initial: shouldMarkInitial }); + + if (value !== undefined) { + this.hasEmittedInitialValue = true; + } } render() { diff --git a/core/src/components/accordion/test/accordion.spec.ts b/core/src/components/accordion/test/accordion.spec.ts index e37b62a9bf..a132772e02 100644 --- a/core/src/components/accordion/test/accordion.spec.ts +++ b/core/src/components/accordion/test/accordion.spec.ts @@ -236,6 +236,43 @@ it('should not animate when initial value is set before load', async () => { expect(firstAccordion.classList.contains('accordion-expanding')).toEqual(false); }); +it('should not animate when initial value is set after load', async () => { + const page = await newSpecPage({ + components: [Item, Accordion, AccordionGroup], + }); + + const accordionGroup = page.doc.createElement('ion-accordion-group'); + accordionGroup.innerHTML = ` + + Label +
Content
+
+ + Label +
Content
+
+ `; + + const details: AccordionGroupChangeEventDetail[] = []; + accordionGroup.addEventListener('ionValueChange', (event: CustomEvent) => { + details.push(event.detail); + }); + + page.body.appendChild(accordionGroup); + await page.waitForChanges(); + + accordionGroup.value = 'first'; + await page.waitForChanges(); + + const firstDetail = details.find((detail) => detail.value === 'first'); + expect(firstDetail?.initial).toBe(true); + + const firstAccordion = accordionGroup.querySelector('ion-accordion[value="first"]')!; + + expect(firstAccordion.classList.contains('accordion-expanded')).toEqual(true); + expect(firstAccordion.classList.contains('accordion-expanding')).toEqual(false); +}); + // Verifies fix for https://github.com/ionic-team/ionic-framework/issues/27047 it('should not have animated class when animated="false"', async () => { const page = await newSpecPage({