Skip to content

Commit acaf3a9

Browse files
Add pane navigation shortcuts
1 parent 9018064 commit acaf3a9

11 files changed

Lines changed: 1193 additions & 50 deletions

File tree

app/src/app.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,14 @@ import { PublishDialog, PublishShortNoteDialog } from "@/features/publishing";
2424
import { SidebarPane } from "@/features/shell/sidebar-pane";
2525
import { useRevealMainWindow } from "@/features/shell/use-reveal-main-window";
2626
import { useShellController } from "@/features/shell/use-shell-controller";
27+
import { useShellStore } from "@/features/shell/store/use-shell-store";
2728
import { useUIStore } from "@/features/settings/store/use-ui-store";
2829
import {
30+
dispatchFocusEditor,
31+
dispatchFocusNotesPane,
32+
} from "@/shared/lib/pane-navigation";
33+
import {
34+
getPaneFocusShortcut,
2935
isCommandPaletteShortcut,
3036
isEditorFindShortcut,
3137
isNotesSearchShortcut,
@@ -77,6 +83,7 @@ function App() {
7783
useRevealMainWindow(!hasCompletedStartupReveal && !readyToRevealWindow);
7884

7985
const setSettingsOpen = useUIStore((s) => s.setSettingsOpen);
86+
const setFocusedPane = useShellStore((s) => s.setFocusedPane);
8087

8188
const openCommandPalette = useEffectEvent(() => {
8289
setCommandPaletteOpen(true);
@@ -90,6 +97,20 @@ function App() {
9097
window.dispatchEvent(new CustomEvent(OPEN_EDITOR_FIND_EVENT));
9198
});
9299

100+
const focusPane = useEffectEvent((pane: "sidebar" | "notes" | "editor") => {
101+
if (pane === "editor") {
102+
dispatchFocusEditor();
103+
return;
104+
}
105+
106+
if (pane === "notes") {
107+
dispatchFocusNotesPane();
108+
return;
109+
}
110+
111+
setFocusedPane(pane);
112+
});
113+
93114
const handleKeyDown = useEffectEvent((event: KeyboardEvent) => {
94115
if (isCommandPaletteShortcut(event)) {
95116
event.preventDefault();
@@ -115,6 +136,15 @@ function App() {
115136
return;
116137
}
117138

139+
const paneShortcut = getPaneFocusShortcut(event);
140+
if (paneShortcut) {
141+
event.preventDefault();
142+
event.stopPropagation();
143+
event.stopImmediatePropagation();
144+
focusPane(paneShortcut);
145+
return;
146+
}
147+
118148
if (!event.metaKey) return;
119149

120150
const key = event.key.toLowerCase();

app/src/features/editor/note-editor.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ type NoteEditorProps = {
109109
export type NoteEditorHandle = {
110110
blur(): void;
111111
focus(): void;
112+
focusAtStart(): void;
112113
focusAtEnd(): void;
113114
redo(): boolean;
114115
undo(): boolean;
@@ -271,6 +272,20 @@ function focusEditorAtEndPreservingScroll(view: EditorView) {
271272
}
272273
}
273274

275+
function focusEditorAtStart(view: EditorView) {
276+
useShellStore.getState().setFocusedPane("editor");
277+
view.dispatch({
278+
selection: EditorSelection.cursor(0),
279+
scrollIntoView: false,
280+
});
281+
view.focus();
282+
283+
const scrollContainer = findEditorScrollContainer(view);
284+
if (scrollContainer) {
285+
scrollContainer.scrollTop = 0;
286+
}
287+
}
288+
274289
function dispatchPointerCursorSelection(view: EditorView, pos: number) {
275290
view.dispatch({
276291
annotations: Transaction.userEvent.of("select.pointer"),
@@ -766,6 +781,13 @@ export const NoteEditor = forwardRef<NoteEditorHandle, NoteEditorProps>(
766781
}
767782
viewRef.current?.focus();
768783
},
784+
focusAtStart() {
785+
if (readOnly || !viewRef.current) {
786+
return;
787+
}
788+
789+
focusEditorAtStart(viewRef.current);
790+
},
769791
focusAtEnd() {
770792
if (readOnly || !viewRef.current) {
771793
return;

0 commit comments

Comments
 (0)