Skip to content

Commit a204f12

Browse files
authored
Add keyboard shortcut for sidebar search (#24753)
1 parent f3b19e9 commit a204f12

File tree

4 files changed

+177
-1
lines changed

4 files changed

+177
-1
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
diff --git a/node_modules/@astrojs/starlight-docsearch/DocSearch.astro b/node_modules/@astrojs/starlight-docsearch/DocSearch.astro
2+
index f50c208..5309557 100644
3+
--- a/node_modules/@astrojs/starlight-docsearch/DocSearch.astro
4+
+++ b/node_modules/@astrojs/starlight-docsearch/DocSearch.astro
5+
@@ -109,15 +109,20 @@ const docsearchTranslations: DocSearchTranslationProps = {
6+
.DocSearch-Button-Keys {
7+
margin-inline-start: auto;
8+
}
9+
- .DocSearch-Button-Keys::before {
10+
- content: '';
11+
- width: 1em;
12+
- height: 1em;
13+
- -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M17 2H7a5 5 0 0 0-5 5v10a5 5 0 0 0 5 5h10a5 5 0 0 0 5-5V7a5 5 0 0 0-5-5Zm3 15a3 3 0 0 1-3 3H7a3 3 0 0 1-3-3V7a3 3 0 0 1 3-3h10a3 3 0 0 1 3 3v10Z'%3E%3C/path%3E%3Cpath d='M15.293 6.707a1 1 0 1 1 1.414 1.414l-8.485 8.486a1 1 0 0 1-1.414-1.415l8.485-8.485Z'%3E%3C/path%3E%3C/svg%3E");
14+
- mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M17 2H7a5 5 0 0 0-5 5v10a5 5 0 0 0 5 5h10a5 5 0 0 0 5-5V7a5 5 0 0 0-5-5Zm3 15a3 3 0 0 1-3 3H7a3 3 0 0 1-3-3V7a3 3 0 0 1 3-3h10a3 3 0 0 1 3 3v10Z'%3E%3C/path%3E%3Cpath d='M15.293 6.707a1 1 0 1 1 1.414 1.414l-8.485 8.486a1 1 0 0 1-1.414-1.415l8.485-8.485Z'%3E%3C/path%3E%3C/svg%3E");
15+
- -webkit-mask-size: 100%;
16+
- mask-size: 100%;
17+
- background-color: currentColor;
18+
+ .DocSearch-Button-Key:first-child {
19+
+ margin-right: 0.4em;
20+
+ }
21+
+ .DocSearch-Button-Key {
22+
+ display: inline-block;
23+
+ font-size: 0.75em;
24+
+ font-weight: 600;
25+
+ opacity: 0.8;
26+
+ border: 1px solid var(--sl-color-gray-4);
27+
+ border-radius: 0.25rem;
28+
+ padding: 0.125rem 0.375rem;
29+
+ background-color: var(--sl-color-gray-6);
30+
+ color: var(--sl-color-gray-1);
31+
+ line-height: 1;
32+
}
33+
}
34+
</style>
35+
@@ -128,6 +133,7 @@ const docsearchTranslations: DocSearchTranslationProps = {
36+
class StarlightDocSearch extends HTMLElement {
37+
constructor() {
38+
super();
39+
+
40+
window.addEventListener('DOMContentLoaded', async () => {
41+
const { default: docsearch } = await import('@docsearch/js');
42+
const options = { ...config, container: 'sl-doc-search' };
43+
@@ -136,6 +142,27 @@ const docsearchTranslations: DocSearchTranslationProps = {
44+
Object.assign(options, translations);
45+
} catch {}
46+
docsearch(options);
47+
+
48+
+ const keyboardShortcuts = options.keyboardShortcuts ?? {};
49+
+ const slashEnabled = keyboardShortcuts?.['/'] !== false;
50+
+ const ctrlCmdKEnabled = keyboardShortcuts?.['Ctrl/Cmd+K'] !== false;
51+
+
52+
+ if (slashEnabled && !ctrlCmdKEnabled) {
53+
+ const styleContainer = document.createElement('style');
54+
+ styleContainer.innerHTML = `
55+
+ .DocSearch-Button-Keys::before {
56+
+ content: '';
57+
+ width: 1em;
58+
+ height: 1em;
59+
+ -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M17 2H7a5 5 0 0 0-5 5v10a5 5 0 0 0 5 5h10a5 5 0 0 0 5-5V7a5 5 0 0 0-5-5Zm3 15a3 3 0 0 1-3 3H7a3 3 0 0 1-3-3V7a3 3 0 0 1 3-3h10a3 3 0 0 1 3 3v10Z'%3E%3C/path%3E%3Cpath d='M15.293 6.707a1 1 0 1 1 1.414 1.414l-8.485 8.486a1 1 0 0 1-1.414-1.415l8.485-8.485Z'%3E%3C/path%3E%3C/svg%3E");
60+
+ mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M17 2H7a5 5 0 0 0-5 5v10a5 5 0 0 0 5 5h10a5 5 0 0 0 5-5V7a5 5 0 0 0-5-5Zm3 15a3 3 0 0 1-3 3H7a3 3 0 0 1-3-3V7a3 3 0 0 1 3-3h10a3 3 0 0 1 3 3v10Z'%3E%3C/path%3E%3Cpath d='M15.293 6.707a1 1 0 1 1 1.414 1.414l-8.485 8.486a1 1 0 0 1-1.414-1.415l8.485-8.485Z'%3E%3C/path%3E%3C/svg%3E");
61+
+ -webkit-mask-size: 100%;
62+
+ mask-size: 100%;
63+
+ background-color: currentColor;
64+
+ }
65+
+ `;
66+
+ document.head.appendChild(styleContainer);
67+
+ }
68+
});
69+
}
70+
}
71+
diff --git a/node_modules/@astrojs/starlight-docsearch/index.ts b/node_modules/@astrojs/starlight-docsearch/index.ts
72+
index e8cc7e5..6c88e07 100644
73+
--- a/node_modules/@astrojs/starlight-docsearch/index.ts
74+
+++ b/node_modules/@astrojs/starlight-docsearch/index.ts
75+
@@ -43,6 +43,18 @@ const DocSearchConfigSchema = z
76+
* @see https://www.algolia.com/doc/api-reference/search-api-parameters/
77+
*/
78+
searchParameters: z.custom<SearchOptions>(),
79+
+ /**
80+
+ * Configuration for keyboard shortcuts that trigger the DocSearch modal.
81+
+ * @see https://docsearch.algolia.com/docs/api/#keyboardshortcuts
82+
+ */
83+
+ keyboardShortcuts: z
84+
+ .object({
85+
+ /** Enable/disable Ctrl/Cmd+K shortcut. @default true */
86+
+ 'Ctrl/Cmd+K': z.boolean().optional(),
87+
+ /** Enable/disable / shortcut. @default true */
88+
+ '/': z.boolean().optional(),
89+
+ })
90+
+ .optional(),
91+
})
92+
.strict()
93+
.or(

patches/@docsearch+js+3.8.2.patch

Lines changed: 38 additions & 0 deletions
Large diffs are not rendered by default.

src/components/overrides/Sidebar.astro

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ const [product, module] = Astro.url.pathname.split("/").filter(Boolean);
2222
type="text"
2323
id="sidebar-search"
2424
placeholder="Search sidebar..."
25-
class="w-full px-3 py-2 text-sm border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:focus:ring-orange-500 dark:focus:border-orange-500 transition-colors duration-200"
25+
class="w-full px-3 py-2 pr-10 text-sm border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:focus:ring-orange-500 dark:focus:border-orange-500 transition-colors duration-200"
2626
/>
27+
<div class="sidebar-search-icon"></div>
2728
</div>
2829

2930
<!-- No Results Message -->
@@ -255,6 +256,30 @@ const [product, module] = Astro.url.pathname.split("/").filter(Boolean);
255256
}
256257
}
257258
});
259+
260+
document.addEventListener(
261+
"keydown",
262+
(keyboardEvent) => {
263+
const target = keyboardEvent.target;
264+
265+
const isInput =
266+
target instanceof EventTarget &&
267+
(("tagName" in target &&
268+
(target.tagName === "INPUT" ||
269+
target.tagName === "TEXTAREA" ||
270+
target.tagName === "SELECT")) ||
271+
("isContentEditable" in target && target.isContentEditable));
272+
273+
if (keyboardEvent.key === "/" && !isInput) {
274+
keyboardEvent.preventDefault();
275+
keyboardEvent.stopPropagation();
276+
searchInput.focus();
277+
}
278+
},
279+
{
280+
capture: true,
281+
},
282+
);
258283
}
259284

