edit mode UI works

This commit is contained in:
2026-02-03 15:22:42 +13:00
parent f5db0fdf02
commit 3acb9cc80f
6 changed files with 58 additions and 42 deletions

View File

@@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
let { let {
image = $bindable(''), image = $bindable(),
edit = $bindable(true) edit = $bindable(true)
} = $props() } = $props()

View File

@@ -1,18 +1,30 @@
<script lang="ts"> <script lang="ts">
import ImageTarget from "./imageTarget.svelte" import ImageTarget from "./imageTarget.svelte";
import TextEditor from "./textEditor.svelte" import TextEditor from "./textEditor.svelte";
import { formatDate } from "$lib/date.ts";
let { let {
edit = $bindable(true), entry = $bindable(""),
image = $bindable(''), editorState = $bindable({ editor: null })
content = $bindable(''), } = $props();
editorState = $bindable({editor: null})
} = $props() let edit = $state(false);
let editModeText = $derived(edit ? "done" : "edit")
function getContent() { function getContent() {
return editorState.editor.getJSON() return editorState.editor.getJSON();
} }
</script> </script>
<ImageTarget bind:image bind:edit /> <div class="flex flex-row mb-2">
<TextEditor bind:content bind:editorState bind:edit /> <p class="text-3xl font-bold">{formatDate(entry.date)}</p>
<button
class="bg-white/20 px-3 rounded-lg ml-auto"
onclick={() => edit = !edit}
>
{editModeText}
</button>
</div>
<ImageTarget bind:image={entry.image} bind:edit />
<TextEditor bind:content={entry.content} bind:editorState bind:edit />

View File

@@ -1,37 +1,40 @@
<script lang="ts"> <script lang="ts">
let { let {
content = $bindable(''), content = $bindable(),
edit = $bindable(false), edit = $bindable(false),
editorState = $bindable({editor: null}) editorState = $bindable({ editor: null }),
} = $props() } = $props();
import { onMount, onDestroy } from 'svelte' import { onMount, onDestroy } from "svelte";
import { Editor } from '@tiptap/core' import { Editor } from "@tiptap/core";
import { StarterKit } from '@tiptap/starter-kit' import { StarterKit } from "@tiptap/starter-kit";
let element = $state() let element = $state();
onMount(() => { onMount(() => {
editorState.editor = new Editor({ editorState.editor = new Editor({
element: element, element: element,
editable: edit, editable: edit,
extensions: [ extensions: [StarterKit],
StarterKit,
],
content: content, content: content,
onTransaction: ({ editor }) => { onTransaction: ({ editor }) => {
// Update the state signal to force a re-render // Update the state signal to force a re-render
editorState = { editor } editorState = { editor };
}, },
}) });
}) });
onDestroy(() => { onDestroy(() => {
editorState.editor?.destroy() editorState.editor?.destroy();
}) });
$effect(() => editorState.editor.setOptions({ editable: edit }));
</script> </script>
<div class="bg-white/20 rounded-2xl p-2 mt-4"> <div class="bg-white/20 rounded-2xl p-2 mt-4">
<div class="bg-white/10 rounded-xl p-2 text-white/90" bind:this={element}></div> <div
class="bg-white/10 rounded-xl p-2 text-white/90"
bind:this={element}
></div>
</div> </div>
<style> <style>
@@ -43,5 +46,4 @@
:global(.tiptap) { :global(.tiptap) {
min-height: 240px; min-height: 240px;
} }
</style> </style>

View File

@@ -1,20 +1,17 @@
<script lang="ts"> <script lang="ts">
import { generateHTML } from "@tiptap/html"; import { generateHTML } from "@tiptap/html";
import { StarterKit } from "@tiptap/starter-kit"; import { StarterKit } from "@tiptap/starter-kit";
import { formatDate } from "$lib/date.ts";
const { entry, clickCB } = $props(); const { entry, clickCB } = $props();
const formatDate = (dateString) => { const formattedDate = formatDate(entry.date);
const date = new Date(dateString);
const options = { year: "numeric", month: "long", day: "numeric" };
return date.toLocaleDateString(undefined, options);
};
</script> </script>
<li class="bg-white/30 rounded-2xl mb-4 p-3" onclick={clickCB}> <li class="bg-white/30 rounded-2xl mb-4 p-3" onclick={clickCB}>
<div class="flex flex-row"> <div class="flex flex-row">
<div> <div>
<p class="text-sm text-white/60">{formatDate(entry.date)}</p> <p class="text-sm text-white/60">{formattedDate}</p>
{@html generateHTML(entry.content, [StarterKit])} {@html generateHTML(entry.content, [StarterKit])}
</div> </div>
<img <img

5
src/lib/date.ts Normal file
View File

@@ -0,0 +1,5 @@
export const formatDate = (dateString: string) => {
const date = new Date(dateString);
const options = { year: "numeric", month: "long", day: "numeric" };
return date.toLocaleDateString(undefined, options);
};

View File

@@ -29,7 +29,7 @@
<div id="right" class="md:w-1/2"> <div id="right" class="md:w-1/2">
{#if selectedEntry} {#if selectedEntry}
<Editor bind:edit bind:image={selectedEntry.image} bind:content={selectedEntry.content} /> <Editor bind:edit bind:entry={selectedEntry} />
{:else} {:else}
<div class="flex flex-col items-center justify-center h-full"> <div class="flex flex-col items-center justify-center h-full">
<p class="text-white/60">Select an entry to view/edit</p> <p class="text-white/60">Select an entry to view/edit</p>