ronantakizawa/codereview-bench huggingface dataset:
Repository: element-plus/element-plus
File: packages/components/mention/src/mention.vue (Vue)

Code before:
const cursorStyle = ref<CSSProperties>()
const mentionCtx = ref<MentionCtx>()

const computedPlacement = computed<Placement>(() =>
  props.showArrow ? props.placement : `${props.placement}-start`
)

const computedFallbackPlacements = computed<Placement[]>(() =>
  props.showArrow ? ['bottom', 'top'] : ['bottom-start', 'top-start']
)

const aliasProps = computed(() => ({
  ...mentionDefaultProps,
  ...props.props,
}))

const mapOption = (option: MentionOption) => {
  const base = {
    label: option[aliasProps.value.label],
    value: option[aliasProps.value.value],
    disabled: option[aliasProps.value.disabled],
  }
  return { ...option, ...base }
}

const options = computed(() => props.options.map((option) => mapOption(option)))

const filteredOptions = computed(() => {
  const { filterOption } = props
  if (!mentionCtx.value || !filterOption) return options.value
  return options.value.filter((option) =>
    filterOption(mentionCtx.value!.pattern, option)
  )
})

const dropdownVisible = computed(() => {
  return visible.value && (!!filteredOptions.value.length || props.loading)
})

const hoveringId = computed(() => {
  return `${contentId.value}-${dropdownRef.value?.hoveringIndex}`
})

const handleInputChange = (value: string) => {
  emit(UPDATE_MODEL_EVENT, value)
  emit(INPUT_EVENT, value)
  syncAfterCursorMove()
}

const handleInputKeyDown = (event: KeyboardEvent | Event) => {
  if (!('code' in event) || elInputRef.value?.isComposing) return

Review comment (suggestion):
**nit**:

```suggestion
const options = computed(() => props.options.map(mapOption))
```

Code after:
const cursorStyle = ref<CSSProperties>()
const mentionCtx = ref<MentionCtx>()

const computedPlacement = computed<Placement>(() =>
  props.showArrow ? props.placement : `${props.placement}-start`
)

const computedFallbackPlacements = computed<Placement[]>(() =>
  props.showArrow ? ['bottom', 'top'] : ['bottom-start', 'top-start']
)

const aliasProps = computed(() => ({
  ...mentionDefaultProps,
  ...props.props,
}))

const mapOption = (option: MentionOption) => {
  const base = {
    label: option[aliasProps.value.label],
    value: option[aliasProps.value.value],
    disabled: option[aliasProps.value.disabled],
  }
  return { ...option, ...base }
}

const options = computed(() => props.options.map(mapOption))

const filteredOptions = computed(() => {
  const { filterOption } = props
  if (!mentionCtx.value || !filterOption) return options.value
  return options.value.filter((option) =>
    filterOption(mentionCtx.value!.pattern, option)
  )
})

const dropdownVisible = computed(() => {
  return visible.value && (!!filteredOptions.value.length || props.loading)
})

const hoveringId = computed(() => {
  return `${contentId.value}-${dropdownRef.value?.hoveringIndex}`
})

const handleInputChange = (value: string) => {
  emit(UPDATE_MODEL_EVENT, value)
  emit(INPUT_EVENT, value)
  syncAfterCursorMove()
}

const handleInputKeyDown = (event: KeyboardEvent | Event) => {
  if (!('code' in event) || elInputRef.value?.isComposing) return
Repository: element-plus/element-plus
File: packages/components/popconfirm/src/popconfirm.vue (Vue)

Code before:
const popperRef = computed(() => {
  return unref(tooltipRef)?.popperRef
})

const hidePopper = () => {
  tooltipRef.value?.onClose?.()
}

const style = computed(() => {
  return {
    width: addUnit(props.width),
  }
})

const confirm = (e: MouseEvent) => {
  emit('confirm', e)
  hidePopper()
}
const cancel = (e: MouseEvent | KeyboardEvent) => {
  emit('cancel', e)
  hidePopper()
}

const onCloseRequested = (event: KeyboardEvent) => {
  if (props.closeOnPressEscape) {
    if (event.code === EVENT_CODE.esc) {
      cancel(event)
    }
  }
}

const finalConfirmButtonText = computed(
  () => props.confirmButtonText || t('el.popconfirm.confirmButtonText')
)
const finalCancelButtonText = computed(
  () => props.cancelButtonText || t('el.popconfirm.cancelButtonText')
)

defineExpose({
  popperRef,
  hide: hidePopper,
})
</script>


Review comment (security):
can be simplified to:

```suggestion
  if (props.closeOnPressEscape && event.code === EVENT_CODE.esc) {
```

Code after:
  return unref(tooltipRef)?.popperRef
})

