Repository: element-plus/element-plus
File: packages/components/input-tag/src/composables/use-input-tag-dom.ts (TypeScript)

Code before:
      !props.readonly &&
      (props.modelValue?.length || inputValue.value) &&
      (isFocused.value || hovering.value)
    )
  })
  const showSuffix = computed(() => {
    return (
      slots.suffix ||
      showClear.value ||
      (validateState.value && validateIcon.value && needStatusIcon.value)
    )
  })

  const getGapWidth = () => {
    if (!wrapperRef.value) return 0
    const innerElement = wrapperRef.value.querySelector(`.${ns.e('inner')}`)
    if (!innerElement) return 0
    const style = window.getComputedStyle(innerElement)
    return Number.parseFloat(style.gap || '6px')
  }

  const getInnerWidth = () => {
    if (!wrapperRef.value) return 0
    const innerElement = wrapperRef.value.querySelector(`.${ns.e('inner')}`)
    if (!innerElement) return 0
    return innerElement.clientWidth
  }

  const tagStyle = computed(() => {
    if (!props.collapseTags) return {}
    const gapWidth = getGapWidth()
    const inputSlotWidth = gapWidth + MINIMUM_INPUT_WIDTH
    const innerWidth = getInnerWidth()
    const collapseItemWidth = collapseItemRef.value?.offsetWidth || 40

    const maxWidth =
      collapseItemRef.value && props.maxCollapseTags === 1
        ? innerWidth - collapseItemWidth - gapWidth - inputSlotWidth
        : innerWidth - inputSlotWidth

    return { maxWidth: `${Math.max(maxWidth, 0)}px` }
  })

  return {
    ns,
    nsInput,
    containerKls,
    containerStyle,
    innerKls,
    showClear,
    showSuffix,

Review comment (suggestion):
I have 2 suggestions here:
- We can create a template ref `innerRef` instead of using `querySelector`.
- Maybe we can use `window.getComputedStyle(...).width` instead of `clientWidth` to mimic the same diff as [select](https://github.com/element-plus/element-plus/blob/dev/packages/components/select/src/useSelect.ts#L466-L468) (?).

Code after:
      (props.modelValue?.length || inputValue.value) &&
      (isFocused.value || hovering.value)
    )
  })
  const showSuffix = computed(() => {
    return (
      slots.suffix ||
      showClear.value ||
      (validateState.value && validateIcon.value && needStatusIcon.value)
    )
  })

  const states = reactive({
    innerWidth: 0,
    collapseItemWidth: 0,
  })

  const getGapWidth = () => {
    if (!innerRef.value) return 0
    const style = window.getComputedStyle(innerRef.value)
    return Number.parseFloat(style.gap || '6px')
  }

  const resetInnerWidth = () => {
    states.innerWidth = Number.parseFloat(
      window.getComputedStyle(innerRef.value!).width
    )
  }

  const resetCollapseItemWidth = () => {
    states.collapseItemWidth =
      collapseItemRef.value!.getBoundingClientRect().width
  }

  const tagStyle = computed(() => {
    if (!props.collapseTags) return {}
    const gapWidth = getGapWidth()

    const inputSlotWidth = gapWidth + MINIMUM_INPUT_WIDTH

    const maxWidth =
      collapseItemRef.value && props.maxCollapseTags === 1
        ? states.innerWidth -
          states.collapseItemWidth -
          gapWidth -
          inputSlotWidth
        : states.innerWidth - inputSlotWidth

    return { maxWidth: `${Math.max(maxWidth, 0)}px` }
  })