NoteMenu.svelte 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. <script lang="ts">
  2. import { DropdownMenu } from 'bits-ui';
  3. import { getContext, onMount } from 'svelte';
  4. import { flyAndScale } from '$lib/utils/transitions';
  5. import { fade, slide } from 'svelte/transition';
  6. import { showSettings, mobile, showSidebar, user } from '$lib/stores';
  7. import Tooltip from '$lib/components/common/Tooltip.svelte';
  8. import ArchiveBox from '$lib/components/icons/ArchiveBox.svelte';
  9. import Download from '$lib/components/icons/ArrowDownTray.svelte';
  10. import GarbageBin from '$lib/components/icons/GarbageBin.svelte';
  11. import DocumentDuplicate from '$lib/components/icons/DocumentDuplicate.svelte';
  12. import Share from '$lib/components/icons/Share.svelte';
  13. import Link from '$lib/components/icons/Link.svelte';
  14. const i18n = getContext('i18n');
  15. export let show = false;
  16. export let className = 'max-w-[180px]';
  17. export let onDownload = (type) => {};
  18. export let onDelete = () => {};
  19. export let onCopyLink = null;
  20. export let onCopyToClipboard = null;
  21. export let onChange = () => {};
  22. </script>
  23. <DropdownMenu.Root
  24. bind:open={show}
  25. onOpenChange={(state) => {
  26. onChange(state);
  27. }}
  28. >
  29. <DropdownMenu.Trigger>
  30. <slot />
  31. </DropdownMenu.Trigger>
  32. <slot name="content">
  33. <DropdownMenu.Content
  34. class="w-full {className} text-sm rounded-xl px-1 py-1.5 z-50 bg-white dark:bg-gray-850 dark:text-white shadow-lg font-primary"
  35. sideOffset={6}
  36. side="bottom"
  37. align="end"
  38. transition={(e) => fade(e, { duration: 100 })}
  39. >
  40. <DropdownMenu.Sub>
  41. <DropdownMenu.SubTrigger
  42. class="flex gap-2 items-center px-3 py-2 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
  43. >
  44. <Download strokeWidth="2" />
  45. <div class="flex items-center">{$i18n.t('Download')}</div>
  46. </DropdownMenu.SubTrigger>
  47. <DropdownMenu.SubContent
  48. class="w-full rounded-xl px-1 py-1.5 z-50 bg-white dark:bg-gray-850 dark:text-white shadow-lg"
  49. transition={flyAndScale}
  50. sideOffset={8}
  51. align="end"
  52. >
  53. <DropdownMenu.Item
  54. class="flex gap-2 items-center px-3 py-2 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
  55. on:click={() => {
  56. onDownload('txt');
  57. }}
  58. >
  59. <div class="flex items-center line-clamp-1">{$i18n.t('Plain text (.txt)')}</div>
  60. </DropdownMenu.Item>
  61. <DropdownMenu.Item
  62. class="flex gap-2 items-center px-3 py-2 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
  63. on:click={() => {
  64. onDownload('md');
  65. }}
  66. >
  67. <div class="flex items-center line-clamp-1">{$i18n.t('Plain text (.md)')}</div>
  68. </DropdownMenu.Item>
  69. <DropdownMenu.Item
  70. class="flex gap-2 items-center px-3 py-2 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
  71. on:click={() => {
  72. onDownload('pdf');
  73. }}
  74. >
  75. <div class="flex items-center line-clamp-1">{$i18n.t('PDF document (.pdf)')}</div>
  76. </DropdownMenu.Item>
  77. </DropdownMenu.SubContent>
  78. </DropdownMenu.Sub>
  79. {#if onCopyLink || onCopyToClipboard}
  80. <DropdownMenu.Sub>
  81. <DropdownMenu.SubTrigger
  82. class="flex gap-2 items-center px-3 py-2 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
  83. >
  84. <Share strokeWidth="2" />
  85. <div class="flex items-center">{$i18n.t('Share')}</div>
  86. </DropdownMenu.SubTrigger>
  87. <DropdownMenu.SubContent
  88. class="w-full rounded-xl px-1 py-1.5 z-50 bg-white dark:bg-gray-850 dark:text-white shadow-lg"
  89. transition={flyAndScale}
  90. sideOffset={8}
  91. align="end"
  92. >
  93. {#if onCopyLink}
  94. <DropdownMenu.Item
  95. class="flex gap-2 items-center px-3 py-2 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
  96. on:click={() => {
  97. onCopyLink();
  98. }}
  99. >
  100. <Link />
  101. <div class="flex items-center">{$i18n.t('Copy link')}</div>
  102. </DropdownMenu.Item>
  103. {/if}
  104. {#if onCopyToClipboard}
  105. <DropdownMenu.Item
  106. class="flex gap-2 items-center px-3 py-2 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
  107. on:click={() => {
  108. onCopyToClipboard();
  109. }}
  110. >
  111. <DocumentDuplicate strokeWidth="2" />
  112. <div class="flex items-center">{$i18n.t('Copy to clipboard')}</div>
  113. </DropdownMenu.Item>
  114. {/if}
  115. </DropdownMenu.SubContent>
  116. </DropdownMenu.Sub>
  117. {/if}
  118. <DropdownMenu.Item
  119. class="flex gap-2 items-center px-3 py-1.5 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
  120. on:click={() => {
  121. onDelete();
  122. }}
  123. >
  124. <GarbageBin strokeWidth="2" />
  125. <div class="flex items-center">{$i18n.t('Delete')}</div>
  126. </DropdownMenu.Item>
  127. </DropdownMenu.Content>
  128. </slot>
  129. </DropdownMenu.Root>