const hidePopper = () => {
  tooltipRef.value?.onClose?.()
}

const style = computed(() => {
  return {
    width: addUnit(props.width),
  }
})

const confirm = (e: MouseEvent) => {
  emit('confirm', e)
  hidePopper()
}
const cancel = (e: MouseEvent | KeyboardEvent) => {
  emit('cancel', e)
  hidePopper()
}

const onCloseRequested = (event: KeyboardEvent) => {
  if (props.closeOnPressEscape) {
    cancel(event)
  }
}

const finalConfirmButtonText = computed(
  () => props.confirmButtonText || t('el.popconfirm.confirmButtonText')
)
const finalCancelButtonText = computed(
  () => props.cancelButtonText || t('el.popconfirm.cancelButtonText')
)

defineExpose({
  popperRef,
  hide: hidePopper,
})
</script>
Repository: element-plus/element-plus
File: packages/components/popconfirm/src/popconfirm.vue (Vue)

Code before:
const tooltipRef = ref<TooltipInstance>()
const popperRef = computed(() => {
  return unref(tooltipRef)?.popperRef
})

const hidePopper = () => {
  tooltipRef.value?.onClose?.()
}

const style = computed(() => {
  return {
    width: addUnit(props.width),
  }
})

const confirm = (e: MouseEvent) => {
  emit('confirm', e)
  hidePopper()
}
const cancel = (e: MouseEvent | KeyboardEvent) => {
  emit('cancel', e)
  hidePopper()
}

const onCloseRequested = (event: KeyboardEvent) => {
  if (props.closeOnPressEscape && event.code === EVENT_CODE.esc) {
    cancel(event)
  }
}

const finalConfirmButtonText = computed(
  () => props.confirmButtonText || t('el.popconfirm.confirmButtonText')
)
const finalCancelButtonText = computed(
  () => props.cancelButtonText || t('el.popconfirm.cancelButtonText')
)

defineExpose({
  popperRef,
  hide: hidePopper,
})
</script>


Review comment (security):
```suggestion
  if (props.closeOnPressEscape) {
```
https://github.com/element-plus/element-plus/blob/b04b827a1fba0175e316a377b2d6775b296aba28/packages/hooks/use-escape-keydown/index.ts#L8

The judgment has been made inside the hook.

Code after:
const popperRef = computed(() => {
  return unref(tooltipRef)?.popperRef
})

const hidePopper = () => {
  tooltipRef.value?.onClose?.()
}

const style = computed(() => {
  return {
    width: addUnit(props.width),
  }
})

const confirm = (e: MouseEvent) => {
  emit('confirm', e)
  hidePopper()
}
const cancel = (e: MouseEvent | KeyboardEvent) => {
  emit('cancel', e)
  hidePopper()
}

const onCloseRequested = (event: KeyboardEvent) => {
  if (props.closeOnPressEscape) {
    cancel(event)
  }
}

const finalConfirmButtonText = computed(
  () => props.confirmButtonText || t('el.popconfirm.confirmButtonText')
)
const finalCancelButtonText = computed(
  () => props.cancelButtonText || t('el.popconfirm.cancelButtonText')
)

defineExpose({
  popperRef,
  hide: hidePopper,
})
</script>
Repository: element-plus/element-plus
File: packages/components/splitter/src/split-bar.vue (Vue)

Code before:
  window.removeEventListener('touchend', onTouchEnd)
  window.removeEventListener('touchmove', onTouchMove)
  emit('moveEnd', props.index)
}

