Skip to content

Commit 29cf054

Browse files
Update Root.tsx
1 parent 65ff8c3 commit 29cf054

1 file changed

Lines changed: 82 additions & 0 deletions

File tree

src/theme/Root.tsx

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,61 @@ import styles from "./Root.module.css"; // Import the CSS module
77
import { useLocation } from "@docusaurus/router";
88
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
99

10+
function isEditableEventTarget(target: EventTarget | null): boolean {
11+
if (!(target instanceof Element)) {
12+
return false;
13+
}
14+
15+
if (target.isContentEditable) {
16+
return true;
17+
}
18+
19+
const tagName = target.tagName.toLowerCase();
20+
if (tagName === "textarea" || tagName === "select") {
21+
return true;
22+
}
23+
24+
if (target instanceof HTMLInputElement) {
25+
const editableTypes = new Set([
26+
"text",
27+
"search",
28+
"url",
29+
"tel",
30+
"email",
31+
"password",
32+
"number",
33+
"date",
34+
"datetime-local",
35+
"month",
36+
"time",
37+
"week",
38+
]);
39+
return !target.readOnly && !target.disabled && editableTypes.has(target.type);
40+
}
41+
42+
return target.matches(
43+
"[contenteditable='true'], [contenteditable=''], [contenteditable='plaintext-only']",
44+
);
45+
}
46+
47+
function focusSearchInput(): boolean {
48+
const navbarSearch = document.querySelector<HTMLInputElement>(
49+
"#algolia-sitesearch-navbar input",
50+
);
51+
if (navbarSearch) {
52+
navbarSearch.focus({ preventScroll: true });
53+
return true;
54+
}
55+
56+
const blogSearch = document.querySelector<HTMLInputElement>(".blog-search-input");
57+
if (blogSearch) {
58+
blogSearch.focus({ preventScroll: true });
59+
return true;
60+
}
61+
62+
return false;
63+
}
64+
1065
// A simple Trophy SVG icon component
1166
function TrophyIcon() {
1267
return (
@@ -144,6 +199,33 @@ export default function Root({ children }: { children: React.ReactNode }) {
144199
};
145200
}, []);
146201

202+
useEffect(() => {
203+
function handleGlobalSearchShortcut(event: KeyboardEvent) {
204+
if (
205+
event.key !== "/" ||
206+
event.defaultPrevented ||
207+
event.metaKey ||
208+
event.altKey ||
209+
event.ctrlKey
210+
) {
211+
return;
212+
}
213+
214+
if (isEditableEventTarget(event.target)) {
215+
return;
216+
}
217+
218+
if (focusSearchInput()) {
219+
event.preventDefault();
220+
}
221+
}
222+
223+
document.addEventListener("keydown", handleGlobalSearchShortcut);
224+
return () => {
225+
document.removeEventListener("keydown", handleGlobalSearchShortcut);
226+
};
227+
}, []);
228+
147229
// Show toast on initial load for all pages
148230
useEffect(() => {
149231
setShowToast(true);

0 commit comments

Comments
 (0)