<commit_before>import { h, defineComponent, ref, computed, Transition, onBeforeUnmount, getCurrentInstance } from 'vue'

import QIcon from '../icon/QIcon.js'
import QSpinner from '../spinner/QSpinner.js'

import Ripple from '../../directives/Ripple.js'

import useBtn, { useBtnProps } from './use-btn.js'

import { hMergeSlot, hDir } from '../../utils/private/render.js'
import { stop, prevent, stopAndPrevent, listenOpts } from '../../utils/event.js'
import { getTouchTarget } from '../../utils/private/touch.js'
import { isKeyCode } from '../../utils/private/key-composition.js'

const { passiveCapture } = listenOpts

let
  touchTarget = null,
  keyboardTarget = null,
  mouseTarget = null

export default defineComponent({
  name: 'QBtn',

  props: {
    ...useBtnProps,

    percentage: Number,
    darkPercentage: Boolean
  },

  emits: [ 'click', 'keydown', 'touchstart', 'mousedown', 'keyup' ],

  setup (props, { slots, emit }) {
    const { proxy } = getCurrentInstance()

    const {
      classes, style, innerClasses,
      attributes,
      hasLink, isLink, navigateToLink,
      isActionable
    } = useBtn(props)

    const rootRef = ref(null)
    const blurTargetRef = ref(null)

    let localTouchTargetEl = null, avoidMouseRipple, mouseTimer

    const hasLabel = computed(() =>
      props.label !== void 0 && props.label !== null && props.label !== ''
    )

    const ripple = computed(() => (
      props.ripple === false
        ? false
        : {
            keyCodes: isLink.value === true ? [ 13, 32 ] : [ 13 ],
            ...(props.ripple === true ? {} : props.ripple)
          }
    ))

    const percentageStyle = computed(() => {
      const val = Math.max(0, Math.min(100, props.percentage))
      return val > 0
        ? { transition: 'transform 0.6s', transform: `translateX(${ val - 100 }%)` }
        : {}
    })

    const onEvents = computed(() => {
      if (props.loading === true) {
        return {
          onMousedown: onLoadingEvt,
          onTouchstartPassive: onLoadingEvt,
          onClick: onLoadingEvt,
          onKeydown: onLoadingEvt,
          onKeyup: onLoadingEvt
        }
      }
      else if (isActionable.value === true) {
        return {
          onClick,
          onKeydown,
          onMousedown,
          onTouchstartPassive
        }
      }

      return {}
    })

    const directives = computed(() => {
      // if props.disable !== true && props.ripple !== false
      return [ [
        Ripple,
        ripple.value,
        void 0,
        { center: props.round }
      ] ]
    })

    const nodeProps = computed(() => ({
      ref: rootRef,
      class: 'q-btn q-btn-item non-selectable no-outline ' + classes.value,
      style: style.value,
      ...attributes.value,
      ...onEvents.value<commit_msg>fix(QBtn): disable not working correctly with type="a" + href #9258<commit_after>import { h, defineComponent, ref, computed, Transition, onBeforeUnmount, getCurrentInstance } from 'vue'

import QIcon from '../icon/QIcon.js'
import QSpinner from '../spinner/QSpinner.js'

import Ripple from '../../directives/Ripple.js'

import useBtn, { useBtnProps } from './use-btn.js'

import { hMergeSlot, hDir } from '../../utils/private/render.js'
import { stop, prevent, stopAndPrevent, listenOpts } from '../../utils/event.js'
import { getTouchTarget } from '../../utils/private/touch.js'
import { isKeyCode } from '../../utils/private/key-composition.js'

const { passiveCapture } = listenOpts

let
  touchTarget = null,
  keyboardTarget = null,
  mouseTarget = null

export default defineComponent({
  name: 'QBtn',

  props: {
    ...useBtnProps,

    percentage: Number,
    darkPercentage: Boolean
  },

  emits: [ 'click', 'keydown', 'touchstart', 'mousedown', 'keyup' ],

  setup (props, { slots, emit }) {
    const { proxy } = getCurrentInstance()

    const {
      classes, style, innerClasses,
      attributes,
      hasLink, isLink, navigateToLink,
      isActionable
    } = useBtn(props)

    const rootRef = ref(null)
    const blurTargetRef = ref(null)

    let localTouchTargetEl = null, avoidMouseRipple, mouseTimer

    const hasLabel = computed(() =>
      props.label !== void 0 && props.label !== null && props.label !== ''
    )

    const ripple = computed(() => (
      props.ripple === false
        ? false
        : {
            keyCodes: isLink.value === true ? [ 13, 32 ] : [ 13 ],
            ...(props.ripple === true ? {} : props.ripple)
          }
    ))

    const percentageStyle = computed(() => {
      const val = Math.max(0, Math.min(100, props.percentage))
      return val > 0
        ? { transition: 'transform 0.6s', transform: `translateX(${ val - 100 }%)` }
        : {}
    })

    const onEvents = computed(() => {
      if (props.loading === true) {
        return {
          onMousedown: onLoadingEvt,
          onTouchstartPassive: onLoadingEvt,
          onClick: onLoadingEvt,
          onKeydown: onLoadingEvt,
          onKeyup: onLoadingEvt
        }
      }

      if (isActionable.value === true) {
        return {
          onClick,
          onKeydown,
          onMousedown,
          onTouchstartPassive
        }
      }

      return {
        // needed; especially for disabled <a> tags
        onClick: stopAndPrevent
      }
    })

    const directives = computed(() => {
      // if props.disable !== true && props.ripple !== false
      return [ [
        Ripple,
        ripple.value,
        void 0,
        { center: props.round }
      ] ]
    })

    const nodeProps = computed(() => ({
      ref: rootRef,
      class: 'q-btn q-btn-item non-selectable no-outline ' + classes.value,
      style: style.value,
      ...attributes.value,
      ...onEvents.value
{'fraction_non_alphanumeric': 0.14123404999126027, 'fraction_numerical': 0.006991784653032687, 'mean_word_length': 2.2002237136465324, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 18, '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': '2204419', 'n_tokens_mistral': 1794, 'n_tokens_neox': 1725, 'n_words': 416}