const StartIcon = computed(() => (isHorizontal.value ? ArrowLeft : ArrowUp))
const EndIcon = computed(() => (isHorizontal.value ? ArrowRight : ArrowDown))
</script>

<template>
  <div :class="[ns.b()]" :style="barWrapStyles">
    <div
      v-if="startCollapsible"
      :class="[ns.e('collapse-icon'), ns.e(`${layout}-collapse-icon-start`)]"
      @click="emit('collapse', index, 'start')"
    >
      <slot name="start-collapsible">
        <component :is="StartIcon" style="width: 12px; height: 12px" />
      </slot>
    </div>

    <div
      :class="[
        ns.e('dragger'),
        draggerPseudoClass,
        resizable ? '' : ns.is('disabled'),
        ns.is('lazy', resizable && lazy),
      ]"
      :style="draggerStyles"
      @mousedown="onMousedown"
      @touchstart="onTouchStart"
    />
    <div
      v-if="endCollapsible"
      :class="[ns.e('collapse-icon'), ns.e(`${layout}-collapse-icon-end`)]"
      @click="emit('collapse', index, 'end')"
    >
      <slot name="end-collapsible">
        <component :is="EndIcon" style="width: 12px; height: 12px" />
      </slot>
    </div>
  </div>
</template>


Review comment (suggestion):
I think the condition can be placed inside `ns.is` to make it more consistent.

```suggestion
       ns.is('disabled', !resizable),
```

Code after:
  window.removeEventListener('touchend', onTouchEnd)
  window.removeEventListener('touchmove', onTouchMove)
  emit('moveEnd', props.index)
}

const StartIcon = computed(() => (isHorizontal.value ? ArrowLeft : ArrowUp))
const EndIcon = computed(() => (isHorizontal.value ? ArrowRight : ArrowDown))
</script>

<template>
  <div :class="[ns.b()]" :style="barWrapStyles">
    <div
      v-if="startCollapsible"
      :class="[ns.e('collapse-icon'), ns.e(`${layout}-collapse-icon-start`)]"
      @click="emit('collapse', index, 'start')"
    >
      <slot name="start-collapsible">
        <component :is="StartIcon" style="width: 12px; height: 12px" />
      </slot>
    </div>

    <div
      :class="[
        ns.e('dragger'),
        draggerPseudoClass,
        ns.is('disabled', !resizable),
        ns.is('lazy', resizable && lazy),
      ]"
      :style="draggerStyles"
      @mousedown="onMousedown"
      @touchstart="onTouchStart"
    />
    <div
      v-if="endCollapsible"
      :class="[ns.e('collapse-icon'), ns.e(`${layout}-collapse-icon-end`)]"
      @click="emit('collapse', index, 'end')"
    >
      <slot name="end-collapsible">
        <component :is="EndIcon" style="width: 12px; height: 12px" />
      </slot>
    </div>
  </div>
</template>
Repository: element-plus/element-plus
File: packages/components/alert/src/alert.vue (Vue)

Code before:
</template>

<script lang="ts" setup>
import { computed, ref, toRef, useSlots } from 'vue'
import { ElIcon } from '@element-plus/components/icon'
import {
  TypeComponents,
  TypeComponentsMap,
  isClient,
} from '@element-plus/utils'
import { useDelayedToggle, useNamespace } from '@element-plus/hooks'
import { alertEmits, alertProps } from './alert'

const { Close } = TypeComponents

defineOptions({
  name: 'ElAlert',
})

const props = defineProps(alertProps)
const emit = defineEmits(alertEmits)
const slots = useSlots()

const ns = useNamespace('alert')

const visible = ref(props.showAfter === undefined)

const iconComponent = computed(() => TypeComponentsMap[props.type])

const hasDesc = computed(() => !!(props.description || slots.default))

const open = () => {
  visible.value = true
  emit('open')
}

const close = (event?: Event) => {
  visible.value = false
  emit('close', event)
}

