cl-badge.uvue 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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. :size="10"
  20. :pt="{
  21. className: parseClass(['cl-badge__text text-white', pt.text?.className])
  22. }"
  23. v-if="!dot"
  24. >
  25. {{ value }}
  26. </cl-text>
  27. <slot></slot>
  28. </view>
  29. </template>
  30. <script setup lang="ts">
  31. import { computed } from "vue";
  32. import type { PropType } from "vue";
  33. import type { PassThroughProps, Type } from "../../types";
  34. import { parseClass, parsePt } from "@/.cool";
  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. type PassThrough = {
  61. className?: string;
  62. text?: PassThroughProps;
  63. };
  64. const pt = computed(() => parsePt<PassThrough>(props.pt));
  65. const badgeStyle = computed(() => {
  66. const style = {};
  67. if (props.dot) {
  68. style["height"] = "5px";
  69. style["width"] = "5px";
  70. style["minWidth"] = "5px";
  71. style["padding"] = 0;
  72. } else {
  73. style["height"] = "14px";
  74. style["minWidth"] = "14px";
  75. style["padding"] = "0 3px";
  76. }
  77. if (props.position) {
  78. style["transform"] = "translate(50%, -50%)";
  79. if (props.dot) {
  80. style["transform"] = `translate(-3px, 3px)`;
  81. }
  82. }
  83. return style;
  84. });
  85. </script>
  86. <style lang="scss" scoped>
  87. .cl-badge {
  88. @apply flex flex-row items-center justify-center;
  89. @apply rounded-full;
  90. &--position {
  91. @apply absolute z-10 right-0 top-0;
  92. }
  93. }
  94. </style>