Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
1369d09
literally the whole feature
HoodieRocks Aug 7, 2026
53377c5
thank you test suite for reminding me i left that open
HoodieRocks Aug 7, 2026
0112e12
small fixes
HoodieRocks Aug 7, 2026
78c86d9
minor saved page changes
HoodieRocks Aug 10, 2026
0374176
Merge branch 'main' of https://github.com/Datapack-Hub/text into feat…
HoodieRocks Aug 10, 2026
d43d80d
add option to export only selected text
Silabear Aug 10, 2026
7d5d82a
add settings option to hide export this button
Silabear Aug 10, 2026
c6b3ad1
fix modal errors
Silabear Aug 10, 2026
9591aa9
Merge branch 'main' of https://github.com/Datapack-Hub/text into feat…
HoodieRocks Aug 10, 2026
30fdf4f
apply padding only when overlapping events, show warning if image siz…
HoodieRocks Aug 10, 2026
bc3de10
add gap
HoodieRocks Aug 11, 2026
209fc8a
shrink max output height
Silabear Aug 11, 2026
3781057
minor toolbar changes
Silabear Aug 11, 2026
ef1ffbc
on second thoughts, this makes no sense
Silabear Aug 11, 2026
97d73a8
fix tests
Silabear Aug 11, 2026
3b5e9f5
Merge pull request #61 from Datapack-Hub/feature/image-conversion
Silabear Aug 14, 2026
f5bc359
Merge branch 'main' into feature/selection-export
Silabear Aug 14, 2026
937f136
remove commented out code
Silabear Aug 14, 2026
545569f
Merge pull request #63 from Datapack-Hub/feature/selection-export
Silabear Aug 14, 2026
64c91a2
fix: rerun optimiser to catch possible skipped merges
Silabear Aug 14, 2026
29c7aab
fix: cannot copy paste obfuscated mark
Silabear Aug 14, 2026
92d6afd
fix: add failsafe to defaultColorLUT fixes #62
Silabear Aug 14, 2026
c9c8691
fix: hover and click event borders no longer split when interrupted b…
Silabear Aug 14, 2026
c8cd646
fix from prev commit: text style now correctly applies while using in…
Silabear Aug 14, 2026
9ef0b1e
fix from prev commit: wrong variable reference
Silabear Aug 14, 2026
37ecdeb
initial welcome screen design
Silabear Aug 14, 2026
7d1c61a
welcome screen changes + style rearranging
Silabear Aug 15, 2026
73e7098
welcome screen changes
Silabear Aug 15, 2026
c1fc72b
gradient change
Silabear Aug 15, 2026
1043d80
fix: optimised components with just one object will now just output t…
Silabear Aug 15, 2026
ebf5031
fix: "block" now correctly shows instead of "entity" on the block nbt…
Silabear Aug 15, 2026
5a46116
update main image on readme.mc
Silabear Aug 15, 2026
8208912
fix tests
Silabear Aug 15, 2026
62348cc
Merge branch 'main' into feature/welcome_screen
Silabear Aug 15, 2026
2e8162d
only show welcome screen once, unless needed
Silabear Aug 16, 2026
c028c60
wording changes + style fix
Silabear Aug 16, 2026
cfd7ae5
click out of the welcome modal
Silabear Aug 16, 2026
24d35cd
fix tests
Silabear Aug 16, 2026
d442617
Merge pull request #64 from Datapack-Hub/feature/welcome_screen
Silabear Aug 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This is an online and open source Minecraft Text Component WYSIWYG editor, updat

Check it out at: https://text.datapackhub.net/

