@burdenoff/fe-libs 2026.1029.9 → 2026.1029.11

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.
@@ -2,7 +2,8 @@ import { ReactNode } from 'react';
2
2
  import { QuotaKind } from '../quota';
3
3
  import { AIAssistantPanelProps } from './AIAssistantPanel';
4
4
  import { AssistantNavigate } from './AssistantMarkdownRenderer';
5
- import { AssistantOverlayKeys } from './assistantOverlayState';
5
+ import { AssistantPresentation } from './composer/AssistantComposer';
6
+ import { AssistantOverlayKeys, AssistantSurface } from './assistantOverlayState';
6
7
  export interface AssistantOverlayContextValue {
7
8
  isOpen: boolean;
8
9
  open: () => void;
@@ -29,6 +30,43 @@ export interface AssistantOverlayContextValue {
29
30
  * that builds this value itself keeps compiling.
30
31
  */
31
32
  registerCloseGuard?: (guard: () => boolean) => () => void;
33
+ /** How the assistant is presented. `classic` unless the provider was given `compact`. */
34
+ presentation: AssistantPresentation;
35
+ /**
36
+ * BOFF-10178: what the open assistant is showing, in the ONE container it
37
+ * always renders: the Quick assistant `window` or the full `panel`. Always
38
+ * `panel` in the classic presentation. Session-scoped, like `isOpen`.
39
+ */
40
+ surface: AssistantSurface;
41
+ /** The Quick assistant window is hidden but mounted (compact only; false in classic). */
42
+ minimized: boolean;
43
+ /**
44
+ * The FULL assistant is open and showing: the state a header button that
45
+ * opens it reports as `aria-expanded`. In classic: the same as `isOpen`.
46
+ */
47
+ fullOpen: boolean;
48
+ /**
49
+ * Open the FULL assistant, whatever it is doing now: closed, the Quick
50
+ * window, or minimized. The same instance is kept, so a draft and a turn in
51
+ * flight carry over. Idempotent. This is what Ctrl/Cmd+Shift+A, the
52
+ * `<prefix>:toggle-ai-assistant` event with `detail.open: true`, and a
53
+ * product's own header button call. In classic it is `open()`.
54
+ */
55
+ openFull: () => void;
56
+ /**
57
+ * Open the Quick assistant window — or, when it is minimized, bring it back.
58
+ * The launcher calls it. Does nothing to a full panel that is already open
59
+ * and, in classic, is `open()`.
60
+ */
61
+ openWindow: () => void;
62
+ /** Hide the Quick assistant window, keeping everything in it. A no-op for the full panel and in classic. */
63
+ minimize: () => void;
64
+ /**
65
+ * The full panel is Expanded to its fixed 760 px (compact, N2). Reported by
66
+ * the panel itself; per session, never stored. Always false in classic.
67
+ */
68
+ expanded: boolean;
69
+ setExpanded: (expanded: boolean) => void;
32
70
  }
33
71
  /** The overlay state in force, or null when no provider is mounted. */
34
72
  export declare function useAssistantOverlayOrNull(): AssistantOverlayContextValue | null;
@@ -73,6 +111,19 @@ export interface AssistantOverlayProviderProps {
73
111
  product: string;
74
112
  onExhausted: (kind: QuotaKind, event: Event) => void;
75
113
  };
114
+ /**
115
+ * BOFF-10178: how the overlay is presented. Absent or `classic`: the overlay
116
+ * of before, attribute for attribute (the eager write of the legacy dock key
117
+ * included). `compact` opts this product into the Quick assistant window, the
118
+ * `surface`, the N2 geometry, the D1-A layout rule, the published insets of
119
+ * the new geometry and the keyboard-aware sheet.
120
+ *
121
+ * ★ On the PROVIDER, not the overlay, because the provider owns what it
122
+ * changes (the open and layout state, the shortcut and the published
123
+ * variables). The overlay reads it from here and hands the panel
124
+ * `presentation="compact"` itself, so the two cannot disagree.
125
+ */
126
+ presentation?: AssistantPresentation;
76
127
  children: ReactNode;
77
128
  }
78
129
  /**
@@ -88,7 +139,7 @@ export interface AssistantOverlayProviderProps {
88
139
  * Mount ONE per page: the published dock width and panel inset are single
89
140
  * `<html>` variables.
90
141
  */
