<commit_before>import React from 'react';
import { OverlayEventDetail } from '@ionic/core';
import { attachEventProps, ensureElementInBody, dashToPascalCase, generateUniqueId } from './utils'
import { OverlayComponentElement, OverlayControllerComponentElement } from '../types';

export function createControllerComponent<T extends object, E extends OverlayComponentElement, C extends OverlayControllerComponentElement<E>>(tagName: string, controllerTagName: string) {
  const displayName = dashToPascalCase(tagName);
  const dismissEventName = `on${displayName}DidDismiss`;

  type ReactControllerProps = {
    isOpen: boolean;
    onDidDismiss: (event: CustomEvent<OverlayEventDetail>) => void;
  }
  type Props = T & ReactControllerProps;

  return class ReactControllerComponent extends React.Component<Props> {
    element: E;
    controllerElement: C;
    id: string;

    constructor(props: Props) {
      super(props);

      this.id = generateUniqueId();
    }

    static get displayName() {
      return displayName;
    }

    componentDidMount() {
      this.controllerElement = ensureElementInBody<C>(controllerTagName);
    }

    async componentDidUpdate(prevProps: Props) {
      if (prevProps.isOpen !== this.props.isOpen && this.props.isOpen === true) {
        const { isOpen, onDidDismiss, ...cProps} = this.props;
        const elementProps = {
          ...cProps,
          [dismissEventName]: onDidDismiss
        };

        if (this.controllerElement.componentOnReady) {
          await this.controllerElement.componentOnReady();
        }

        this.element = await this.controllerElement.create(elementProps);
        attachEventProps(this.element, elementProps, prevProps);

        await this.element.present();
      }
      if (prevProps.isOpen !== this.props.isOpen && this.props.isOpen === false) {
        await this.element.dismiss();
      }
    }

    render(): null {
      return null;
    }
  }
}
<commit_msg>fix(react): ensure element exists in controller before dismissing it<commit_after>import React from 'react';
import { OverlayEventDetail } from '@ionic/core';
import { attachEventProps, ensureElementInBody, dashToPascalCase, generateUniqueId } from './utils'
import { OverlayComponentElement, OverlayControllerComponentElement } from '../types';

export function createControllerComponent<T extends object, E extends OverlayComponentElement, C extends OverlayControllerComponentElement<E>>(tagName: string, controllerTagName: string) {
  const displayName = dashToPascalCase(tagName);
  const dismissEventName = `on${displayName}DidDismiss`;

  type ReactControllerProps = {
    isOpen: boolean;
    onDidDismiss: (event: CustomEvent<OverlayEventDetail>) => void;
  }
  type Props = T & ReactControllerProps;

  return class ReactControllerComponent extends React.Component<Props> {
    element: E;
    controllerElement: C;
    id: string;

    constructor(props: Props) {
      super(props);

      this.id = generateUniqueId();
    }

    static get displayName() {
      return displayName;
    }

    componentDidMount() {
      this.controllerElement = ensureElementInBody<C>(controllerTagName);
    }

    async componentDidUpdate(prevProps: Props) {
      if (prevProps.isOpen !== this.props.isOpen && this.props.isOpen === true) {
        const { isOpen, onDidDismiss, ...cProps} = this.props;
        const elementProps = {
          ...cProps,
          [dismissEventName]: onDidDismiss
        };

        if (this.controllerElement.componentOnReady) {
          await this.controllerElement.componentOnReady();
        }

        this.element = await this.controllerElement.create(elementProps);
        attachEventProps(this.element, elementProps, prevProps);

        await this.element.present();
      }
      if (this.element && prevProps.isOpen !== this.props.isOpen && this.props.isOpen === false) {
        await this.element.dismiss();
      }
    }

    render(): null {
      return null;
    }
  }
}

{'fraction_non_alphanumeric': 0.10806735360643378, 'fraction_numerical': 0.0, 'mean_word_length': 3.412416851441242, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6607951', 'n_tokens_mistral': 1109, 'n_tokens_neox': 1083, 'n_words': 243}