menu-badge.vue 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. <script setup lang="ts">
  2. import type { MenuRecordBadgeRaw } from '@vben-core/typings';
  3. import { computed } from 'vue';
  4. import { isValidColor } from '@vben-core/shared/color';
  5. import BadgeDot from './menu-badge-dot.vue';
  6. interface Props extends MenuRecordBadgeRaw {
  7. hasChildren?: boolean;
  8. }
  9. const props = withDefaults(defineProps<Props>(), {});
  10. const variantsMap: Record<string, string> = {
  11. default: 'bg-green-500',
  12. destructive: 'bg-destructive',
  13. primary: 'bg-primary',
  14. success: 'bg-green-500',
  15. warning: 'bg-yellow-500',
  16. };
  17. const isDot = computed(() => props.badgeType === 'dot');
  18. const badgeClass = computed(() => {
  19. const { badgeVariants } = props;
  20. if (!badgeVariants) {
  21. return variantsMap.default;
  22. }
  23. return variantsMap[badgeVariants] || badgeVariants;
  24. });
  25. const badgeStyle = computed(() => {
  26. if (badgeClass.value && isValidColor(badgeClass.value)) {
  27. return {
  28. backgroundColor: badgeClass.value,
  29. };
  30. }
  31. return {};
  32. });
  33. </script>
  34. <template>
  35. <span v-if="isDot || badge" :class="$attrs.class" class="absolute">
  36. <BadgeDot v-if="isDot" :dot-class="badgeClass" :dot-style="badgeStyle" />
  37. <div
  38. v-else
  39. :class="badgeClass"
  40. :style="badgeStyle"
  41. class="text-primary-foreground flex-center rounded-xl px-1.5 py-0.5 text-[10px]"
  42. >
  43. {{ badge }}
  44. </div>
  45. </span>
  46. </template>