Skip to content

Commit 6ef07cc

Browse files
authored
Merge pull request #403 from penge/tab-lists
Indent and outdent lists using Tab
2 parents a19598b + a7548d6 commit 6ef07cc

File tree

3 files changed

+55
-7
lines changed

3 files changed

+55
-7
lines changed

src/notes/components/content/ContentHtml.tsx

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import runUploadPreconditions from "background/google-drive/preconditions/run-up
44
import { KeyboardShortcut } from "notes/keyboard-shortcuts";
55
import { useKeyboardShortcut } from "notes/hooks/use-keyboard-shortcut";
66
import __range from "notes/range";
7+
import { insideListItem } from "notes/content/list";
78
import { reinitTables } from "notes/content/table";
89
import { commands, InsertTabFactory } from "../../commands";
910
import { ContentProps, reattachEditNote } from "./common";
@@ -43,13 +44,35 @@ const ContentHtml = ({
4344
}: ContentProps): h.JSX.Element => {
4445
const contentRef = useRef<HTMLDivElement | null>(null);
4546

46-
const [setIndentOnTabHandlerOnTab] = useKeyboardShortcut(KeyboardShortcut.OnTab);
47+
const [setOnTabHandler] = useKeyboardShortcut(KeyboardShortcut.OnTab);
48+
const [setOnShiftTabHandler] = useKeyboardShortcut(KeyboardShortcut.OnShiftTab);
4749

48-
useEffect(() => setIndentOnTabHandlerOnTab(
49-
indentOnTab
50-
? InsertTabFactory({ tabSize })
51-
: undefined,
52-
), [indentOnTab, tabSize]);
50+
useEffect(() => {
51+
const insertTab = InsertTabFactory({ tabSize });
52+
53+
setOnTabHandler(() => {
54+
if (!indentOnTab) {
55+
return;
56+
}
57+
58+
if (insideListItem({ canBeFirstDescendant: true })) {
59+
commands.Indent();
60+
return;
61+
}
62+
63+
insertTab();
64+
});
65+
66+
setOnShiftTabHandler(() => {
67+
if (!indentOnTab) {
68+
return;
69+
}
70+
71+
if (insideListItem({ canBeFirstDescendant: false })) {
72+
commands.Outdent();
73+
}
74+
});
75+
}, [indentOnTab, tabSize]);
5376

5477
useEffect(() => {
5578
if (contentRef.current) {

src/notes/content/list.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// eslint-disable-next-line import/prefer-default-export
2+
export const insideListItem = ({ canBeFirstDescendant }: { canBeFirstDescendant: boolean }) => {
3+
const selection = window.getSelection();
4+
if (!selection || !selection.rangeCount) {
5+
return false;
6+
}
7+
8+
const LIST_TAGS = ["UL", "OL"];
9+
const ancestor = selection.getRangeAt(0).commonAncestorContainer;
10+
const closestList = LIST_TAGS.includes((ancestor as HTMLOListElement | HTMLUListElement).tagName)
11+
? ancestor
12+
: ancestor.parentElement?.closest(LIST_TAGS.join(","));
13+
14+
return canBeFirstDescendant
15+
? closestList != null
16+
: LIST_TAGS.includes(closestList?.parentElement?.tagName || "");
17+
};

src/notes/keyboard-shortcuts.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export enum KeyboardShortcut {
2020
OnEscape,
2121
OnEnter,
2222
OnTab,
23+
OnShiftTab,
2324

2425
// Commands
2526
OnRepeatLastExecutedCommand,
@@ -137,11 +138,17 @@ const registerEnter = (event: KeyboardEvent) => {
137138
};
138139

139140
const registerTab = (event: KeyboardEvent) => {
140-
if (event.key === "Tab") {
141+
if (event.key === "Tab" && !event.shiftKey) {
141142
publish(KeyboardShortcut.OnTab, event);
142143
}
143144
};
144145

146+
const registerShiftTab = (event: KeyboardEvent) => {
147+
if (event.key === "Tab" && event.shiftKey) {
148+
publish(KeyboardShortcut.OnShiftTab, event);
149+
}
150+
};
151+
145152
const registerRepeatLastExecutedCommand = (event: KeyboardEvent, os: Os) => {
146153
if (
147154
(isMac(os) && event.metaKey && event.shiftKey && event.code === "KeyP")
@@ -247,6 +254,7 @@ const keydown = (os: Os) => document.addEventListener("keydown", (event) => {
247254
registerEscape(event);
248255
registerEnter(event);
249256
registerTab(event);
257+
registerShiftTab(event);
250258

251259
// Commands
252260
registerRepeatLastExecutedCommand(event, os);

0 commit comments

Comments
 (0)