@av-pi-studio/ui-library 0.0.0-stage → 0.0.115

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 (69) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +137 -2
  3. package/dist/brand/config.d.ts +125 -0
  4. package/dist/brand/index.d.ts +3 -0
  5. package/dist/brand/index.js +6 -0
  6. package/dist/brand/theme-injection.d.ts +9 -0
  7. package/dist/breakpoints.d.ts +34 -0
  8. package/dist/breakpoints.js +32 -0
  9. package/dist/chunks/theme-injection-BHAAhBYz.js +103 -0
  10. package/dist/chunks/token-guard-B85Ysv3w.js +813 -0
  11. package/dist/index.d.ts +13 -0
  12. package/dist/index.js +1049 -0
  13. package/dist/kv-store.d.ts +3 -0
  14. package/dist/primitives/Announcer.d.ts +13 -0
  15. package/dist/primitives/Avatar.d.ts +15 -0
  16. package/dist/primitives/Button.d.ts +18 -0
  17. package/dist/primitives/Checkbox.d.ts +11 -0
  18. package/dist/primitives/Dialog.d.ts +58 -0
  19. package/dist/primitives/Divider.d.ts +10 -0
  20. package/dist/primitives/EmptyState.d.ts +11 -0
  21. package/dist/primitives/Icon.d.ts +20 -0
  22. package/dist/primitives/IconButton.d.ts +25 -0
  23. package/dist/primitives/Menu.d.ts +50 -0
  24. package/dist/primitives/Panel.d.ts +9 -0
  25. package/dist/primitives/Popover.d.ts +25 -0
  26. package/dist/primitives/ResizeHandle.d.ts +20 -0
  27. package/dist/primitives/ScreenTitle.d.ts +15 -0
  28. package/dist/primitives/ScrollArea.d.ts +11 -0
  29. package/dist/primitives/Select.d.ts +25 -0
  30. package/dist/primitives/Shortcut.d.ts +15 -0
  31. package/dist/primitives/Spinner.d.ts +14 -0
  32. package/dist/primitives/StatusBadge.d.ts +13 -0
  33. package/dist/primitives/StatusDot.d.ts +17 -0
  34. package/dist/primitives/Surface.d.ts +13 -0
  35. package/dist/primitives/Switch.d.ts +14 -0
  36. package/dist/primitives/TextInput.d.ts +14 -0
  37. package/dist/primitives/ToastViewport.d.ts +17 -0
  38. package/dist/primitives/helpers.d.ts +47 -0
  39. package/dist/primitives/index.d.ts +24 -0
  40. package/dist/primitives/useHover.d.ts +16 -0
  41. package/dist/reset.css +43 -0
  42. package/dist/stores/announcer-store.d.ts +37 -0
  43. package/dist/stores/toast-store.d.ts +37 -0
  44. package/dist/styles.css +1 -0
  45. package/dist/theme/ThemeBoundary.d.ts +38 -0
  46. package/dist/theme/appearance-store.d.ts +37 -0
  47. package/dist/theme/color-utils.d.ts +13 -0
  48. package/dist/theme/colors.d.ts +111 -0
  49. package/dist/theme/css-bridge.d.ts +21 -0
  50. package/dist/theme/dev-warnings.d.ts +23 -0
  51. package/dist/theme/index.d.ts +10 -0
  52. package/dist/theme/index.js +39 -0
  53. package/dist/theme/palette.d.ts +19 -0
  54. package/dist/theme/theme.d.ts +47 -0
  55. package/dist/theme/token-guard.d.ts +20 -0
  56. package/dist/theme/tokens.d.ts +105 -0
  57. package/dist/theme/variants.d.ts +12 -0
  58. package/dist/ui/avatar.d.ts +11 -0
  59. package/dist/ui/button.d.ts +34 -0
  60. package/dist/ui/combobox.d.ts +55 -0
  61. package/dist/ui/index.d.ts +10 -0
  62. package/dist/ui/index.js +406 -0
  63. package/dist/ui/option-groups.d.ts +36 -0
  64. package/dist/ui/screen-header.d.ts +23 -0
  65. package/dist/ui/shortcut.d.ts +13 -0
  66. package/dist/ui/status-badge.d.ts +15 -0
  67. package/dist/ui/status-dot.d.ts +20 -0
  68. package/dist/ui/toast.d.ts +60 -0
  69. package/package.json +68 -4
