HighlightMenu.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. <!-- Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <script setup lang="ts">
  3. import { storeToRefs } from 'pinia'
  4. import { onMounted, ref } from 'vue'
  5. import CommonPopover from '#shared/components/CommonPopover/CommonPopover.vue'
  6. import { usePopover } from '#shared/components/CommonPopover/usePopover.ts'
  7. import type { HightlightColor } from '#shared/composables/useColorPallet/types.ts'
  8. import { useColorPallet } from '#shared/composables/useColorPallet/useColorPallet.ts'
  9. import CommonPopoverMenu from '#desktop/components/CommonPopoverMenu/CommonPopoverMenu.vue'
  10. import type { MenuItem } from '#desktop/components/CommonPopoverMenu/types.ts'
  11. import { useThemeStore } from '#desktop/stores/theme.ts'
  12. interface ExtendedMenuItem extends MenuItem, Omit<HightlightColor, 'label'> {}
  13. const { highlightColors } = useColorPallet()
  14. const items = highlightColors.map((color) => {
  15. return {
  16. key: `${color.label}`,
  17. ...color,
  18. }
  19. })
  20. const colorLabels = highlightColors.map((color) => color.label)
  21. const color = defineModel<ExtendedMenuItem>('currentColor') // Remove if we might not need it to read it from parent
  22. const isActive = ref(false)
  23. const { popover, popoverTarget, toggle, close, isOpen } = usePopover()
  24. const { isDarkMode } = storeToRefs(useThemeStore())
  25. const selectColor = (event: ExtendedMenuItem) => {
  26. color.value = event
  27. close()
  28. isActive.value = true
  29. }
  30. const toggleHighlighterActive = () => {
  31. isActive.value = !isActive.value
  32. }
  33. onMounted(() => {
  34. color.value = items[0]
  35. })
  36. </script>
  37. <template>
  38. <div>
  39. <div class="flex items-center gap-1">
  40. <button
  41. class="flex items-center gap-2 bg-[--highlight-color]"
  42. :style="{
  43. '--highlight-color': isDarkMode
  44. ? color?.value?.dark
  45. : color?.value?.light,
  46. background: !isActive ? 'transparent' : undefined,
  47. }"
  48. @click="toggleHighlighterActive"
  49. >
  50. <CommonIcon size="xs" name="highlighter" />
  51. <CommonLabel
  52. class="rounded-sm p-1 text-xs"
  53. :class="{ 'text-black dark:text-white': isActive }"
  54. :style="{ backgroundColor: isActive ? color?.value : undefined }"
  55. >{{ $t('Highlight') }}</CommonLabel
  56. >
  57. </button>
  58. <CommonIcon
  59. ref="popoverTarget"
  60. class="cursor-pointer text-gray-100 transition-transform dark:text-neutral-400"
  61. :class="{ 'rotate-180': isOpen }"
  62. role="button"
  63. size="xs"
  64. name="chevron-down"
  65. @click="toggle(true)"
  66. />
  67. </div>
  68. <CommonPopover ref="popover" placement="arrowEnd" :owner="popoverTarget">
  69. <CommonPopoverMenu
  70. class="overflow-clip"
  71. :items="items"
  72. :popover="popover"
  73. >
  74. <template
  75. v-for="(label, index) in colorLabels"
  76. #[`item-${label}`]="item"
  77. :key="label"
  78. >
  79. <button
  80. :aria-label="$t((item as ExtendedMenuItem).name)"
  81. class="relative flex grow items-center gap-2 p-2.5 text-gray-100 outline-none dark:text-neutral-400"
  82. :class="{
  83. 'bg-blue-600 text-black dark:bg-blue-900 dark:text-white':
  84. (item as ExtendedMenuItem).id === color?.id,
  85. 'rounded-t-lg': index === 0,
  86. 'rounded-b-lg': index === colorLabels.length - 1,
  87. 'pseudo-border-b': index !== colorLabels.length - 1,
  88. }"
  89. @click="selectColor(item as ExtendedMenuItem)"
  90. >
  91. <span
  92. class="inline-block h-4 w-4"
  93. :style="{
  94. backgroundColor: (item as ExtendedMenuItem).value.light,
  95. }"
  96. />
  97. <CommonLabel class="p-1 text-current">{{ $t(label) }}</CommonLabel>
  98. <Transition name="fade">
  99. <CommonIcon
  100. v-if="(item as ExtendedMenuItem).id === color?.id"
  101. class="rtl:-order-1"
  102. size="small"
  103. name="check2"
  104. />
  105. </Transition>
  106. </button>
  107. </template>
  108. </CommonPopoverMenu>
  109. </CommonPopover>
  110. </div>
  111. </template>
  112. <style scoped>
  113. .pseudo-border-b::after {
  114. content: '';
  115. @apply absolute bottom-0 left-1/2 h-[1px] w-[calc(100%-1rem)] -translate-x-1/2 bg-neutral-100 dark:bg-gray-900;
  116. }
  117. </style>