@@ -41,6 +41,16 @@ export class Accordion implements ComponentInterface {
4141 private accordionGroupEl ?: HTMLIonAccordionGroupElement | null ;
4242 private updateListener = ( ev : CustomEvent < AccordionGroupChangeEventDetail > ) => {
4343 const initialUpdate = ev . detail ?. initial ?? false ;
44+ console . log ( '[Accordion]' , this . value , 'updateListener - initial:' , initialUpdate , 'hasInteracted:' , this . hasInteracted , 'hasEverBeenExpanded:' , this . hasEverBeenExpanded ) ;
45+ /**
46+ * If this is not an initial update (meaning it's from a user interaction
47+ * or programmatic call after load), mark that we've had an interaction.
48+ * This enables animations for this and future updates.
49+ */
50+ if ( ! initialUpdate ) {
51+ console . log ( '[Accordion]' , this . value , 'Setting hasInteracted to true' ) ;
52+ this . hasInteracted = true ;
53+ }
4454 this . updateState ( initialUpdate ) ;
4555 } ;
4656 private contentEl : HTMLDivElement | undefined ;
@@ -55,12 +65,18 @@ export class Accordion implements ComponentInterface {
5565 @State ( ) isNext = false ;
5666 @State ( ) isPrevious = false ;
5767 /**
58- * Tracks whether the component has completed its initial render.
59- * Animations are disabled until after the first render completes.
60- * This prevents the accordion from animating when it starts
61- * expanded or collapsed on initial load.
68+ * Tracks whether a user-initiated interaction has occurred.
69+ * Animations are disabled until the first interaction happens.
70+ * This prevents the accordion from animating when it's programmatically
71+ * set to an expanded or collapsed state on initial load.
72+ */
73+ @State ( ) hasInteracted = false ;
74+
75+ /**
76+ * Tracks if this accordion has ever been expanded.
77+ * Used to prevent the first expansion from animating.
6278 */
63- @ State ( ) hasRendered = false ;
79+ private hasEverBeenExpanded = false ;
6480
6581 /**
6682 * The value of the accordion. Defaults to an autogenerated
@@ -130,17 +146,6 @@ export class Accordion implements ComponentInterface {
130146 } ) ;
131147 }
132148
133- componentDidRender ( ) {
134- /**
135- * After the first render completes, mark that we've rendered.
136- * Setting this state property triggers a re-render, at which point
137- * animations will be enabled. This ensures animations are disabled
138- * only for the initial render, avoiding unwanted animations on load.
139- */
140- if ( ! this . hasRendered ) {
141- this . hasRendered = true ;
142- }
143- }
144149
145150 private setItemDefaults = ( ) => {
146151 const ionItem = this . getSlottedHeaderIonItem ( ) ;
@@ -236,21 +241,37 @@ export class Accordion implements ComponentInterface {
236241 } ;
237242
238243 private expandAccordion = ( initialUpdate = false ) => {
244+ console . log ( '[Accordion]' , this . value , 'expandAccordion - initialUpdate:' , initialUpdate , 'state:' , this . state ) ;
239245 const { contentEl, contentElWrapper } = this ;
240246 if ( initialUpdate || contentEl === undefined || contentElWrapper === undefined ) {
241247 this . state = AccordionState . Expanded ;
248+ /**
249+ * Mark that this accordion has been expanded at least once.
250+ * Do this even on initial expansion so future interactions animate.
251+ */
252+ this . hasEverBeenExpanded = true ;
253+ console . log ( '[Accordion]' , this . value , 'expandAccordion early return - hasEverBeenExpanded set to true' ) ;
242254 return ;
243255 }
244256
245257 if ( this . state === AccordionState . Expanded ) {
258+ console . log ( '[Accordion]' , this . value , 'expandAccordion - already expanded, returning' ) ;
246259 return ;
247260 }
248261
249262 if ( this . currentRaf !== undefined ) {
250263 cancelAnimationFrame ( this . currentRaf ) ;
251264 }
252265
266+ /**
267+ * Mark that this accordion has been expanded at least once.
268+ * This allows subsequent expansions to animate.
269+ */
270+ this . hasEverBeenExpanded = true ;
271+ console . log ( '[Accordion]' , this . value , 'expandAccordion - hasEverBeenExpanded set to true' ) ;
272+
253273 if ( this . shouldAnimate ( ) ) {
274+ console . log ( '[Accordion]' , this . value , 'expandAccordion - will animate' ) ;
254275 raf ( ( ) => {
255276 this . state = AccordionState . Expanding ;
256277
@@ -315,11 +336,16 @@ export class Accordion implements ComponentInterface {
315336 */
316337 private shouldAnimate = ( ) => {
317338 /**
318- * Don't animate until after the first render cycle completes .
339+ * Don't animate until after the first user interaction .
319340 * This prevents animations on initial load when accordions
320- * start in an expanded or collapsed state.
341+ * start in an expanded or collapsed state programmatically.
342+ *
343+ * Additionally, don't animate the very first expansion even if
344+ * hasInteracted is true. This handles edge cases like React StrictMode
345+ * where effects run twice and might incorrectly mark as interacted.
321346 */
322- if ( ! this . hasRendered ) {
347+ if ( ! this . hasInteracted || ! this . hasEverBeenExpanded ) {
348+ console . log ( '[Accordion]' , this . value , 'shouldAnimate: false - hasInteracted:' , this . hasInteracted , 'hasEverBeenExpanded:' , this . hasEverBeenExpanded ) ;
323349 return false ;
324350 }
325351
@@ -418,6 +444,12 @@ export class Accordion implements ComponentInterface {
418444
419445 if ( disabled || readonly ) return ;
420446
447+ /**
448+ * Mark that the user has interacted with the accordion.
449+ * This enables animations for all future state changes.
450+ */
451+ this . hasInteracted = true ;
452+
421453 if ( accordionGroupEl ) {
422454 /**
423455 * Because the accordion group may or may
@@ -438,6 +470,9 @@ export class Accordion implements ComponentInterface {
438470 const expanded = this . state === AccordionState . Expanded || this . state === AccordionState . Expanding ;
439471 const headerPart = expanded ? 'header expanded' : 'header' ;
440472 const contentPart = expanded ? 'content expanded' : 'content' ;
473+ const shouldAnimate = this . shouldAnimate ( ) ;
474+
475+ console . log ( '[Accordion]' , this . value , 'render - state:' , this . state , 'shouldAnimate:' , shouldAnimate , 'hasInteracted:' , this . hasInteracted , 'hasEverBeenExpanded:' , this . hasEverBeenExpanded ) ;
441476
442477 this . setAria ( expanded ) ;
443478
@@ -456,7 +491,7 @@ export class Accordion implements ComponentInterface {
456491 'accordion-disabled' : disabled ,
457492 'accordion-readonly' : readonly ,
458493
459- 'accordion-animated' : this . shouldAnimate ( ) ,
494+ 'accordion-animated' : shouldAnimate ,
460495 } }
461496 >
462497 < div
0 commit comments