Focus on and fold notes by clicking

Also tweaks the look a bit, of course.
This commit is contained in:
Joscha 2025-02-05 22:44:15 +01:00
parent 37f1b0e9d1
commit 21cd015ada
2 changed files with 52 additions and 21 deletions

View file

@ -9,8 +9,8 @@ const ui = useUiStore();
<template> <template>
<div class="flex h-screen touch-pan-x touch-pan-y flex-col"> <div class="flex h-screen touch-pan-x touch-pan-y flex-col">
<CNavbar /> <CNavbar />
<div class="h-full overflow-auto px-2 py-1"> <div class="h-full overflow-auto p-1">
<CNote :noteId="ui.anchor" :focusPath="ui.focusPath" /> <CNote :noteId="ui.anchor" :path="[]" :focusPath="ui.focusPath" />
</div> </div>
</div> </div>
</template> </template>

View file

@ -1,17 +1,20 @@
<script setup lang="ts"> <script setup lang="ts">
import { useNotesStore } from "@/stores/notes"; import { useNotesStore } from "@/stores/notes";
import { useUiStore } from "@/stores/ui";
import { RiArrowDownSLine, RiArrowRightSLine } from "@remixicon/vue"; import { RiArrowDownSLine, RiArrowRightSLine } from "@remixicon/vue";
import { computed, ref, watchEffect } from "vue"; import { computed, ref, watchEffect } from "vue";
const { notes } = useNotesStore(); const notes = useNotesStore();
const ui = useUiStore();
const props = defineProps<{ const props = defineProps<{
noteId?: string; noteId?: string;
focusPath?: number[]; path: number[]; // From root to here
focusPath?: number[]; // From here to focus
}>(); }>();
const note = computed(() => const note = computed(() =>
props.noteId ? notes.get(props.noteId) : undefined, props.noteId ? notes.notes.get(props.noteId) : undefined,
); );
// Our children and their locally unique keys. // Our children and their locally unique keys.
@ -30,7 +33,6 @@ const children = computed(() => {
const open = ref(false); const open = ref(false);
// We're the node pointed to by the `focusPath`.
const focused = computed(() => props.focusPath?.length === 0); const focused = computed(() => props.focusPath?.length === 0);
// We want to set open to true when we're on the focus path, but then it should // We want to set open to true when we're on the focus path, but then it should
@ -45,24 +47,55 @@ function focusPathFor(index: number): number[] | undefined {
if (index !== props.focusPath[0]) return undefined; if (index !== props.focusPath[0]) return undefined;
return props.focusPath.slice(1); return props.focusPath.slice(1);
} }
function focusOnThis() {
ui.focusPath = props.path.slice();
}
function toggleOpen() {
if (props.focusPath) {
// We're on the focus path, so the situation is one of these cases:
//
// 1. We're closed and focused, in which case this does nothing.
// 2. We're open and focused, in which case this does nothing.
// 3. We're open and on the focus path, in which case closing will hide the
// actual focus and we should be focused instead.
//
// In any case, we can just...
focusOnThis();
}
open.value = !open.value;
}
function onClick() {
if (!focused.value) {
focusOnThis();
return;
}
toggleOpen();
}
</script> </script>
<template> <template>
<div class="flex flex-col"> <div class="flex flex-col">
<div <div
class="flex flex-row gap-1" class="flex flex-row gap-1 pl-1"
:class="focused ? ['bg-neutral-200'] : []" :class="focused ? ['bg-neutral-200'] : ['hover:bg-neutral-100']"
@click="open = !open" @click="onClick"
> >
<!-- Fold/unfold symbol --> <!-- Fold/unfold symbol -->
<div v-if="children.length > 0 && !open" class="flex items-center"> <div class="flex items-center">
<RiArrowRightSLine size="16px" /> <div
class="rounded"
:class="focused ? ['hover:bg-neutral-300'] : ['hover:bg-neutral-200']"
@click.stop="toggleOpen()"
>
<RiArrowRightSLine v-if="children.length > 0 && !open" size="16px" />
<RiArrowDownSLine v-else-if="children.length > 0" size="16px" />
<RiArrowRightSLine v-else size="16px" class="text-neutral-400" />
</div> </div>
<div v-else-if="children.length > 0" class="flex items-center">
<RiArrowDownSLine size="16px" />
</div>
<div v-else class="flex items-center">
<RiArrowRightSLine size="16px" class="text-neutral-400" />
</div> </div>
<!-- Text --> <!-- Text -->
@ -71,14 +104,12 @@ function focusPathFor(index: number): number[] | undefined {
</div> </div>
<!-- Children --> <!-- Children -->
<div <div v-if="open && children.length > 0" class="flex flex-col pl-2">
v-if="open && children.length > 0"
class="flex flex-col border-l border-neutral-300 pl-3"
>
<CNote <CNote
v-for="([noteId, key], index) in children" v-for="([noteId, key], index) in children"
:key :key
:note-id :note-id
:path="path.concat(index)"
:focusPath="focusPathFor(index)" :focusPath="focusPathFor(index)"
/> />
</div> </div>