Edit existing notes

This commit is contained in:
Joscha 2025-02-07 22:51:21 +01:00
parent 32193376bc
commit 363f88edcf
2 changed files with 45 additions and 13 deletions

View file

@ -6,6 +6,7 @@ import {
RiAddLine, RiAddLine,
RiArrowDownSLine, RiArrowDownSLine,
RiArrowRightSLine, RiArrowRightSLine,
RiEditLine,
RiStickyNoteAddLine, RiStickyNoteAddLine,
} from "@remixicon/vue"; } from "@remixicon/vue";
import { computed, ref, watchEffect } from "vue"; import { computed, ref, watchEffect } from "vue";
@ -41,8 +42,10 @@ const mayOpen = computed(() => children.value.length > 0);
const open = computed(() => mayOpen.value && ui.openPaths.has(props.path)); const open = computed(() => mayOpen.value && ui.openPaths.has(props.path));
const focused = computed(() => ui.focusPath === props.path); const focused = computed(() => ui.focusPath === props.path);
const hover = ref(false); const hover = computed(() => hovering.value && !editing.value);
const hovering = ref(false);
const editing = ref(false);
const creating = ref(false); const creating = ref(false);
// Ensure we're open if we need to be. // Ensure we're open if we need to be.
@ -80,18 +83,32 @@ function onClick() {
toggleOpen(); toggleOpen();
} }
function onCreateClick() { function onEditButtonClick() {
focusOnThis();
editing.value = true;
}
function onEditEditorClose() {
editing.value = false;
}
function onEditEditorFinish(text: string) {
if (note.value) note.value.text = text;
onEditEditorClose();
}
function onCreateButtonClick() {
creating.value = true; creating.value = true;
} }
function onChildEditorClose() { function onCreateEditorClose() {
creating.value = false; creating.value = false;
} }
function onChildEditorFinish(text: string) { function onCreateEditorFinish(text: string) {
notes.appendNewChildNote(props.noteId, text); notes.appendNewChildNote(props.noteId, text);
ui.focusPath = pathAppend(props.path, children.value.length - 1); ui.focusPath = pathAppend(props.path, children.value.length - 1);
onChildEditorClose(); onCreateEditorClose();
} }
</script> </script>
@ -100,8 +117,8 @@ function onChildEditorFinish(text: string) {
<div <div
class="relative flex min-h-6 pl-1" class="relative flex min-h-6 pl-1"
:class="focused ? 'bg-neutral-200' : hover ? 'bg-neutral-100' : ''" :class="focused ? 'bg-neutral-200' : hover ? 'bg-neutral-100' : ''"
@mouseenter="hover = true" @mouseenter="hovering = true"
@mouseleave="hover = false" @mouseleave="hovering = false"
@click="onClick" @click="onClick"
> >
<!-- Fold/unfold symbol --> <!-- Fold/unfold symbol -->
@ -119,7 +136,14 @@ function onChildEditorFinish(text: string) {
</div> </div>
<!-- Text --> <!-- Text -->
<div v-if="note && note.text.trim().length > 0" class="whitespace-pre-wrap px-1"> <CNoteEditor
v-if="editing"
class="flex-1"
:initialText="note?.text"
@close="onEditEditorClose"
@finish="onEditEditorFinish"
/>
<div v-else-if="note && note.text.trim().length > 0" class="whitespace-pre-wrap px-1">
{{ note.text }} {{ note.text }}
</div> </div>
<div v-else-if="note" class="px-1 font-light italic">empty</div> <div v-else-if="note" class="px-1 font-light italic">empty</div>
@ -127,7 +151,10 @@ function onChildEditorFinish(text: string) {
<!-- Controls --> <!-- Controls -->
<div v-if="hover" class="absolute right-0 flex h-6 items-center gap-0.5"> <div v-if="hover" class="absolute right-0 flex h-6 items-center gap-0.5">
<CNoteButton @click.stop="onCreateClick"> <CNoteButton @click.stop="onEditButtonClick">
<RiEditLine size="16px" />
</CNoteButton>
<CNoteButton @click.stop="onCreateButtonClick">
<RiStickyNoteAddLine size="16px" /> <RiStickyNoteAddLine size="16px" />
</CNoteButton> </CNoteButton>
</div> </div>
@ -150,7 +177,7 @@ function onChildEditorFinish(text: string) {
<RiAddLine size="16px" /> <RiAddLine size="16px" />
</div> </div>
<CNoteEditor class="flex-1" @close="onChildEditorClose" @finish="onChildEditorFinish" /> <CNoteEditor class="flex-1" @close="onCreateEditorClose" @finish="onCreateEditorFinish" />
</div> </div>
</div> </div>
</template> </template>

View file

@ -3,13 +3,17 @@ import { RiCheckLine, RiCloseLine } from "@remixicon/vue";
import { onMounted, ref, useTemplateRef } from "vue"; import { onMounted, ref, useTemplateRef } from "vue";
import CNoteButton from "./CNoteButton.vue"; import CNoteButton from "./CNoteButton.vue";
const props = defineProps<{
initialText?: string;
}>();
const emit = defineEmits<{ const emit = defineEmits<{
(e: "close"): void; (e: "close"): void;
(e: "finish", text: string): void; (e: "finish", text: string): void;
}>(); }>();
const textarea = useTemplateRef<HTMLTextAreaElement>("textarea"); const textarea = useTemplateRef<HTMLTextAreaElement>("textarea");
const text = ref(""); const text = ref(props.initialText || "");
onMounted(() => { onMounted(() => {
textarea.value?.focus(); textarea.value?.focus();
@ -48,16 +52,17 @@ function onKeyPress(ev: KeyboardEvent) {
autofocus autofocus
@input="onInput" @input="onInput"
@keypress="onKeyPress" @keypress="onKeyPress"
@click.stop
></textarea> ></textarea>
<div class="flex h-6 items-center"> <div class="flex h-6 items-center">
<CNoteButton @click="emit('finish', text)"> <CNoteButton @click.stop="emit('finish', text)">
<RiCheckLine size="16px" /> <RiCheckLine size="16px" />
</CNoteButton> </CNoteButton>
</div> </div>
<div class="flex h-6 items-center"> <div class="flex h-6 items-center">
<CNoteButton @click="emit('close')"> <CNoteButton @click.stop="emit('close')">
<RiCloseLine size="16px" /> <RiCloseLine size="16px" />
</CNoteButton> </CNoteButton>
</div> </div>