CollapseButton.vue 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. <!-- Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <script setup lang="ts">
  3. import { computed } from 'vue'
  4. import { useTouchDevice } from '#shared/composables/useTouchDevice.ts'
  5. import { EnumTextDirection } from '#shared/graphql/types.ts'
  6. import { useLocaleStore } from '#shared/stores/locale.ts'
  7. import CommonButton from '#desktop/components/CommonButton/CommonButton.vue'
  8. const { isTouchDevice } = useTouchDevice()
  9. interface Props {
  10. ownerId: string
  11. isCollapsed?: boolean
  12. group?: 'heading' | 'sidebar'
  13. orientation?: 'horizontal' | 'vertical'
  14. inverse?: boolean
  15. }
  16. const props = withDefaults(defineProps<Props>(), {
  17. orientation: 'horizontal',
  18. isCollapsed: false,
  19. })
  20. defineEmits<{
  21. 'toggle-collapse': [MouseEvent]
  22. }>()
  23. const locale = useLocaleStore()
  24. const collapseButtonIcon = computed(() => {
  25. if (props.orientation === 'vertical')
  26. return props.isCollapsed ? 'arrows-expand' : 'arrows-collapse'
  27. if (
  28. (props.inverse && locale.localeData?.dir !== EnumTextDirection.Rtl) ||
  29. (!props.inverse && locale.localeData?.dir === EnumTextDirection.Rtl)
  30. )
  31. return props.isCollapsed ? 'arrow-bar-left' : 'arrow-bar-right'
  32. return props.isCollapsed ? 'arrow-bar-right' : 'arrow-bar-left'
  33. })
  34. const parentGroupClass = computed(() => {
  35. // Tailwindcss must be able to scan the class names to generate CSS
  36. // https://tailwindcss.com/docs/content-configuration#dynamic-class-names
  37. switch (props.group) {
  38. case 'heading':
  39. return 'group-hover/heading:opacity-100'
  40. case 'sidebar':
  41. return 'group-hover/sidebar:opacity-100'
  42. default:
  43. return ''
  44. }
  45. })
  46. </script>
  47. <template>
  48. <div>
  49. <CommonButton
  50. v-tooltip="
  51. props.isCollapsed
  52. ? $t('Expand this element')
  53. : $t('Collapse this element')
  54. "
  55. :class="[
  56. { 'opacity-0 transition-opacity': !isTouchDevice && parentGroupClass },
  57. 'focus:opacity-100',
  58. parentGroupClass,
  59. ]"
  60. class="collapse-button"
  61. :icon="collapseButtonIcon"
  62. :aria-expanded="!props.isCollapsed"
  63. :aria-controls="ownerId"
  64. :aria-label="
  65. props.isCollapsed
  66. ? $t('Expand this element')
  67. : $t('Collapse this element')
  68. "
  69. size="small"
  70. variant="subtle"
  71. @click="$emit('toggle-collapse', $event)"
  72. />
  73. </div>
  74. </template>