![image](https://github.com/user-attachments/assets/2c16718a-c8dd-49cc-9eb5-90167834e76e)
<img width="730" height="313" alt="image" src="https://github.com/user-attachments/assets/98a803d9-30b5-40c5-9cc0-33e54d63a78b" />

:eyes: To prove it works, the generated text from the image above is below:

Expand Down
37 changes: 37 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"@types/node": "^26.1.2",
"@types/sortablejs": "^1.15.9",
"@vitest/coverage-v8": "4.1.10",
"@vitest/ui": "^4.1.10",
"file-type": "^22.0.1",
"oxlint": "^1.77.0",
"prettier": "^3.9.6",
Expand Down
39 changes: 32 additions & 7 deletions src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ strong {
@apply text-xl;
}

.tiptap-minirenderer {
@apply h-full w-full p-2;
@apply focus:outline-none;
font-family: Minecraft;
@apply text-xl;
}

.tiptap p.is-editor-empty:first-child::before {
color: #7f7f7f;
content: attr(data-placeholder);
Expand All @@ -63,20 +70,25 @@ strong {
}

.clickEvent {
background-color: #3c3c40aa;
border-bottom: solid #ff5555 2px;
padding-top: 2px;
padding-bottom: 2px;
background-color: #45454e80;
border: solid #45454e 1px;
border-bottom: solid #a868e7 2px;
z-index: 10;
--custom-source-align: top;
padding-bottom: 1px;
}

.clickEvent:has(.hoverEvent) {
padding-bottom: 3px;
}

.hoverEvent {
background-color: #3c3c40aa;
border-bottom: solid #ffff55 2px;
padding-top: 4px;
background-color: #45454e80;
border: solid #45454e 1px;
border-bottom: solid #e57e2b 2px;
z-index: 10;
--custom-source-align: top;
padding-bottom: 1px;
}

.obfuscated {
Expand All @@ -87,6 +99,11 @@ strong {
filter: blur(3px);
}

.export-button {
@apply items-center p-1 px-1.5 bg-zinc-900 text-zinc-200 hover:text-white rounded-md font-lexend text-xs h-6;
@apply w-0 invisible sm:w-fit sm:visible; /* hide on mobile */
}

/* Useful */

.nomob {
Expand All @@ -103,6 +120,14 @@ strong {
@apply rounded-md p-1 text-lg font-medium hover:bg-white/3;
}

.input-basic {
@apply rounded-md bg-zinc-900 p-2;
}

.link {
@apply font-bold underline;
}

.tippy-box[data-theme~="dph"] {
background-color: var(--color-zinc-700);
font-family: "Lexend", sans-serif;
Expand Down
8 changes: 3 additions & 5 deletions src/lib/components/TopUI.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import IconUpload from "~icons/tabler/upload";
import IconSettings from "~icons/tabler/settings";

const { editor }: { editor: Editor | undefined } = $props();
let { editor, welcomeScreenVisible = $bindable() }: { editor: Editor | undefined, welcomeScreenVisible: boolean } = $props();

let snapshots = $state<object[]>([]);
let importText: string = $state("");
Expand All @@ -28,18 +28,16 @@

function importToEditor() {
const jsonContent = snbtToDocument(convertToTextOrEmpty(importText));
console.log("importing to editor", jsonContent);
editor?.commands.setContent(jsonContent, { emitUpdate: true });
importDialog?.close();
console.log("imported to editor");
}
</script>

<div class="flex w-full items-center bg-zinc-950 text-sm text-zinc-300" style="font-family: Lexend">
<div class="flex items-center px-3 py-2 hover:bg-white/3">
<button class="flex items-center px-3 py-2 hover:bg-white/3" onclick={() => welcomeScreenVisible = true}>
<img src="/dph.svg" class="size-5" alt="logo" height="20" width="20" />
<span class="nomob ml-2 font-semibold">Minecraft Text Editor</span>
</div>
</button>
<button
class="flex items-center space-x-[0.45rem] px-[0.6rem] py-2 hover:bg-white/3"
onclick={importDialog?.open}>
Expand Down
105 changes: 105 additions & 0 deletions src/lib/components/WelcomeScreen.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<script lang="ts">
import IconImport from "~icons/tabler/upload";
import IconGradient from "~icons/tabler/contrast-2";
import IconLore from "~icons/tabler/swords";
import IconCode from "~icons/tabler/code";
import IconClose from "~icons/tabler/X"
import { onMount } from "svelte";
import { welcomeScreenFormat } from "$lib/globals";

let { visible = $bindable(false) }: { visible: boolean } = $props()

function handleKeydown(event: KeyboardEvent) {
if (event.key === "Escape" && visible) {
visible = false;
}
}

onMount(() => {
let seenWelcome = localStorage.getItem("seen_welcome")
if (seenWelcome && seenWelcome == welcomeScreenFormat) {
visible = false
} else {
visible = true
localStorage.setItem("seen_welcome", welcomeScreenFormat);
}
})
</script>

<svelte:window onkeydown={handleKeydown} />

{#if visible}
<div class="absolute">
<div
class="fixed top-0 left-0 z-40 flex h-screen w-screen flex-col items-center overflow-auto bg-black/65 text-zinc-100"
style="font-family: Lexend">
<div
aria-hidden="true"
onclick={() => visible = false}
class="fixed top-0 left-0 z-40 h-screen w-screen bg-transparent"
tabindex="-1">
</div>
<div
class="z-50 w-[95%] md:w-[50%] 2xl:w-[40%] m-auto py-4">
<div class="flex items-center rounded-t-lg bg-zinc-900 p-2 text-xl">
<img src="/dph.svg" class="h-8 ml-1 " alt="logo" />
<span class="text-lg font-black m-2 bg-linear-to-r from-red-500 to-yellow-500 bg-clip-text text-transparent">Minecraft Text Editor</span>
<div class="grow"></div>
<button aria-label="close" class="p-2 hover:bg-black/15 rounded-md" onclick={() => visible = false}><IconClose /></button>
</div>
<div class="rounded-b-lg px-4 pb-4 flex flex-col space-y-1 bg-zinc-900">
<h1 class="font-black">Welcome! </h1>
<p class="text-zinc-300 text-sm">With this tool, you can easily generate text components for Minecraft datapacks, tellraw commands, and more. Here's what makes us unique:</p>

<div class="grid grid-cols-1 lg:grid-cols-2 gap-2 mt-2">

<div class="flex items-center space-x-2 bg-green-500/20 text-zinc-200 rounded-md border-green-500 p-2 border-2 shadow-xl drop-shadow-lg">
<IconImport class="w-[7.5%] lg:w-1/10" />
<div class="flex flex-col space-y-1 my-1 w-[92.5%] lg:w-9/10">
<span class="uppercase text-xs text-green-500 font-bold">Import</span>
<span class="text-sm text-green-100">Import text components from any version into the editor.</span>
</div>
</div>

<div class="flex items-center space-x-2 bg-rose-500/20 text-zinc-200 rounded-md border-rose-500 p-2 border-2 shadow-xl drop-shadow-lg">
<IconGradient class="w-[7.5%] lg:w-1/10" />
<div class="flex flex-col space-y-1 my-1 w-[92.5%] lg:w-9/10">
<span class="uppercase text-xs text-rose-500 font-bold">Gradient</span>
<span class="text-sm text-rose-100">Add gradients to text, while keeping styles and interactivity.</span>
</div>
</div>

<div class="flex items-center space-x-2 bg-blue-500/20 text-zinc-200 rounded-md border-blue-500 p-2 border-2 shadow-xl drop-shadow-lg">
<IconLore class="w-[7.5%] lg:w-1/10" />
<div class="flex flex-col space-y-1 my-1 w-[92.5%] lg:w-9/10">
<span class="uppercase text-xs text-blue-500 font-bold">Lore output</span>
<span class="text-sm text-blue-100">Get an output correctly formatted for item lore components.</span>
</div>
</div>

<div class="flex items-center space-x-2 bg-zinc-800 text-zinc-200 rounded-md border-zinc-500 p-2 border-2 shadow-xl drop-shadow-lg">
<IconCode class="w-[7.5%] lg:w-1/10" />
<div class="flex flex-col space-y-1 my-1 w-[92.5%] lg:w-9/10">
<span class="uppercase text-xs text-zinc-500 font-bold">Open source</span>
<span class="text-sm">All the code is public, and we maintain and update it regularly.</span>
</div>
</div>
</div>

<p class="text-sm text-zinc-400 mt-2"><b class="text-zinc-300">Feedback?</b> We are a small team and would love to hear any feedback you have! Let us know what you think on our <a href="https://discord.datapackhub.net/" class="link">Discord server</a>.</p>

<p class="text-sm text-zinc-400 mt-1"><b class="text-zinc-300">Bugs?</b> Report them on our <a href="https://discord.datapackhub.net/" class="link">Discord server</a>, or create an issue on <a href="https://github.com/Datapack-Hub/text/issues" class="link">Github</a>.</p>

<p class="text-zinc-500 text-xs mt-2">This site is maintained by Datapack Hub, and is <b>not</b> endorsed by Mojang Studios.</p>

<noscript>
<div class="rounded-md border-2 border-red-500 bg-red-500/20 px-3 py-2 mt-2 text-rose-200">
<h1 class="font-bold text-white">This website requires JavaScript to work.</h1>
<p class="text-sm">Please enable Javascript access in your site settings, then refresh the page. If you still see this notice, try a different browser, or ask for help in our <a href="https://discord.datapackhub.net/">Discord server</a>.</p>
</div>
</noscript>
</div>
</div>
</div>
</div>
{/if}
12 changes: 6 additions & 6 deletions src/lib/components/modals/ClickEventModal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

<Modal title="Click Event" bind:this={clickEventDialog} key="T">
<p>Event Type</p>
<select bind:value={clickEventType} class="rounded-md bg-zinc-900 p-2">
<select bind:value={clickEventType} class="input-basic">
<option value="open_url">Open URL</option>
<option value="run_command">Run Command</option>
<option value="suggest_command">Suggest Command</option>
Expand All @@ -32,37 +32,37 @@
<p class="mt-2">Command:</p>
<input
type="text"
class="rounded-md bg-zinc-900 p-2"
class="input-basic"
placeholder="/give @s apple"
bind:value={clickEventValue} />
<p class="text-zinc-400">Note: the player must have permission to run the command!</p>
{:else if clickEventType == "suggest_command"}
<p class="mt-2">Command:</p>
<input
type="text"
class="rounded-md bg-zinc-900 p-2"
class="input-basic"
placeholder="/give @s apple"
bind:value={clickEventValue} />
<p class="text-zinc-400">Note: the player must have permission to run the command!</p>
{:else if clickEventType == "copy_to_clipboard"}
<p class="mt-2">Text to copy:</p>
<input
type="text"
class="rounded-md bg-zinc-900 p-2"
class="input-basic"
placeholder="I love the Wuppertal Suspension Railway"
bind:value={clickEventValue} />
{:else if clickEventType == "change_page"}
<p class="mt-2">Page to go to:</p>
<input
type="number"
class="rounded-md bg-zinc-900 p-2"
class="input-basic"
placeholder="32"
bind:value={clickEventValue} />
{:else if clickEventType == "open_dialog"}
<p class="mt-2">Dialog ID:</p>
<input
type="text"
class="rounded-md bg-zinc-900 p-2"
class="input-basic"
placeholder="namespace:example_dialog"
bind:value={clickEventValue} />
{/if}
Expand Down
Loading