CommonButton.vue 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. <!-- Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <script setup lang="ts">
  3. import { startCase } from 'lodash-es'
  4. import { computed } from 'vue'
  5. import type { CommonButtonProps } from '#mobile/components/CommonButton/types.ts'
  6. const props = withDefaults(defineProps<CommonButtonProps>(), {
  7. type: 'button',
  8. variant: 'secondary',
  9. size: 'medium',
  10. })
  11. const transparentBackgroundClasses = computed(() => {
  12. if (props.transparentBackground) return ['rounded-none', 'bg-transparent']
  13. return ['rounded-xl']
  14. })
  15. const variantClasses = computed(() => {
  16. switch (props.variant) {
  17. case 'primary':
  18. if (props.transparentBackground) return ['text-blue']
  19. return ['bg-blue', 'text-white']
  20. case 'submit':
  21. if (props.transparentBackground) return ['font-semibold', 'text-yellow']
  22. return ['bg-yellow', 'font-semibold', 'text-black-full']
  23. case 'danger':
  24. if (props.transparentBackground) return ['text-red-bright']
  25. return ['bg-red-dark', 'text-red-bright']
  26. case 'secondary':
  27. default:
  28. if (props.transparentBackground) return ['text-white']
  29. return ['bg-gray-500', 'text-white']
  30. }
  31. })
  32. const sizeClasses = computed(() => {
  33. switch (props.size) {
  34. case 'small':
  35. return ['btn-sm', 'text-sm']
  36. case 'medium':
  37. default:
  38. return ['btn-md', 'text-base']
  39. }
  40. })
  41. const iconSizeClass = computed(() => {
  42. switch (props.size) {
  43. case 'small':
  44. return 'tiny'
  45. case 'medium':
  46. default:
  47. return 'small'
  48. }
  49. })
  50. </script>
  51. <template>
  52. <button
  53. :type="type"
  54. :form="form"
  55. :disabled="disabled"
  56. class="inline-flex flex-shrink-0 flex-nowrap items-center justify-center gap-x-1 border-0"
  57. :class="[
  58. ...transparentBackgroundClasses,
  59. ...variantClasses,
  60. ...sizeClasses,
  61. {
  62. 'opacity-50': disabled,
  63. },
  64. ]"
  65. >
  66. <CommonIcon
  67. v-if="prefixIcon"
  68. class="shrink-0"
  69. decorative
  70. :size="iconSizeClass"
  71. :name="prefixIcon"
  72. />
  73. <CommonIcon
  74. v-if="icon"
  75. class="shrink-0"
  76. :size="iconSizeClass"
  77. decorative
  78. :name="icon"
  79. />
  80. <span v-else class="truncate"
  81. ><slot>{{ $t(startCase(variant)) }}</slot></span
  82. >
  83. <CommonIcon
  84. v-if="suffixIcon"
  85. class="shrink-0"
  86. decorative
  87. :size="iconSizeClass"
  88. :name="suffixIcon"
  89. />
  90. </button>
  91. </template>