index.vue 3.75 KB
<template>
  <div class="zui-tag" @click="onClick">
    <template v-if="showQuarter">
      <div :class="computedClass">
        <div class="quarter-content">
          <slot></slot>
        </div>
        <div class="quarter-bg" :style="colorStyle"></div>
      </div>
    </template>
    <template v-else-if="showCoupon">
      <div :class="computedClass">
        <div class="coupon-container" :style="colorStyle">
          <div class="left-coupon" :style="leftCoupon" v-if="showCoupon"></div>
          <slot></slot>
          <div class="right-coupon" :style="rightCoupon" v-if="showCoupon"></div>
        </div>
      </div>
    </template>
    <template v-else>
      <div :class="computedClass" :style="[colorStyle, sizeStyle]">
        <slot></slot>
      </div>
    </template>
  </div>
</template>

<script>
export default {
  name: 'Tag',
  props: {
    size: {
      type: String, // tiny, small, large
      default: 'large',
    },
    shape: {
      // square, circle, fillet, quarter, coupon, bubble
      type: String,
      default: 'square',
    },
    sharp: {
      // top-left, top-right, bottom-left, bottom-right
      type: String,
      default: '',
    },
    type: {
      // fill ghost
      type: String,
      default: 'ghost',
    },
    fillColor: {
      type: String,
      default: '',
    },
    fontWeight: {
      // normal, bold, bolder
      type: String,
      default: 'normal',
    },
    fontColor: {
      type: String,
      default: '',
    },
    dotSize: String,
    radius: String,
  },
  data: function () {
    return {
      sizeStyle: {},
    };
  },
  mounted: function () {
    this.$nextTick(function () {
      if (this.shape == 'circle') {
        var radius = this.$el.offsetHeight / 2;
        this.$set(this.sizeStyle, 'paddingLeft', radius / 2 + 'px');
        this.$set(this.sizeStyle, 'paddingRight', radius / 2 + 'px');
        this.$set(this.sizeStyle, 'borderRadius', radius + 'px');
        if (this.sharp) {
          this.$set(this.sizeStyle, this.transformCamelCase('border-' + this.sharp + '-radius'), 0);
        }
      }
    });
  },
  computed: {
    computedClass: function () {
      return ['default', 'size-' + this.size, 'shape-' + this.shape, 'type-' + this.type, 'font-weight-' + this.fontWeight];
    },
    colorStyle: function () {
      var style = {};
      if (this.type == 'fill') {
        // eslint-disable-next-line
        style.background = this.fillColor || '#ff5151';
      }
      if (this.shape == 'dot') {
        style.height = this.dotSize;
        style.width = this.dotSize;
        style.display = 'flex';
        style.alignItems = 'center';
        style.justifyContent = 'center';
      }
      if (this.fontColor) {
        if (this.type == 'ghost') {
          style.borderColor = this.fontColor;
        }
        style.color = this.fontColor;
      }
      if (this.radius) {
        style.borderRadius = this.radius;
      }
      return style;
    },
    leftCoupon: function () {
      return {
        background: this.fillColor ? 'radial-gradient(circle at left, transparent 33%, ' + this.fillColor + ' 33%)' : '',
      };
    },
    rightCoupon: function () {
      return {
        background: this.fillColor ? 'radial-gradient(circle at right, transparent 33%, ' + this.fillColor + ' 33%)' : '',
      };
    },
    showQuarter: function () {
      return this.shape == 'quarter';
    },
    showCoupon: function () {
      return this.shape == 'coupon';
    },
  },
  methods: {
    transformCamelCase: function (str) {
      var re = /-(\w)/g;
      return str.replace(re, function ($0, $1) {
        return $1.toUpperCase();
      });
    },
    onClick: function () {
      if (this.$listeners['click']) {
        this.$emit('click');
      }
    },
  },
};
</script>

<style>
@import './index.css';
</style>