Skip to content

Commit 761d06f

Browse files
committed
fix(accordion-group): fixing animation in react
1 parent 58c2a8a commit 761d06f

File tree

2 files changed

+51
-4
lines changed

2 files changed

+51
-4
lines changed

core/src/components/accordion-group/accordion-group.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ export class AccordionGroup implements ComponentInterface {
7373
*/
7474
@Event() ionValueChange!: EventEmitter<AccordionGroupChangeEventDetail>;
7575

76+
private hasEmittedInitialValue = false;
77+
7678
@Watch('value')
7779
valueChanged() {
7880
this.emitValueChange(false);
@@ -163,7 +165,9 @@ export class AccordionGroup implements ComponentInterface {
163165
* We work around this by manually emitting a value change when the component
164166
* has loaded and the watcher is configured.
165167
*/
166-
this.emitValueChange(true);
168+
if (!this.hasEmittedInitialValue) {
169+
this.emitValueChange(true);
170+
}
167171
}
168172

169173
/**
@@ -273,10 +277,16 @@ export class AccordionGroup implements ComponentInterface {
273277
}
274278

275279
/**
276-
* Do not use `value` here as that will not account
277-
* for the adjustment we make above.
280+
* Track if this is the initial value update so accordions
281+
* can skip transition animations when they first render.
278282
*/
279-
this.ionValueChange.emit({ value: this.value, initial });
283+
const shouldMarkInitial = initial || (!this.hasEmittedInitialValue && value !== undefined);
284+
285+
this.ionValueChange.emit({ value, initial: shouldMarkInitial });
286+
287+
if (value !== undefined) {
288+
this.hasEmittedInitialValue = true;
289+
}
280290
}
281291

282292
render() {

core/src/components/accordion/test/accordion.spec.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,43 @@ it('should not animate when initial value is set before load', async () => {
236236
expect(firstAccordion.classList.contains('accordion-expanding')).toEqual(false);
237237
});
238238

239+
it('should not animate when initial value is set after load', async () => {
240+
const page = await newSpecPage({
241+
components: [Item, Accordion, AccordionGroup],
242+
});
243+
244+
const accordionGroup = page.doc.createElement('ion-accordion-group');
245+
accordionGroup.innerHTML = `
246+
<ion-accordion value="first">
247+
<ion-item slot="header">Label</ion-item>
248+
<div slot="content">Content</div>
249+
</ion-accordion>
250+
<ion-accordion value="second">
251+
<ion-item slot="header">Label</ion-item>
252+
<div slot="content">Content</div>
253+
</ion-accordion>
254+
`;
255+
256+
const details: AccordionGroupChangeEventDetail[] = [];
257+
accordionGroup.addEventListener('ionValueChange', (event: CustomEvent<AccordionGroupChangeEventDetail>) => {
258+
details.push(event.detail);
259+
});
260+
261+
page.body.appendChild(accordionGroup);
262+
await page.waitForChanges();
263+
264+
accordionGroup.value = 'first';
265+
await page.waitForChanges();
266+
267+
const firstDetail = details.find((detail) => detail.value === 'first');
268+
expect(firstDetail?.initial).toBe(true);
269+
270+
const firstAccordion = accordionGroup.querySelector('ion-accordion[value="first"]')!;
271+
272+
expect(firstAccordion.classList.contains('accordion-expanded')).toEqual(true);
273+
expect(firstAccordion.classList.contains('accordion-expanding')).toEqual(false);
274+
});
275+
239276
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/27047
240277
it('should not have animated class when animated="false"', async () => {
241278
const page = await newSpecPage({

0 commit comments

Comments
 (0)