91
- export declare function AssistantOverlayProvider({ keyPrefix, quota, children, }: AssistantOverlayProviderProps): import('react/jsx-runtime').JSX.Element;
142
+ export declare function AssistantOverlayProvider({ keyPrefix, quota, presentation, children, }: AssistantOverlayProviderProps): import('react/jsx-runtime').JSX.Element;
92
143
  /** What the overlay hands the panel it renders. */
93
144
  export interface AssistantOverlayPanelProps {
94
145
  panelId: string;
@@ -99,7 +150,29 @@ export interface AssistantOverlayPanelProps {
99
150
  onNavigate?: AssistantNavigate;
100
151
  /** Opens in a new tab, leaving this page alone: a tap on it asks nothing (BOFF-8060 N4). */
101
152
  isShellLessTarget?: (path: string) => boolean;
153
+ /**
154
+ * Compact presentation only (BOFF-10178) — absent in classic, so a product's
155
+ * own `renderPanel` wrapper that spreads these onto the shared panel passes
156
+ * exactly what it passed before. The overlay's own values win over
157
+ * `panelProps`.
158
+ */
159
+ presentation?: AssistantPresentation;
160
+ /** Which surface this one panel is shown in. */
161
+ surface?: AssistantSurface;
162
+ /** The window's "Open full assistant": the same instance, shown as the full panel. */
163
+ onOpenFull?: () => void;
164
+ /** The window's "Minimize" (and its Escape): hidden, mounted, `visible` false. */
165
+ onMinimize?: () => void;
166
+ /** Told when Expand/Restore is pressed, so the container takes the N2 width. */
167
+ onExpandedChange?: (expanded: boolean) => void;
102
168
  }
169
+ /**
170
+ * The props the overlay itself decides, which a product's `panelProps` may not
171
+ * set. `presentation` and `onExpandedChange` are NOT in it: both were already
172
+ * accepted in `panelProps` (Slice 2), and the overlay's value is merged over
173
+ * them only in the compact presentation.
174
+ */
175
+ type AssistantOverlayOwnedPanelProp = 'panelId' | 'visible' | 'onClose' | 'docked' | 'onToggleDock' | 'onNavigate' | 'isShellLessTarget' | 'surface' | 'onOpenFull' | 'onMinimize';
103
176
  export interface AssistantOverlayProps {
104
177
  /** Panel id handed to the panel. */
105
178
  panelId?: string;
@@ -118,7 +191,7 @@ export interface AssistantOverlayProps {
118
191
  * closed panel's turns and deletes queued keeps going out, and a reopened
119
192
  * panel finds the list already current.
120
193
  */
121
- panelProps?: Omit<AIAssistantPanelProps, keyof AssistantOverlayPanelProps>;
194
+ panelProps?: Omit<AIAssistantPanelProps, AssistantOverlayOwnedPanelProp>;
122
195
  /**
123
196
  * Render something other than the shared `AIAssistantPanel` — a product
124
197
  * wrapper around it. Receives the props the overlay owns; spread them.
@@ -158,3 +231,4 @@ export interface AssistantOverlayProps {
158
231
  * `AssistantOverlayProvider` above it — there is no state to show.
159
232
  */
160
233
  export declare function AssistantOverlay(props: AssistantOverlayProps): import('react/jsx-runtime').JSX.Element | null;
234
+ export {};
@@ -2,10 +2,11 @@ import { quotaExhaustedEventName as e } from "../quota.js";
2
2
  import { useAssistantTr as t } from "../i18n.js";
3
3
  import { assistantPanelOwnsEscape as n } from "./panelOverlays.js";
4
4
  import { AssistantPreviewBridgeHost as r } from "../preview/bridgeHost.js";
5
- import { ASSISTANT_DOCK_WIDTH_VAR as i, ASSISTANT_OVERLAY_DESKTOP_QUERY as a, ASSISTANT_OVERLAY_TOP_VAR as o, ASSISTANT_PANEL_INSET_VAR as s, ASSISTANT_SHEET_BOTTOM_VAR as c, assistantLauncherBottom as l, assistantLauncherRight as u, assistantOverlayClassName as d, assistantOverlayEscapeAction as f, assistantOverlayKeys as p, assistantQuotaKindOf as m, closestAround as h, createAssistantNavigate as g, isAssistantToggleShortcut as _, nextAssistantOpenState as v, publishedAssistantDockWidth as y, publishedAssistantPanelInset as b, readAssistantOverlayFlag as x, requestedAssistantOpenState as S, writeAssistantOverlayFlag as C } from "./assistantOverlayState.js";
6
- import { useAssistantServerHistory as w } from "../history/useAssistantServerHistory.js";
7
- import { AssistantCloseGuardContext as T } from "./closeGuard.js";
5
+ import { ASSISTANT_COMPACT_DOCKED_DEFAULT_QUERY as i, ASSISTANT_DOCK_WIDTH_VAR as a, ASSISTANT_OVERLAY_DESKTOP_QUERY as o, ASSISTANT_OVERLAY_TOP_VAR as s, ASSISTANT_PANEL_INSET_VAR as c, ASSISTANT_SHEET_BOTTOM_VAR as l, ASSISTANT_WINDOW_BOTTOM_VAR as u, assistantCompactLauncherVisibility as d, assistantCompactOverlayClassName as f, assistantCompactOverlayKeys as p, assistantLauncherBottom as ee, assistantLauncherRight as m, assistantOverlayClassName as te, assistantOverlayEscapeAction as ne, assistantOverlayKeys as re, assistantQuotaKindOf as h, assistantWindowBottom as g, closestAround as ie, createAssistantNavigate as ae, isAssistantSurface as _, isAssistantToggleShortcut as oe, nextAssistantOpenState as v, publishedAssistantDockWidth as y, publishedAssistantPanelInset as se, publishedCompactDockWidth as ce, publishedCompactPanelInset as b, readAssistantLayoutChoice as le, readAssistantLegacyDockChoice as ue, readAssistantOverlayFlag as x, requestedAssistantOpenState as S, resolveCompactDocked as C, writeAssistantLayoutChoice as de, writeAssistantOverlayFlag as w } from "./assistantOverlayState.js";
6
+ import { useAssistantServerHistory as T } from "../history/useAssistantServerHistory.js";
7
+ import { AssistantCloseGuardContext as fe } from "./closeGuard.js";
8
8
  import { AIAssistantPanel as E } from "./AIAssistantPanel.js";
9
+ import { useAssistantVisualViewport as pe } from "./useAssistantVisualViewport.js";
9
10
  import { createContext as D, useCallback as O, useContext as k, useEffect as A, useMemo as j, useRef as M, useState as N, useSyncExternalStore as P } from "react";
10
11
  import { Sparkles as F } from "lucide-react";
11
12
  import { jsx as I, jsxs as L } from "react/jsx-runtime";
@@ -23,195 +24,395 @@ function V() {
23
24
  var H = () => typeof window > "u" ? void 0 : window.sessionStorage, U = () => typeof window > "u" ? void 0 : window.localStorage;
24
25
  function W(e) {
25
26
  if (typeof window > "u" || typeof window.matchMedia != "function") return () => {};
26
- let t = window.matchMedia(a);
27
+ let t = window.matchMedia(o);
27
28
  return t.addEventListener("change", e), () => t.removeEventListener("change", e);
28
29
  }
29
30
  function G() {
30
31
  return typeof window < "u" && typeof window.matchMedia == "function" && window.matchMedia("(min-width: 640px)").matches;
31
32
  }
32
- function K() {
33
+ function me() {
33
34
  return P(W, G, () => !1);
34
35
  }
35
- function q(t, n) {
36
+ function K(t, n) {
36
37
  let r = M(n);
37
38
  A(() => {
38
39
  r.current = n;
39
40
  }, [n]), A(() => {
40
41
  if (!t || typeof window > "u") return;
41
- let n = e(t), i = (e) => r.current(m(e), e);
42
+ let n = e(t), i = (e) => r.current(h(e), e);
42
43
  return window.addEventListener(n, i), () => window.removeEventListener(n, i);
43
44
  }, [t]);
44
45
  }
45
- var J = () => {};
46
- function Y({ keyPrefix: e, quota: t, children: n }) {
47
- let r = j(() => p(e), [e]), [a, o] = N(() => x(H, r.openStorageKey)), [c, l] = N(() => x(U, r.dockStorageKey)), u = M(null), d = M(a);
46
+ var he = () => {};
47
+ function q(e) {
48
+ if (typeof window > "u" || typeof window.matchMedia != "function") return () => {};
49
+ let t = window.matchMedia(i);
50
+ return t.addEventListener("change", e), () => t.removeEventListener("change", e);
51
+ }
52
+ function J() {
53
+ return typeof window < "u" && typeof window.matchMedia == "function" && window.matchMedia(i).matches;
54
+ }
55
+ var Y = () => () => {}, X = () => !1;
56
+ function ge(e) {
57
+ return P(e ? q : Y, e ? J : X, X);
58
+ }
59
+ function _e({ keyPrefix: e, quota: t, presentation: n = "classic", children: r }) {
60
+ let i = j(() => re(e), [e]), o = j(() => p(e), [e]), s = n === "compact", l = M(s);
61
+ A(() => {
62
+ l.current = s;
63
+ }, [s]);
64
+ let [u, d] = N(() => x(H, i.openStorageKey)), [f, ee] = N(() => x(U, i.dockStorageKey)), [m, te] = N(() => {
65
+ if (!s) return "panel";
66
+ try {
67
+ let e = H()?.getItem(o.surfaceStorageKey);
68
+ return _(e) ? e : "panel";
69
+ } catch {
70
+ return "panel";
71
+ }
72
+ }), [ne, h] = N(() => s && x(H, o.minimizedStorageKey)), g = s && u && m === "window" && ne, [ie, ae] = N(!1), T = s && u && m === "panel" && ie, [fe] = N(() => s ? {
73
+ explicit: le(U, o.layoutStorageKey),
74
+ legacy: ue(U, i.dockStorageKey)
75
+ } : {
76
+ explicit: null,
77
+ legacy: null
78
+ }), [E, pe] = N(null), D = ge(s), k = s ? C({
79
+ explicit: E ?? fe.explicit,
80
+ legacy: fe.legacy,
81
+ wideViewport: D
82
+ }) : f, P = M(k);
48
83
  A(() => {
49
- d.current = a;
50
- }, [a]);
51
- let f = O(() => u.current?.() === !0, []), m = O((e) => (u.current = e, () => {
52
- u.current === e && (u.current = null);
53
- }), []), h = O(() => o(!0), []), g = O(() => {
54
- f() || o(!1);
55
- }, [f]), w = O(() => {
56
- d.current && f() || o((e) => !e);
57
- }, [f]), T = O(() => l((e) => !e), []);
84
+ P.current = k;
85
+ }, [k]);
86
+ let F = M(null), L = M(u);
58
87
  A(() => {
59
- C(H, r.openStorageKey, a);
60
- }, [r.openStorageKey, a]), A(() => {
61
- C(U, r.dockStorageKey, c);
62
- }, [r.dockStorageKey, c]), A(() => {
88
+ L.current = u;
89
+ }, [u]);
90
+ let z = M(!1), B = u && (!s || m === "panel" && !g);
91
+ A(() => {
92
+ z.current = B;
93
+ }, [B]);
94
+ let V = O(() => {
95
+ let e = F.current?.() === !0;
96
+ return e && l.current && h(!1), e;
97
+ }, []), W = O((e) => (F.current = e, () => {
98
+ F.current === e && (F.current = null);
99
+ }), []), G = O(() => {
100
+ d(!0), te("panel"), h(!1);
101
+ }, []), q = O(() => {
102
+ d(!1), h(!1), ae(!1);
103
+ }, []), J = O(() => {
104
+ l.current ? G() : d(!0);
105
+ }, [G]), Y = O(() => {
106
+ V() || (l.current ? q() : d(!1));
107
+ }, [V, q]), X = O(() => {
108
+ if (l.current) {
109
+ if (z.current) {
110
+ if (V()) return;
111
+ q();
112
+ } else G();
113
+ return;
114
+ }
115
+ L.current && V() || d((e) => !e);
116
+ }, [
117
+ V,
118
+ q,
119
+ G
120
+ ]), _e = O(() => {
121
+ if (l.current) {
122
+ let e = P.current ? "floating" : "docked";
123
+ P.current = e === "docked", pe(e);
124
+ return;
125
+ }
126
+ ee((e) => !e);
127
+ }, []), ve = J, ye = O(() => {
128
+ if (!l.current) {
129
+ d(!0);
130
+ return;
131
+ }
132
+ z.current || (d(!0), te("window"), h(!1));
133
+ }, []), be = O(() => {
134
+ !l.current || !L.current || z.current || h(!0);
135
+ }, []);
136
+ A(() => {
137
+ w(H, i.openStorageKey, u);
138
+ }, [i.openStorageKey, u]), A(() => {
139
+ s || w(U, i.dockStorageKey, f);
140
+ }, [
141
+ s,
142
+ i.dockStorageKey,
143
+ f
144
+ ]), A(() => {
145
+ !s || E === null || de(U, o.layoutStorageKey, E);
146
+ }, [
147
+ s,
148
+ o.layoutStorageKey,
149
+ E
150
+ ]), A(() => {
151
+ if (s) try {
152
+ H()?.setItem(o.surfaceStorageKey, m);
153
+ } catch {}
154
+ }, [
155
+ s,
156
+ o.surfaceStorageKey,
157
+ m
158
+ ]), A(() => {
159
+ s && w(H, o.minimizedStorageKey, g);
160
+ }, [
161
+ s,
162
+ o.minimizedStorageKey,
163
+ g
164
+ ]), A(() => {
63
165
  if (typeof window > "u") return;
64
166
  let e = (e) => {
65
167
  let t = S(e);
66
- d.current && !v(!0, t) && u.current?.() === !0 || o((e) => v(e, t));
168
+ if (l.current) {
169
+ t === !0 ? G() : t === !1 ? L.current && !V() && q() : z.current ? V() || q() : G();
170
+ return;
171
+ }
172
+ L.current && !v(!0, t) && F.current?.() === !0 || d((e) => v(e, t));
67
173
  };
68
- return window.addEventListener(r.toggleEvent, e), () => window.removeEventListener(r.toggleEvent, e);
69
- }, [r.toggleEvent]), A(() => {
174
+ return window.addEventListener(i.toggleEvent, e), () => window.removeEventListener(i.toggleEvent, e);
175
+ }, [
176
+ i.toggleEvent,
177
+ G,
178
+ q,
179
+ V
180
+ ]), A(() => {
70
181
  if (typeof document > "u") return;
71
182
  let e = (e) => {
72
- _(e) && (e.preventDefault(), !(d.current && u.current?.() === !0) && o((e) => !e));
183
+ if (oe(e)) {
184
+ if (e.preventDefault(), l.current) {
185
+ z.current ? V() || q() : G();
186
+ return;
187
+ }
188
+ L.current && F.current?.() === !0 || d((e) => !e);
189
+ }
73
190
  };
74
191
  return document.addEventListener("keydown", e), () => document.removeEventListener("keydown", e);
75
- }, []), q(t?.product ?? null, t?.onExhausted ?? J);
76
- let E = K(), D = y({
77
- isOpen: a,
78
- docked: c,
79
- isDesktop: E
80
- }), k = b({
81
- isOpen: a,
82
- docked: c,
83
- isDesktop: E
192
+ }, [
193
+ G,
194
+ q,
195
+ V
196
+ ]), K(t?.product ?? null, t?.onExhausted ?? he);
197
+ let Z = me(), Q = s ? ce({
198
+ isOpen: u,
199
+ docked: k,
200
+ isDesktop: Z,
201
+ surface: m,
202
+ expanded: T
203
+ }) : y({
204
+ isOpen: u,
205
+ docked: f,
206
+ isDesktop: Z
207
+ }), $ = s ? b({
208
+ isOpen: u,
209
+ docked: k,
210
+ isDesktop: Z,
211
+ surface: m,
212
+ expanded: T
213
+ }) : se({
214
+ isOpen: u,
215
+ docked: f,
216
+ isDesktop: Z
84
217
  });
85
218
  A(() => {
86
219
  if (typeof document > "u") return;
87
220
  let e = document.documentElement.style;
88
- return e.setProperty(i, `${D}px`), () => {
89
- e.removeProperty(i);
221
+ return e.setProperty(a, `${Q}px`), () => {
222
+ e.removeProperty(a);
90
223
  };
91
- }, [D]), A(() => {
224
+ }, [Q]), A(() => {
92
225
  if (typeof document > "u") return;
93
226
  let e = document.documentElement.style;
94
- return e.setProperty(s, `${k}px`), () => {
95
- e.removeProperty(s);
227
+ return e.setProperty(c, `${$}px`), () => {
228
+ e.removeProperty(c);
96
229
  };
97
- }, [k]);
98
- let P = j(() => ({
99
- isOpen: a,
100
- open: h,
101
- close: g,
102
- toggle: w,
103
- docked: c,
104
- toggleDock: T,
105
- dockWidthPx: D,
106
- panelInsetPx: k,
107
- keys: r,
108
- registerCloseGuard: m
230
+ }, [$]);
231
+ let xe = j(() => ({
232
+ isOpen: u,
233
+ open: J,
234
+ close: Y,
235
+ toggle: X,
236
+ docked: k,
237
+ toggleDock: _e,
238
+ dockWidthPx: Q,
239
+ panelInsetPx: $,
240
+ keys: i,
241
+ registerCloseGuard: W,
242
+ presentation: n,
243
+ surface: m,
244
+ minimized: g,
245
+ fullOpen: B,
246
+ openFull: ve,
247
+ openWindow: ye,
248
+ minimize: be,
249
+ expanded: T,
250
+ setExpanded: ae
109
251
  }), [
110
- a,
111
- h,
112
- g,
113
- w,
114
- c,
115
- T,
116
- D,
252
+ u,
253
+ J,
254
+ Y,
255
+ X,
117
256
  k,
118
- r,
119
- m
257
+ _e,
258
+ Q,
259
+ $,
260
+ i,
261
+ W,
262
+ n,
263
+ m,
264
+ g,
265
+ B,
266
+ ve,
267
+ ye,
268
+ be,
269
+ T
120
270
  ]);
121
271
  return /* @__PURE__ */ I(R.Provider, {
122
- value: P,
123
- children: n
272
+ value: xe,
273
+ children: r
124
274
  });
125
275
  }
126
- var X = (e, t) => /* @__PURE__ */ I(E, {
276
+ var ve = (e, t) => /* @__PURE__ */ I(E, {
127
277
  ...e,
128
278
  ...t
129
279
  });
130
- function Z(e) {
280
+ function ye(e) {
131
281
  let t = z();
132
- return t ? /* @__PURE__ */ I(Q, {
282
+ return t ? /* @__PURE__ */ I(be, {
133
283
  state: t,
134
284
  ...e
135
285
  }) : null;
136
286
  }
137
- function Q({ state: e, panelId: i = "ai-assistant", panelProps: a, renderPanel: s, navigate: p, isShellLessTarget: m, topOffsetPx: _ = 56, launcherIcon: v, launcherBottomInset: y = "1.5rem", showLauncher: b = !0, closeOnEscape: x = !0 }) {
138
- let { isOpen: S, close: C, toggle: E, docked: D, toggleDock: O, dockWidthPx: k } = e, M = t();
139
- w(a?.serverHistory === !0);
140
- let [P, R] = N(!1), z = j(() => p ? g({
141
- navigate: p,
142
- isShellLessTarget: m,
287
+ function be({ state: e, panelId: i = "ai-assistant", panelProps: a, renderPanel: o, navigate: c, isShellLessTarget: p, topOffsetPx: re = 56, launcherIcon: h, launcherBottomInset: _ = "1.5rem", showLauncher: oe = !0, closeOnEscape: v = !0 }) {
288
+ let { isOpen: y, close: se, toggle: ce, docked: b, toggleDock: le, dockWidthPx: ue } = e, x = e.presentation === "compact", { surface: S, minimized: C, setExpanded: de } = e, w = t();
289
+ T(a?.serverHistory === !0);
290
+ let [E, D] = N(!1), k = M(null), P = M(null), R = me(), [z, B] = N(0);
291
+ A(() => {
292
+ z !== 0 && k.current?.querySelector("[data-testid=\"assistant-input\"]")?.focus({ preventScroll: !0 });
293
+ }, [z]), pe(k, x && y && !C && !R);
294
+ let V = M(a?.onExpandedChange);
295
+ A(() => {
296
+ V.current = a?.onExpandedChange;
297
+ });
298
+ let H = O((e) => {
299
+ de(e), V.current?.(e);
300
+ }, [de]), U = j(() => c ? ae({
301
+ navigate: c,
302
+ isShellLessTarget: p,
143
303
  isDesktop: G,
144
- collapseSheet: () => R(!1),
304
+ collapseSheet: () => D(!1),
145
305
  openInNewTab: (e) => window.open(e, "_blank", "noopener,noreferrer")
146
- }) : void 0, [p, m]);
306
+ }) : void 0, [c, p]), W = x && S === "window" ? e.minimize : se;
147
307
  A(() => {
148
- if (!S || !x) return;
308
+ if (!y || !v || C) return;
149
309
  let e = (e) => {
150
- f({
310
+ ne({
151
311
  key: e.key,
152
- isOpen: S,
312
+ isOpen: y,
153
313
  alreadyHandled: e.defaultPrevented,
154
314
  dialogOpen: document.querySelector("[role=\"dialog\"],[role=\"alertdialog\"],dialog[open]") !== null,
155
- pressedInsideDialog: h(e.target, "[role=\"dialog\"],[role=\"alertdialog\"],dialog[open]") !== null,
315
+ pressedInsideDialog: ie(e.target, "[role=\"dialog\"],[role=\"alertdialog\"],dialog[open]") !== null,
156
316
  panelOwnsEscape: n()
157
- }) === "close" && (e.preventDefault(), C());
317
+ }) === "close" && (e.preventDefault(), W());
158
318
  };
159
319
  return document.addEventListener("keydown", e), () => document.removeEventListener("keydown", e);
160
320
  }, [
161
- S,
321
+ y,
162
322
  C,
163
- x
323
+ W,
324
+ v
164
325
  ]);
165
- let B = {
326
+ let K = M(C);
327
+ A(() => {
328
+ if (x && C && !K.current) {
329
+ let e = document.activeElement;
330
+ (!e || e === document.body || k.current?.contains(e)) && P.current?.focus({ preventScroll: !0 });
331
+ }
332
+ K.current = C;
333
+ }, [x, C]);
334
+ let he = {
166
335
  panelId: i,
167
- visible: !0,
168
- onClose: C,
169
- docked: D,
170
- onToggleDock: O,
171
- onNavigate: z,
172
- isShellLessTarget: m
173
- }, V = M("overlay.launcher", "AI Assistant"), H = {
174
- [o]: `${_}px`,
175
- [c]: "var(--mobile-tabbar-height, 0px)"
336
+ visible: !C,
337
+ onClose: se,
338
+ docked: b,
339
+ onToggleDock: le,
340
+ onNavigate: U,
341
+ isShellLessTarget: p,
342
+ ...x ? {
343
+ presentation: "compact",
344
+ surface: S,
345
+ onOpenFull: e.openFull,
346
+ onMinimize: e.minimize,
347
+ onExpandedChange: H
348
+ } : {}
349
+ }, q = x ? w("overlay.launcherQuick", "Open quick assistant") : w("overlay.launcher", "AI Assistant"), J = {
350
+ [s]: `${re}px`,
351
+ [l]: "var(--mobile-tabbar-height, 0px)"
352
+ }, Y = {
353
+ ...J,
354
+ [u]: g(_)
355
+ }, X = x ? d({
356
+ isOpen: y,
357
+ surface: S,
358
+ minimized: C
359
+ }) : y ? "desktop-only" : "always", ge = (t) => {
360
+ !x || e.fullOpen ? ce() : y && !C ? e.minimize() : (e.openWindow(), (R || t.detail === 0) && B((e) => e + 1));
176
361
  };
177
362
  return /* @__PURE__ */ L(r, {
178
363
  preview: a?.preview,
179
- children: [S && /* @__PURE__ */ L("div", {
180
- className: d({
181
- expanded: P,
182
- docked: D
364
+ children: [y && /* @__PURE__ */ L("div", {
365
+ ref: k,
366
+ className: x ? f({
367
+ surface: S,
368
+ minimized: C,
369
+ docked: b,
370
+ expanded: e.expanded,
371
+ sheetExpanded: E
372
+ }) : te({
373
+ expanded: E,
374
+ docked: b
183
375
  }),
184
- style: H,
376
+ style: x ? Y : J,
185
377
  "data-testid": "assistant-overlay",
378
+ ...x ? {
379
+ "data-surface": S,
380
+ ...C ? {
381
+ hidden: !0,
382
+ inert: !0,
383
+ "data-minimized": ""
384
+ } : {}
385
+ } : {},
186
386
  children: [/* @__PURE__ */ I("button", {
187
387
  type: "button",
188
- onClick: () => R((e) => !e),
388
+ onClick: () => D((e) => !e),
189
389
  className: "flex w-full shrink-0 justify-center pt-2 pb-1 sm:hidden",
190
- "aria-label": P ? M("sheet.collapse", "Shrink the assistant") : M("sheet.expand", "Expand the assistant"),
191
- "aria-expanded": P,
390
+ "aria-label": E ? w("sheet.collapse", "Shrink the assistant") : w("sheet.expand", "Expand the assistant"),
391
+ "aria-expanded": E,
192
392
  "data-testid": "assistant-sheet-handle",
193
393
  children: /* @__PURE__ */ I("span", { className: "h-1.5 w-10 rounded-full bg-border-strong" })
194
394
  }), /* @__PURE__ */ I("div", {
195
395
  className: "flex min-h-0 flex-1 flex-col",
196
- children: /* @__PURE__ */ I(T.Provider, {
396
+ children: /* @__PURE__ */ I(fe.Provider, {
197
397
  value: e.registerCloseGuard ?? null,
198
- children: s ? s(B) : X(a, B)
398
+ children: o ? o(he) : ve(a, he)
199
399
  })
200
400
  })]
201
- }), b && /* @__PURE__ */ I("button", {
401
+ }), oe && /* @__PURE__ */ I("button", {
402
+ ref: P,
202
403
  type: "button",
203
- onClick: E,
204
- title: M("overlay.launcherTitle", "AI Assistant ({{shortcut}})", { shortcut: "Ctrl+Shift+A" }),
205
- "aria-label": V,
206
- "aria-haspopup": "dialog",
207
- "aria-expanded": S,
404
+ onClick: ge,
405
+ title: x ? q : w("overlay.launcherTitle", "AI Assistant ({{shortcut}})", { shortcut: "Ctrl+Shift+A" }),
406
+ "aria-label": q,
407
+ "aria-haspopup": x ? void 0 : "dialog",
408
+ "aria-expanded": x ? y && !C : y,
208
409
  "data-testid": "assistant-fab",
209
410
  style: {
210
- bottom: l(y),
211
- right: u(k)
411
+ bottom: ee(_),
412
+ right: m(ue)
212
413
  },
213
- className: "fixed z-30 size-14 items-center justify-center rounded-full border border-border-strong bg-[var(--color-accent-soft)] text-action-primary-bg shadow-float transition-colors duration-200 hover:border-action-primary-bg focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] cursor-pointer " + (S ? "hidden sm:inline-flex" : "inline-flex"),
214
- children: v ?? /* @__PURE__ */ I(F, {
414
+ className: "fixed z-30 size-14 items-center justify-center rounded-full border border-border-strong bg-[var(--color-accent-soft)] text-action-primary-bg shadow-float transition-colors duration-200 hover:border-action-primary-bg focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] cursor-pointer " + (X === "hidden" ? "hidden" : X === "desktop-only" ? "hidden sm:inline-flex" : "inline-flex"),
415
+ children: h ?? /* @__PURE__ */ I(F, {
215
416
  className: "size-6",
216
417
  "aria-hidden": "true"
217
418
  })
@@ -219,4 +420,4 @@ function Q({ state: e, panelId: i = "ai-assistant", panelProps: a, renderPanel:
219
420
  });
220
421
  }
221
422
  //#endregion
222
- export { Z as AssistantOverlay, Y as AssistantOverlayProvider, B as useAssistantDockWidth, z as useAssistantOverlayOrNull, V as useAssistantPanelInset, q as useAssistantQuotaExhausted };
423
+ export { ye as AssistantOverlay, _e as AssistantOverlayProvider, B as useAssistantDockWidth, z as useAssistantOverlayOrNull, V as useAssistantPanelInset, K as useAssistantQuotaExhausted };