@bendyline/docblocks-react 2.2.1 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/THIRD_PARTY_NOTICES.txt +11842 -0
- package/dist/{ExportToolbarControls-2VB43ITO.js → ExportToolbarControls-773QRE4R.js} +140 -73
- package/dist/{GitToolbarControl-FW3BZFXV.js → GitToolbarControl-VJVK2B4X.js} +4 -3
- package/dist/{GitUI-GMH3PAYL.js → GitUI-CAKFVKWY.js} +4 -3
- package/dist/chunk-APC4KI4B.js +0 -0
- package/dist/{chunk-BPGEBGAN.js → chunk-JDJVRDOP.js} +23 -0
- package/dist/{chunk-TFMO7EVO.js → chunk-MRUK56JS.js} +23 -4
- package/dist/chunk-VRRL6VTD.js +606 -0
- package/dist/editor.d.ts +12 -1
- package/dist/editor.js +9 -3
- package/dist/index.d.ts +60 -7
- package/dist/index.js +1914 -737
- package/dist/settings/index.d.ts +34 -2
- package/dist/settings/index.js +9 -3
- package/package.json +10 -9
- package/src/styles/docblocks.css +458 -5
- package/dist/chunk-3QSZY74C.js +0 -255
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useMenuKeyboard
|
|
3
|
+
} from "./chunk-MRUK56JS.js";
|
|
1
4
|
import {
|
|
2
5
|
loadTransformStyleSummaries
|
|
3
6
|
} from "./chunk-YBEYTVU2.js";
|
|
@@ -36,6 +39,8 @@ function loadRunExportModule() {
|
|
|
36
39
|
runExportModulePromise ?? (runExportModulePromise = import("./run-export-Z5BVFLIR.js"));
|
|
37
40
|
return runExportModulePromise;
|
|
38
41
|
}
|
|
42
|
+
var ExportCancelledError = class extends Error {
|
|
43
|
+
};
|
|
39
44
|
var SHARED_USE_MODES = Object.freeze({
|
|
40
45
|
slideshow: "slideshow",
|
|
41
46
|
video: "video",
|
|
@@ -69,10 +74,10 @@ function loadVideoExportModules() {
|
|
|
69
74
|
return videoExportModulesPromise;
|
|
70
75
|
}
|
|
71
76
|
function exportErrorMessage(caught) {
|
|
72
|
-
const detail = caught instanceof Error ? caught.message.trim() : "";
|
|
77
|
+
const detail = caught instanceof Error ? caught.message.replace(/^Error invoking remote method '[^']+': Error:\s*/, "").trim() : "";
|
|
73
78
|
return detail ? `Export failed: ${detail}` : "Export failed. The document could not be exported.";
|
|
74
79
|
}
|
|
75
|
-
function quickLabel(opts, transformSummaries) {
|
|
80
|
+
function quickLabel(opts, transformSummaries, destinationPath) {
|
|
76
81
|
const baseExt = FORMAT_EXTENSIONS[opts.format].toUpperCase().replace(".", "");
|
|
77
82
|
const isRecursiveHtml = opts.format === "html" && opts.includeLinkedDocs;
|
|
78
83
|
const ext = opts.format === "html" && (opts.htmlBundle === "zip" || isRecursiveHtml) ? "ZIP" : baseExt;
|
|
@@ -92,9 +97,11 @@ function quickLabel(opts, transformSummaries) {
|
|
|
92
97
|
if (transform) parts.push(transform.name);
|
|
93
98
|
}
|
|
94
99
|
if (parts.length > 0) {
|
|
95
|
-
|
|
100
|
+
const label2 = `Export ${ext} with ${parts.join(" + ")}`;
|
|
101
|
+
return destinationPath ? `${label2} to ${destinationPath}` : label2;
|
|
96
102
|
}
|
|
97
|
-
|
|
103
|
+
const label = `Export ${ext}`;
|
|
104
|
+
return destinationPath ? `${label} to ${destinationPath}` : label;
|
|
98
105
|
}
|
|
99
106
|
function ExportToolbarControls({
|
|
100
107
|
selectedFile,
|
|
@@ -123,9 +130,14 @@ function ExportToolbarControls({
|
|
|
123
130
|
const [exporting, setExporting] = useState(false);
|
|
124
131
|
const [exportError, setExportError] = useState(null);
|
|
125
132
|
const [destinationTarget, setDestinationTarget] = useState(null);
|
|
133
|
+
const [quickDestination, setQuickDestination] = useState(null);
|
|
134
|
+
const [quickDestinationPending, setQuickDestinationPending] = useState(false);
|
|
126
135
|
const destinationRequestRef = useRef(0);
|
|
127
|
-
const
|
|
136
|
+
const menuContainerRef = useRef(null);
|
|
137
|
+
const { menuRef, triggerRef, handleMenuKeyDown, handleTriggerKeyDown, closeMenu } = useMenuKeyboard(menuOpen, setMenuOpen);
|
|
128
138
|
const lastOptions = loadLastExportOptions();
|
|
139
|
+
const quickDestinationKey = lastOptions ? JSON.stringify([selectedFile, lastOptions]) : null;
|
|
140
|
+
const quickDestinationTarget = quickDestination?.key === quickDestinationKey ? quickDestination.target : null;
|
|
129
141
|
const docThemeId = useMemo(() => {
|
|
130
142
|
const fm = markdownDoc?.frontmatter;
|
|
131
143
|
if (!fm) return null;
|
|
@@ -142,12 +154,17 @@ function ExportToolbarControls({
|
|
|
142
154
|
useEffect(() => {
|
|
143
155
|
if (!menuOpen) return;
|
|
144
156
|
const onPointerDown = (e) => {
|
|
145
|
-
if (
|
|
146
|
-
|
|
157
|
+
if (menuContainerRef.current && !menuContainerRef.current.contains(e.target)) {
|
|
158
|
+
closeMenu(false);
|
|
147
159
|
}
|
|
148
160
|
};
|
|
149
161
|
document.addEventListener("pointerdown", onPointerDown);
|
|
150
162
|
return () => document.removeEventListener("pointerdown", onPointerDown);
|
|
163
|
+
}, [closeMenu, menuOpen]);
|
|
164
|
+
useEffect(() => {
|
|
165
|
+
if (menuOpen) return;
|
|
166
|
+
setQuickDestination(null);
|
|
167
|
+
setQuickDestinationPending(false);
|
|
151
168
|
}, [menuOpen]);
|
|
152
169
|
useEffect(() => {
|
|
153
170
|
if (!menuOpen || lastOptions?.format !== "pptx" || !lastOptions.transformStyle || transformSummaries.length > 0) {
|
|
@@ -163,9 +180,33 @@ function ExportToolbarControls({
|
|
|
163
180
|
cancelled = true;
|
|
164
181
|
};
|
|
165
182
|
}, [lastOptions?.format, lastOptions?.transformStyle, menuOpen, transformSummaries.length]);
|
|
183
|
+
useEffect(() => {
|
|
184
|
+
if (!menuOpen || !destinationAdapter || !quickDestinationKey) return;
|
|
185
|
+
const quickOptions = loadLastExportOptions();
|
|
186
|
+
if (!quickOptions) return;
|
|
187
|
+
let cancelled = false;
|
|
188
|
+
setQuickDestination(null);
|
|
189
|
+
setQuickDestinationPending(true);
|
|
190
|
+
void loadRunExportModule().then(
|
|
191
|
+
({ buildExportFilename }) => destinationAdapter.resolveTarget(buildExportFilename(selectedFile, quickOptions))
|
|
192
|
+
).then((target) => {
|
|
193
|
+
if (!cancelled) setQuickDestination({ key: quickDestinationKey, target });
|
|
194
|
+
}).catch(() => {
|
|
195
|
+
if (!cancelled) setQuickDestination(null);
|
|
196
|
+
}).finally(() => {
|
|
197
|
+
if (!cancelled) setQuickDestinationPending(false);
|
|
198
|
+
});
|
|
199
|
+
return () => {
|
|
200
|
+
cancelled = true;
|
|
201
|
+
};
|
|
202
|
+
}, [destinationAdapter, menuOpen, quickDestinationKey, selectedFile]);
|
|
166
203
|
const handleToggleMenu = useCallback(() => {
|
|
204
|
+
if (!menuOpen && destinationAdapter) {
|
|
205
|
+
setQuickDestination(null);
|
|
206
|
+
setQuickDestinationPending(true);
|
|
207
|
+
}
|
|
167
208
|
setMenuOpen((prev) => !prev);
|
|
168
|
-
}, []);
|
|
209
|
+
}, [destinationAdapter, menuOpen]);
|
|
169
210
|
const refreshDestination = useCallback(
|
|
170
211
|
async (options) => {
|
|
171
212
|
if (!destinationAdapter) return;
|
|
@@ -245,6 +286,7 @@ function ExportToolbarControls({
|
|
|
245
286
|
const pickedTarget = await destinationAdapter.pickTarget(filename, destinationTarget);
|
|
246
287
|
if (pickedTarget === null) return;
|
|
247
288
|
setDestinationTarget(pickedTarget);
|
|
289
|
+
setQuickDestination(null);
|
|
248
290
|
} catch {
|
|
249
291
|
}
|
|
250
292
|
},
|
|
@@ -254,7 +296,8 @@ function ExportToolbarControls({
|
|
|
254
296
|
async (blob, filename, target) => {
|
|
255
297
|
if (!destinationAdapter) return;
|
|
256
298
|
const savedTarget = await destinationAdapter.saveBlob(blob, filename, target);
|
|
257
|
-
if (savedTarget)
|
|
299
|
+
if (!savedTarget) throw new ExportCancelledError();
|
|
300
|
+
setDestinationTarget(savedTarget);
|
|
258
301
|
},
|
|
259
302
|
[destinationAdapter]
|
|
260
303
|
);
|
|
@@ -279,7 +322,7 @@ function ExportToolbarControls({
|
|
|
279
322
|
);
|
|
280
323
|
setDialogOpen(false);
|
|
281
324
|
} catch (caught) {
|
|
282
|
-
setExportError(exportErrorMessage(caught));
|
|
325
|
+
if (!(caught instanceof ExportCancelledError)) setExportError(exportErrorMessage(caught));
|
|
283
326
|
} finally {
|
|
284
327
|
setExporting(false);
|
|
285
328
|
}
|
|
@@ -303,10 +346,8 @@ function ExportToolbarControls({
|
|
|
303
346
|
const { runExport } = await loadRunExportModule();
|
|
304
347
|
let quickTarget = null;
|
|
305
348
|
if (destinationAdapter) {
|
|
306
|
-
|
|
307
|
-
quickTarget =
|
|
308
|
-
buildExportFilename(selectedFile, lastOptions)
|
|
309
|
-
);
|
|
349
|
+
if (!quickDestinationTarget) return;
|
|
350
|
+
quickTarget = quickDestinationTarget;
|
|
310
351
|
}
|
|
311
352
|
await runExport(
|
|
312
353
|
markdownSource,
|
|
@@ -316,7 +357,7 @@ function ExportToolbarControls({
|
|
|
316
357
|
destinationAdapter ? async (blob, filename) => saveToDestination(blob, filename, quickTarget) : saveBlob
|
|
317
358
|
);
|
|
318
359
|
} catch (caught) {
|
|
319
|
-
setExportError(exportErrorMessage(caught));
|
|
360
|
+
if (!(caught instanceof ExportCancelledError)) setExportError(exportErrorMessage(caught));
|
|
320
361
|
} finally {
|
|
321
362
|
setExporting(false);
|
|
322
363
|
}
|
|
@@ -327,7 +368,8 @@ function ExportToolbarControls({
|
|
|
327
368
|
mediaContainer,
|
|
328
369
|
saveBlob,
|
|
329
370
|
saveToDestination,
|
|
330
|
-
selectedFile
|
|
371
|
+
selectedFile,
|
|
372
|
+
quickDestinationTarget
|
|
331
373
|
]);
|
|
332
374
|
const handleDismissExportError = useCallback(() => {
|
|
333
375
|
setExportError(null);
|
|
@@ -347,13 +389,15 @@ function ExportToolbarControls({
|
|
|
347
389
|
"data-tooltip": exporting ? "Exporting..." : "Export document",
|
|
348
390
|
children: /* @__PURE__ */ jsx(ExportGlyph, {})
|
|
349
391
|
}
|
|
350
|
-
) : /* @__PURE__ */ jsxs("div", { className: "db-toolbar-menu", ref:
|
|
392
|
+
) : /* @__PURE__ */ jsxs("div", { className: "db-toolbar-menu", ref: menuContainerRef, children: [
|
|
351
393
|
/* @__PURE__ */ jsxs(
|
|
352
394
|
"button",
|
|
353
395
|
{
|
|
396
|
+
ref: triggerRef,
|
|
354
397
|
type: "button",
|
|
355
398
|
className: "db-toolbar-menu-trigger",
|
|
356
399
|
onClick: handleToggleMenu,
|
|
400
|
+
onKeyDown: handleTriggerKeyDown,
|
|
357
401
|
"aria-label": "Export and share",
|
|
358
402
|
"aria-haspopup": "menu",
|
|
359
403
|
"aria-expanded": menuOpen,
|
|
@@ -364,62 +408,85 @@ function ExportToolbarControls({
|
|
|
364
408
|
]
|
|
365
409
|
}
|
|
366
410
|
),
|
|
367
|
-
menuOpen && /* @__PURE__ */ jsxs(
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
411
|
+
menuOpen && /* @__PURE__ */ jsxs(
|
|
412
|
+
"div",
|
|
413
|
+
{
|
|
414
|
+
ref: menuRef,
|
|
415
|
+
className: "db-toolbar-menu-dropdown db-export-toolbar-menu-dropdown",
|
|
416
|
+
role: "menu",
|
|
417
|
+
onKeyDown: handleMenuKeyDown,
|
|
418
|
+
children: [
|
|
419
|
+
lastOptions && /* @__PURE__ */ jsx(
|
|
420
|
+
"button",
|
|
421
|
+
{
|
|
422
|
+
type: "button",
|
|
423
|
+
role: "menuitem",
|
|
424
|
+
tabIndex: -1,
|
|
425
|
+
className: "db-toolbar-menu-item",
|
|
426
|
+
onClick: handleQuickExport,
|
|
427
|
+
disabled: exporting || Boolean(destinationAdapter) && !quickDestinationTarget,
|
|
428
|
+
title: quickDestinationTarget ? quickLabel(
|
|
429
|
+
lastOptions,
|
|
430
|
+
transformSummaries,
|
|
431
|
+
quickDestinationTarget.displayPath
|
|
432
|
+
) : void 0,
|
|
433
|
+
children: quickDestinationTarget ? quickLabel(
|
|
434
|
+
lastOptions,
|
|
435
|
+
transformSummaries,
|
|
436
|
+
quickDestinationTarget.displayPath
|
|
437
|
+
) : quickLabel(lastOptions, transformSummaries) + (destinationAdapter ? quickDestinationPending ? " (finding destination...)" : " (destination unavailable)" : "")
|
|
438
|
+
}
|
|
439
|
+
),
|
|
440
|
+
/* @__PURE__ */ jsx(
|
|
441
|
+
"button",
|
|
442
|
+
{
|
|
443
|
+
type: "button",
|
|
444
|
+
role: "menuitem",
|
|
445
|
+
tabIndex: -1,
|
|
446
|
+
className: "db-toolbar-menu-item",
|
|
447
|
+
onClick: handleOpenDialog,
|
|
448
|
+
children: "Export..."
|
|
449
|
+
}
|
|
450
|
+
),
|
|
451
|
+
/* @__PURE__ */ jsx(
|
|
452
|
+
"button",
|
|
453
|
+
{
|
|
454
|
+
type: "button",
|
|
455
|
+
role: "menuitem",
|
|
456
|
+
tabIndex: -1,
|
|
457
|
+
className: "db-toolbar-menu-item",
|
|
458
|
+
onClick: handleOpenShareDialog,
|
|
459
|
+
children: "Share link with content embedded..."
|
|
460
|
+
}
|
|
461
|
+
),
|
|
462
|
+
showVideoExport && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
463
|
+
/* @__PURE__ */ jsx("div", { className: "db-toolbar-menu-divider", role: "separator" }),
|
|
464
|
+
/* @__PURE__ */ jsx(
|
|
465
|
+
"button",
|
|
466
|
+
{
|
|
467
|
+
type: "button",
|
|
468
|
+
role: "menuitem",
|
|
469
|
+
tabIndex: -1,
|
|
470
|
+
className: "db-toolbar-menu-item",
|
|
471
|
+
onClick: () => void handleOpenVideoModal("mp4"),
|
|
472
|
+
children: "Export video..."
|
|
473
|
+
}
|
|
474
|
+
),
|
|
475
|
+
showAnimatedGifExport && /* @__PURE__ */ jsx(
|
|
476
|
+
"button",
|
|
477
|
+
{
|
|
478
|
+
type: "button",
|
|
479
|
+
role: "menuitem",
|
|
480
|
+
tabIndex: -1,
|
|
481
|
+
className: "db-toolbar-menu-item",
|
|
482
|
+
onClick: () => void handleOpenVideoModal("gif"),
|
|
483
|
+
children: "Export animated gif..."
|
|
484
|
+
}
|
|
485
|
+
)
|
|
486
|
+
] })
|
|
487
|
+
]
|
|
488
|
+
}
|
|
489
|
+
)
|
|
423
490
|
] }),
|
|
424
491
|
dialogOpen && /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(
|
|
425
492
|
ExportDialog,
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
useMenuKeyboard
|
|
3
|
-
} from "./chunk-TFMO7EVO.js";
|
|
1
|
+
import "./chunk-APC4KI4B.js";
|
|
4
2
|
import {
|
|
5
3
|
isFileDirty,
|
|
6
4
|
useGitContext
|
|
7
5
|
} from "./chunk-HFYPTTCH.js";
|
|
6
|
+
import {
|
|
7
|
+
useMenuKeyboard
|
|
8
|
+
} from "./chunk-MRUK56JS.js";
|
|
8
9
|
|
|
9
10
|
// src/Git/GitToolbarControl.tsx
|
|
10
11
|
import { useEffect, useRef, useState } from "react";
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
useMenuKeyboard
|
|
3
|
-
} from "./chunk-TFMO7EVO.js";
|
|
1
|
+
import "./chunk-APC4KI4B.js";
|
|
4
2
|
import {
|
|
5
3
|
BADGE_GLYPHS,
|
|
6
4
|
BADGE_LABELS,
|
|
@@ -9,6 +7,9 @@ import {
|
|
|
9
7
|
summarizeDirty,
|
|
10
8
|
useGitContext
|
|
11
9
|
} from "./chunk-HFYPTTCH.js";
|
|
10
|
+
import {
|
|
11
|
+
useMenuKeyboard
|
|
12
|
+
} from "./chunk-MRUK56JS.js";
|
|
12
13
|
import {
|
|
13
14
|
Dialog
|
|
14
15
|
} from "./chunk-LG6HAWCK.js";
|
|
File without changes
|
|
@@ -1,4 +1,24 @@
|
|
|
1
1
|
// src/editor.ts
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
var PORTRAIT_FORM_FACTOR_QUERY = "(orientation: portrait)";
|
|
4
|
+
function previewViewportPresetForOrientation(isPortrait) {
|
|
5
|
+
return isPortrait ? "portrait" : "landscape";
|
|
6
|
+
}
|
|
7
|
+
function useResponsivePreviewViewportPreset() {
|
|
8
|
+
const [isPortrait, setIsPortrait] = useState(() => {
|
|
9
|
+
if (typeof globalThis.matchMedia !== "function") return false;
|
|
10
|
+
return globalThis.matchMedia(PORTRAIT_FORM_FACTOR_QUERY).matches;
|
|
11
|
+
});
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
if (typeof globalThis.matchMedia !== "function") return;
|
|
14
|
+
const query = globalThis.matchMedia(PORTRAIT_FORM_FACTOR_QUERY);
|
|
15
|
+
const update = () => setIsPortrait(query.matches);
|
|
16
|
+
update();
|
|
17
|
+
query.addEventListener("change", update);
|
|
18
|
+
return () => query.removeEventListener("change", update);
|
|
19
|
+
}, []);
|
|
20
|
+
return previewViewportPresetForOrientation(isPortrait);
|
|
21
|
+
}
|
|
2
22
|
var EMPTY_DOCUMENT_PROMPTS = [
|
|
3
23
|
"Start typing your content, or drop images on top of me...",
|
|
4
24
|
"Write anything -- paste markdown, drag in images, or just start typing...",
|
|
@@ -64,6 +84,9 @@ function pickEmptyDocumentPrompt(random = Math.random) {
|
|
|
64
84
|
}
|
|
65
85
|
|
|
66
86
|
export {
|
|
87
|
+
PORTRAIT_FORM_FACTOR_QUERY,
|
|
88
|
+
previewViewportPresetForOrientation,
|
|
89
|
+
useResponsivePreviewViewportPreset,
|
|
67
90
|
EMPTY_DOCUMENT_PROMPTS,
|
|
68
91
|
pickEmptyDocumentPrompt
|
|
69
92
|
};
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
import {
|
|
1
|
+
// src/components/useMenuKeyboard.ts
|
|
2
|
+
import {
|
|
3
|
+
useCallback,
|
|
4
|
+
useEffect,
|
|
5
|
+
useRef
|
|
6
|
+
} from "react";
|
|
3
7
|
function useMenuKeyboard(open, setOpen) {
|
|
4
8
|
const menuRef = useRef(null);
|
|
5
9
|
const triggerRef = useRef(null);
|
|
@@ -22,7 +26,7 @@ function useMenuKeyboard(open, setOpen) {
|
|
|
22
26
|
(returnFocus) => {
|
|
23
27
|
pendingFocusRef.current = "none";
|
|
24
28
|
setOpen(false);
|
|
25
|
-
if (returnFocus) triggerRef.current?.focus();
|
|
29
|
+
if (returnFocus) triggerRef.current?.focus({ preventScroll: true });
|
|
26
30
|
},
|
|
27
31
|
[setOpen]
|
|
28
32
|
);
|
|
@@ -32,6 +36,17 @@ function useMenuKeyboard(open, setOpen) {
|
|
|
32
36
|
pendingFocusRef.current = "none";
|
|
33
37
|
focusItem(where === "last" ? items().length - 1 : 0);
|
|
34
38
|
}, [open, focusItem, items]);
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (!open) return;
|
|
41
|
+
const handleDocumentKeyDown = (event) => {
|
|
42
|
+
if (event.key !== "Escape" || event.defaultPrevented) return;
|
|
43
|
+
event.preventDefault();
|
|
44
|
+
event.stopPropagation();
|
|
45
|
+
closeMenu(true);
|
|
46
|
+
};
|
|
47
|
+
document.addEventListener("keydown", handleDocumentKeyDown);
|
|
48
|
+
return () => document.removeEventListener("keydown", handleDocumentKeyDown);
|
|
49
|
+
}, [closeMenu, open]);
|
|
35
50
|
const handleTriggerKeyDown = useCallback(
|
|
36
51
|
(event) => {
|
|
37
52
|
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
|
@@ -48,12 +63,16 @@ function useMenuKeyboard(open, setOpen) {
|
|
|
48
63
|
);
|
|
49
64
|
const handleMenuKeyDown = useCallback(
|
|
50
65
|
(event) => {
|
|
51
|
-
if (event.key === "Escape"
|
|
66
|
+
if (event.key === "Escape") {
|
|
52
67
|
event.preventDefault();
|
|
53
68
|
event.stopPropagation();
|
|
54
69
|
closeMenu(true);
|
|
55
70
|
return;
|
|
56
71
|
}
|
|
72
|
+
if (event.key === "Tab") {
|
|
73
|
+
closeMenu(false);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
57
76
|
const all = items();
|
|
58
77
|
if (all.length === 0) return;
|
|
59
78
|
const current = all.indexOf(document.activeElement);
|