diff --git a/frontend/src/components/AppShell.vue b/frontend/src/components/AppShell.vue index 2a4ab75..1b6c184 100644 --- a/frontend/src/components/AppShell.vue +++ b/frontend/src/components/AppShell.vue @@ -428,7 +428,21 @@ async function signOut() { -
+ +
+ + + + + +
diff --git a/frontend/src/components/NoteGrid.vue b/frontend/src/components/NoteGrid.vue new file mode 100644 index 0000000..5d3d402 --- /dev/null +++ b/frontend/src/components/NoteGrid.vue @@ -0,0 +1,56 @@ + + + diff --git a/frontend/src/style.css b/frontend/src/style.css index 46d9060..8330f34 100644 --- a/frontend/src/style.css +++ b/frontend/src/style.css @@ -127,6 +127,21 @@ body { transform: scale(0.94); } +/* Lens cross-fade (M7). Only fires between genuinely different surfaces; the + * board's own lenses share a component and reflow in place instead. Out is quicker + * than in so the gap between them stays short — `mode="out-in"` means the two + * durations are additive, and anything slower starts to feel like waiting. */ +.lens-enter-active { + transition: opacity 150ms ease-out; +} +.lens-leave-active { + transition: opacity 100ms ease-in; +} +.lens-enter-from, +.lens-leave-to { + opacity: 0; +} + @layer components { .icon-btn { @apply rounded-md p-1.5 text-neutral-500 transition hover:bg-black/5 focus:outline-none diff --git a/frontend/src/views/BoardView.vue b/frontend/src/views/BoardView.vue index e56982e..d77b992 100644 --- a/frontend/src/views/BoardView.vue +++ b/frontend/src/views/BoardView.vue @@ -9,7 +9,7 @@ import { useNoteEditor } from "../composables/useNoteEditor"; import AsyncState from "../components/AsyncState.vue"; import EmptyState from "../components/EmptyState.vue"; import FilterBar from "../components/FilterBar.vue"; -import NoteCard from "../components/NoteCard.vue"; +import NoteGrid from "../components/NoteGrid.vue"; import NoteEditor from "../components/NoteEditor.vue"; import { isDesktop, sync as syncBridge } from "../desktop/bridge"; @@ -76,6 +76,9 @@ const orderedNotes = computed(() => isMainBoard.value ? [...pinnedNotes.value, ...otherNotes.value] : notes.items, ); const focusedIndex = ref(-1); +/** The focused note's id — what the grids compare against, so neither has to know + * its own offset within the combined keyboard-navigation order. */ +const focusedId = computed(() => orderedNotes.value[focusedIndex.value]?.id ?? null); const inTrash = computed(() => currentView.value === "trash"); function moveFocus(delta: number) { @@ -300,59 +303,42 @@ async function onDrop(targetId: string) { - - - + :notes="notes.items" + :active-id="focusedId" + reorderable + @open="openEditor" + @dragstart="onDragStart" + @dragend="onDragEnd" + @drop="onDrop" + /> diff --git a/frontend/src/views/SearchView.vue b/frontend/src/views/SearchView.vue index 65efebb..1bf7d16 100644 --- a/frontend/src/views/SearchView.vue +++ b/frontend/src/views/SearchView.vue @@ -6,7 +6,7 @@ import { useNoteList } from "../composables/useNoteList"; import { useNoteEditor } from "../composables/useNoteEditor"; import AsyncState from "../components/AsyncState.vue"; import EmptyState from "../components/EmptyState.vue"; -import NoteCard from "../components/NoteCard.vue"; +import NoteGrid from "../components/NoteGrid.vue"; import NoteEditor from "../components/NoteEditor.vue"; const route = useRoute(); @@ -38,9 +38,7 @@ watch(query, run, { immediate: true }); -
- -
+
diff --git a/frontend/src/views/TimelineView.vue b/frontend/src/views/TimelineView.vue index dda3078..3beccde 100644 --- a/frontend/src/views/TimelineView.vue +++ b/frontend/src/views/TimelineView.vue @@ -8,7 +8,7 @@ import { useNoteList } from "../composables/useNoteList"; import { useNoteEditor } from "../composables/useNoteEditor"; import AsyncState from "../components/AsyncState.vue"; import EmptyState from "../components/EmptyState.vue"; -import NoteCard from "../components/NoteCard.vue"; +import NoteGrid from "../components/NoteGrid.vue"; import NoteEditor from "../components/NoteEditor.vue"; // The "find by WHEN" recall lens: your notes grouped by when you captured them, @@ -149,9 +149,7 @@ onMounted(load);

{{ group.label }}

-
- -
+