@burdenoff/fe-libs 2026.928.1 → 2026.928.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.
Files changed (41) hide show
  1. package/dist/chrome/SideNavigation.d.ts.map +1 -1
  2. package/dist/chrome/SideNavigation.js +71 -68
  3. package/dist/chrome/sideNavigation/sideNavEscape.d.ts +41 -0
  4. package/dist/chrome/sideNavigation/sideNavEscape.d.ts.map +1 -0
  5. package/dist/chrome/sideNavigation/sideNavEscape.js +8 -0
  6. package/dist/chrome/sideNavigation/useSideNavigationState.d.ts +8 -1
  7. package/dist/chrome/sideNavigation/useSideNavigationState.d.ts.map +1 -1
  8. package/dist/chrome/sideNavigation/useSideNavigationState.js +35 -23
  9. package/dist/shared/assistant/ui/AIAssistantPanel.d.ts.map +1 -1
  10. package/dist/shared/assistant/ui/AIAssistantPanel.js +82 -79
  11. package/dist/shared/assistant/ui/AssistantOverlay.d.ts.map +1 -1
  12. package/dist/shared/assistant/ui/AssistantOverlay.js +86 -84
  13. package/dist/shared/assistant/ui/assistantOverlayState.d.ts +31 -8
  14. package/dist/shared/assistant/ui/assistantOverlayState.d.ts.map +1 -1
  15. package/dist/shared/assistant/ui/assistantOverlayState.js +22 -16
  16. package/dist/shared/assistant/ui/panelOverlays.d.ts +31 -0
  17. package/dist/shared/assistant/ui/panelOverlays.d.ts.map +1 -1
  18. package/dist/shared/assistant/ui/panelOverlays.js +11 -8
  19. package/dist/shared/assistant/ui/voice/AssistantVoiceSession.d.ts.map +1 -1
  20. package/dist/shared/assistant/ui/voice/AssistantVoiceSession.js +78 -74
  21. package/dist/shared/assistant/ui/voice/VoiceTranscriptDrawer.d.ts.map +1 -1
  22. package/dist/shared/assistant/ui/voice/VoiceTranscriptDrawer.js +40 -39
  23. package/dist/shared/assistant/ui/voice/voiceSessionEscape.d.ts.map +1 -1
  24. package/dist/shared/assistant/ui/voice/voiceSessionEscape.js +7 -10
  25. package/dist/shared/assistant/useAssistantKeyboardShortcuts.d.ts +3 -1
  26. package/dist/shared/assistant/useAssistantKeyboardShortcuts.d.ts.map +1 -1
  27. package/dist/shared/assistant/useAssistantKeyboardShortcuts.js +25 -25
  28. package/dist/shared/hooks/index.d.ts +1 -0
  29. package/dist/shared/hooks/index.d.ts.map +1 -1
  30. package/dist/shared/hooks/useReturnFocus.d.ts +56 -0
  31. package/dist/shared/hooks/useReturnFocus.d.ts.map +1 -0
  32. package/dist/shared/hooks/useReturnFocus.js +41 -0
  33. package/dist/shared/providers/AppShellProvider.d.ts +12 -1
  34. package/dist/shared/providers/AppShellProvider.d.ts.map +1 -1
  35. package/dist/shared/providers/AppShellProvider.js +175 -161
  36. package/dist/shared-assistant.js +76 -76
  37. package/dist/shared-hooks.js +34 -33
  38. package/dist/shared.js +89 -88
  39. package/dist/ui/modal-shell.d.ts.map +1 -1
  40. package/dist/ui/modal-shell.js +23 -13
  41. package/package.json +1 -1
@@ -1,51 +1,54 @@
1
- import { useAssistantTr as e } from "../../i18n.js";
2
- import { micIsInterrupt as t, showsAssistantCaption as n, voiceStageState as r } from "../../voice/voiceStageState.js";
3
- import { VOICE_THINKING_LABEL as i, composeVoiceStatus as ee, voiceStatusSuffix as te } from "../../voice/voiceStatus.js";
4
- import { spokenSoFar as a } from "../../voice/voiceSession.js";
5
- import { AssistantAttachmentButton as ne } from "../composer/AssistantAttachmentButton.js";
6
- import { AssistantAttachmentChips as o } from "../composer/AssistantAttachmentChips.js";
7
- import { AssistantVoiceOrb as s } from "./AssistantVoiceOrb.js";
8
- import { VoiceMiniController as c } from "./VoiceMiniController.js";
9
- import { VoiceStage as l } from "./VoiceStage.js";
10
- import { VoiceTranscriptDrawer as re } from "./VoiceTranscriptDrawer.js";
11
- import { escapeBelongsToLayerAbove as ie, voiceSessionEscapeAction as ae } from "./voiceSessionEscape.js";
12
- import { useCallback as u, useEffect as d, useRef as f, useState as p } from "react";
13
- import { Maximize2 as m, Minimize2 as oe, ScrollText as h, X as se } from "lucide-react";
14
- import { jsx as g, jsxs as _ } from "react/jsx-runtime";
1
+ import { useReturnFocus as e } from "../../../hooks/useReturnFocus.js";
2
+ import { useAssistantTr as t } from "../../i18n.js";
3
+ import { micIsInterrupt as n, showsAssistantCaption as r, voiceStageState as i } from "../../voice/voiceStageState.js";
4
+ import { VOICE_THINKING_LABEL as a, composeVoiceStatus as ee, voiceStatusSuffix as te } from "../../voice/voiceStatus.js";
5
+ import { spokenSoFar as o } from "../../voice/voiceSession.js";
6
+ import { ASSISTANT_PANEL_ATTR as ne, ASSISTANT_VOICE_SESSION_ATTR as s } from "../panelOverlays.js";
7
+ import { AssistantAttachmentButton as c } from "../composer/AssistantAttachmentButton.js";
8
+ import { AssistantAttachmentChips as l } from "../composer/AssistantAttachmentChips.js";
9
+ import { AssistantVoiceOrb as u } from "./AssistantVoiceOrb.js";
10
+ import { VoiceMiniController as re } from "./VoiceMiniController.js";
11
+ import { VoiceStage as ie } from "./VoiceStage.js";
12
+ import { VoiceTranscriptDrawer as ae } from "./VoiceTranscriptDrawer.js";
13
+ import { escapeBelongsToLayerAbove as oe, voiceSessionEscapeAction as se } from "./voiceSessionEscape.js";
14
+ import { useCallback as d, useEffect as f, useRef as p, useState as m } from "react";
15
+ import { Maximize2 as ce, Minimize2 as le, ScrollText as ue, X as de } from "lucide-react";
16
+ import { jsx as h, jsxs as g } from "react/jsx-runtime";
15
17
  //#region src/shared/assistant/ui/voice/AssistantVoiceSession.tsx
