@agent-native/toolkit 0.14.0 → 0.14.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/canvas-interactions/canvas-interactions.d.ts +3 -3
- package/dist/canvas-interactions/canvas-interactions.d.ts.map +1 -1
- package/dist/canvas-interactions/canvas-interactions.js +54 -19
- package/dist/canvas-interactions/canvas-interactions.js.map +1 -1
- package/dist/canvas-interactions/canvas-interactions.spec.js +57 -2
- package/dist/canvas-interactions/canvas-interactions.spec.js.map +1 -1
- package/dist/chat-history/ChatHistoryList.d.ts.map +1 -1
- package/dist/chat-history/ChatHistoryList.js +9 -28
- package/dist/chat-history/ChatHistoryList.js.map +1 -1
- package/dist/chat-history/ChatHistoryList.spec.js +46 -36
- package/dist/chat-history/ChatHistoryList.spec.js.map +1 -1
- package/dist/chat-history.css +5 -15
- package/dist/collab-ui/PresenceBar.js +1 -1
- package/dist/collab-ui/PresenceBar.js.map +1 -1
- package/dist/collab-ui/PresenceBar.spec.d.ts +2 -0
- package/dist/collab-ui/PresenceBar.spec.d.ts.map +1 -0
- package/dist/collab-ui/PresenceBar.spec.js +30 -0
- package/dist/collab-ui/PresenceBar.spec.js.map +1 -0
- package/dist/composer/VoiceButton.js +1 -1
- package/dist/composer/VoiceButton.js.map +1 -1
- package/package.json +1 -1
- package/src/canvas-interactions/canvas-interactions.spec.ts +79 -2
- package/src/canvas-interactions/canvas-interactions.ts +56 -24
- package/src/chat-history/ChatHistoryList.spec.tsx +80 -48
- package/src/chat-history/ChatHistoryList.tsx +86 -93
- package/src/chat-history.css +5 -15
- package/src/collab-ui/PresenceBar.spec.tsx +44 -0
- package/src/collab-ui/PresenceBar.tsx +1 -1
- package/src/composer/VoiceButton.tsx +1 -1
|
@@ -33,6 +33,27 @@ function typeIntoInput(input: HTMLInputElement, value: string) {
|
|
|
33
33
|
input.dispatchEvent(new Event("change", { bubbles: true }));
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
async function openMenu(trigger: HTMLButtonElement) {
|
|
37
|
+
await act(async () => {
|
|
38
|
+
trigger.dispatchEvent(
|
|
39
|
+
new PointerEvent("pointerdown", {
|
|
40
|
+
bubbles: true,
|
|
41
|
+
button: 0,
|
|
42
|
+
pointerType: "mouse",
|
|
43
|
+
}),
|
|
44
|
+
);
|
|
45
|
+
await Promise.resolve();
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function getMenuItems() {
|
|
50
|
+
return Array.from(
|
|
51
|
+
document.body.querySelectorAll<HTMLElement>(
|
|
52
|
+
".an-chat-history-row__menu-item",
|
|
53
|
+
),
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
36
57
|
describe("ChatHistoryList", () => {
|
|
37
58
|
let container: HTMLDivElement;
|
|
38
59
|
let root: Root;
|
|
@@ -216,7 +237,7 @@ describe("ChatHistoryList", () => {
|
|
|
216
237
|
expect(container.querySelector(".an-chat-history-row__menu")).toBeNull();
|
|
217
238
|
});
|
|
218
239
|
|
|
219
|
-
it("supports pin toggling via the row action menu", () => {
|
|
240
|
+
it("supports pin toggling via the row action menu", async () => {
|
|
220
241
|
const onTogglePin = vi.fn();
|
|
221
242
|
const items: ChatHistoryItem[] = [
|
|
222
243
|
item({ id: "thread-1", title: "First chat" }),
|
|
@@ -235,13 +256,11 @@ describe("ChatHistoryList", () => {
|
|
|
235
256
|
".an-chat-history-row__menu-trigger",
|
|
236
257
|
);
|
|
237
258
|
expect(trigger).not.toBeNull();
|
|
238
|
-
|
|
239
|
-
trigger!.click();
|
|
240
|
-
});
|
|
259
|
+
await openMenu(trigger!);
|
|
241
260
|
|
|
242
|
-
const pinItem =
|
|
243
|
-
|
|
244
|
-
)
|
|
261
|
+
const pinItem = getMenuItems().find((el) =>
|
|
262
|
+
el.textContent?.includes("Pin to top"),
|
|
263
|
+
);
|
|
245
264
|
expect(pinItem).toBeDefined();
|
|
246
265
|
act(() => {
|
|
247
266
|
(pinItem as HTMLButtonElement).click();
|
|
@@ -249,7 +268,32 @@ describe("ChatHistoryList", () => {
|
|
|
249
268
|
expect(onTogglePin).toHaveBeenCalledWith("thread-1");
|
|
250
269
|
});
|
|
251
270
|
|
|
252
|
-
it("
|
|
271
|
+
it("ports rail row menus outside the scroll container", async () => {
|
|
272
|
+
act(() => {
|
|
273
|
+
root.render(
|
|
274
|
+
<ChatHistoryList
|
|
275
|
+
variant="rail"
|
|
276
|
+
items={[item({ id: "thread-1" })]}
|
|
277
|
+
onSelect={() => {}}
|
|
278
|
+
onDelete={() => {}}
|
|
279
|
+
/>,
|
|
280
|
+
);
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
const trigger = container.querySelector<HTMLButtonElement>(
|
|
284
|
+
".an-chat-history-row__menu-trigger",
|
|
285
|
+
);
|
|
286
|
+
await openMenu(trigger!);
|
|
287
|
+
|
|
288
|
+
const menu = document.body.querySelector<HTMLElement>(
|
|
289
|
+
".an-chat-history-row__menu-content",
|
|
290
|
+
);
|
|
291
|
+
expect(menu).not.toBeNull();
|
|
292
|
+
expect(menu?.closest(".an-chat-history__list")).toBeNull();
|
|
293
|
+
expect(menu?.getAttribute("role")).toBe("menu");
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
it("uses custom labels for localized row actions", async () => {
|
|
253
297
|
const onTogglePin = vi.fn();
|
|
254
298
|
const onDelete = vi.fn();
|
|
255
299
|
const labels = {
|
|
@@ -281,16 +325,14 @@ describe("ChatHistoryList", () => {
|
|
|
281
325
|
".an-chat-history-row__menu-trigger",
|
|
282
326
|
);
|
|
283
327
|
expect(trigger?.getAttribute("aria-label")).toBe(labels.options);
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
expect(
|
|
288
|
-
expect(container.textContent).toContain(labels.pin);
|
|
289
|
-
expect(container.textContent).toContain(labels.delete);
|
|
328
|
+
await openMenu(trigger!);
|
|
329
|
+
expect(document.body.textContent).toContain(labels.rename);
|
|
330
|
+
expect(document.body.textContent).toContain(labels.pin);
|
|
331
|
+
expect(document.body.textContent).toContain(labels.delete);
|
|
290
332
|
|
|
291
|
-
const archiveItem =
|
|
292
|
-
|
|
293
|
-
)
|
|
333
|
+
const archiveItem = getMenuItems().find((element) =>
|
|
334
|
+
element.textContent?.includes(labels.delete),
|
|
335
|
+
);
|
|
294
336
|
act(() => {
|
|
295
337
|
(archiveItem as HTMLButtonElement).click();
|
|
296
338
|
});
|
|
@@ -300,12 +342,10 @@ describe("ChatHistoryList", () => {
|
|
|
300
342
|
const renameTrigger = container.querySelector<HTMLButtonElement>(
|
|
301
343
|
".an-chat-history-row__menu-trigger",
|
|
302
344
|
);
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
container.querySelectorAll(".an-chat-history-row__menu-item"),
|
|
308
|
-
).find((element) => element.textContent?.includes(labels.rename));
|
|
345
|
+
await openMenu(renameTrigger!);
|
|
346
|
+
const renameItem = getMenuItems().find((element) =>
|
|
347
|
+
element.textContent?.includes(labels.rename),
|
|
348
|
+
);
|
|
309
349
|
act(() => {
|
|
310
350
|
(renameItem as HTMLButtonElement).click();
|
|
311
351
|
});
|
|
@@ -319,13 +359,11 @@ describe("ChatHistoryList", () => {
|
|
|
319
359
|
const pinnedTrigger = container.querySelector<HTMLButtonElement>(
|
|
320
360
|
".an-chat-history-row__menu-trigger",
|
|
321
361
|
);
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
});
|
|
325
|
-
expect(container.textContent).toContain(labels.unpin);
|
|
362
|
+
await openMenu(pinnedTrigger!);
|
|
363
|
+
expect(document.body.textContent).toContain(labels.unpin);
|
|
326
364
|
});
|
|
327
365
|
|
|
328
|
-
it("supports inline rename via the row action menu", () => {
|
|
366
|
+
it("supports inline rename via the row action menu", async () => {
|
|
329
367
|
const onRename = vi.fn();
|
|
330
368
|
const items: ChatHistoryItem[] = [
|
|
331
369
|
item({ id: "thread-1", title: "Old title", titleText: "Old title" }),
|
|
@@ -344,12 +382,10 @@ describe("ChatHistoryList", () => {
|
|
|
344
382
|
const trigger = container.querySelector<HTMLButtonElement>(
|
|
345
383
|
".an-chat-history-row__menu-trigger",
|
|
346
384
|
);
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
container.querySelectorAll(".an-chat-history-row__menu-item"),
|
|
352
|
-
).find((el) => el.textContent?.includes("Rename"));
|
|
385
|
+
await openMenu(trigger!);
|
|
386
|
+
const renameItem = getMenuItems().find((el) =>
|
|
387
|
+
el.textContent?.includes("Rename"),
|
|
388
|
+
);
|
|
353
389
|
act(() => {
|
|
354
390
|
(renameItem as HTMLButtonElement).click();
|
|
355
391
|
});
|
|
@@ -372,7 +408,7 @@ describe("ChatHistoryList", () => {
|
|
|
372
408
|
expect(onRename).toHaveBeenCalledWith("thread-1", "New title");
|
|
373
409
|
});
|
|
374
410
|
|
|
375
|
-
it("supports item-aware labels and app-specific actions", () => {
|
|
411
|
+
it("supports item-aware labels and app-specific actions", async () => {
|
|
376
412
|
const onShare = vi.fn();
|
|
377
413
|
const items: ChatHistoryItem[] = [
|
|
378
414
|
item({ id: "thread-1", title: "Campaign", titleText: "Campaign" }),
|
|
@@ -407,27 +443,23 @@ describe("ChatHistoryList", () => {
|
|
|
407
443
|
".an-chat-history-row__menu-trigger",
|
|
408
444
|
);
|
|
409
445
|
expect(trigger?.getAttribute("aria-label")).toBe("Options for Campaign");
|
|
410
|
-
|
|
411
|
-
trigger!.click();
|
|
412
|
-
});
|
|
446
|
+
await openMenu(trigger!);
|
|
413
447
|
|
|
414
|
-
const shareItem =
|
|
415
|
-
|
|
416
|
-
)
|
|
448
|
+
const shareItem = getMenuItems().find(
|
|
449
|
+
(element) => element.textContent === "Share",
|
|
450
|
+
);
|
|
417
451
|
act(() => {
|
|
418
452
|
(shareItem as HTMLButtonElement).click();
|
|
419
453
|
});
|
|
420
454
|
expect(onShare).toHaveBeenCalledWith("thread-1");
|
|
421
455
|
expect(
|
|
422
|
-
|
|
456
|
+
document.body.querySelector(".an-chat-history-row__menu-content"),
|
|
423
457
|
).toBeNull();
|
|
424
458
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
container.querySelectorAll(".an-chat-history-row__menu-item"),
|
|
430
|
-
).find((element) => element.textContent === "Rename");
|
|
459
|
+
await openMenu(trigger!);
|
|
460
|
+
const renameItem = getMenuItems().find(
|
|
461
|
+
(element) => element.textContent === "Rename",
|
|
462
|
+
);
|
|
431
463
|
act(() => {
|
|
432
464
|
(renameItem as HTMLButtonElement).click();
|
|
433
465
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
1
2
|
import {
|
|
2
3
|
IconDots,
|
|
3
4
|
IconPencil,
|
|
@@ -6,7 +7,7 @@ import {
|
|
|
6
7
|
IconSearch,
|
|
7
8
|
IconTrash,
|
|
8
9
|
} from "@tabler/icons-react";
|
|
9
|
-
import React, {
|
|
10
|
+
import React, { useMemo, useRef, useState } from "react";
|
|
10
11
|
|
|
11
12
|
import { cn } from "../utils.js";
|
|
12
13
|
|
|
@@ -288,7 +289,6 @@ const ChatHistoryRow = React.memo(function ChatHistoryRow({
|
|
|
288
289
|
const [draftTitle, setDraftTitle] = useState("");
|
|
289
290
|
const [menuOpen, setMenuOpen] = useState(false);
|
|
290
291
|
const renameInputRef = useRef<HTMLInputElement | null>(null);
|
|
291
|
-
const menuRef = useRef<HTMLDivElement | null>(null);
|
|
292
292
|
|
|
293
293
|
const hasMenu = Boolean(
|
|
294
294
|
onTogglePin ||
|
|
@@ -298,24 +298,6 @@ const ChatHistoryRow = React.memo(function ChatHistoryRow({
|
|
|
298
298
|
renderAdditionalRowActions,
|
|
299
299
|
);
|
|
300
300
|
|
|
301
|
-
useEffect(() => {
|
|
302
|
-
if (!menuOpen) return;
|
|
303
|
-
function handlePointerDown(event: PointerEvent) {
|
|
304
|
-
if (menuRef.current && !menuRef.current.contains(event.target as Node)) {
|
|
305
|
-
setMenuOpen(false);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
function handleKeyDown(event: KeyboardEvent) {
|
|
309
|
-
if (event.key === "Escape") setMenuOpen(false);
|
|
310
|
-
}
|
|
311
|
-
document.addEventListener("pointerdown", handlePointerDown);
|
|
312
|
-
document.addEventListener("keydown", handleKeyDown);
|
|
313
|
-
return () => {
|
|
314
|
-
document.removeEventListener("pointerdown", handlePointerDown);
|
|
315
|
-
document.removeEventListener("keydown", handleKeyDown);
|
|
316
|
-
};
|
|
317
|
-
}, [menuOpen]);
|
|
318
|
-
|
|
319
301
|
function startRename() {
|
|
320
302
|
setDraftTitle(item.titleText ?? "");
|
|
321
303
|
setIsRenaming(true);
|
|
@@ -409,79 +391,90 @@ const ChatHistoryRow = React.memo(function ChatHistoryRow({
|
|
|
409
391
|
)}
|
|
410
392
|
|
|
411
393
|
{!isRenaming && hasMenu && (
|
|
412
|
-
<
|
|
413
|
-
<
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
<
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
394
|
+
<DropdownMenuPrimitive.Root open={menuOpen} onOpenChange={setMenuOpen}>
|
|
395
|
+
<div className="an-chat-history-row__menu">
|
|
396
|
+
<DropdownMenuPrimitive.Trigger asChild>
|
|
397
|
+
<button
|
|
398
|
+
type="button"
|
|
399
|
+
className={cn(
|
|
400
|
+
"an-chat-history-row__menu-trigger",
|
|
401
|
+
item.pinned && "an-chat-history-row__menu-trigger--pinned",
|
|
402
|
+
)}
|
|
403
|
+
aria-label={optionsLabel}
|
|
404
|
+
aria-haspopup="menu"
|
|
405
|
+
aria-expanded={menuOpen}
|
|
406
|
+
>
|
|
407
|
+
{item.pinned ? (
|
|
408
|
+
<IconPinned size={13} strokeWidth={1.8} />
|
|
409
|
+
) : (
|
|
410
|
+
<IconDots size={14} strokeWidth={1.8} />
|
|
411
|
+
)}
|
|
412
|
+
</button>
|
|
413
|
+
</DropdownMenuPrimitive.Trigger>
|
|
414
|
+
<DropdownMenuPrimitive.Portal>
|
|
415
|
+
<DropdownMenuPrimitive.Content
|
|
416
|
+
className="an-chat-history-row__menu-content"
|
|
417
|
+
align="end"
|
|
418
|
+
collisionPadding={8}
|
|
419
|
+
side="bottom"
|
|
420
|
+
sideOffset={4}
|
|
421
|
+
>
|
|
422
|
+
{renderRowActions ? (
|
|
423
|
+
renderRowActions(item)
|
|
424
|
+
) : (
|
|
425
|
+
<>
|
|
426
|
+
{onRename && (
|
|
427
|
+
<button
|
|
428
|
+
type="button"
|
|
429
|
+
role="menuitem"
|
|
430
|
+
className="an-chat-history-row__menu-item"
|
|
431
|
+
onClick={startRename}
|
|
432
|
+
>
|
|
433
|
+
<IconPencil size={13} strokeWidth={1.8} />
|
|
434
|
+
<span>{labels.rename}</span>
|
|
435
|
+
</button>
|
|
436
|
+
)}
|
|
437
|
+
{onTogglePin && (
|
|
438
|
+
<button
|
|
439
|
+
type="button"
|
|
440
|
+
role="menuitem"
|
|
441
|
+
className="an-chat-history-row__menu-item"
|
|
442
|
+
onClick={() => {
|
|
443
|
+
setMenuOpen(false);
|
|
444
|
+
onTogglePin(item.id);
|
|
445
|
+
}}
|
|
446
|
+
>
|
|
447
|
+
{item.pinned ? (
|
|
448
|
+
<IconPinnedOff size={13} strokeWidth={1.8} />
|
|
449
|
+
) : (
|
|
450
|
+
<IconPinned size={13} strokeWidth={1.8} />
|
|
451
|
+
)}
|
|
452
|
+
<span>{item.pinned ? labels.unpin : labels.pin}</span>
|
|
453
|
+
</button>
|
|
454
|
+
)}
|
|
455
|
+
{renderAdditionalRowActions?.(item, () =>
|
|
456
|
+
setMenuOpen(false),
|
|
457
|
+
)}
|
|
458
|
+
{onDelete && (
|
|
459
|
+
<button
|
|
460
|
+
type="button"
|
|
461
|
+
role="menuitem"
|
|
462
|
+
className="an-chat-history-row__menu-item an-chat-history-row__menu-item--danger"
|
|
463
|
+
onClick={() => {
|
|
464
|
+
setMenuOpen(false);
|
|
465
|
+
onDelete(item.id);
|
|
466
|
+
}}
|
|
467
|
+
>
|
|
468
|
+
<IconTrash size={13} strokeWidth={1.8} />
|
|
469
|
+
<span>{labels.delete}</span>
|
|
470
|
+
</button>
|
|
471
|
+
)}
|
|
472
|
+
</>
|
|
473
|
+
)}
|
|
474
|
+
</DropdownMenuPrimitive.Content>
|
|
475
|
+
</DropdownMenuPrimitive.Portal>
|
|
476
|
+
</div>
|
|
477
|
+
</DropdownMenuPrimitive.Root>
|
|
485
478
|
)}
|
|
486
479
|
</div>
|
|
487
480
|
);
|
package/src/chat-history.css
CHANGED
|
@@ -293,22 +293,14 @@
|
|
|
293
293
|
transition: opacity 100ms ease;
|
|
294
294
|
}
|
|
295
295
|
|
|
296
|
-
.an-chat-history--rail
|
|
297
|
-
.an-chat-history-row--has-menu
|
|
298
|
-
.an-chat-history-row__timestamp {
|
|
299
|
-
display: inline-flex;
|
|
300
|
-
min-width: 24px;
|
|
301
|
-
justify-content: flex-end;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
296
|
.an-chat-history--rail
|
|
305
297
|
.an-chat-history-row--active
|
|
306
298
|
.an-chat-history-row__timestamp {
|
|
307
299
|
color: hsl(var(--accent-foreground));
|
|
308
300
|
}
|
|
309
301
|
|
|
310
|
-
/*
|
|
311
|
-
the title's available width or moves the rest of the rail. */
|
|
302
|
+
/* Hide trailing metadata while the absolute menu takes its place so hover
|
|
303
|
+
never changes the title's available width or moves the rest of the rail. */
|
|
312
304
|
.an-chat-history--rail
|
|
313
305
|
.an-chat-history-row--has-menu:hover
|
|
314
306
|
.an-chat-history-row__timestamp,
|
|
@@ -375,10 +367,11 @@
|
|
|
375
367
|
position: absolute;
|
|
376
368
|
top: 4px;
|
|
377
369
|
inset-inline-end: 4px;
|
|
370
|
+
z-index: 1;
|
|
378
371
|
}
|
|
379
372
|
|
|
380
373
|
.an-chat-history--rail .an-chat-history-row__menu {
|
|
381
|
-
inset-inline-end:
|
|
374
|
+
inset-inline-end: 8px;
|
|
382
375
|
}
|
|
383
376
|
|
|
384
377
|
.an-chat-history-row__menu-trigger {
|
|
@@ -428,10 +421,7 @@
|
|
|
428
421
|
}
|
|
429
422
|
|
|
430
423
|
.an-chat-history-row__menu-content {
|
|
431
|
-
|
|
432
|
-
top: calc(100% + 4px);
|
|
433
|
-
inset-inline-end: 0;
|
|
434
|
-
z-index: 30;
|
|
424
|
+
z-index: 290;
|
|
435
425
|
min-width: 160px;
|
|
436
426
|
padding: 4px;
|
|
437
427
|
border: 1px solid hsl(var(--border));
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// @vitest-environment happy-dom
|
|
2
|
+
|
|
3
|
+
import { act } from "react";
|
|
4
|
+
import { createRoot, type Root } from "react-dom/client";
|
|
5
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
6
|
+
|
|
7
|
+
import { PresenceBar } from "./PresenceBar.js";
|
|
8
|
+
|
|
9
|
+
describe("PresenceBar", () => {
|
|
10
|
+
let container: HTMLDivElement;
|
|
11
|
+
let root: Root;
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true);
|
|
15
|
+
container = document.createElement("div");
|
|
16
|
+
document.body.appendChild(container);
|
|
17
|
+
root = createRoot(container);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
afterEach(() => {
|
|
21
|
+
act(() => root.unmount());
|
|
22
|
+
container.remove();
|
|
23
|
+
vi.restoreAllMocks();
|
|
24
|
+
vi.unstubAllGlobals();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("gives the integrated AI editing label space after the avatar", () => {
|
|
28
|
+
act(() => {
|
|
29
|
+
root.render(
|
|
30
|
+
<PresenceBar
|
|
31
|
+
activeUsers={[]}
|
|
32
|
+
agentPresent
|
|
33
|
+
agentActive
|
|
34
|
+
showAgentEditingDot={false}
|
|
35
|
+
/>,
|
|
36
|
+
);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const label = Array.from(container.querySelectorAll("span")).find(
|
|
40
|
+
(element) => element.textContent === "AI editing",
|
|
41
|
+
);
|
|
42
|
+
expect(label?.style.padding).toBe("0px 0px 0px 2px");
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -247,7 +247,7 @@ function AgentEditingChip({
|
|
|
247
247
|
alignItems: "center",
|
|
248
248
|
gap: showDot ? 4 : 0,
|
|
249
249
|
height: integrated ? "auto" : 20,
|
|
250
|
-
padding: integrated ? 0 : "0 8px",
|
|
250
|
+
padding: integrated ? "0 0 0 2px" : "0 8px",
|
|
251
251
|
borderRadius: integrated ? 0 : 9999,
|
|
252
252
|
backgroundColor: integrated ? "transparent" : `${AGENT_COLOR}20`,
|
|
253
253
|
color: AGENT_COLOR,
|
|
@@ -147,7 +147,7 @@ export function VoiceButton({ voice, isMac, disabled }: VoiceButtonProps) {
|
|
|
147
147
|
? "Stop recording"
|
|
148
148
|
: transcribing
|
|
149
149
|
? "Transcribing…"
|
|
150
|
-
: `Dictate (${isMac ? "
|
|
150
|
+
: `Dictate (${isMac ? "Cmd Shift M" : "Ctrl Shift M"})`;
|
|
151
151
|
|
|
152
152
|
const onClick = () => {
|
|
153
153
|
if (recording) stop();
|