context-menu.svelte 970 B

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. <script lang="ts">
  2. import { clickOutside } from '$lib/utils/click-outside';
  3. import { createEventDispatcher } from 'svelte';
  4. import { quintOut } from 'svelte/easing';
  5. import { slide } from 'svelte/transition';
  6. /**
  7. * x coordiante of the context menu.
  8. * @type {number}
  9. */
  10. export let x: number = 0;
  11. /**
  12. * x coordiante of the context menu.
  13. * @type {number}
  14. */
  15. export let y: number = 0;
  16. const dispatch = createEventDispatcher();
  17. let menuEl: HTMLElement;
  18. $: (() => {
  19. if (!menuEl) return;
  20. const rect = menuEl.getBoundingClientRect();
  21. x = Math.min(window.innerWidth - rect.width, x);
  22. if (y > window.innerHeight - rect.height) {
  23. y -= rect.height;
  24. }
  25. })();
  26. </script>
  27. <div
  28. transition:slide={{ duration: 200, easing: quintOut }}
  29. bind:this={menuEl}
  30. class="absolute bg-white w-[175px] z-[99999] rounded-lg shadow-md"
  31. style={`top: ${y}px; left: ${x}px;`}
  32. use:clickOutside
  33. on:out-click={() => dispatch('clickoutside')}
  34. >
  35. <slot />
  36. </div>