CommonBadge.vue 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. <!-- Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <script setup lang="ts">
  3. import { computed } from 'vue'
  4. import { getBadgeClasses } from '#shared/initializer/initializeBadgeClasses.ts'
  5. import type { BadgeSize, BadgeVariant } from './types.ts'
  6. export interface Props {
  7. variant?: BadgeVariant
  8. size?: BadgeSize
  9. tag?: 'span' | 'div'
  10. rounded?: boolean
  11. }
  12. const props = withDefaults(defineProps<Props>(), {
  13. variant: 'info',
  14. size: 'small',
  15. tag: 'span',
  16. })
  17. const sizeClasses = computed(() => {
  18. switch (props.size) {
  19. case 'large':
  20. return 'text-base'
  21. case 'medium':
  22. return 'text-sm'
  23. case 'xs':
  24. return 'text-[10px]'
  25. case 'small':
  26. default:
  27. return 'text-xs'
  28. }
  29. })
  30. const paddingClasses = computed(() => {
  31. switch (props.size) {
  32. case 'large':
  33. return ['px-4', 'py-2.5']
  34. case 'medium':
  35. return ['px-3', 'py-2']
  36. case 'xs':
  37. return ['px-1.5', 'py-0.5']
  38. case 'small':
  39. default:
  40. return ['px-2', 'py-1']
  41. }
  42. })
  43. const borderRadiusClass = computed(() => {
  44. if (props.rounded) return 'rounded-full'
  45. switch (props.size) {
  46. case 'large':
  47. return 'rounded-xl'
  48. case 'medium':
  49. return 'rounded-lg'
  50. case 'small':
  51. default:
  52. return 'rounded-md'
  53. }
  54. })
  55. const classMap = getBadgeClasses()
  56. </script>
  57. <template>
  58. <component
  59. :is="tag"
  60. class="cursor-default"
  61. :class="[
  62. classMap.base,
  63. classMap[props.variant],
  64. ...paddingClasses,
  65. sizeClasses,
  66. borderRadiusClass,
  67. ]"
  68. data-test-id="common-badge"
  69. >
  70. <slot />
  71. </component>
  72. </template>