{"version":3,"file":"index2.mjs","sources":["../../../../../src/components/ivue-ellipsis/index.vue"],"sourcesContent":["<template>\r\n  <div :class=\"prefixCls\" ref=\"wrapper\">\r\n    <template v-if=\"data.computedReady\">\r\n      <!-- tooltip -->\r\n      <ivue-tooltip\r\n        :class=\"`${prefixCls}-tooltip--wrapper`\"\r\n        :content=\"text\"\r\n        :placement=\"placement\"\r\n        :theme=\"theme\"\r\n        :transfer=\"transfer\"\r\n        :maxWidth=\"maxWidth\"\r\n        v-if=\"tooltip\"\r\n      >\r\n        <span :class=\"`${prefixCls}-tooltip`\">\r\n          <!-- text -->\r\n          <span :class=\"`${prefixCls}-text`\" ref=\"textRef\">{{ text }}</span>\r\n          <!-- oversize -->\r\n          <span\r\n            :class=\"`${prefixCls}-more`\"\r\n            v-show=\"data.oversize\"\r\n            ref=\"moreRef\"\r\n          >\r\n            <slot name=\"more\">...</slot>\r\n          </span>\r\n          <!-- suffix -->\r\n          <slot name=\"suffix\"></slot>\r\n        </span>\r\n      </ivue-tooltip>\r\n      <!-- 普通显示 -->\r\n      <template v-else>\r\n        <!-- text -->\r\n        <span :class=\"`${prefixCls}-text`\" ref=\"textRef\">{{ text }}</span>\r\n        <!-- oversize -->\r\n        <span :class=\"`${prefixCls}-more`\" v-show=\"data.oversize\" ref=\"moreRef\">\r\n          <slot name=\"more\">...</slot>\r\n        </span>\r\n        <!-- suffix -->\r\n        <slot name=\"suffix\"></slot>\r\n      </template>\r\n    </template>\r\n    <!-- 站位节点 -->\r\n    <div :class=\"`${prefixCls}-hidden`\" v-else>\r\n      <!-- text -->\r\n      <span :class=\"`${prefixCls}-text`\" ref=\"textRef\">{{ text }}</span>\r\n      <!-- oversize -->\r\n      <span :class=\"`${prefixCls}-more`\" v-show=\"data.oversize\" ref=\"moreRef\">\r\n        <slot name=\"more\">...</slot>\r\n      </span>\r\n      <!-- suffix -->\r\n      <slot name=\"suffix\"></slot>\r\n    </div>\r\n  </div>\r\n</template>\r\n\r\n<script lang=\"ts\">\r\nimport {\r\n  defineComponent,\r\n  onMounted,\r\n  reactive,\r\n  ref,\r\n  watch,\r\n  nextTick,\r\n  getCurrentInstance,\r\n} from 'vue';\r\nimport { useEventListener } from '@vueuse/core';\r\n\r\n// utils\r\nimport { oneOf } from '../../utils/assist';\r\nimport { getStyle } from '../../utils/assist';\r\n\r\nimport IvueTooltip from '../ivue-tooltip';\r\n\r\n// type\r\nimport type { Props, Data } from './types/ellipsis';\r\n\r\nconst prefixCls = 'ivue-ellipsis';\r\n\r\nexport default defineComponent({\r\n  name: prefixCls,\r\n  emits: ['on-hide', 'on-show'],\r\n  props: {\r\n    /**\r\n     * 文本\r\n     *\r\n     * @type {String}\r\n     */\r\n    text: {\r\n      type: String,\r\n    },\r\n    /**\r\n     * 按照指定长度截取\r\n     *\r\n     * @type {Number}\r\n     */\r\n    length: {\r\n      type: Number,\r\n    },\r\n    /**\r\n     * 限制的高度\r\n     *\r\n     * @type {Number}\r\n     */\r\n    height: {\r\n      type: Number,\r\n    },\r\n    /**\r\n     * 是否禁用省略\r\n     *\r\n     * @type {Boolean}\r\n     */\r\n    disabled: {\r\n      type: Boolean,\r\n      default: false,\r\n    },\r\n    /**\r\n     * 限制行数，将换算为 height。如果设置了 height，则直接使用 height 计算\r\n     *\r\n     * @type {Number}\r\n     */\r\n    lines: {\r\n      type: Number,\r\n    },\r\n    /**\r\n     * 是否将全角字符的长度视为2来计算字符串长度，适用于 length\r\n     *\r\n     * @type {Boolean}\r\n     */\r\n    fullWidthRecognition: {\r\n      type: Boolean,\r\n      default: false,\r\n    },\r\n    /**\r\n     * 是否自动根据外层宽度动态改变 (设置 height 时生效)\r\n     *\r\n     * @type {Boolean}\r\n     */\r\n    autoResize: {\r\n      type: Boolean,\r\n      default: true,\r\n    },\r\n    /**\r\n     * 是否开启 tooltip\r\n     *\r\n     * @type {Boolean}\r\n     */\r\n    tooltip: {\r\n      type: Boolean,\r\n      default: false,\r\n    },\r\n    /**\r\n     * 弹窗的展开方向\r\n     *\r\n     * @type {String}\r\n     */\r\n    placement: {\r\n      type: String,\r\n      validator(value: string) {\r\n        return oneOf(value, [\r\n          'top',\r\n          'top-start',\r\n          'top-end',\r\n          'bottom',\r\n          'bottom-start',\r\n          'bottom-end',\r\n          'left',\r\n          'left-start',\r\n          'left-end',\r\n          'right',\r\n          'right-start',\r\n          'right-end',\r\n        ]);\r\n      },\r\n      default: 'bottom',\r\n    },\r\n    /**\r\n     * 主题，可选值为 dark 或 light\r\n     *\r\n     * @type {String}\r\n     */\r\n    theme: {\r\n      type: String,\r\n      validator(value: string) {\r\n        return oneOf(value, ['dark', 'light']);\r\n      },\r\n      default: 'dark',\r\n    },\r\n    /**\r\n     * 是否将弹层放置于 body 内，在 Tabs、\r\n     * 带有 fixed 的 Table 列内使用时，\r\n     * 建议添加此属性，它将不受父级样式影响，\r\n     * 从而达到更好的效果\r\n     *\r\n     * @type {Boolean}\r\n     */\r\n    transfer: {\r\n      type: Boolean,\r\n      default() {\r\n        const global = getCurrentInstance().appContext.config.globalProperties;\r\n\r\n        return !global.$IVUE || global.$IVUE.transfer === ''\r\n          ? false\r\n          : global.$IVUE.transfer;\r\n      },\r\n    },\r\n    /**\r\n     * 最大宽度，超出最大值后，文本将自动换行，并两端对齐\r\n     *\r\n     * @type {String, Number}\r\n     */\r\n    maxWidth: {\r\n      type: [String, Number],\r\n    },\r\n  },\r\n  setup(props: Props, { emit }) {\r\n    // dom\r\n    const wrapper = ref<HTMLDivElement>();\r\n    const textRef = ref<HTMLSpanElement>();\r\n    const moreRef = ref<HTMLSpanElement>();\r\n\r\n    // data\r\n    const data = reactive<Data>({\r\n      /**\r\n       * 先隐形计算，计算好后，再根据配置显示\r\n       *\r\n       * @type {Boolean}\r\n       */\r\n      computedReady: false,\r\n      /**\r\n       * 计算后显示的text\r\n       *\r\n       * @type {String}\r\n       */\r\n      computedText: '',\r\n      /**\r\n       * 超出长度\r\n       *\r\n       * @type {Boolean}\r\n       */\r\n      oversize: false,\r\n    });\r\n\r\n    // methods\r\n\r\n    // 初始化\r\n    const init = () => {\r\n      // 禁用\r\n      if (!props.disabled) {\r\n        // 计算显示的text\r\n        setShowText();\r\n        // 超出显示\r\n        limitShow();\r\n      }\r\n      // 禁用显示未省略\r\n      else {\r\n        data.computedReady = true;\r\n      }\r\n    };\r\n\r\n    // 计算显示的text\r\n    const setShowText = () => {\r\n      // 初始化状态\r\n      data.oversize = false;\r\n      // 先隐形计算，计算好后，再根据配置显示\r\n      data.computedReady = false;\r\n\r\n      nextTick(() => {\r\n        const $wrapper = wrapper.value;\r\n        const $more = moreRef.value;\r\n\r\n        // 限制的高度\r\n        let height = props.height;\r\n        // 文本\r\n        let text = props.text;\r\n\r\n        // 当 height 未定义，且 lines 定义时，计算真实高度，否则使用 限制的高度\r\n        if (!props.height && props.lines) {\r\n          // 行高\r\n          const lineHeight = parseInt(getStyle($wrapper, 'lineHeight'), 10);\r\n\r\n          // 行高 * 限制行数\r\n          height = lineHeight * props.lines;\r\n        }\r\n\r\n        // 有textRef\r\n        // 指定 length，则按具体字数剪裁\r\n        if (props.length) {\r\n          const textLength = props.fullWidthRecognition\r\n            ? getStrFullLength(text)\r\n            : text.length;\r\n\r\n          // 超出指定长度截取\r\n          if (textLength > props.length) {\r\n            // 超出长度\r\n            data.oversize = true;\r\n            $more.style.display = 'inline-block';\r\n\r\n            // 计算后显示的text\r\n            text = props.fullWidthRecognition\r\n              ? cutStrLength(text, props.length)\r\n              : text.slice(0, props.length);\r\n          }\r\n\r\n          // 计算后显示的text\r\n          data.computedText = text;\r\n        }\r\n        // 指定高度\r\n        else {\r\n          specifiedHeight(height);\r\n        }\r\n      });\r\n    };\r\n\r\n    // 指定高度\r\n    const specifiedHeight = (height: number) => {\r\n      const $wrapper = wrapper.value;\r\n      const $more = moreRef.value;\r\n      const $text = textRef.value;\r\n\r\n      // 文本\r\n      let text = props.text;\r\n\r\n      // 最大执行次数\r\n      let n = 1000;\r\n\r\n      // offsetHeight > 设置的高度\r\n      if ($wrapper.offsetHeight > height) {\r\n        // 超出长度\r\n        data.oversize = true;\r\n\r\n        $more.style.display = 'inline-block';\r\n\r\n        while ($wrapper.offsetHeight > height && n > 0) {\r\n          if ($wrapper.offsetHeight > height * 3) {\r\n            text = text.substring(0, Math.floor(text.length / 2));\r\n\r\n            $text.innerText = text;\r\n          } else {\r\n            text = text.substring(0, text.length - 1);\r\n\r\n            $text.innerText = text;\r\n          }\r\n\r\n          n--;\r\n        }\r\n      }\r\n\r\n      // 没有开启自动根据外层宽度动态改变\r\n      if (!props.autoResize) {\r\n        // 计算后显示的text\r\n        data.computedText = text;\r\n      }\r\n    };\r\n\r\n    // 超出显示\r\n    const limitShow = () => {\r\n      data.computedReady = true;\r\n\r\n      nextTick(() => {\r\n        if (textRef.value) {\r\n          // 文本省略的时候触发\r\n          if (wrapper.value.offsetHeight > props.height) {\r\n            emit('on-hide');\r\n          }\r\n          // 文本全部展示的时候触发\r\n          else {\r\n            emit('on-show');\r\n          }\r\n        }\r\n      });\r\n    };\r\n\r\n    // 获取字符串全部长度\r\n    const getStrFullLength = (str = '') => {\r\n      return str.split('').reduce((pre, cur) => {\r\n        // 字符在字符串中的下标->第一个\r\n        const charCode = cur.charCodeAt(0);\r\n\r\n        // 前 128 ASCII 字符编码\r\n        if (charCode >= 0 && charCode <= 128) {\r\n          return pre + 1;\r\n        }\r\n\r\n        return pre + 2;\r\n      }, 0);\r\n    };\r\n\r\n    // 切割字符串\r\n    const cutStrLength = (str = '', maxLength: number) => {\r\n      let showLength = 0;\r\n\r\n      return str.split('').reduce((pre, cur) => {\r\n        // 字符在字符串中的下标->第一个\r\n        const charCode = cur.charCodeAt(0);\r\n\r\n        // 前 128 ASCII 字符编码\r\n        if (charCode >= 0 && charCode <= 128) {\r\n          showLength += 1;\r\n        }\r\n        // 不是前 128 ASCII 字符编码\r\n        else {\r\n          showLength += 2;\r\n        }\r\n\r\n        // 设置长度\r\n        if (showLength <= maxLength) {\r\n          return pre + cur;\r\n        }\r\n\r\n        return pre;\r\n      }, '');\r\n    };\r\n\r\n    // 自适应高度\r\n    const autoResizeHeight = () => {\r\n      // 已经显示文本 && 有设置高度\r\n      if (data.computedReady && props.height) {\r\n        // 限制的高度\r\n        const height = props.height;\r\n        // 文本\r\n        const text = props.text;\r\n\r\n        // 重新设置文本\r\n        textRef.value.innerText = text;\r\n\r\n        // 指定高度\r\n        specifiedHeight(height);\r\n      }\r\n    };\r\n\r\n    // 设置文本节点文本\r\n    const setTextInnerText = () => {\r\n      // 计算后显示的text\r\n      textRef.value.innerText = data.computedText;\r\n    };\r\n\r\n    // watch\r\n\r\n    // 监听计算后显示的text\r\n    watch(\r\n      () => data.computedText,\r\n      (value) => {\r\n        if (value) {\r\n          data.computedReady = true;\r\n\r\n          // 设置文本节点文本\r\n          setTextInnerText();\r\n        }\r\n      }\r\n    );\r\n\r\n    // 监听按照指定长度截取\r\n    watch(\r\n      () => props.length,\r\n      () => {\r\n        init();\r\n      }\r\n    );\r\n\r\n    // 监听限制的高度\r\n    watch(\r\n      () => props.height,\r\n      () => {\r\n        init();\r\n      }\r\n    );\r\n\r\n    // 监听是否禁用省略\r\n    watch(\r\n      () => props.disabled,\r\n      () => {\r\n        init();\r\n      }\r\n    );\r\n\r\n    // 监听限制行数\r\n    watch(\r\n      () => props.lines,\r\n      () => {\r\n        init();\r\n      }\r\n    );\r\n\r\n    // onMounted\r\n    onMounted(() => {\r\n      // 初始化\r\n      init();\r\n\r\n      // 是否自动根据外层宽度动态改变\r\n      if (props.autoResize && props.height) {\r\n        // window resize\r\n        useEventListener('resize', autoResizeHeight);\r\n      }\r\n    });\r\n\r\n    return {\r\n      prefixCls,\r\n\r\n      // dom\r\n      wrapper,\r\n      textRef,\r\n      moreRef,\r\n\r\n      // data\r\n      data,\r\n    };\r\n  },\r\n  components: {\r\n    IvueTooltip,\r\n  },\r\n});\r\n</script>\r\n"],"names":["_resolveComponent","_openBlock","_createElementBlock","_normalizeClass","_Fragment","_createCommentVNode","_withCtx","_createElementVNode","_toDisplayString","_withDirectives","_vShow"],"mappings":"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"}