260285
// Initialize when DOM is loaded
@@ -269,6 +294,21 @@ const [product, module] = Astro.url.pathname.split("/").filter(Boolean);
269294
</script>
270295

271296
<style is:global>
297+
.sidebar-search-icon {
298+
position: absolute;
299+
right: 12px;
300+
top: 50%;
301+
transform: translateY(-50%);
302+
width: 1em;
303+
height: 1em;
304+
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M17 2H7a5 5 0 0 0-5 5v10a5 5 0 0 0 5 5h10a5 5 0 0 0 5-5V7a5 5 0 0 0-5-5Zm3 15a3 3 0 0 1-3 3H7a3 3 0 0 1-3-3V7a3 3 0 0 1 3-3h10a3 3 0 0 1 3 3v10Z'%3E%3C/path%3E%3Cpath d='M15.293 6.707a1 1 0 1 1 1.414 1.414l-8.485 8.486a1 1 0 0 1-1.414-1.415l8.485-8.485Z'%3E%3C/path%3E%3C/svg%3E");
305+
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M17 2H7a5 5 0 0 0-5 5v10a5 5 0 0 0 5 5h10a5 5 0 0 0 5-5V7a5 5 0 0 0-5-5Zm3 15a3 3 0 0 1-3 3H7a3 3 0 0 1-3-3V7a3 3 0 0 1 3-3h10a3 3 0 0 1 3 3v10Z'%3E%3C/path%3E%3Cpath d='M15.293 6.707a1 1 0 1 1 1.414 1.414l-8.485 8.486a1 1 0 0 1-1.414-1.415l8.485-8.485Z'%3E%3C/path%3E%3C/svg%3E");
306+
-webkit-mask-size: 100%;
307+
mask-size: 100%;
308+
background-color: currentColor;
309+
pointer-events: none;
310+
}
311+
272312
:root {
273313
.sidebar-content {
274314
--sl-color-hairline-light: #cacaca !important;

src/plugins/docsearch/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,9 @@ export default {
4343
},
4444
};
4545
},
46+
// @ts-expect-error Will be fixed with the next release of @docsearch/js
47+
keyboardShortcuts: {
48+
"Ctrl/Cmd+K": true,
49+
"/": false,
50+
},
4651
} satisfies DocSearchClientOptions;

0 commit comments

Comments
 (0)