Skip to content

Commit b38d076

Browse files
committed
begin working on context menu
1 parent c5b1405 commit b38d076

File tree

4 files changed

+84
-26
lines changed

4 files changed

+84
-26
lines changed

package-lock.json

Lines changed: 1 addition & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,7 @@ button {
9797
@apply bg-zinc-700;
9898
font-family: "Lexend", sans-serif;
9999
}
100+
101+
.ctxItem {
102+
@apply flex space-x-2 items-center px-3 py-1.5 hover:bg-white/10;
103+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<script lang="ts">
2+
// Icons
3+
import IconCut from "~icons/tabler/cut";
4+
import IconCopy from "~icons/tabler/copy";
5+
import IconPaste from "~icons/tabler/clipboard";
6+
import IconClearFormatting from "~icons/tabler/clear-formatting";
7+
import IconLowercase from "~icons/tabler/letter-case-lower";
8+
import IconUppercase from "~icons/tabler/letter-case-upper";
9+
import IconItalic from "~icons/tabler/italic";
10+
11+
let pos = { x: 0, y: 0 };
12+
let browser = { h:0, w:0 };
13+
let menu = { h: 0, w: 0 };
14+
let showMenu = false;
15+
16+
function onOpen(e: MouseEvent){
17+
e.preventDefault()
18+
showMenu = true
19+
browser = {
20+
w: window.innerWidth,
21+
h: window.innerHeight
22+
};
23+
pos = {
24+
x: e.clientX,
25+
y: e.clientY
26+
};
27+
// If bottom part of context menu will be displayed
28+
// after right-click, then change the position of the
29+
// context menu. This position is controlled by `top` and `left`
30+
// at inline style.
31+
// Instead of context menu is displayed from top left of cursor position
32+
// when right-click occur, it will be displayed from bottom left.
33+
if (browser.h - pos.y < menu.h)
34+
pos.y = pos.y - menu.h
35+
if (browser.w - pos.x < menu.w)
36+
pos.x = pos.x - menu.w
37+
}
38+
39+
function getContextMenuDimension(node: HTMLDivElement){
40+
// This function will get context menu dimension
41+
// when navigation is shown => showMenu = true
42+
let height = node.offsetHeight
43+
let width = node.offsetWidth
44+
menu = {
45+
h: height,
46+
w: width
47+
}
48+
}
49+
</script>
50+
51+
{#if showMenu}
52+
<div use:getContextMenuDimension class="z-10 bg-zinc-900 rounded-lg absolute top-32 left-32 text-sm">
53+
<div class="flex flex-col">
54+
<button class="ctxItem"><IconCut /><span>Cut</span></button>
55+
<button class="ctxItem"><IconCopy /><span>Copy</span></button>
56+
<button class="ctxItem"><IconPaste /><span>Paste</span></button>
57+
<hr class="text-zinc-800" />
58+
<button class="ctxItem"><IconCopy /><span>Copy Formatting</span></button>
59+
<button class="ctxItem"><IconClearFormatting /><span>Clear Formatting</span></button>
60+
<hr class="text-zinc-800" />
61+
<button class="ctxItem"><IconLowercase /><span>Convert to lowercase</span></button>
62+
<button class="ctxItem"><IconUppercase /><span>Convert to uppercase</span></button>
63+
</div>
64+
</div>
65+
{/if}

src/routes/+page.svelte

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,24 @@
1818
AtlasObjectNode,
1919
PlayerObjectNode,
2020
} from "$lib/tiptap/extensions/index";
21+
2122
// Components
2223
import Modal from "$lib/components/Modal.svelte";
2324
import MiniEditor from "$lib/components/text/MiniEditor.svelte";
2425
import MiniRenderer from "$lib/components/text/MiniRenderer.svelte";
2526
import ColorPicker from "svelte-awesome-color-picker";
27+
import TextStyleButtons from "$lib/components/text/TextStyleButtons.svelte";
28+
import ToolbarButton from "$lib/components/text/ToolbarButton.svelte";
29+
import ContextMenu from "$lib/components/text/ContextMenu.svelte";
2630
31+
// Important functions things
2732
import { convertToTextOrEmpty, snbtToDocument } from "$lib/text/nbt";
2833
import { Editor, type JSONContent } from "@tiptap/core";
2934
import Color from "@tiptap/extension-color";
3035
import Placeholder from "@tiptap/extension-placeholder";
3136
import StarterKit from "@tiptap/starter-kit";
3237
import { onDestroy, onMount } from "svelte";
38+
3339
// Icons
3440
import IconUndo from "~icons/tabler/arrow-back-up";
3541
import IconRedo from "~icons/tabler/arrow-forward-up";
@@ -48,12 +54,9 @@
4854
import IconSquare from "~icons/tabler/square-filled";
4955
import IconHollow from "~icons/tabler/square-x";
5056
57+
// Random variables
5158
import { page } from "$app/state";
52-
53-
import TextStyleButtons from "$lib/components/text/TextStyleButtons.svelte";
5459
import { colorMap } from "$lib/text/general";
55-
56-
import ToolbarButton from "$lib/components/text/ToolbarButton.svelte";
5760
import { openDataStore } from "$lib/db";
5861
import { fontLUT } from "$lib/tiptap/extensions/fonts";
5962
import { tooltip } from "$lib/tooltip";
@@ -73,6 +76,8 @@
7376
let doesContentExist: boolean = $state(false);
7477
let shouldOptimise = $state(true);
7578
79+
let editorCtxMenu: ContextMenu | undefined = $state()!;
80+
7681
// Import
7782
let importDialog: Modal = $state()!;
7883
let importText: string = $state("");
@@ -541,8 +546,10 @@
541546
</div>
542547

543548
<div
549+
role="none"
544550
class="font-minecraft w-full grow overflow-auto bg-zinc-800 first:focus:outline-none"
545551
spellcheck="false"
552+
oncontextmenu={editorCtxMenu!.onOpen}
546553
bind:this={element}>
547554
</div>
548555

@@ -567,7 +574,7 @@
567574
recentlyCopied = true;
568575
setTimeout(() => (recentlyCopied = false), 2000);
569576
}}
570-
aria-label="Copy">
577+
aria-label="Copy output">
571578
{#if recentlyCopied}
572579
<IconTick />
573580
{:else}
@@ -825,3 +832,5 @@
825832
<modal.default editor={editor!} bind:unicodeSelectorDialog />
826833
{/await}
827834
</div>
835+
836+
<ContextMenu bind:this={editorCtxMenu} />

0 commit comments

Comments
 (0)