cl-badge.uvue 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. <template>
  2. <view
  3. class="cl-badge"
  4. :class="[
  5. {
  6. 'bg-primary-500': type == 'primary',
  7. 'bg-green-500': type == 'success',
  8. 'bg-yellow-500': type == 'warn',
  9. 'bg-red-500': type == 'error',
  10. 'bg-surface-500': type == 'info',
  11. 'cl-badge--dot': dot,
  12. 'cl-badge--position': position
  13. },
  14. pt.className
  15. ]"
  16. :style="badgeStyle"
  17. >
  18. <cl-text
  19. :pt="{
  20. className: parseClass(['cl-badge__text', pt.text?.className])
  21. }"
  22. v-if="!dot"
  23. >
  24. {{ value }}
  25. </cl-text>
  26. <slot></slot>
  27. </view>
  28. </template>
  29. <script setup lang="ts">
  30. import { computed } from "vue";
  31. import type { PropType } from "vue";
  32. import type { PassThroughProps, Type } from "../../types";
  33. import { parseClass, parsePt } from "@/cool";
  34. import { useSize } from "../../hooks";
  35. defineOptions({
  36. name: "cl-badge"
  37. });
  38. const props = defineProps({
  39. pt: {
  40. type: Object,
  41. default: () => ({})
  42. },
  43. type: {
  44. type: String as PropType<Type>,
  45. default: "error"
  46. },
  47. dot: {
  48. type: Boolean,
  49. default: false
  50. },
  51. value: {
  52. type: [Number, String],
  53. default: 0
  54. },
  55. position: {
  56. type: Boolean,
  57. default: false
  58. }
  59. });
  60. const { getRpx } = useSize();
  61. type PassThrough = {
  62. className?: string;
  63. text?: PassThroughProps;
  64. };
  65. const pt = computed(() => parsePt<PassThrough>(props.pt));
  66. const badgeStyle = computed(() => {
  67. const style = {};
  68. if (props.dot) {
  69. style["height"] = getRpx(10);
  70. style["width"] = getRpx(10);
  71. style["minWidth"] = getRpx(10);
  72. style["padding"] = 0;
  73. } else {
  74. style["height"] = getRpx(30);
  75. style["minWidth"] = getRpx(30);
  76. style["padding"] = `0 ${getRpx(6)}`;
  77. }
  78. if (props.position) {
  79. style["transform"] = "translate(50%, -50%)";
  80. if (props.dot) {
  81. style["transform"] = `translate(-${getRpx(5)}, ${getRpx(5)})`;
  82. }
  83. }
  84. return style;
  85. });
  86. </script>
  87. <style lang="scss" scoped>
  88. .cl-badge {
  89. @apply flex flex-row items-center justify-center;
  90. @apply rounded-full;
  91. &__text {
  92. @apply text-white text-sm;
  93. }
  94. &--position {
  95. @apply absolute z-10 right-0 top-0;
  96. }
  97. }
  98. </style>