16
- var v = ({ session: v, turns: b = [], onSaveTranscript: le, onContinueInChat: x, notice: S = null, spoken: C, onInterrupt: ue, onToggleMute: w, attachments: T = [], onAttachFiles: E, onRemoveAttachment: de, onRetryAttachment: fe, canAttachMore: pe = !0, preparingAttachments: D = 0, spokenChunks: O = null, onEnd: k, capturing: me = !0, interrupting: he = !1, awaitingEndpoint: A = !1 }) => {
17
- let j = e(), { muted: M, error: N } = v, P = f(null), F = f(null), [I, L] = p("mini"), R = I === "full", z = I === "mini", B = I === "mini" ? "panel" : I === "panel" ? "full" : "mini", [V, H] = p(!1), U = f(!1), W = f(w);
18
- W.current = w;
19
- let G = u(() => {
20
- v.phase === "listening" && (M || U.current || a(v) || (U.current = !0, W.current()));
21
- }, [M, v]), K = u(() => {
18
+ var _ = ({ session: _, turns: fe = [], onSaveTranscript: pe, onContinueInChat: me, notice: b = null, spoken: x, onInterrupt: he, onToggleMute: S, attachments: C = [], onAttachFiles: w, onRemoveAttachment: ge, onRetryAttachment: _e, canAttachMore: ve = !0, preparingAttachments: T = 0, spokenChunks: E = null, onEnd: D, capturing: O = !0, interrupting: k = !1, awaitingEndpoint: A = !1 }) => {
19
+ let j = t(), { muted: M, error: N } = _, P = p(null), F = p(null), [I, L] = m("mini"), R = I === "full", z = I === "mini", B = I === "mini" ? "panel" : I === "panel" ? "full" : "mini", [V, H] = m(!1), U = p(!1), W = p(S);
20
+ W.current = S;
21
+ let G = d(() => {
22
+ _.phase === "listening" && (M || U.current || o(_) || (U.current = !0, W.current()));
23
+ }, [M, _]), K = d(() => {
22
24
  U.current && (U.current = !1, W.current());
23
- }, []), ge = G;
24
- d(() => {
25
+ }, []), ye = G;
26
+ f(() => {
25
27
  let e = () => {
26
28
  document.visibilityState === "hidden" ? G() : K();
27
29
  };
28
30
  return document.addEventListener("visibilitychange", e), () => document.removeEventListener("visibilitychange", e);
29
- }, [G, K]), d(() => {
31
+ }, [G, K]), f(() => {
30
32
  let e = K;
31
33
  return window.addEventListener("focus", e), () => {
32
34
  window.removeEventListener("focus", e), U.current = !1;
33
35
  };
34
- }, []), d(() => {
36
+ }, []), f(() => {
35
37
  P.current?.focus();
36
- }, []), d(() => {
38
+ }, []), e(F, { fallbackSelector: `[${ne}]` }), f(() => {
37
39
  let e = (e) => {
38
40
  if (e.key === "Escape") {
39
- let t = ae({
41
+ let t = se({
40
42
  defaultPrevented: e.defaultPrevented,
41
- layerAbove: ie({
43
+ layerAbove: oe({
42
44
  target: e.target,
43
45
  session: F.current,
44
46
  doc: document
45
47
  }),
46
48
  transcriptOpen: V
47
49
  });
48
- t === "close-transcript" ? H(!1) : t === "end" && k();
50
+ if (t === "ignore") return;
51
+ e.preventDefault(), t === "close-transcript" ? H(!1) : D();
49
52
  return;
50
53
  }
51
54
  if (e.key !== "Tab" || !R) return;
@@ -56,21 +59,21 @@ var v = ({ session: v, turns: b = [], onSaveTranscript: le, onContinueInChat: x,
56
59
  };
57
60
  return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
58
61
  }, [
59
- k,
62
+ D,
60
63
  R,
61
64
  V
62
65
  ]);
63
- let q = S !== null && N === null, J = a(v), Y = r({
64
- snapshot: v,
65
- capturing: me,
66
- interrupting: he,
66
+ let q = b !== null && N === null, J = o(_), Y = i({
67
+ snapshot: _,
68
+ capturing: O,
69
+ interrupting: k,
67
70
  awaitingEndpoint: A
68
71
  }), X = (() => {
69
72
  switch (Y) {
70
73
  case "connecting": return j("voiceSession.connecting", "Starting the microphone…");
71
74
  case "endpoint-grace": return j("voiceSession.endpointGrace", "Still listening — take your time");
72
75
  case "interrupting": return j("voiceSession.interrupting", "Stopped — go ahead");
73
- case "thinking": return j(i.key, i.fallback);
76
+ case "thinking": return j(a.key, a.fallback);
74
77
  case "speaking": return j("voiceSession.speaking", "Speaking — tap to stop");
75
78
  case "mic-error":
76
79
  case "ended": return "";
@@ -83,59 +86,60 @@ var v = ({ session: v, turns: b = [], onSaveTranscript: le, onContinueInChat: x,
83
86
  muted: M,
84
87
  label: X
85
88
  }), Q = ee(X, Z), $ = Y === "thinking";
86
- return /* @__PURE__ */ _("div", {
89
+ return /* @__PURE__ */ g("div", {
87
90
  ref: F,
88
91
  className: `flex flex-col items-center justify-between bg-bg-sunken ${I === "full" ? "fixed inset-x-0 bottom-0 top-14 z-[60] px-6 py-8" : I === "panel" ? "absolute inset-0 z-20 px-4 py-6" : "absolute inset-x-0 bottom-0 z-20 h-[11.25rem] border-t border-border-subtle px-3 py-3 shadow-lg"}`,
89
92
  role: "dialog",
90
93
  "aria-modal": R || void 0,
91
94
  "aria-label": j("voiceSession.title", "Voice conversation"),
92
95
  "data-testid": "assistant-voice-session",
96
+ [s]: "",
93
97
  children: [
94
- /* @__PURE__ */ _("button", {
98
+ /* @__PURE__ */ g("button", {
95
99
  ref: P,
96
100
  type: "button",
97
- onClick: k,
101
+ onClick: D,
98
102
  className: `absolute ${R ? "right-6 top-6 h-14 gap-2 px-5 text-base" : z ? "right-12 top-2 h-8 gap-1.5 px-2.5 text-xs" : "right-3 top-3 h-11 gap-2 px-4 text-sm"} flex items-center justify-center rounded-full border border-border-default bg-bg-elevated text-text-secondary hover:bg-bg-sunken transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong`,
99
103
  title: j("voiceSession.end", "End the voice conversation"),
100
104
  "data-testid": "assistant-voice-end",
101
- children: [/* @__PURE__ */ g(se, {
105
+ children: [/* @__PURE__ */ h(de, {
102
106
  className: R ? "size-6" : z ? "size-4" : "size-5",
103
107
  "aria-hidden": "true"
104
- }), /* @__PURE__ */ g("span", {
108
+ }), /* @__PURE__ */ h("span", {
105
109
  className: `truncate whitespace-nowrap font-medium ${z ? "max-w-[3.5rem] text-xs" : "max-w-[7rem]"}`,
106
110
  children: j("voiceSession.endShort", "End")
107
111
  })]
108
112
  }),
109
- /* @__PURE__ */ g("div", {
113
+ /* @__PURE__ */ h("div", {
110
114
  className: `flex flex-col items-center ${z ? "px-3" : `min-h-[1.5rem] ${q ? R ? "pt-14" : "pt-10" : ""}`}`,
111
- children: q ? /* @__PURE__ */ g("p", {
115
+ children: q ? /* @__PURE__ */ h("p", {
112
116
  className: "max-w-xs text-center text-xs text-status-warning",
113
117
  "data-testid": "assistant-voice-notice",
114
- children: ce(S, j)
118
+ children: v(b, j)
115
119
  }) : null
116
120
  }),
117
121
  (() => {
118
- let e = /* @__PURE__ */ g(s, {
119
- session: v,
122
+ let e = /* @__PURE__ */ h(u, {
123
+ session: _,
120
124
  compact: z,
121
125
  connecting: Y === "connecting",
122
- onPress: t(Y) ? ue : w,
123
- label: t(Y) ? j("voiceSession.interrupt", "Stop the assistant and speak") : M ? j("voiceSession.unmute", "Turn the microphone on") : j("voiceSession.mute", "Turn the microphone off")
124
- }), r = n(Y) ? C : J || null, i = N === null ? null : y(N, j);
125
- return z ? /* @__PURE__ */ g(c, {
126
- spokenChunks: O,
126
+ onPress: n(Y) ? he : S,
127
+ label: n(Y) ? j("voiceSession.interrupt", "Stop the assistant and speak") : M ? j("voiceSession.unmute", "Turn the microphone on") : j("voiceSession.mute", "Turn the microphone off")
128
+ }), t = r(Y) ? x : J || null, i = N === null ? null : y(N, j);
129
+ return z ? /* @__PURE__ */ h(re, {
130
+ spokenChunks: E,
127
131
  state: Y,
128
- caption: r,
132
+ caption: t,
129
133
  statusText: Q,
130
134
  statusSuffix: Z,
131
135
  rotateStatus: $,
132
136
  errorText: i,
133
137
  control: e
134
- }) : /* @__PURE__ */ g(l, {
138
+ }) : /* @__PURE__ */ h(ie, {
135
139
  state: Y,
136
140
  userCaption: J || null,
137
- spokenChunks: O,
138
- assistantCaption: C,
141
+ spokenChunks: E,
142
+ assistantCaption: x,
139
143
  expanded: R,
140
144
  statusText: Q,
141
145
  statusSuffix: Z,
@@ -144,54 +148,54 @@ var v = ({ session: v, turns: b = [], onSaveTranscript: le, onContinueInChat: x,
144
148
  control: e
145
149
  });
146
150
  })(),
147
- V ? /* @__PURE__ */ g(re, {
148
- turns: b,
151
+ V ? /* @__PURE__ */ h(ae, {
152
+ turns: fe,
149
153
  onClose: () => H(!1),
150
- onSave: le,
151
- onContinueInChat: x
154
+ onSave: pe,
155
+ onContinueInChat: me
152
156
  }) : null,
153
- E ? /* @__PURE__ */ g("div", {
157
+ w ? /* @__PURE__ */ h("div", {
154
158
  className: `absolute ${R ? "left-6 top-6" : z ? "left-11 top-2" : "left-3 top-3"}`,
155
- children: /* @__PURE__ */ g(ne, {
159
+ children: /* @__PURE__ */ h(c, {
156
160
  onFiles: (e) => {
157
- E(e), L((e) => e === "mini" ? "panel" : e);
161
+ w(e), L((e) => e === "mini" ? "panel" : e);
158
162
  },
159
- onPickerOpen: ge,
163
+ onPickerOpen: ye,
160
164
  direction: "down",
161
- canAddMore: pe
165
+ canAddMore: ve
162
166
  })
163
167
  }) : null,
164
- (T.length > 0 || D > 0) && !z ? /* @__PURE__ */ g("div", {
168
+ (C.length > 0 || T > 0) && !z ? /* @__PURE__ */ h("div", {
165
169
  className: `absolute ${R ? "bottom-24 left-24 right-24" : "bottom-16 left-16 right-16"}`,
166
170
  "data-testid": "assistant-voice-attachments",
167
- children: /* @__PURE__ */ g(o, {
168
- attachments: T,
169
- onRemove: de ?? (() => void 0),
170
- onRetry: fe ?? (() => void 0),
171
- preparingCount: D
171
+ children: /* @__PURE__ */ h(l, {
172
+ attachments: C,
173
+ onRemove: ge ?? (() => void 0),
174
+ onRetry: _e ?? (() => void 0),
175
+ preparingCount: T
172
176
  })
173
177
  }) : null,
174
- /* @__PURE__ */ g("button", {
178
+ /* @__PURE__ */ h("button", {
175
179
  type: "button",
176
180
  onClick: () => H((e) => !e),
177
181
  className: `absolute ${R ? "bottom-6 right-6 size-14" : z ? "right-2 top-2 size-8" : "bottom-3 right-3 size-11"} flex items-center justify-center rounded-full bg-bg-elevated text-text-secondary transition-colors hover:bg-bg-raised hover:text-text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong`,
178
182
  "aria-pressed": V,
179
183
  "aria-label": j("voiceSession.transcriptTitle", "Voice transcript"),
180
184
  "data-testid": "assistant-voice-transcript-toggle",
181
- children: /* @__PURE__ */ g(h, { className: R ? "size-6" : z ? "size-4" : "size-5" })
185
+ children: /* @__PURE__ */ h(ue, { className: R ? "size-6" : z ? "size-4" : "size-5" })
182
186
  }),
183
- /* @__PURE__ */ g("button", {
187
+ /* @__PURE__ */ h("button", {
184
188
  type: "button",
185
189
  onClick: () => L(B),
186
190
  className: `absolute ${R ? "bottom-6 left-6 size-14" : z ? "left-2 top-2 size-8" : "bottom-3 left-3 size-11"} flex items-center justify-center rounded-full bg-bg-elevated text-text-secondary transition-colors hover:bg-bg-raised hover:text-text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong`,
187
191
  "aria-label": B === "panel" ? j("voiceSession.expandPanel", "Show the conversation in the panel") : B === "full" ? j("voiceSession.expand", "Expand the conversation to full screen") : j("voiceSession.collapse", "Shrink to the compact controller"),
188
192
  "data-testid": "assistant-voice-expand",
189
- children: R ? /* @__PURE__ */ g(oe, { className: "size-5" }) : /* @__PURE__ */ g(m, { className: z ? "size-4" : "size-5" })
193
+ children: R ? /* @__PURE__ */ h(le, { className: "size-5" }) : /* @__PURE__ */ h(ce, { className: z ? "size-4" : "size-5" })
190
194
  })
191
195
  ]
192
196
  });
193
197
  };
194
- function ce(e, t) {
198
+ function v(e, t) {
195
199
  switch (e) {
196
200
  case "network": return t("voiceSession.noticeNetwork", "Speech recognition lost its connection. Check your network — it will retry.");
197
201
  case "not-capturing": return t("voiceSession.noticeNotCapturing", "The microphone did not start. Check that this site is allowed to use it, then try again.");
@@ -209,4 +213,4 @@ function y(e, t) {
209
213
  }
210
214
  }
211
215
  //#endregion
212
- export { v as AssistantVoiceSession };
216
+ export { _ as AssistantVoiceSession };
@@ -1 +1 @@
1
- {"version":3,"file":"VoiceTranscriptDrawer.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/VoiceTranscriptDrawer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAMnD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtE;;;;;;;;;;;;;;;;;;GAkBG;AAEH,UAAU,KAAK;IACb,KAAK,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAC1C,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB;;;;;;;;;;;;OAYG;IACH,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,+CAA+C;IAC/C,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,KAAK,CA+I3C,CAAC"}
1
+ {"version":3,"file":"VoiceTranscriptDrawer.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/VoiceTranscriptDrawer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAOnD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtE;;;;;;;;;;;;;;;;;;GAkBG;AAEH,UAAU,KAAK;IACb,KAAK,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAC1C,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB;;;;;;;;;;;;OAYG;IACH,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,+CAA+C;IAC/C,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,KAAK,CAoJ3C,CAAC"}
@@ -1,70 +1,71 @@
1
- import { useAssistantTr as e } from "../../i18n.js";
2
- import { ASSISTANT_PANEL_ATTR as t, focusIsInsidePanel as n } from "../panelOverlays.js";
3
- import { VoiceConversationView as r } from "./VoiceConversationView.js";
4
- import { AssistantHistoryShowEarlier as i } from "../AssistantHistoryNotices.js";
5
- import { useEffect as a, useRef as o } from "react";
6
- import { ArrowRight as s, Download as c, X as l } from "lucide-react";
7
- import { jsx as u, jsxs as d } from "react/jsx-runtime";
1
+ import { useReturnFocus as e } from "../../../hooks/useReturnFocus.js";
2
+ import { useAssistantTr as t } from "../../i18n.js";
3
+ import { ASSISTANT_PANEL_ATTR as n, focusIsInsidePanel as r } from "../panelOverlays.js";
4
+ import { VoiceConversationView as i } from "./VoiceConversationView.js";
5
+ import { AssistantHistoryShowEarlier as a } from "../AssistantHistoryNotices.js";
6
+ import { useEffect as o, useRef as s } from "react";
7
+ import { ArrowRight as c, Download as l, X as u } from "lucide-react";
8
+ import { jsx as d, jsxs as f } from "react/jsx-runtime";
8
9
  //#region src/shared/assistant/ui/voice/VoiceTranscriptDrawer.tsx
9
- var f = ({ turns: f, onClose: p, onSave: m, onContinueInChat: h, closeOnEscape: g = !1, onShowEarlier: _, showEarlierDisabled: v = !1 }) => {
10
- let y = e(), b = o(null);
11
- return a(() => {
12
- if (!g) return;
10
+ var p = ({ turns: p, onClose: m, onSave: h, onContinueInChat: g, closeOnEscape: _ = !1, onShowEarlier: v, showEarlierDisabled: y = !1 }) => {
11
+ let b = t(), x = s(null);
12
+ return e(x, { fallbackSelector: `[${n}]` }), o(() => {
13
+ if (!_) return;
13
14
  let e = (e) => {
14
15
  if (e.key !== "Escape" || document.querySelector("[role=\"alertdialog\"]")) return;
15
- let r = b.current?.closest(`[${t}]`), i = document.activeElement;
16
- n(r ?? null, i) && (e.preventDefault(), e.stopPropagation(), p());
16
+ let t = x.current?.closest(`[${n}]`), i = document.activeElement;
17
+ r(t ?? null, i) && (e.preventDefault(), e.stopPropagation(), m());
17
18
  };
18
19
  return document.addEventListener("keydown", e, !0), () => document.removeEventListener("keydown", e, !0);
19
- }, [g, p]), /* @__PURE__ */ d("div", {
20
- ref: b,
20
+ }, [_, m]), /* @__PURE__ */ f("div", {
21
+ ref: x,
21
22
  className: "absolute inset-0 z-30 flex flex-col bg-bg-sunken/95 backdrop-blur-sm",
22
23
  role: "dialog",
23
- "aria-label": y("voiceSession.transcriptTitle", "Voice transcript"),
24
+ "aria-label": b("voiceSession.transcriptTitle", "Voice transcript"),
24
25
  "data-testid": "assistant-voice-transcript",
25
26
  children: [
26
- /* @__PURE__ */ d("div", {
27
+ /* @__PURE__ */ f("div", {
27
28
  className: "flex items-center justify-between border-b border-border-subtle px-4 py-3",
28
- children: [/* @__PURE__ */ d("div", {
29
+ children: [/* @__PURE__ */ f("div", {
29
30
  className: "min-w-0",
30
- children: [/* @__PURE__ */ u("h2", {
31
+ children: [/* @__PURE__ */ d("h2", {
31
32
  className: "text-sm font-semibold text-text-primary",
32
- children: y("voiceSession.transcript", "Voice conversation")
33
- }), /* @__PURE__ */ u("p", {
33
+ children: b("voiceSession.transcript", "Voice conversation")
34
+ }), /* @__PURE__ */ d("p", {
34
35
  className: "truncate text-xs text-text-muted",
35
- children: y("voiceSession.transcriptHint", "Spoken turns in this conversation — kept out of your typed chat.")
36
+ children: b("voiceSession.transcriptHint", "Spoken turns in this conversation — kept out of your typed chat.")
36
37
  })]
37
- }), /* @__PURE__ */ u("button", {
38
+ }), /* @__PURE__ */ d("button", {
38
39
  type: "button",
39
- onClick: p,
40
+ onClick: m,
40
41
  className: "flex size-8 items-center justify-center rounded-full text-text-secondary transition-colors hover:bg-bg-raised hover:text-text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong",
41
- "aria-label": y("voiceSession.transcriptClose", "Close the transcript"),
42
+ "aria-label": b("voiceSession.transcriptClose", "Close the transcript"),
42
43
  "data-testid": "assistant-voice-transcript-close",
43
- children: /* @__PURE__ */ u(l, { className: "size-4" })
44
+ children: /* @__PURE__ */ d(u, { className: "size-4" })
44
45
  })]
45
46
  }),
46
- _ ? /* @__PURE__ */ u(i, {
47
- onShowEarlier: _,
48
- disabled: v
47
+ v ? /* @__PURE__ */ d(a, {
48
+ onShowEarlier: v,
49
+ disabled: y
49
50
  }) : null,
50
- /* @__PURE__ */ u(r, { turns: f }),
51
- (m || h) && f.length > 0 ? /* @__PURE__ */ d("div", {
51
+ /* @__PURE__ */ d(i, { turns: p }),
52
+ (h || g) && p.length > 0 ? /* @__PURE__ */ f("div", {
52
53
  className: "flex items-center justify-end gap-2 border-t border-border-subtle px-4 py-3",
53
- children: [m ? /* @__PURE__ */ d("button", {
54
+ children: [h ? /* @__PURE__ */ f("button", {
54
55
  type: "button",
55
- onClick: m,
56
+ onClick: h,
56
57
  className: "flex items-center gap-1.5 rounded-lg border border-border-default px-3 py-1.5 text-xs text-text-secondary transition-colors hover:bg-bg-elevated hover:text-text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong",
57
58
  "data-testid": "assistant-voice-save-transcript",
58
- children: [/* @__PURE__ */ u(c, {
59
+ children: [/* @__PURE__ */ d(l, {
59
60
  className: "size-3.5",
60
61
  "aria-hidden": "true"
61
- }), y("voiceSession.save", "Save transcript")]
62
- }) : null, h ? /* @__PURE__ */ d("button", {
62
+ }), b("voiceSession.save", "Save transcript")]
63
+ }) : null, g ? /* @__PURE__ */ f("button", {
63
64
  type: "button",
64
- onClick: h,
65
+ onClick: g,
65
66
  className: "flex items-center gap-1.5 rounded-lg bg-action-primary-bg px-3 py-1.5 text-xs font-medium text-action-primary-fg transition-opacity hover:opacity-90 focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong",
66
67
  "data-testid": "assistant-voice-continue-in-chat",
67
- children: [y("voiceSession.continueInChat", "Continue in chat"), /* @__PURE__ */ u(s, {
68
+ children: [b("voiceSession.continueInChat", "Continue in chat"), /* @__PURE__ */ d(c, {
68
69
  className: "size-3.5",
69
70
  "aria-hidden": "true"
70
71
  })]
@@ -74,4 +75,4 @@ var f = ({ turns: f, onClose: p, onSave: m, onContinueInChat: h, closeOnEscape:
74
75
  });
75
76
  };
76
77
  //#endregion
77
- export { f as VoiceTranscriptDrawer };
78
+ export { p as VoiceTranscriptDrawer };
@@ -1 +1 @@
1
- {"version":3,"file":"voiceSessionEscape.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/voiceSessionEscape.ts"],"names":[],"mappings":"AAwBA;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,gFAAqD,CAAC;AAE9F;;;;;;;;GAQG;AACH,eAAO,MAAM,2BAA2B,iDACI,CAAC;AAE7C,MAAM,MAAM,wBAAwB,GAAG,QAAQ,GAAG,kBAAkB,GAAG,KAAK,CAAC;AAE7E;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,gBAAgB,EAAE,OAAO,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;CACzB,GAAG,wBAAwB,CAI3B;AAkDD;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE;IAC/C,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,eAAe,GAAG,kBAAkB,CAAC,CAAC;CAC3D,GAAG,OAAO,CAOV"}
1
+ {"version":3,"file":"voiceSessionEscape.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/voiceSessionEscape.ts"],"names":[],"mappings":"AA2BA;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,gFAAqD,CAAC;AAE9F;;;;;;;;GAQG;AACH,eAAO,MAAM,2BAA2B,iDACI,CAAC;AAE7C,MAAM,MAAM,wBAAwB,GAAG,QAAQ,GAAG,kBAAkB,GAAG,KAAK,CAAC;AAE7E;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,gBAAgB,EAAE,OAAO,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;CACzB,GAAG,wBAAwB,CAI3B;AAmCD;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE;IAC/C,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,eAAe,GAAG,kBAAkB,CAAC,CAAC;CAC3D,GAAG,OAAO,CAOV"}
@@ -1,22 +1,19 @@
1
1
  import { focusIsInsidePanel as e } from "../panelOverlays.js";
2
- import { ASSISTANT_DIALOG_SELECTOR as t } from "../assistantOverlayState.js";
2
+ import { ASSISTANT_DIALOG_SELECTOR as t, closestAround as n } from "../assistantOverlayState.js";
3
3
  //#region src/shared/assistant/ui/voice/voiceSessionEscape.ts
4
- var n = `${t},[aria-modal="true"]`, r = "[aria-modal=\"true\"],[role=\"alertdialog\"]";
5
- function i(e) {
6
- return e.defaultPrevented || e.layerAbove ? "ignore" : e.transcriptOpen ? "close-transcript" : "end";
7
- }
4
+ var r = `${t},[aria-modal="true"]`, i = "[aria-modal=\"true\"],[role=\"alertdialog\"]";
8
5
  function a(e) {
9
- return typeof e == "object" && !!e && "closest" in e && typeof e.closest == "function";
6
+ return e.defaultPrevented || e.layerAbove ? "ignore" : e.transcriptOpen ? "close-transcript" : "end";
10
7
  }
11
8
  function o(e) {
12
- return a(e) ? e.closest(n) : null;
9
+ return n(e, r);
13
10
  }
14
11
  function s(t, n) {
15
12
  return !(!t || e(n, t) || n && t.contains(n));
16
13
  }
17
14
  function c(e) {
18
- let { target: t, session: n, doc: i } = e;
19
- return s(o(t), n) || s(o(i.activeElement), n) ? !0 : Array.from(i.querySelectorAll(r)).some((e) => s(e, n));
15
+ let { target: t, session: n, doc: r } = e;
16
+ return s(o(t), n) || s(o(r.activeElement), n) ? !0 : Array.from(r.querySelectorAll(i)).some((e) => s(e, n));
20
17
  }
21
18
  //#endregion
22
- export { n as VOICE_ESCAPE_LAYER_SELECTOR, r as VOICE_ESCAPE_MODAL_SELECTOR, c as escapeBelongsToLayerAbove, i as voiceSessionEscapeAction };
19
+ export { r as VOICE_ESCAPE_LAYER_SELECTOR, i as VOICE_ESCAPE_MODAL_SELECTOR, c as escapeBelongsToLayerAbove, a as voiceSessionEscapeAction };
@@ -14,7 +14,9 @@ interface Options {
14
14
  * anyway and were just adding visible "shortcut listed, doesn't work"
15
15
  * inconsistencies. The shortcuts here match the in-app shortcuts modal.
16
16
  *
17
- * - Escape: Close panel
17
+ * - Escape: back out of the topmost layer — a full-surface overlay (history,
18
+ * preview), else nothing here while a live voice session owns the key (it
19
+ * closes its transcript, then ends), else close the panel
18
20
  * - Ctrl/Cmd+Shift+N: New conversation
19
21
  * - Ctrl/Cmd+Shift+E: Export (triggers click on export button)
20
22
  * - /: Focus input (only when no input/textarea is already focused)
@@ -1 +1 @@
1
- {"version":3,"file":"useAssistantKeyboardShortcuts.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/useAssistantKeyboardShortcuts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIlD,UAAU,OAAO;IACf,QAAQ,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC3C,QAAQ,CAAC,EAAE,SAAS,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;IACjD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,6BAA6B,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,QA+ErF"}
1
+ {"version":3,"file":"useAssistantKeyboardShortcuts.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/useAssistantKeyboardShortcuts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIlD,UAAU,OAAO;IACf,QAAQ,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC3C,QAAQ,CAAC,EAAE,SAAS,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;IACjD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,6BAA6B,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,QAyFrF"}
@@ -1,41 +1,41 @@
1
1
  import { useAssistantStore as e } from "./store.js";
2
- import { focusIsInsidePanel as t, panelOwnsEscape as n } from "./ui/panelOverlays.js";
3
- import { useEffect as r } from "react";
2
+ import { focusIsInsidePanel as t, panelOwnsEscape as n, voiceSessionOwnsEscape as r } from "./ui/panelOverlays.js";
3
+ import { useEffect as i } from "react";
4
4
  //#region src/shared/assistant/useAssistantKeyboardShortcuts.ts
5
- function i({ panelRef: i, inputRef: a, onClose: o }) {
6
- r(() => {
7
- let r = (r) => {
8
- let s = i.current;
9
- if (!s) return;
10
- let c = document.activeElement;
11
- if (r.key === "Escape") {
12
- if (!n(s, c, document.body)) return;
13
- r.preventDefault(), o();
5
+ function a({ panelRef: a, inputRef: o, onClose: s }) {
6
+ i(() => {
7
+ let i = (i) => {
8
+ let c = a.current;
9
+ if (!c) return;
10
+ let l = document.activeElement;
11
+ if (i.key === "Escape") {
12
+ if (i.defaultPrevented || !n(c, l, document.body) || r(c)) return;
13
+ i.preventDefault(), s();
14
14
  return;
15
15
  }
16
- if (!t(s, c)) return;
17
- let l = r.ctrlKey || r.metaKey;
18
- if (l && r.shiftKey && (r.key === "N" || r.key === "n")) {
19
- r.preventDefault(), e.getState().createConversation();
16
+ if (!t(c, l)) return;
17
+ let u = i.ctrlKey || i.metaKey;
18
+ if (u && i.shiftKey && (i.key === "N" || i.key === "n")) {
19
+ i.preventDefault(), e.getState().createConversation();
20
20
  return;
21
21
  }
22
- if (l && r.shiftKey && (r.key === "E" || r.key === "e")) {
23
- r.preventDefault();
24
- let e = s.querySelector("[data-testid=\"assistant-more\"]");
22
+ if (u && i.shiftKey && (i.key === "E" || i.key === "e")) {
23
+ i.preventDefault();
24
+ let e = c.querySelector("[data-testid=\"assistant-more\"]");
25
25
  e?.focus(), e?.click();
26
26
  return;
27
27
  }
28
- if (r.key === "/" && !l && !r.shiftKey) {
29
- let e = c?.tagName;
30
- e !== "INPUT" && e !== "TEXTAREA" && (r.preventDefault(), a?.current?.focus());
28
+ if (i.key === "/" && !u && !i.shiftKey) {
29
+ let e = l?.tagName;
30
+ e !== "INPUT" && e !== "TEXTAREA" && (i.preventDefault(), o?.current?.focus());
31
31
  }
32
32
  };
33
- return document.addEventListener("keydown", r), () => document.removeEventListener("keydown", r);
33
+ return document.addEventListener("keydown", i), () => document.removeEventListener("keydown", i);
34
34
  }, [
35
- i,
36
35
  a,
37
- o
36
+ o,
37
+ s
38
38
  ]);
39
39
  }
40
40
  //#endregion
41
- export { i as useAssistantKeyboardShortcuts };
41
+ export { a as useAssistantKeyboardShortcuts };
@@ -16,6 +16,7 @@ export { useOnClickOutside, useOnClickOutsideWithRef } from './useOnClickOutside
16
16
  export { useKeyPress, useKeyboardShortcut } from './useKeyPress';
17
17
  export { useCopyToClipboard } from './useCopyToClipboard';
18
18
  export { useExclusiveMenu } from './useExclusiveMenu';
19
+ export { useReturnFocus, type UseReturnFocusOptions } from './useReturnFocus';
19
20
  export { useLocalStorage } from './useLocalStorage';
20
21
  export { useSessionStorage } from './useSessionStorage';
21
22
  export { usePrevious, usePreviousDistinct, usePreviousHistory } from './usePrevious';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/hooks/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAc,MAAM,OAAO,CAAC;AACnC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAEvD;;GAEG;AACH,eAAO,MAAM,oBAAoB,8CAA2D,CAAC;AAE7F;;GAEG;AACH,wBAAgB,uBAAuB,2BAMtC;AAOD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACnG,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGtD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACrF,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC/E,OAAO,EACL,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,GACzB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAG9E,cAAc,aAAa,CAAC;AAG5B,cAAc,WAAW,CAAC;AAG1B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGlC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,YAAY,EAAE,gCAAgC,EAAE,MAAM,6BAA6B,CAAC;AACpF,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,6BAA6B,CAAC;AACrC,YAAY,EACV,kBAAkB,EAClB,6BAA6B,EAC7B,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAGjG,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,uBAAuB,EACvB,sBAAsB,EACtB,cAAc,EACd,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,6BAA6B,EAC7B,mBAAmB,GACpB,MAAM,iCAAiC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/hooks/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAc,MAAM,OAAO,CAAC;AACnC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAEvD;;GAEG;AACH,eAAO,MAAM,oBAAoB,8CAA2D,CAAC;AAE7F;;GAEG;AACH,wBAAgB,uBAAuB,2BAMtC;AAOD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACnG,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAG9E,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACrF,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC/E,OAAO,EACL,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,GACzB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAG9E,cAAc,aAAa,CAAC;AAG5B,cAAc,WAAW,CAAC;AAG1B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGlC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,YAAY,EAAE,gCAAgC,EAAE,MAAM,6BAA6B,CAAC;AACpF,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,6BAA6B,CAAC;AACrC,YAAY,EACV,kBAAkB,EAClB,6BAA6B,EAC7B,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAGjG,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,uBAAuB,EACvB,sBAAsB,EACtB,cAAc,EACd,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,6BAA6B,EAC7B,mBAAmB,GACpB,MAAM,iCAAiC,CAAC"}
@@ -0,0 +1,56 @@
1
+ import { RefObject } from 'react';
2
+ /** The slice of a document this reads. */
3
+ export type FocusReturnDocument = Pick<Document, 'activeElement' | 'body'>;
4
+ type Focusable = Element & {
5
+ focus(options?: FocusOptions): void;
6
+ };
7
+ /**
8
+ * Was focus dropped, rather than moved somewhere on purpose?
9
+ *
10
+ * Yes when nothing is focused, `<body>` is (where the browser puts it when the
11
+ * focused element is removed), the focused element is no longer in the
12
+ * document, or it is inside `layer`, the layer that is closing.
13
+ */
14
+ export declare function focusWasDropped(doc: FocusReturnDocument, layer?: Pick<Node, 'contains'> | null): boolean;
15
+ /**
16
+ * Is `candidate` worth trying: still in the document, able to take focus at
17
+ * all, and not disabled?
18
+ */
19
+ export declare function canReturnFocusTo(candidate: Element | null | undefined): candidate is Focusable;
20
+ /**
21
+ * Focus the first candidate that takes it, and return it; null when none did.
22
+ *
23
+ * ★ Checked by reading focus back. `focus()` fails silently on an element that
24
+ * is hidden (`display: none`, such as the launcher on a phone while the panel
25
+ * is open) or inside an `inert` subtree (the composer behind a live voice
26
+ * session), so "it did not throw" says nothing. The next candidate gets its
27
+ * turn instead.
28
+ */
29
+ export declare function returnFocusTo(doc: FocusReturnDocument, candidates: ReadonlyArray<Element | null | undefined>): Element | null;
30
+ /** What is focused, when it is a real control rather than `<body>`. */
31
+ export declare function focusedControl(doc: FocusReturnDocument): Element | null;
32
+ export interface UseReturnFocusOptions {
33
+ /**
34
+ * Where focus goes when the opener is gone: the nearest ancestor of the
35
+ * layer matching this selector, found while the layer is still mounted.
36
+ * The assistant's layers pass the panel root, which is focusable
37
+ * (`tabIndex=-1`) and keeps focus inside the assistant.
38
+ */
39
+ fallbackSelector?: string;
40
+ }
41
+ /**
42
+ * Return focus to this layer's opener when it closes.
43
+ *
44
+ * The opener is what had focus when the layer first RENDERED, before any
45
+ * effect of its own (the voice session focuses End on open) moves focus into
46
+ * it. If that element is gone by the time the layer mounts, what focus fell
47
+ * back to then is used instead: the post-session transcript drawer renders
48
+ * while End still has focus, End is removed in that same commit, and by the
49
+ * time the drawer's effects run the voice session has handed focus back to
50
+ * the voice button.
51
+ *
52
+ * @param layerRef the layer's root element.
53
+ */
54
+ export declare function useReturnFocus(layerRef: RefObject<Element | null>, { fallbackSelector }?: UseReturnFocusOptions): void;
55
+ export {};
56
+ //# sourceMappingURL=useReturnFocus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useReturnFocus.d.ts","sourceRoot":"","sources":["../../../src/shared/hooks/useReturnFocus.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE5D,0CAA0C;AAC1C,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAAC,CAAC;AAE3E,KAAK,SAAS,GAAG,OAAO,GAAG;IAAE,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI,CAAA;CAAE,CAAC;AAOnE;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,mBAAmB,EACxB,KAAK,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,GAAG,IAAI,GACpC,OAAO,CAIT;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,SAAS,IAAI,SAAS,CAK9F;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,mBAAmB,EACxB,UAAU,EAAE,aAAa,CAAC,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,GACpD,OAAO,GAAG,IAAI,CAOhB;AAED,uEAAuE;AACvE,wBAAgB,cAAc,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,GAAG,IAAI,CAGvE;AAID,MAAM,WAAW,qBAAqB;IACpC;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC,EACnC,EAAE,gBAAgB,EAAE,GAAE,qBAA0B,GAC/C,IAAI,CA0BN"}