const { onOpen, onClose } = useDelayedToggle({
  showAfter: toRef(props, 'showAfter', 0),
  hideAfter: toRef(props, 'hideAfter'),
  autoClose: toRef(props, 'autoClose'),
  open,
  close,
})

if (isClient) {
  onOpen()

Review comment (suggestion):
```suggestion
const visible = ref(isUndefined(props.showAfter))
```

Code after:
</template>

<script lang="ts" setup>
import { computed, ref, toRef, useSlots } from 'vue'
import { ElIcon } from '@element-plus/components/icon'
import {
  TypeComponents,
  TypeComponentsMap,
  isClient,
  isUndefined,
} from '@element-plus/utils'
import { useDelayedToggle, useNamespace } from '@element-plus/hooks'
import { alertEmits, alertProps } from './alert'

const { Close } = TypeComponents

defineOptions({
  name: 'ElAlert',
})

const props = defineProps(alertProps)
const emit = defineEmits(alertEmits)
const slots = useSlots()

const ns = useNamespace('alert')

const visible = ref(isUndefined(props.showAfter))

const iconComponent = computed(() => TypeComponentsMap[props.type])

const hasDesc = computed(() => !!(props.description || slots.default))

const open = () => {
  visible.value = true
  emit('open')
}

const close = (event?: Event) => {
  visible.value = false
  emit('close', event)
}

const { onOpen, onClose } = useDelayedToggle({
  showAfter: toRef(props, 'showAfter', 0),
  hideAfter: toRef(props, 'hideAfter'),
  autoClose: toRef(props, 'autoClose'),
  open,
  close,
})

if (isClient) {
Repository: element-plus/element-plus
File: packages/components/image-viewer/src/image-viewer.vue (Vue)

Code before:
    name: 'original',
    icon: markRaw(ScaleToOriginal),
  },
}

defineOptions({
  name: 'ElImageViewer',
})

const props = defineProps(imageViewerProps)
const emit = defineEmits(imageViewerEmits)

let stopWheelListener: (() => void) | undefined
let prevOverflow = ''

const { t } = useLocale()
const ns = useNamespace('image-viewer')
const { nextZIndex } = useZIndex()
const wrapper = ref<HTMLDivElement>()
const imgRefs = ref<HTMLImageElement[]>([])

const scopeEventListener = effectScope()

const initialScaleClamped = computed(() => {
  const { initialScale, minScale, maxScale } = props
  return Math.max(minScale, Math.min(maxScale, initialScale))
})

const loading = ref(true)
const activeIndex = ref(props.initialIndex)
const mode = shallowRef<ImageViewerMode>(modes.CONTAIN)
const transform = ref({
  scale: initialScaleClamped.value,
  deg: 0,
  offsetX: 0,
  offsetY: 0,
  enableTransition: false,
})
const zIndex = ref(props.zIndex ?? nextZIndex())

const isSingle = computed(() => {
  const { urlList } = props
  return urlList.length <= 1
})

const isFirst = computed(() => activeIndex.value === 0)

const isLast = computed(() => activeIndex.value === props.urlList.length - 1)

const currentImg = computed(() => props.urlList[activeIndex.value])


Review comment (suggestion):
**nit**: You can use clamp from [lodash](https://lodash.com/docs/4.17.15#clamp).

```suggestion
  return clamp(initialScale, minScale, maxScale)
```

Code after:
    name: 'original',
    icon: markRaw(ScaleToOriginal),
  },
}

defineOptions({
  name: 'ElImageViewer',
})

const props = defineProps(imageViewerProps)
const emit = defineEmits(imageViewerEmits)

let stopWheelListener: (() => void) | undefined
let prevOverflow = ''

const { t } = useLocale()
const ns = useNamespace('image-viewer')
const { nextZIndex } = useZIndex()
const wrapper = ref<HTMLDivElement>()
const imgRefs = ref<HTMLImageElement[]>([])

const scopeEventListener = effectScope()

const scaleClamped = computed(() => {
  const { scale, minScale, maxScale } = props
  return clamp(scale, minScale, maxScale)
})

