index.vue 4.15 KB
<template>
  <n-popover
    :disabled="disabled"
    :placement="popupConfig.placement"
    trigger="click"
    raw
    @update:show="handleUpdateShow"
  >
    <template #trigger>
      <slot />
    </template>
    <div
      style="transform-origin: inherit"
      :style="`width:${popupConfig.borderWidth}px;
         height: ${popupConfig.borderHeight}px; 
         box-shadow: 0 0 10px 10px ${popupConfig.boxShadowColor};
         background:linear-gradient(to right, ${popupConfig.linearLeftColor} , ${popupConfig.linearRightColor});
         `"
    >
      <div class="popup-body">
        <div class="popup-arrow-right" :style="`border-color:${popupConfig.arrowColor}`"></div>
        <div class="popup-header-content">
          <p
            class="header-title"
            :style="`color:${popupConfig.fontColor};font-size:${popupConfig.fontSize}px;font-weight:${popupConfig.fontWeight}`"
          >
            {{ popupConfig.fontContent }}
          </p>
          <div class="header-content-graphical">
            <div class="graphical-circle-left"><Circle /></div>
            <div class="graphical-line">
              <div class="line-left" :style="`background-color:${popupConfig.lineColor}`"></div>
              <div class="line-center" :style="`background-color:${popupConfig.lineColor}`"></div>
              <div class="line-right" :style="`background-color:${popupConfig.lineColor}`"></div>
            </div>
            <div class="graphical-circle-right"><Circle /></div>
          </div>
        </div>
      </div>
      <div class="content-body">
        <div class="body" v-for="(item, index) in popupConfigData" :key="index">
          <span :style="`color:${popupConfig.labelColor};`">{{ item.label }}</span>
          <span :style="`color:${popupConfig.valueColor};`">{{ item.value }}</span>
        </div>
      </div>
    </div>
  </n-popover>
</template>

<script lang="ts" setup name="TKDialog">
import { PropType } from 'vue'
import { PopupConfigInterface, PopupConfigData } from './index.d'
import Circle from './components/Circle.vue'

defineProps({
  popupConfig: {
    type: Object as PropType<PopupConfigInterface>,
    required: true
  },
  popupConfigData: {
    type: Array as PropType<PopupConfigData[]>
  },
  w: Number,
  h: Number,
  disabled: {
    type: Boolean,
    default: false
  }
})

const emits = defineEmits(['updateShow'])

const handleUpdateShow = (show: boolean) => {
  console.log(show)
  emits('updateShow', show)
}
</script>

<style lang="scss" scoped>
@mixin base-text-ellipsis() {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  -o-text-overflow: ellipsis;
}
.popup-body {
  display: flex;
  justify-content: center;
  flex-direction: column;
  .popup-arrow-right {
    position: absolute;
    top: 15px;
    left: 10px;
    border-right: 1px solid;
    border-bottom: 1px solid;
    width: 7px;
    height: 7px;
    transform: rotate(-45deg);
    -o-transform: rotate(-45deg);
    -webkit-transform: rotate(-45deg);
    -moz-transform: rotate(-45deg);
    -ms-transform: rotate(-45deg);
  }
  .popup-header-content {
    margin: 23px;
    display: flex;
    justify-content: center;
    flex-direction: column;
    .header-title {
      @include base-text-ellipsis;
    }
    .header-content-graphical {
      display: flex;
      align-items: center;
      .graphical-circle-left {
        position: relative;
        left: -2px;
      }
      .graphical-line {
        display: flex;
        position: relative;
        .line-left {
          width: 115px;
          height: 2px;
          position: relative;
        }
        .line-center {
          width: 35px;
          height: 2px;
          transform: rotateZ(145deg);
          position: absolute;
          top: -10px;
          left: 112px;
        }
        .line-right {
          width: 50px;
          height: 2px;
          position: absolute;
          top: -20px;
          left: 143px;
        }
      }
      .graphical-circle-right {
        position: absolute;
        top: 29px;
        left: 231px;
      }
    }
  }
}
.content-body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  width: v-bind('w+"px"');
  margin: 0 15px;
  height: v-bind('h+"px"');
}
</style>