useCollapseHandler.ts 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. // Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/
  2. import { useLocalStorage } from '@vueuse/core'
  3. import { onMounted, type Ref, ref, watch } from 'vue'
  4. import emitter from '#shared/utils/emitter.ts'
  5. import type { CollapseOptions, CollapseEmit } from './types.ts'
  6. /**
  7. * @args emit - The emit function from the setup function
  8. * @args options.storageKey - The key to store the collapse state in local storage
  9. * * */
  10. export const useCollapseHandler = (
  11. emit: CollapseEmit,
  12. options?: CollapseOptions,
  13. ) => {
  14. let isCollapsed: Ref<boolean>
  15. if (options?.storageKey) {
  16. isCollapsed = useLocalStorage(options.storageKey, false)
  17. } else {
  18. isCollapsed = ref(false)
  19. }
  20. const callEmit = () =>
  21. isCollapsed.value ? emit('collapse', true) : emit('expand', true)
  22. const toggleCollapse = () => {
  23. isCollapsed.value = !isCollapsed.value
  24. callEmit()
  25. }
  26. emitter.on('expand-collapsed-content', (name: string) => {
  27. if (options?.name === name && isCollapsed.value) toggleCollapse()
  28. })
  29. onMounted(() => {
  30. // Set up watcher on the local storage value, so other browser tabs can sync their collapse states.
  31. if (options?.storageKey) {
  32. watch(
  33. isCollapsed,
  34. () => {
  35. callEmit()
  36. },
  37. {
  38. immediate: true,
  39. },
  40. )
  41. }
  42. })
  43. return {
  44. isCollapsed,
  45. toggleCollapse,
  46. }
  47. }