Repository: ionic-team/ionic-framework
File: core/src/components/accordion/accordion.tsx (TypeScript)

Code before:
 * with the `header` and `content` parts (i.e. `::part(header expanded)`).
 */
@Component({
  tag: 'ion-accordion',
  styleUrls: {
    ios: 'accordion.ios.scss',
    md: 'accordion.md.scss',
  },
  shadow: {
    delegatesFocus: true,
  },
})
export class Accordion implements ComponentInterface {
  private accordionGroupEl?: HTMLIonAccordionGroupElement | null;
  private updateListener = () => {
    /**
     * Determine if this update will cause an actual state change.
     * We only want to mark as "interacted" if the state is changing.
     */
    const accordionGroup = this.accordionGroupEl;
    if (accordionGroup) {
      const value = accordionGroup.value;
      const accordionValue = this.value;
      const shouldExpand = Array.isArray(value) ? value.includes(accordionValue) : value === accordionValue;
      const isExpanded = this.state === AccordionState.Expanded || this.state === AccordionState.Expanding;
      const stateWillChange = shouldExpand !== isExpanded;

      /**
       * Only mark as interacted if:
       * 1. This is not the first update we've received with a defined value
       * 2. The state is actually changing (prevents redundant updates from enabling animations)
       */
      if (this.hasReceivedFirstUpdate && stateWillChange) {
        this.hasInteracted = true;
      }

      /**
       * Only count this as the first update if the group value is defined.
       * This prevents the initial undefined value from the group's componentDidLoad
       * from being treated as the first real update.
       */
      if (value !== undefined) {
        this.hasReceivedFirstUpdate = true;
      }
    }

    this.updateState();
  };
  private contentEl: HTMLDivElement | undefined;
  private contentElWrapper: HTMLDivElement | undefined;
  private headerEl: HTMLDivElement | undefined;

Review comment (suggestion):
Nit: It might make more sense to clarify which value belongs to the group, since I'd expect `value` to refer to the current component:

```suggestion
      const groupValue = accordionGroup.value;
      const value = this.value;
      const shouldExpand = Array.isArray(groupValue) ? groupValue.includes(value) : groupValue === value;
      const isExpanded = this.state === AccordionState.Expanded || this.state === AccordionState.Expanding;
      const stateWillChange = shouldExpand !== isExpanded;
```

Code after:
 * with the `header` and `content` parts (i.e. `::part(header expanded)`).
 */
@Component({
  tag: 'ion-accordion',
  styleUrls: {
    ios: 'accordion.ios.scss',
    md: 'accordion.md.scss',
  },
  shadow: {
    delegatesFocus: true,
  },
})
export class Accordion implements ComponentInterface {
  private accordionGroupEl?: HTMLIonAccordionGroupElement | null;
  private accordionGroupUpdateHandler = () => {
    /**
     * Determine if this update will cause an actual state change.
     * We only want to mark as "interacted" if the state is changing.
     */
    const accordionGroup = this.accordionGroupEl;
    if (accordionGroup) {
      const value = accordionGroup.value;
      const accordionValue = this.value;
      const shouldExpand = Array.isArray(value) ? value.includes(accordionValue) : value === accordionValue;
      const isExpanded = this.state === AccordionState.Expanded || this.state === AccordionState.Expanding;
      const stateWillChange = shouldExpand !== isExpanded;

      /**
       * Only mark as interacted if:
       * 1. This is not the first update we've received with a defined value
       * 2. The state is actually changing (prevents redundant updates from enabling animations)
       */
      if (this.hasReceivedFirstUpdate && stateWillChange) {
        this.hasInteracted = true;
      }

      /**
       * Only count this as the first update if the group value is defined.
       * This prevents the initial undefined value from the group's componentDidLoad
       * from being treated as the first real update.
       */
      if (value !== undefined) {
        this.hasReceivedFirstUpdate = true;
      }
    }

    this.updateState();
  };
  private contentEl: HTMLDivElement | undefined;
  private contentElWrapper: HTMLDivElement | undefined;
  private headerEl: HTMLDivElement | undefined;