CommonLoader.vue 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. <!-- Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <script setup lang="ts">
  3. /* eslint-disable vue/no-v-html */
  4. import { computed } from 'vue'
  5. import type { Sizes } from '#shared/components/CommonIcon/types.ts'
  6. import { markup } from '#shared/utils/markup.ts'
  7. interface Props {
  8. loading?: boolean
  9. error?: string | null
  10. size?: Sizes
  11. noTransition?: boolean
  12. }
  13. const props = withDefaults(defineProps<Props>(), {
  14. size: 'medium',
  15. })
  16. const minHeightClass = computed(() => {
  17. switch (props.size) {
  18. case 'xs':
  19. return 'min-h-4'
  20. case 'tiny':
  21. return 'min-h-6'
  22. case 'small':
  23. return 'min-h-8'
  24. case 'base':
  25. return 'min-h-10'
  26. case 'large':
  27. return 'min-h-20'
  28. case 'xl':
  29. return 'min-h-36'
  30. case 'medium':
  31. default:
  32. return 'min-h-12'
  33. }
  34. })
  35. </script>
  36. <script lang="ts">
  37. export default {
  38. inheritAttrs: false,
  39. }
  40. </script>
  41. <template>
  42. <Transition :name="noTransition ? 'none' : 'fade'" mode="out-in">
  43. <div
  44. v-if="loading"
  45. v-bind="$attrs"
  46. class="flex items-center justify-center"
  47. :class="minHeightClass"
  48. role="status"
  49. >
  50. <CommonIcon
  51. class="fill-yellow-300"
  52. name="spinner"
  53. :size="size"
  54. animation="spin"
  55. :label="__('Loading…')"
  56. />
  57. </div>
  58. <CommonAlert v-else-if="error" v-bind="$attrs" variant="danger">
  59. <span v-html="markup($t(error))" />
  60. </CommonAlert>
  61. <slot v-else />
  62. </Transition>
  63. </template>