<commit_before><template>

  <div>
    <div
      v-if="!disabled"
      class="focus-trap-first"
      tabindex="0"
      @focus="handleFirstTrapFocus"
    ></div>

    <slot></slot>

    <div
      v-if="!disabled"
      class="focus-trap-last"
      tabindex="0"
      @focus="handleLastTrapFocus"
    ></div>
  </div>

</template>


<script>

  /**
   * This component ensures that focus moves between the first element
   * and the last element of content provided by the default slot.
   * In disabled state, it only renders whatever has been passed
   * to the default slot, and doesn't add any focus trap behavior,
   * allowing for flexible use from parent components.
   */
  export default {
    name: 'FocusTrap',
    props: {
      firstEl: {
        type: HTMLElement,
        required: false,
        default: null,
      },
      lastEl: {
        type: HTMLElement,
        required: false,
        default: null,
      },
      disabled: {
        type: Boolean,
        required: false,
        default: false,
      },
    },
    data() {
      return {
        isTrapActive: false,
      };
    },
    methods: {
      handleFirstTrapFocus(e) {
        e.stopPropagation();
        if (!this.isTrapActive) {
          // On first focus, redirect to first option, then activate trap
          this.firstEl.focus();
          this.isTrapActive = true;
        } else {
          this.lastEl.focus();
        }
      },
      handleLastTrapFocus(e) {
        e.stopPropagation();
        this.firstEl.focus();
      },
      /**
       * @public
       * Reset the next focus to the first focus element
       */
      reset() {<commit_msg>Add ability to emit events to FocusTrap<commit_after><template>

  <div>
    <div
      v-if="!disabled"
      class="focus-trap-first"
      tabindex="0"
      @focus="handleFirstTrapFocus"
    ></div>

    <slot></slot>

    <div
      v-if="!disabled"
      class="focus-trap-last"
      tabindex="0"
      @focus="handleLastTrapFocus"
    ></div>
  </div>

</template>


<script>

  /**
   * This component ensures that focus moves between the first element
   * and the last element of content provided by the default slot.
   * In disabled state, it only renders whatever has been passed
   * to the default slot, and doesn't add any focus trap behavior,
   * allowing for flexible use from parent components.
   */
  export default {
    name: 'FocusTrap',
    props: {
      firstEl: {
        type: HTMLElement,
        required: false,
        default: null,
      },
      lastEl: {
        type: HTMLElement,
        required: false,
        default: null,
      },
      disabled: {
        type: Boolean,
        required: false,
        default: false,
      },
    },
    data() {
      return {
        isTrapActive: false,
      };
    },
    methods: {
      handleFirstTrapFocus(e) {
        e.stopPropagation();
        if (!this.isTrapActive) {
          // On first focus, redirect to first option, then activate trap
          this.focusFirstEl();
          this.isTrapActive = true;
        } else {
          this.focusLastEl();
        }
      },
      handleLastTrapFocus(e) {
        e.stopPropagation();
        this.focusFirstEl();
      },
      focusFirstEl() {
        this.$emit('shouldFocusFirstEl');
        if (this.firstEl) {
          this.firstEl.focus();
        }
      },
      focusLastEl() {
        this.$emit('shouldFocusLastEl');
        if (this.lastEl) {
          this.lastEl.focus();
        }
      },
      /**
       * @public
       * Reset the next focus to the first focus element
       */
      reset() {
{'fraction_non_alphanumeric': 0.11620204250621033, 'fraction_numerical': 0.0011040574109853713, 'mean_word_length': 1.7706422018348624, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 25, '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': '7578690', 'n_tokens_mistral': 1084, 'n_tokens_neox': 1073, 'n_words': 278}