QoL: Shift+Enter save-and-continue + autofocus quick-add on landing
- Shift+Enter in the quick-add title/body saves the current note and immediately starts a fresh one, staying focused for rapid capture. Plain Enter is still a newline (body) / title→body (title). Placeholder hints the shortcut. - Landing on the board auto-opens + focuses the note input (QuickAdd autofocus prop, passed from BoardView) so you can start typing on arrival. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FRgehjoz7Yv8LkUfADxACm
This commit is contained in:
@@ -4,6 +4,8 @@ import { useNotesStore } from "../stores/notes";
|
||||
import ColorPicker from "./ColorPicker.vue";
|
||||
import type { NoteColor } from "../notes/colors";
|
||||
|
||||
const props = withDefaults(defineProps<{ autofocus?: boolean }>(), { autofocus: false });
|
||||
|
||||
const notes = useNotesStore();
|
||||
|
||||
const expanded = ref(false);
|
||||
@@ -20,24 +22,41 @@ async function open() {
|
||||
bodyInput.value?.focus();
|
||||
}
|
||||
|
||||
function reset() {
|
||||
expanded.value = false;
|
||||
function hasContent(): boolean {
|
||||
return title.value.trim() !== "" || body.value.trim() !== "";
|
||||
}
|
||||
|
||||
function clearFields() {
|
||||
title.value = "";
|
||||
body.value = "";
|
||||
color.value = "default";
|
||||
}
|
||||
|
||||
async function commit() {
|
||||
const hasContent = title.value.trim() !== "" || body.value.trim() !== "";
|
||||
if (hasContent) {
|
||||
saving.value = true;
|
||||
try {
|
||||
await notes.create({ title: title.value, body: body.value, color: color.value });
|
||||
} finally {
|
||||
saving.value = false;
|
||||
}
|
||||
async function persist(): Promise<void> {
|
||||
if (!hasContent()) return;
|
||||
saving.value = true;
|
||||
try {
|
||||
await notes.create({ title: title.value, body: body.value, color: color.value });
|
||||
} finally {
|
||||
saving.value = false;
|
||||
}
|
||||
reset();
|
||||
}
|
||||
|
||||
// Close the composer, saving anything typed.
|
||||
async function commit() {
|
||||
await persist();
|
||||
clearFields();
|
||||
expanded.value = false;
|
||||
}
|
||||
|
||||
// Shift+Enter: save the current note and immediately start a fresh one, staying
|
||||
// open + focused for rapid-fire capture.
|
||||
async function commitAndContinue() {
|
||||
if (!hasContent()) return;
|
||||
await persist();
|
||||
clearFields();
|
||||
await nextTick();
|
||||
bodyInput.value?.focus();
|
||||
}
|
||||
|
||||
function onDocumentMousedown(e: MouseEvent) {
|
||||
@@ -46,7 +65,11 @@ function onDocumentMousedown(e: MouseEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => document.addEventListener("mousedown", onDocumentMousedown));
|
||||
onMounted(() => {
|
||||
document.addEventListener("mousedown", onDocumentMousedown);
|
||||
// Landing on the board drops the cursor straight into the note input.
|
||||
if (props.autofocus) void open();
|
||||
});
|
||||
onBeforeUnmount(() => document.removeEventListener("mousedown", onDocumentMousedown));
|
||||
</script>
|
||||
|
||||
@@ -68,14 +91,16 @@ onBeforeUnmount(() => document.removeEventListener("mousedown", onDocumentMoused
|
||||
type="text"
|
||||
placeholder="Title"
|
||||
class="w-full bg-transparent px-1 text-sm font-semibold outline-none placeholder:text-neutral-400"
|
||||
@keydown.enter.prevent="bodyInput?.focus()"
|
||||
@keydown.enter.shift.prevent="commitAndContinue"
|
||||
@keydown.enter.exact.prevent="bodyInput?.focus()"
|
||||
/>
|
||||
<textarea
|
||||
ref="bodyInput"
|
||||
v-model="body"
|
||||
rows="3"
|
||||
placeholder="Take a note…"
|
||||
placeholder="Take a note… (Shift+Enter saves & starts a new one)"
|
||||
class="w-full resize-none bg-transparent px-1 text-sm outline-none placeholder:text-neutral-400"
|
||||
@keydown.enter.shift.prevent="commitAndContinue"
|
||||
@keydown.esc="commit"
|
||||
/>
|
||||
<div class="flex items-center justify-between gap-2 pt-1">
|
||||
|
||||
@@ -112,7 +112,7 @@ async function signOut() {
|
||||
</header>
|
||||
|
||||
<main class="mx-auto w-full max-w-6xl flex-1 px-4 py-6">
|
||||
<QuickAdd v-if="currentView === 'active'" class="mb-8" />
|
||||
<QuickAdd v-if="currentView === 'active'" autofocus class="mb-8" />
|
||||
|
||||
<div v-if="notes.loading" class="py-24 text-center text-sm text-neutral-400">Loading…</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user