Folder.svelte 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. <script>
  2. import { getContext, createEventDispatcher, onMount, onDestroy } from 'svelte';
  3. const i18n = getContext('i18n');
  4. const dispatch = createEventDispatcher();
  5. import ChevronDown from '../icons/ChevronDown.svelte';
  6. import ChevronRight from '../icons/ChevronRight.svelte';
  7. import Collapsible from './Collapsible.svelte';
  8. export let open = true;
  9. export let id = '';
  10. export let name = '';
  11. export let collapsible = true;
  12. let folderElement;
  13. let dragged = false;
  14. const onDragOver = (e) => {
  15. e.preventDefault();
  16. dragged = true;
  17. };
  18. const onDrop = (e) => {
  19. e.preventDefault();
  20. if (folderElement.contains(e.target)) {
  21. console.log('Dropped on the Button');
  22. // get data from the drag event
  23. const dataTransfer = e.dataTransfer.getData('text/plain');
  24. const data = JSON.parse(dataTransfer);
  25. console.log(data);
  26. dispatch('drop', data);
  27. dragged = false;
  28. }
  29. };
  30. const onDragLeave = (e) => {
  31. e.preventDefault();
  32. dragged = false;
  33. };
  34. onMount(() => {
  35. folderElement.addEventListener('dragover', onDragOver);
  36. folderElement.addEventListener('drop', onDrop);
  37. folderElement.addEventListener('dragleave', onDragLeave);
  38. });
  39. onDestroy(() => {
  40. folderElement.addEventListener('dragover', onDragOver);
  41. folderElement.removeEventListener('drop', onDrop);
  42. folderElement.removeEventListener('dragleave', onDragLeave);
  43. });
  44. </script>
  45. <div bind:this={folderElement} class="relative">
  46. {#if dragged}
  47. <div
  48. class="absolute top-0 left-0 w-full h-full rounded-sm bg-gray-200 bg-opacity-50 dark:bg-opacity-10 z-50 pointer-events-none touch-none"
  49. ></div>
  50. {/if}
  51. {#if collapsible}
  52. <Collapsible
  53. bind:open
  54. className="w-full "
  55. buttonClassName="w-full"
  56. on:change={(e) => {
  57. dispatch('change', e.detail);
  58. }}
  59. >
  60. <!-- svelte-ignore a11y-no-static-element-interactions -->
  61. <div class="mx-2 w-full">
  62. <button
  63. class="w-full py-1 px-1.5 rounded-md flex items-center gap-1 text-xs text-gray-500 dark:text-gray-500 font-medium hover:bg-gray-100 dark:hover:bg-gray-900 transition"
  64. >
  65. <div class="text-gray-300">
  66. {#if open}
  67. <ChevronDown className=" size-3" strokeWidth="2.5" />
  68. {:else}
  69. <ChevronRight className=" size-3" strokeWidth="2.5" />
  70. {/if}
  71. </div>
  72. <div class="translate-y-[0.5px]">
  73. {name}
  74. </div>
  75. </button>
  76. </div>
  77. <div slot="content">
  78. <slot></slot>
  79. </div>
  80. </Collapsible>
  81. {:else}
  82. <slot></slot>
  83. {/if}
  84. </div>