const loading = ref(true)
const activeIndex = ref(props.initialIndex)
const mode = shallowRef<ImageViewerMode>(modes.CONTAIN)
const transform = ref({
  scale: scaleClamped.value,
  deg: 0,
  offsetX: 0,
  offsetY: 0,
  enableTransition: false,
})
const zIndex = ref(props.zIndex ?? nextZIndex())

const isSingle = computed(() => {
  const { urlList } = props
  return urlList.length <= 1
})

const isFirst = computed(() => activeIndex.value === 0)

const isLast = computed(() => activeIndex.value === props.urlList.length - 1)

const currentImg = computed(() => props.urlList[activeIndex.value])
Repository: element-plus/element-plus
File: packages/components/image/src/image.ts (TypeScript)

Code before:
    type: Number,
    default: 0,
  },
  /**
   * @description whether the viewer preview is infinite.
   */
  infinite: {
    type: Boolean,
    default: true,
  },
  /**
   * @description whether the image-viewer can be closed by pressing ESC.
   */
  closeOnPressEscape: {
    type: Boolean,
    default: true,
  },
  /**
   * @description the zoom rate of the image viewer zoom event
   */
  zoomRate: {
    type: Number,
    default: 1.2,
  },
  /**
   * @description initial preview image scale.
   */
  scale: {
    type: Number,
    default: 1,
  },
  /**
   * @description the min scale of the image viewer zoom event.
   */
  minScale: {
    type: Number,
    default: 0.2,
  },
  /**
   * @description the max scale of the image viewer zoom event.
   */
  maxScale: {
    type: Number,
    default: 7,
  },
  /**
   * @description show preview image progress content.
   */
  showProgress: Boolean,
  /**
   * @description set HTML attribute: crossorigin.

Review comment (suggestion):
```suggestion
   * @description preview image scale.
```

Code after:
    type: Number,
    default: 0,
  },
  /**
   * @description whether the viewer preview is infinite.
   */
  infinite: {
    type: Boolean,
    default: true,
  },
  /**
   * @description whether the image-viewer can be closed by pressing ESC.
   */
  closeOnPressEscape: {
    type: Boolean,
    default: true,
  },
  /**
   * @description the zoom rate of the image viewer zoom event
   */
  zoomRate: {
    type: Number,
    default: 1.2,
  },
  /**
   * @description preview image scale.
   */
  scale: {
    type: Number,
    default: 1,
  },
  /**
   * @description the min scale of the image viewer zoom event.
   */
  minScale: {
    type: Number,
    default: 0.2,
  },
  /**
   * @description the max scale of the image viewer zoom event.
   */
  maxScale: {
    type: Number,
    default: 7,
  },
  /**
   * @description show preview image progress content.
   */
  showProgress: Boolean,
  /**
   * @description set HTML attribute: crossorigin.
Repository: element-plus/element-plus
File: packages/components/image-viewer/src/image-viewer.ts (TypeScript)

Code before:
    default: true,
  },
  /**
   * @description whether user can emit close event when clicking backdrop.
   */
  hideOnClickModal: Boolean,
  /**
   * @description whether to append image itself to body. A nested parent element attribute transform should have this attribute set to `true`.
   */
  teleported: Boolean,
  /**
   * @description whether the image-viewer can be closed by pressing ESC.
   */
  closeOnPressEscape: {
    type: Boolean,
    default: true,
  },
  /**
   * @description the zoom rate of the image viewer zoom event.
   */
  zoomRate: {
    type: Number,
    default: 1.2,
  },
  /**
   * @description initial preview image scale.
   */
  scale: {
    type: Number,
    default: 1,
  },
  /**
   * @description the min scale of the image viewer zoom event.
   */
  minScale: {
    type: Number,
    default: 0.2,
  },
  /**
   * @description the max scale of the image viewer zoom event.
   */
  maxScale: {
    type: Number,
    default: 7,
  },
  /**
   * @description show preview image progress content.
   */
  showProgress: Boolean,
  /**
   * @description set HTML attribute: crossorigin.

Review comment (suggestion):
```suggestion
   * @description preview image scale.
```

Code after:
    default: true,
  },
  /**
   * @description whether user can emit close event when clicking backdrop.
   */
  hideOnClickModal: Boolean,
  /**
   * @description whether to append image itself to body. A nested parent element attribute transform should have this attribute set to `true`.
   */
  teleported: Boolean,
  /**
   * @description whether the image-viewer can be closed by pressing ESC.
   */
  closeOnPressEscape: {
    type: Boolean,
    default: true,
  },
  /**
   * @description the zoom rate of the image viewer zoom event.
   */
  zoomRate: {
    type: Number,
    default: 1.2,
  },
  /**
   * @description preview image scale.
   */
  scale: {
    type: Number,
    default: 1,
  },
  /**
   * @description the min scale of the image viewer zoom event.
   */
  minScale: {
    type: Number,
    default: 0.2,
  },
  /**
   * @description the max scale of the image viewer zoom event.
   */
  maxScale: {
    type: Number,
    default: 7,
  },
  /**
   * @description show preview image progress content.
   */
  showProgress: Boolean,
  /**
   * @description set HTML attribute: crossorigin.
Repository: element-plus/element-plus
File: packages/components/dropdown/src/dropdown.vue (Vue)

Code before:
    const popperRef = ref<TooltipInstance>()
    const contentRef = ref<HTMLElement>()
    const scrollbar = ref(null)
    const currentTabId = ref<string | null>(null)
    const isUsingKeyboard = ref(false)

    const wrapStyle = computed<CSSProperties>(() => ({
      maxHeight: addUnit(props.maxHeight),
    }))
    const dropdownTriggerKls = computed(() => [ns.m(dropdownSize.value)])
    const trigger = computed(() => ensureArray(props.trigger))

    const defaultTriggerId = useId().value
    const triggerId = computed<string>(() => props.id || defaultTriggerId)

    const { registerTimeout } = useTimeout()
    const isClearTimeout = ref(false)
    const wrapHideTimeout = computed(() => {
      if (props.trigger === 'hover' && !isClearTimeout.value) {
        return props.hideTimeout
      }
      return 0
    })

    function handleClick() {
      handleClose()
    }

    function handleClose() {
      if (props.trigger === 'hover') {
        isClearTimeout.value = true
      }
      nextTick(() => {
        popperRef.value?.onClose()
        registerTimeout(() => {
          isClearTimeout.value = false
        })
      })
    }

    function handleOpen() {
      popperRef.value?.onOpen()
    }

    const dropdownSize = useFormSize()

    function commandHandler(...args: any[]) {
      emit('command', ...args)
    }

    function onItemEnter() {

Review comment (suggestion):
Maybe we can use the `hide` exposed function to close the menu directly on click.
[Ref](https://github.com/element-plus/element-plus/blob/dev/packages/components/tooltip/src/tooltip.vue#L102).

```suggestion
      popperRef.value?.hide()
```

Code after:
    const contentRef = ref<HTMLElement>()
    const scrollbar = ref(null)
    const currentTabId = ref<string | null>(null)
    const isUsingKeyboard = ref(false)

    const wrapStyle = computed<CSSProperties>(() => ({
      maxHeight: addUnit(props.maxHeight),
    }))
    const dropdownTriggerKls = computed(() => [ns.m(dropdownSize.value)])
    const trigger = computed(() => ensureArray(props.trigger))

    const defaultTriggerId = useId().value
    const triggerId = computed<string>(() => props.id || defaultTriggerId)

    function handleClick() {
      popperRef.value?.onClose(undefined, 0)
    }

    function handleClose() {
      popperRef.value?.onClose()
    }

    function handleOpen() {
      popperRef.value?.onOpen()
    }

    const dropdownSize = useFormSize()

    function commandHandler(...args: any[]) {
      emit('command', ...args)
    }

    function onItemEnter() {
      // NOOP for now
    }

    function onItemLeave() {
      const contentEl = unref(contentRef)

      trigger.value.includes('hover') &&
        contentEl?.focus({
          preventScroll: true,
        })
      currentTabId.value = null
    }

    function handleCurrentTabIdChange(id: string) {
      currentTabId.value = id
    }

    function handleEntryFocus(e: Event) {