<template>
  <div
    v-if="!showAllContent"
    ref="textRef"
    class="g-text"
    :class="{ 'is-ellipse': finalConfig?.ellipse }"
    :style="{ '-webkit-line-clamp': finalConfig?.line }"
  >
    <d-tooltip :position="position" :disabled="!content || !finalConfig?.tooltip" :content="content">
      <slot></slot>
    </d-tooltip>
    <div v-if="finalConfig.showAll && !showAllContent && isOver" class="watch-all" @click="onShowAll">查看全部</div>
  </div>
  <div class="g-text-all" v-else-if="showAllContent && finalConfig.showAll">
    <slot></slot>
  </div>
</template>

<script lang="ts">
export default {
  name: 'GText'
};
</script>

<script setup lang="ts">
import { ref, onUnmounted, computed } from 'vue';
import { useMutationObserver, useResizeObserver } from '@vueuse/core';
const props = withDefaults(defineProps<{
  config?: {
    ellipse?: boolean;
    line?: number;
    tooltip?: boolean;
    showAll?: boolean;
  },
  position?: string[];
}>(), {
  config: () => ({
    ellipse: true,
    line: 1,
    tooltip: true,
    showAll: false
  }),
  position: () => ['top']
});

const textRef = ref(null);
const isOver = ref(false);
const content = ref('');

const showAllContent = ref(false);
const onShowAll = () => {
  showAllContent.value = true;
};

const finalConfig = computed(() => {
  return Object.assign({}, {
    ellipse: true,
    line: 1,
    tooltip: true,
    showAll: false
  }, props.config);
});

const checkTextRange = () => {
  if (!textRef.value) return false;
  isOver.value = textRef.value.scrollHeight > textRef.value.clientHeight;
  if (isOver.value) {
    content.value = textRef.value.innerText || '';
  }
};

const { stop } = useMutationObserver(textRef, (mutations) => {
  if (mutations[0]) {
    checkTextRange();
  }
}, {
  attributes: true,
  childList: true,
  subtree: true,
  characterData: true
});

const { stop: stop2 } = useResizeObserver(textRef, () => {
  checkTextRange();
});

onUnmounted(() => {
  stop();
  stop2();
});
</script>

<style scoped lang="scss">
.g-text {
  position: relative;
  display: inline-block;
  &.is-ellipse {
    display: -webkit-box;
    overflow: hidden;
    text-overflow: ellipsis;
    word-break: break-all;
    -webkit-box-orient: vertical;
  }
  &-all {
    display: inline-block;
    word-break: break-all;
  }
  &:hover {
    .watch-all {
      display: block;
    }
  }
}
.watch-all {
  position: absolute;
  right: 0;
  bottom: 0;
  z-index: 2;
  background-color: var(--devui-global-bg, #f6f6f8);
  padding: 2px 0 0 2px;
  color: var(--color-CG600);
  display: none;
  &:hover {
    cursor: pointer;
  }
}
</style>
