|
1 | 1 | import type { ComponentInterface } from '@stencil/core'; |
2 | | -import { Component, Element, Host, Prop, State, Watch, forceUpdate, h } from '@stencil/core'; |
| 2 | +import { Component, Element, Host, Prop, State, Watch, h } from '@stencil/core'; |
3 | 3 | import { addEventListener, getElementRoot, raf, removeEventListener, transitionEndAsync } from '@utils/helpers'; |
4 | 4 | import { chevronDown } from 'ionicons/icons'; |
5 | 5 |
|
@@ -48,20 +48,19 @@ export class Accordion implements ComponentInterface { |
48 | 48 | private headerEl: HTMLDivElement | undefined; |
49 | 49 |
|
50 | 50 | private currentRaf: number | undefined; |
51 | | - /** |
52 | | - * If true, the next animation will be skipped. |
53 | | - * We want to skip the animation when the accordion |
54 | | - * is expanded or collapsed on the initial load. |
55 | | - * This prevents the accordion from animating when |
56 | | - * it starts expanded or collapsed. |
57 | | - */ |
58 | | - private skipNextAnimation = true; |
59 | 51 |
|
60 | 52 | @Element() el?: HTMLElement; |
61 | 53 |
|
62 | 54 | @State() state: AccordionState = AccordionState.Collapsed; |
63 | 55 | @State() isNext = false; |
64 | 56 | @State() isPrevious = false; |
| 57 | + /** |
| 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. |
| 62 | + */ |
| 63 | + @State() hasRendered = false; |
65 | 64 |
|
66 | 65 | /** |
67 | 66 | * The value of the accordion. Defaults to an autogenerated |
@@ -132,14 +131,14 @@ export class Accordion implements ComponentInterface { |
132 | 131 | } |
133 | 132 |
|
134 | 133 | componentDidRender() { |
135 | | - if (this.skipNextAnimation) { |
136 | | - this.skipNextAnimation = false; |
137 | | - /** |
138 | | - * The initial render disables animations so framework-provided |
139 | | - * values do not cause the accordion to animate. Force a repaint |
140 | | - * so subsequent user interactions animate as expected. |
141 | | - */ |
142 | | - forceUpdate(this); |
| 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; |
143 | 142 | } |
144 | 143 | } |
145 | 144 |
|
@@ -315,7 +314,12 @@ export class Accordion implements ComponentInterface { |
315 | 314 | * of what is set in the config. |
316 | 315 | */ |
317 | 316 | private shouldAnimate = () => { |
318 | | - if (this.skipNextAnimation) { |
| 317 | + /** |
| 318 | + * Don't animate until after the first render cycle completes. |
| 319 | + * This prevents animations on initial load when accordions |
| 320 | + * start in an expanded or collapsed state. |
| 321 | + */ |
| 322 | + if (!this.hasRendered) { |
319 | 323 | return false; |
320 | 324 | } |
321 | 325 |
|
@@ -351,11 +355,6 @@ export class Accordion implements ComponentInterface { |
351 | 355 | const value = accordionGroup.value; |
352 | 356 |
|
353 | 357 | const shouldExpand = Array.isArray(value) ? value.includes(accordionValue) : value === accordionValue; |
354 | | - const shouldDisableAnimation = initialUpdate && shouldExpand; |
355 | | - |
356 | | - if (shouldDisableAnimation) { |
357 | | - this.skipNextAnimation = true; |
358 | | - } |
359 | 358 |
|
360 | 359 | if (shouldExpand) { |
361 | 360 | this.expandAccordion(initialUpdate); |
|
0 commit comments