@@ -0,0 +1,34 @@
1
+ export type ButtonVariant = "default" | "secondary" | "outline" | "ghost" | "destructive";
2
+ export type ButtonSize = "xs" | "sm" | "md" | "lg";
3
+ export declare const BUTTON_MIN_HEIGHT: Record<ButtonSize, number>;
4
+ export declare const BUTTON_ICON_SIZE: Record<ButtonSize, number>;
5
+ export declare const BUTTON_PADDING_H: Record<ButtonSize, number>;
6
+ export declare const BUTTON_FONT_SIZE: Record<ButtonSize, string>;
7
+ export type ButtonStateStyle = {
8
+ opacity: number;
9
+ /** Token key for background color. null = no bg (transparent). */
10
+ bgToken: string | null;
11
+ };
12
+ /**
13
+ * Resolve the opacity and background token for a button given its state.
14
+ * - pressed → 0.85 opacity
15
+ * - disabled or loading → 0.5 opacity
16
+ * - ghost hover → special token swap (handled by caller reading `isGhostHover`)
17
+ */
18
+ export declare function resolveButtonState(opts: {
19
+ variant: ButtonVariant;
20
+ pressed: boolean;
21
+ disabled: boolean;
22
+ loading: boolean;
23
+ }): {
24
+ opacity: number;
25
+ isGhostHover: false;
26
+ };
27
+ /**
28
+ * Returns the correct text/icon color token key for each variant.
29
+ * This is what callers pass to the theme-prop binder for icon color.
30
+ */
31
+ export declare function buttonIconColorToken(variant: ButtonVariant): string;
32
+ /** Returns "foreground" when ghost is hovered, else the default ghost color. */
33
+ export declare function ghostHoverIconToken(isHovered: boolean): string;
34
+ //# sourceMappingURL=button.d.ts.map
@@ -0,0 +1,55 @@
1
+ export type ComboboxOption<T> = {
2
+ value: T;
3
+ label: string;
4
+ description?: string;
5
+ kind?: string;
6
+ /** Section this option belongs to — `option-groups.ts`'s `groupOptions` collects consecutive
7
+ * runs of the same value under one header (e.g. `ModelMenu`'s per-provider bands). Options
8
+ * without a `group` fall into a single trailing ungrouped bucket. */
9
+ group?: string;
10
+ disabled?: boolean;
11
+ };
12
+ export type ComboboxState<T> = {
13
+ query: string;
14
+ highlightedIndex: number;
15
+ isOpen: boolean;
16
+ options: ComboboxOption<T>[];
17
+ /** Filtered options (derived from options + query). */
18
+ filtered: ComboboxOption<T>[];
19
+ };
20
+ /**
21
+ * Filter options by a search query (case-insensitive substring match on label
22
+ * and optional description).
23
+ */
24
+ export declare function filterOptions<T>(options: ComboboxOption<T>[], query: string): ComboboxOption<T>[];
25
+ export type ComboboxAction = {
26
+ type: "OPEN";
27
+ } | {
28
+ type: "CLOSE";
29
+ } | {
30
+ type: "SET_QUERY";
31
+ query: string;
32
+ } | {
33
+ type: "ARROW_DOWN";
34
+ } | {
35
+ type: "ARROW_UP";
36
+ } | {
37
+ type: "SELECT_HIGHLIGHTED";
38
+ } | {
39
+ type: "SELECT_INDEX";
40
+ index: number;
41
+ };
42
+ /**
43
+ * Pure reducer for the combobox keyboard-navigation state machine.
44
+ * Callers integrate this with their own state management.
45
+ */
46
+ export declare function comboboxReducer<T>(state: ComboboxState<T>, action: ComboboxAction): ComboboxState<T>;
47
+ /** Build initial combobox state for a given options list. */
48
+ export declare function initialComboboxState<T>(options: ComboboxOption<T>[]): ComboboxState<T>;
49
+ /**
50
+ * If `allowCustomValue` is true and the query doesn't match any existing option
51
+ * exactly (case-insensitive), prepend a synthetic "create" option to the filtered
52
+ * list with the query string as the value.
53
+ */
54
+ export declare function withCustomValueOption(filtered: ComboboxOption<string>[], query: string, prefix?: string): ComboboxOption<string>[];
55
+ //# sourceMappingURL=combobox.d.ts.map
@@ -0,0 +1,10 @@
1
+ export * from "./button.js";
2
+ export * from "./shortcut.js";
3
+ export * from "./avatar.js";
4
+ export * from "./combobox.js";
5
+ export * from "./status-badge.js";
6
+ export * from "./toast.js";
7
+ export * from "./status-dot.js";
8
+ export * from "./screen-header.js";
9
+ export * from "./option-groups.js";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,406 @@
1
+ import { HEADER_INNER_HEIGHT_MOBILE as g, HEADER_INNER_HEIGHT as p, WINDOW_CHROME as h } from "../breakpoints.js";
2
+ const k = {
3
+ xs: 28,
4
+ sm: 32,
5
+ md: 36,
6
+ lg: 40
7
+ }, x = {
8
+ xs: 12,
9
+ sm: 14,
10
+ md: 16,
11
+ lg: 20
12
+ }, S = {
13
+ xs: 8,
14
+ sm: 10,
15
+ md: 12,
16
+ lg: 16
17
+ }, v = {
18
+ xs: "var(--pi-font-size-xs)",
19
+ sm: "var(--pi-font-size-sm)",
20
+ md: "var(--pi-font-size-md)",
21
+ lg: "var(--pi-font-size-base)"
22
+ };
23
+ function b(e) {
24
+ const { pressed: n, disabled: t, loading: r } = e;
25
+ return t || r ? { opacity: 0.5, isGhostHover: !1 } : n ? { opacity: 0.85, isGhostHover: !1 } : { opacity: 1, isGhostHover: !1 };
26
+ }
27
+ function E(e) {
28
+ switch (e) {
29
+ case "default":
30
+ return "accentForeground";
31
+ case "secondary":
32
+ return "foreground";
33
+ case "outline":
34
+ return "accent";
35
+ case "ghost":
36
+ return "foregroundMuted";
37
+ // swaps to "foreground" on hover
38
+ case "destructive":
39
+ return "destructiveForeground";
40
+ }
41
+ }
42
+ function M(e) {
43
+ return e ? "foreground" : "foregroundMuted";
44
+ }
45
+ const m = {
46
+ cmd: "⌘",
47
+ command: "⌘",
48
+ ctrl: "⌃",
49
+ control: "⌃",
50
+ shift: "⇧",
51
+ alt: "⌥",
52
+ option: "⌥",
53
+ meta: "⌘"
54
+ }, w = {
55
+ cmd: "Ctrl",
56
+ command: "Ctrl",
57
+ ctrl: "Ctrl",
58
+ control: "Ctrl",
59
+ shift: "Shift",
60
+ alt: "Alt",
61
+ option: "Alt",
62
+ meta: "Win"
63
+ }, _ = {
64
+ cmd: "Ctrl",
65
+ command: "Ctrl",
66
+ ctrl: "Ctrl",
67
+ control: "Ctrl",
68
+ shift: "Shift",
69
+ alt: "Alt",
70
+ option: "Alt",
71
+ meta: "Super"
72
+ };
73
+ function I(e) {
74
+ switch (e) {
75
+ case "macos":
76
+ return m;
77
+ case "windows":
78
+ return w;
79
+ case "linux":
80
+ return _;
81
+ }
82
+ }
83
+ function T(e, n) {
84
+ const t = I(n), r = e.toLowerCase().split("+").map((s) => {
85
+ const o = t[s];
86
+ return o !== void 0 ? o : [
87
+ "enter",
88
+ "return",
89
+ "tab",
90
+ "escape",
91
+ "esc",
92
+ "backspace",
93
+ "delete",
94
+ "space",
95
+ "arrowup",
96
+ "arrowdown",
97
+ "arrowleft",
98
+ "arrowright",
99
+ "home",
100
+ "end",
101
+ "pageup",
102
+ "pagedown",
103
+ "f1",
104
+ "f2",
105
+ "f3",
106
+ "f4",
107
+ "f5",
108
+ "f6",
109
+ "f7",
110
+ "f8",
111
+ "f9",
112
+ "f10",
113
+ "f11",
114
+ "f12"
115
+ ].includes(s) ? s.charAt(0).toUpperCase() + s.slice(1) : s.length === 1 ? s.toUpperCase() : s;
116
+ });
117
+ return n === "macos" ? r.join("") : r.join("+");
118
+ }
119
+ function A(e, n) {
120
+ return e.map((t) => T(t, n)).join(" ");
121
+ }
122
+ const a = [
123
+ "#2563eb",
124
+ // blue-600
125
+ "#16a34a",
126
+ // green-600
127
+ "#9333ea",
128
+ // purple-600
129
+ "#dc2626",
130
+ // red-600
131
+ "#0d9488",
132
+ // teal-600
133
+ "#d97706",
134
+ // amber-600
135
+ "#db2777",
136
+ // pink-600
137
+ "#0891b2",
138
+ // cyan-600
139
+ "#ea580c",
140
+ // orange-600
141
+ "#4f46e5",
142
+ // indigo-600
143
+ "#059669",
144
+ // emerald-600
145
+ "#7c3aed"
146
+ // violet-600
147
+ ];
148
+ function L(e) {
149
+ let n = 0;
150
+ for (let r = 0; r < e.length; r++) {
151
+ const s = e.charCodeAt(r);
152
+ n = n * 31 + s >>> 0;
153
+ }
154
+ return a[n % a.length] ?? a[0];
155
+ }
156
+ function D(e) {
157
+ const n = e.match(/[a-zA-Z0-9]/);
158
+ return n ? n[0].toUpperCase() : "?";
159
+ }
160
+ function O(e, n) {
161
+ if (n.trim() === "") return e;
162
+ const t = n.toLowerCase();
163
+ return e.filter(
164
+ (r) => r.label.toLowerCase().includes(t) || r.description !== void 0 && r.description.toLowerCase().includes(t)
165
+ );
166
+ }
167
+ function N(e, n) {
168
+ switch (n.type) {
169
+ case "OPEN":
170
+ return { ...e, isOpen: !0, highlightedIndex: 0 };
171
+ case "CLOSE":
172
+ return { ...e, isOpen: !1, query: "", filtered: e.options };
173
+ case "SET_QUERY": {
174
+ const t = O(e.options, n.query);
175
+ return {
176
+ ...e,
177
+ query: n.query,
178
+ filtered: t,
179
+ // Reset highlight when query changes; clamp to new filtered length.
180
+ highlightedIndex: t.length > 0 ? 0 : -1
181
+ };
182
+ }
183
+ case "ARROW_DOWN": {
184
+ if (!e.isOpen) return { ...e, isOpen: !0, highlightedIndex: 0 };
185
+ const t = e.filtered.length;
186
+ if (t === 0) return e;
187
+ let r = (e.highlightedIndex + 1) % t, s = 0;
188
+ for (; e.filtered[r]?.disabled && s < t; )
189
+ r = (r + 1) % t, s++;
190
+ return { ...e, highlightedIndex: r };
191
+ }
192
+ case "ARROW_UP": {
193
+ if (!e.isOpen) return { ...e, isOpen: !0, highlightedIndex: 0 };
194
+ const t = e.filtered.length;
195
+ if (t === 0) return e;
196
+ let r = (e.highlightedIndex - 1 + t) % t, s = 0;
197
+ for (; e.filtered[r]?.disabled && s < t; )
198
+ r = (r - 1 + t) % t, s++;
199
+ return { ...e, highlightedIndex: r };
200
+ }
201
+ case "SELECT_HIGHLIGHTED":
202
+ return { ...e, isOpen: !1, query: "", filtered: e.options };
203
+ case "SELECT_INDEX": {
204
+ const t = n.index;
205
+ return t < 0 || t >= e.filtered.length ? e : { ...e, highlightedIndex: t, isOpen: !1, query: "", filtered: e.options };
206
+ }
207
+ }
208
+ }
209
+ function H(e) {
210
+ return {
211
+ query: "",
212
+ highlightedIndex: 0,
213
+ isOpen: !1,
214
+ options: e,
215
+ filtered: e
216
+ };
217
+ }
218
+ function R(e, n, t = "Create") {
219
+ if (n.trim() === "") return e;
220
+ const r = n.toLowerCase();
221
+ return e.some((i) => i.label.toLowerCase() === r) ? e : [{
222
+ value: n,
223
+ label: `${t} "${n}"`,
224
+ kind: "custom"
225
+ }, ...e];
226
+ }
227
+ function y(e) {
228
+ switch (e) {
229
+ case "success":
230
+ return { token: "statusSuccess" };
231
+ case "error":
232
+ return { token: "statusDanger" };
233
+ case "warning":
234
+ return { token: "statusWarning" };
235
+ case "muted":
236
+ return { token: "foregroundMuted" };
237
+ }
238
+ }
239
+ function U(e) {
240
+ switch (e) {
241
+ case "default":
242
+ return { icon: "info", accentToken: "foregroundMuted" };
243
+ case "info":
244
+ return { icon: "info", accentToken: "accent" };
245
+ case "success":
246
+ return { icon: "check-circle", accentToken: "success" };
247
+ case "warning":
248
+ return { icon: "triangle-alert", accentToken: "statusWarning" };
249
+ case "error":
250
+ return { icon: "circle-x", accentToken: "destructive" };
251
+ }
252
+ }
253
+ function W(e, n, t) {
254
+ return e || n || t;
255
+ }
256
+ function B(e) {
257
+ switch (e) {
258
+ case "default":
259
+ return {};
260
+ case "success":
261
+ return { token: "statusSuccess" };
262
+ case "error":
263
+ return { token: "statusDanger" };
264
+ case "warning":
265
+ return { token: "statusWarning" };
266
+ }
267
+ }
268
+ const u = 2200;
269
+ function G(e, n, t, r = Date.now()) {
270
+ return {
271
+ id: e,
272
+ content: n,
273
+ variant: t.variant ?? "default",
274
+ durationMs: t.durationMs !== void 0 ? t.durationMs : u,
275
+ icon: t.icon,
276
+ paused: !1,
277
+ shownAt: r
278
+ };
279
+ }
280
+ function q(e = "Copied") {
281
+ return {
282
+ content: e,
283
+ opts: { variant: "success", durationMs: u }
284
+ };
285
+ }
286
+ function z(e) {
287
+ return { content: e, opts: { variant: "error", durationMs: u } };
288
+ }
289
+ function P(e, n, t = Date.now()) {
290
+ if (e.durationMs === null) return null;
291
+ if (e.paused && n !== null) return n;
292
+ const r = t - e.shownAt;
293
+ return Math.max(0, e.durationMs - r);
294
+ }
295
+ class F {
296
+ _stack = [];
297
+ push(n, t) {
298
+ this._stack.push({ id: n, close: t });
299
+ }
300
+ pop(n) {
301
+ const t = this._stack.findLastIndex((r) => r.id === n);
302
+ t !== -1 && this._stack.splice(t, 1);
303
+ }
304
+ /** Close the topmost entry (if any) and remove it. */
305
+ closeTop() {
306
+ const n = this._stack[this._stack.length - 1];
307
+ return n ? (n.close(), this._stack.pop(), !0) : !1;
308
+ }
309
+ get size() {
310
+ return this._stack.length;
311
+ }
312
+ topId() {
313
+ return this._stack[this._stack.length - 1]?.id;
314
+ }
315
+ }
316
+ function Y(e) {
317
+ const { status: n, requiresAttention: t, attentionReason: r, showInactive: s } = e;
318
+ if (!n) return null;
319
+ if (t)
320
+ switch (r) {
321
+ case "permission":
322
+ case "question":
323
+ return "statusWarning";
324
+ case "error":
325
+ return "statusDanger";
326
+ case "finished":
327
+ default:
328
+ return "statusSuccess";
329
+ }
330
+ switch (n) {
331
+ case "running":
332
+ case "queued":
333
+ return "accent";
334
+ case "waiting":
335
+ return "statusWarning";
336
+ case "finished":
337
+ return "statusSuccess";
338
+ case "error":
339
+ return "statusDanger";
340
+ case "idle":
341
+ case "archived":
342
+ return s ? "foregroundMuted" : null;
343
+ }
344
+ }
345
+ const Z = 8;
346
+ function j(e) {
347
+ const { isDesktop: n, isMobile: t, os: r } = e, s = t ? g : p;
348
+ if (!n)
349
+ return { paddingLeft: 0, paddingRight: 0, height: s };
350
+ const o = r === "macos" ? h.macOS.width : h.windowsLinux.width, i = r === "macos" ? "left" : "right";
351
+ return {
352
+ paddingLeft: i === "left" ? o : 0,
353
+ paddingRight: i === "right" ? o : 0,
354
+ height: s
355
+ };
356
+ }
357
+ function V(e, n = {}) {
358
+ const t = /* @__PURE__ */ new Map();
359
+ for (const c of e) {
360
+ const d = c.group ?? "", f = t.get(d);
361
+ f ? f.push(c) : t.set(d, [c]);
362
+ }
363
+ const r = t.get("");
364
+ t.delete("");
365
+ const s = [...t.keys()], { priorityGroup: o, ungroupedLabel: i } = n;
366
+ o !== void 0 && t.has(o) && (s.splice(s.indexOf(o), 1), s.unshift(o));
367
+ const l = s.map((c) => ({
368
+ key: c,
369
+ label: c,
370
+ options: t.get(c) ?? []
371
+ }));
372
+ return r && l.push({ key: "", label: i, options: r }), l;
373
+ }
374
+ export {
375
+ v as BUTTON_FONT_SIZE,
376
+ x as BUTTON_ICON_SIZE,
377
+ k as BUTTON_MIN_HEIGHT,
378
+ S as BUTTON_PADDING_H,
379
+ u as DEFAULT_TOAST_DURATION_MS,
380
+ F as EscStack,
381
+ p as HEADER_INNER_HEIGHT,
382
+ g as HEADER_INNER_HEIGHT_MOBILE,
383
+ Z as STATUS_DOT_SIZE,
384
+ U as alertIconInfo,
385
+ W as attachmentPillRemoveVisible,
386
+ L as avatarColor,
387
+ D as avatarInitial,
388
+ G as buildToastEntry,
389
+ E as buttonIconColorToken,
390
+ N as comboboxReducer,
391
+ q as copiedToast,
392
+ z as errorToast,
393
+ O as filterOptions,
394
+ A as formatChord,
395
+ T as formatCombo,
396
+ M as ghostHoverIconToken,
397
+ V as groupOptions,
398
+ j as headerPadding,
399
+ H as initialComboboxState,
400
+ P as remainingMs,
401
+ b as resolveButtonState,
402
+ y as statusBadgeTokens,
403
+ Y as statusDotColor,
404
+ B as toastTokens,
405
+ R as withCustomValueOption
406
+ };
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Option grouping for the app's menu/picker surfaces — the pure half of the grouped-menu
3
+ * mechanic whose render half is `components/primitives/Menu.tsx`'s `MenuGroup`. Any list of
4
+ * `ComboboxOption`s can be sectioned by whatever its owner puts in `option.group`
5
+ * (`ModelMenu`: the model's own LLM provider; a slash-command menu could use the command's
6
+ * source kind) without either layer knowing what the grouping means.
7
+ *
8
+ * Group order is FIRST APPEARANCE, never alphabetical: every producer in this app already emits
9
+ * a meaningful order (the daemon's own model ordering, `slash-commands.ts`'s ranking), and
10
+ * re-sorting headers would discard it. `priorityGroup` is the one deliberate exception.
11
+ */
12
+ import type { ComboboxOption } from "./combobox.js";
13
+ /** One rendered section: a header plus the options under it. */
14
+ export interface OptionGroup<T> {
15
+ /** Stable React key — the raw `option.group` value, or `""` for the ungrouped bucket. */
16
+ key: string;
17
+ /** Header text; `undefined` renders no header row (see `MenuGroup`). */
18
+ label?: string;
19
+ options: ComboboxOption<T>[];
20
+ }
21
+ export interface GroupOptionsConfig {
22
+ /** Group hoisted to the front wherever it first appears — e.g. the provider of the model a
23
+ * session is currently on, so the group you are actually using is never buried. Ignored when
24
+ * no option carries it. */
25
+ priorityGroup?: string;
26
+ /** Header for options that carry no `group`. Omit to leave that bucket headerless. */
27
+ ungroupedLabel?: string;
28
+ }
29
+ /**
30
+ * Section `options` for rendering. Grouping REORDERS: a caller that also owns a highlighted
31
+ * index over a flat list (a menu whose Arrow keys live outside it, like `CommandMenu`) must
32
+ * derive that index from `groups.flatMap((g) => g.options)`, not from the list passed in here —
33
+ * an index into the pre-grouping order would highlight a different row than the user sees.
34
+ */
35
+ export declare function groupOptions<T>(options: ComboboxOption<T>[], config?: GroupOptionsConfig): OptionGroup<T>[];
36
+ //# sourceMappingURL=option-groups.d.ts.map
@@ -0,0 +1,23 @@
1
+ import { HEADER_INNER_HEIGHT, HEADER_INNER_HEIGHT_MOBILE } from "../breakpoints.js";
2
+ export type HeaderVariant = "menu" | "back" | "title" | "icon-badge";
3
+ export type WindowControlSide = "left" | "right";
4
+ export type HeaderPadding = {
5
+ paddingLeft: number;
6
+ paddingRight: number;
7
+ height: number;
8
+ };
9
+ /**
10
+ * Compute the effective header padding to avoid overlapping desktop window controls.
11
+ * On non-desktop / mobile, returns zero extra padding.
12
+ *
13
+ * @param isDesktop - True when running in Electron desktop.
14
+ * @param isMobile - True when compact form factor.
15
+ * @param os - "macos" | "windowsLinux" (determines which side the controls are on).
16
+ */
17
+ export declare function headerPadding(opts: {
18
+ isDesktop: boolean;
19
+ isMobile: boolean;
20
+ os: "macos" | "windowsLinux";
21
+ }): HeaderPadding;
22
+ export { HEADER_INNER_HEIGHT, HEADER_INNER_HEIGHT_MOBILE };
23
+ //# sourceMappingURL=screen-header.d.ts.map
@@ -0,0 +1,13 @@
1
+ export type OsFamily = "macos" | "windows" | "linux";
2
+ /**
3
+ * Format a single key combo string (e.g. "cmd+shift+k") for display.
4
+ * Keys are split on `+`, modifiers are translated, non-modifiers are
5
+ * uppercased single chars or kept as-is for special keys.
6
+ */
7
+ export declare function formatCombo(combo: string, os: OsFamily): string;
8
+ /**
9
+ * Format an array of chords (a sequence of combos) for display.
10
+ * e.g. ["cmd+k", "cmd+s"] → "⌘K ⌘S" on macOS
11
+ */
12
+ export declare function formatChord(chords: string[], os: OsFamily): string;
13
+ //# sourceMappingURL=shortcut.d.ts.map
@@ -0,0 +1,15 @@
1
+ export type StatusBadgeVariant = "success" | "error" | "warning" | "muted";
2
+ export type BadgeTokens = {
3
+ token: string;
4
+ };
5
+ export declare function statusBadgeTokens(variant: StatusBadgeVariant): BadgeTokens;
6
+ export type AlertVariant = "default" | "info" | "success" | "warning" | "error";
7
+ export type AlertIconInfo = {
8
+ /** Lucide icon name string for the alert variant. */
9
+ icon: string;
10
+ /** Theme token key for the icon/border/title accent color. */
11
+ accentToken: string;
12
+ };
13
+ export declare function alertIconInfo(variant: AlertVariant): AlertIconInfo;
14
+ export declare function attachmentPillRemoveVisible(isNativeCtx: boolean, isCompact: boolean, hovered: boolean): boolean;
15
+ //# sourceMappingURL=status-badge.d.ts.map
@@ -0,0 +1,20 @@
1
+ export type AgentStatus = "idle" | "running" | "waiting" | "finished" | "error" | "queued" | "archived";
2
+ export type AttentionReason = "finished" | "error" | "permission" | "question";
3
+ export type StatusDotInput = {
4
+ status: AgentStatus | undefined | null;
5
+ requiresAttention?: boolean;
6
+ attentionReason?: AttentionReason;
7
+ /** Count backing an attention reason that is inherently plural (e.g. multiple pending
8
+ * questions/permissions on one target) — method-neutral so it is not tied to `"permission"`
9
+ * specifically (sprint-069/task-001). */
10
+ pendingCount?: number;
11
+ showInactive?: boolean;
12
+ };
13
+ export type StatusDotColor = "accent" | "statusSuccess" | "statusDanger" | "statusWarning" | "foregroundMuted";
14
+ /**
15
+ * Returns the theme token key for the status dot color, or null if the dot
16
+ * should not be rendered (missing/invalid status and showInactive=false).
17
+ */
18
+ export declare function statusDotColor(input: StatusDotInput): StatusDotColor | null;
19
+ export declare const STATUS_DOT_SIZE = 8;
20
+ //# sourceMappingURL=status-dot.d.ts.map
@@ -0,0 +1,60 @@
1
+ export type ToastVariant = "default" | "success" | "error" | "warning";
2
+ export type ToastTokens = {
3
+ token?: string;
4
+ };
5
+ export declare function toastTokens(variant: ToastVariant): ToastTokens;
6
+ export type ToastOptions = {
7
+ icon?: string;
8
+ variant?: ToastVariant;
9
+ /** Duration in ms. null = sticky (never auto-dismisses). Default ~2200ms. */
10
+ durationMs?: number | null;
11
+ /** Android-only: delegate to native toast instead of the in-app one. */
12
+ nativeAndroid?: boolean;
13
+ };
14
+ export declare const DEFAULT_TOAST_DURATION_MS = 2200;
15
+ export type ToastEntry = {
16
+ id: string;
17
+ content: string;
18
+ variant: ToastVariant;
19
+ durationMs: number | null;
20
+ icon?: string;
21
+ /** True while the hover-pause is active (web desktop only). */
22
+ paused: boolean;
23
+ /** Snapshot of `remainingMs` taken the instant `paused` became true, frozen until resume. Kept
24
+ * on the entry itself (not a parallel id-keyed map in the store) so there is exactly one place
25
+ * that can drift out of sync with `paused`. Undefined while not paused. */
26
+ pausedRemaining?: number;
27
+ /** Epoch ms when the toast most recently became visible (used to compute remaining time) — a
28
+ * queued (not-yet-visible) entry has this reset to "now" at promotion time by the store, not
29
+ * left at its original `show()`-time value, so it still gets its full nominal duration once
30
+ * actually shown (sprint-069/task-005). */
31
+ shownAt: number;
32
+ };
33
+ /** Build a toast entry from show() arguments. */
34
+ export declare function buildToastEntry(id: string, content: string, opts: ToastOptions, now?: number): ToastEntry;
35
+ /** Convenience factory for a "copied" toast. */
36
+ export declare function copiedToast(label?: string): {
37
+ content: string;
38
+ opts: ToastOptions;
39
+ };
40
+ /** Convenience factory for an error toast. */
41
+ export declare function errorToast(message: string): {
42
+ content: string;
43
+ opts: ToastOptions;
44
+ };
45
+ /**
46
+ * Returns the remaining dismissal time (ms) for a toast, accounting for hover-pause.
47
+ * If the toast is paused, remaining time is frozen at `pausedRemaining`.
48
+ * Returns `null` for sticky toasts.
49
+ */
50
+ export declare function remainingMs(entry: ToastEntry, pausedRemaining: number | null, now?: number): number | null;
51
+ export declare class EscStack {
52
+ private readonly _stack;
53
+ push(id: string, close: () => void): void;
54
+ pop(id: string): void;
55
+ /** Close the topmost entry (if any) and remove it. */
56
+ closeTop(): boolean;
57
+ get size(): number;
58
+ topId(): string | undefined;
59
+ }
60
+ //# sourceMappingURL=toast.d.ts.map