Skip to content

Instantly share code, notes, and snippets.

@komietty
Last active July 14, 2021 10:19
Show Gist options
  • Save komietty/f4bf487d149bb4f3f7b9ab2160602293 to your computer and use it in GitHub Desktop.
Save komietty/f4bf487d149bb4f3f7b9ab2160602293 to your computer and use it in GitHub Desktop.
<script lang="ts">
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition';
export let x: number;
export let y: number;
let self: HTMLElement;
const dsp = createEventDispatcher();
const hide = (e) => { if (e.target !== self && !self.contains(e.target)) dsp('clickoutside'); }
$: ((x, y) => {
if (!self) return;
const r = self.getBoundingClientRect();
x = Math.min(window.innerWidth - r.width, x);
if (y > window.innerHeight - r.height) y -= r.height;
})(x, y);
</script>
<svelte:body on:click={hide}/>
<div transition:fade={{ duration: 100 }} bind:this={self} style="top:{y}px; left:{x}px;">
<slot/>
</div>
<style>
div {
position: fixed;
border: 1px solid #000;
background-color: white;
border-radius: 5px;
z-index: 100;
width: 150px;
}
</style>
<script lang="ts">
let menu = false;
let prm = {x: 0, y: 0};
const openmenu = async(e) => {
if (menu) await new Promise(res => setTimeout(res, 100));
prm = { x: e.clientX, y: e.clientY };
menu = true;
}
</script>
<div on:contextmenu|preventDefault={e => openmenu(e)}/>
{#if menu}
<MenuComp {...prm} on:clickoutside={e => menu = false}>
<p>any kinda modules</p>
</MenuComp>
{/if}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment