@agent-native/toolkit 0.22.1 → 0.22.2-nightly-20260926235312
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/app-shell/PromptHome.d.ts +1 -2
- package/dist/app-shell/PromptHome.d.ts.map +1 -1
- package/dist/app-shell/PromptHome.js +4 -5
- package/dist/app-shell/PromptHome.js.map +1 -1
- package/dist/app-shell/PromptHome.spec.js +73 -9
- package/dist/app-shell/PromptHome.spec.js.map +1 -1
- package/dist/app-shell/TemplateLibraryGrid.d.ts +4 -2
- package/dist/app-shell/TemplateLibraryGrid.d.ts.map +1 -1
- package/dist/app-shell/TemplateLibraryGrid.js +6 -6
- package/dist/app-shell/TemplateLibraryGrid.js.map +1 -1
- package/dist/app-shell/index.d.ts +1 -0
- package/dist/app-shell/index.d.ts.map +1 -1
- package/dist/app-shell/index.js +1 -0
- package/dist/app-shell/index.js.map +1 -1
- package/dist/app-shell/prompt-home.css +42 -2
- package/dist/app-shell/use-home-search-shortcut.d.ts +2 -0
- package/dist/app-shell/use-home-search-shortcut.d.ts.map +1 -0
- package/dist/app-shell/use-home-search-shortcut.js +32 -0
- package/dist/app-shell/use-home-search-shortcut.js.map +1 -0
- package/dist/composer/ComposerContextMenu.d.ts.map +1 -1
- package/dist/composer/ComposerContextMenu.js +11 -36
- package/dist/composer/ComposerContextMenu.js.map +1 -1
- package/dist/composer/ComposerContextMenu.spec.js +10 -24
- package/dist/composer/ComposerContextMenu.spec.js.map +1 -1
- package/dist/composer/ComposerContextPicker.spec.js +1 -1
- package/dist/composer/PromptComposer.context.spec.js +1 -1
- package/dist/composer/PromptComposer.context.spec.js.map +1 -1
- package/package.json +1 -1
- package/src/app-shell/PromptHome.spec.tsx +84 -10
- package/src/app-shell/PromptHome.tsx +21 -33
- package/src/app-shell/TemplateLibraryGrid.tsx +17 -2
- package/src/app-shell/index.ts +1 -0
- package/src/app-shell/prompt-home.css +42 -2
- package/src/app-shell/use-home-search-shortcut.ts +40 -0
- package/src/composer/ComposerContextMenu.spec.tsx +10 -34
- package/src/composer/ComposerContextMenu.tsx +29 -99
- package/src/composer/ComposerContextPicker.spec.tsx +1 -1
- package/src/composer/PromptComposer.context.spec.tsx +1 -1
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
min-height: clamp(36rem, 64svh, 44rem);
|
|
9
9
|
flex-direction: column;
|
|
10
10
|
align-items: center;
|
|
11
|
-
|
|
11
|
+
justify-content: center;
|
|
12
12
|
text-align: center;
|
|
13
13
|
}
|
|
14
14
|
|
|
@@ -17,10 +17,41 @@
|
|
|
17
17
|
max-width: 43.75rem;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
.agent-prompt-home-connection {
|
|
21
|
+
display: grid;
|
|
22
|
+
grid-template-rows: 0fr;
|
|
23
|
+
opacity: 0;
|
|
24
|
+
transition:
|
|
25
|
+
grid-template-rows 200ms ease,
|
|
26
|
+
opacity 160ms ease;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.agent-prompt-home-connection[data-visible] {
|
|
30
|
+
grid-template-rows: 1fr;
|
|
31
|
+
opacity: 1;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.agent-prompt-home-connection > * {
|
|
35
|
+
min-height: 0;
|
|
36
|
+
overflow: hidden;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.agent-prompt-home-connection > .agent-builder-setup-card--attached {
|
|
40
|
+
margin-bottom: -1.875rem;
|
|
41
|
+
}
|
|
42
|
+
|
|
20
43
|
.agent-prompt-home-library {
|
|
21
44
|
padding-block-start: 2rem;
|
|
22
45
|
}
|
|
23
46
|
|
|
47
|
+
.agent-prompt-home-tabs > div:first-child {
|
|
48
|
+
position: sticky;
|
|
49
|
+
top: 0;
|
|
50
|
+
z-index: 10;
|
|
51
|
+
padding-block: 0.5rem;
|
|
52
|
+
background: hsl(var(--background));
|
|
53
|
+
}
|
|
54
|
+
|
|
24
55
|
.agent-template-library-grid {
|
|
25
56
|
display: grid;
|
|
26
57
|
grid-template-columns: minmax(0, 1fr);
|
|
@@ -28,6 +59,7 @@
|
|
|
28
59
|
}
|
|
29
60
|
|
|
30
61
|
.agent-template-library-preview {
|
|
62
|
+
position: relative;
|
|
31
63
|
aspect-ratio: 16 / 9;
|
|
32
64
|
overflow: hidden;
|
|
33
65
|
border-radius: inherit;
|
|
@@ -41,11 +73,13 @@
|
|
|
41
73
|
|
|
42
74
|
.agent-template-library-primary {
|
|
43
75
|
grid-area: 1 / 1 / 3 / 3;
|
|
76
|
+
position: relative;
|
|
44
77
|
min-width: 0;
|
|
45
78
|
}
|
|
46
79
|
|
|
47
80
|
.agent-template-library-caption {
|
|
48
|
-
height: 5rem;
|
|
81
|
+
min-height: 5rem;
|
|
82
|
+
padding: 1rem;
|
|
49
83
|
padding-inline-end: 3rem;
|
|
50
84
|
}
|
|
51
85
|
|
|
@@ -77,6 +111,12 @@
|
|
|
77
111
|
height: min(85dvh, 60rem);
|
|
78
112
|
}
|
|
79
113
|
|
|
114
|
+
@media (prefers-reduced-motion: reduce) {
|
|
115
|
+
.agent-prompt-home-connection {
|
|
116
|
+
transition: none;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
80
120
|
.agent-template-preview-viewer {
|
|
81
121
|
display: grid;
|
|
82
122
|
min-height: 0;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
|
|
3
|
+
export function useHomeSearchShortcut(enabled: boolean): void {
|
|
4
|
+
useEffect(() => {
|
|
5
|
+
if (!enabled) return;
|
|
6
|
+
const onKeyDown = (event: KeyboardEvent) => {
|
|
7
|
+
if (
|
|
8
|
+
event.key !== "/" ||
|
|
9
|
+
event.metaKey ||
|
|
10
|
+
event.ctrlKey ||
|
|
11
|
+
event.altKey ||
|
|
12
|
+
event.isComposing
|
|
13
|
+
) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const target = event.target instanceof HTMLElement ? event.target : null;
|
|
17
|
+
if (
|
|
18
|
+
target?.isContentEditable ||
|
|
19
|
+
target?.closest("input, textarea, select, [role='textbox']")
|
|
20
|
+
) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (
|
|
24
|
+
document.querySelector(
|
|
25
|
+
'[role="menu"][data-state="open"], [role="dialog"][data-state="open"], [role="alertdialog"][data-state="open"], dialog[open]',
|
|
26
|
+
)
|
|
27
|
+
) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const search = Array.from(
|
|
31
|
+
document.querySelectorAll<HTMLInputElement>("[data-home-search]"),
|
|
32
|
+
).find((input) => input.getClientRects().length > 0);
|
|
33
|
+
if (!search || search.disabled) return;
|
|
34
|
+
event.preventDefault();
|
|
35
|
+
search.focus();
|
|
36
|
+
};
|
|
37
|
+
document.addEventListener("keydown", onKeyDown);
|
|
38
|
+
return () => document.removeEventListener("keydown", onKeyDown);
|
|
39
|
+
}, [enabled]);
|
|
40
|
+
}
|
|
@@ -136,24 +136,10 @@ describe("connected composer menus", () => {
|
|
|
136
136
|
async function click(label: string) {
|
|
137
137
|
await act(async () => row(label).click());
|
|
138
138
|
}
|
|
139
|
-
|
|
140
|
-
const input = document.querySelector<HTMLInputElement>(
|
|
141
|
-
`input[placeholder="${placeholder}"]`,
|
|
142
|
-
)!;
|
|
143
|
-
await act(async () => {
|
|
144
|
-
Object.getOwnPropertyDescriptor(
|
|
145
|
-
HTMLInputElement.prototype,
|
|
146
|
-
"value",
|
|
147
|
-
)!.set!.call(input, value);
|
|
148
|
-
input.dispatchEvent(new Event("input", { bubbles: true }));
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
it("keeps all anchored panels visible with category search overrides and w64", async () => {
|
|
139
|
+
it("shows complete options in each anchored menu with w64", async () => {
|
|
152
140
|
await render(items, { addAttachment: vi.fn() });
|
|
153
141
|
await open();
|
|
154
|
-
expect(
|
|
155
|
-
document.querySelector('input[placeholder="Search…"]'),
|
|
156
|
-
).not.toBeNull();
|
|
142
|
+
expect(document.querySelectorAll('[role="searchbox"]')).toHaveLength(0);
|
|
157
143
|
expect(row("Upload File").querySelector("svg")?.getAttribute("width")).toBe(
|
|
158
144
|
"16",
|
|
159
145
|
);
|
|
@@ -162,14 +148,12 @@ describe("connected composer menus", () => {
|
|
|
162
148
|
await click("Archive");
|
|
163
149
|
expect(menus()).toHaveLength(4);
|
|
164
150
|
expect(menus().every((menu) => menu.classList.contains("w-64"))).toBe(true);
|
|
165
|
-
expect(document.querySelectorAll('[role="searchbox"]')).toHaveLength(
|
|
166
|
-
expect(
|
|
167
|
-
document.querySelector('input[placeholder="Search documents…"]'),
|
|
168
|
-
).not.toBeNull();
|
|
151
|
+
expect(document.querySelectorAll('[role="searchbox"]')).toHaveLength(0);
|
|
169
152
|
expect(row("Documents").getAttribute("aria-expanded")).toBe("true");
|
|
170
153
|
expect(row("Meeting notes").getAttribute("role")).toBe("menuitem");
|
|
154
|
+
expect(row("Project brief")).toBeDefined();
|
|
171
155
|
});
|
|
172
|
-
it("
|
|
156
|
+
it("keeps the menu hierarchy while listing every option", async () => {
|
|
173
157
|
const select = vi.fn();
|
|
174
158
|
await render(
|
|
175
159
|
[
|
|
@@ -187,27 +171,19 @@ describe("connected composer menus", () => {
|
|
|
187
171
|
{ addAttachment: vi.fn() },
|
|
188
172
|
);
|
|
189
173
|
await open();
|
|
190
|
-
|
|
191
|
-
expect(menus()[0].textContent).not.toContain("Upload File");
|
|
174
|
+
expect(row("Upload File")).toBeDefined();
|
|
192
175
|
await click("Add context");
|
|
193
|
-
|
|
194
|
-
expect(menus()[1].textContent).not.toContain("Library");
|
|
176
|
+
expect(row("Library")).toBeDefined();
|
|
195
177
|
await click("Documents");
|
|
196
|
-
|
|
197
|
-
expect(
|
|
178
|
+
expect(row("Notes")).toBeDefined();
|
|
179
|
+
expect(document.querySelectorAll('[role="searchbox"]')).toHaveLength(0);
|
|
198
180
|
await click("Project brief");
|
|
199
181
|
expect(select).toHaveBeenCalledOnce();
|
|
200
182
|
expect(menus()).toHaveLength(0);
|
|
201
183
|
});
|
|
202
|
-
it("
|
|
184
|
+
it("supports native ArrowRight, Left and Escape navigation", async () => {
|
|
203
185
|
await render();
|
|
204
186
|
await open();
|
|
205
|
-
const input =
|
|
206
|
-
document.querySelector<HTMLInputElement>('[role="searchbox"]')!;
|
|
207
|
-
await key(input, "d");
|
|
208
|
-
expect(document.activeElement).toBe(input);
|
|
209
|
-
await key(input, "ArrowDown");
|
|
210
|
-
expect(document.activeElement).toBe(row("Add context"));
|
|
211
187
|
await key(row("Add context"), "ArrowRight");
|
|
212
188
|
await key(row("Documents"), "ArrowRight");
|
|
213
189
|
expect(menus()).toHaveLength(3);
|
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
} from "../ui/dropdown-menu.js";
|
|
21
21
|
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip.js";
|
|
22
22
|
import { formatAttachmentError } from "./attachment-accept.js";
|
|
23
|
-
import { ComposerContextMenuSearch } from "./ComposerContextMenuSearch.js";
|
|
24
23
|
import {
|
|
25
24
|
ComposerContextPicker,
|
|
26
25
|
type ComposerContextPickerConfig,
|
|
@@ -189,37 +188,6 @@ function ContextSubmenu({
|
|
|
189
188
|
);
|
|
190
189
|
}
|
|
191
190
|
|
|
192
|
-
function ContextMenuPanel({
|
|
193
|
-
placeholder,
|
|
194
|
-
children,
|
|
195
|
-
}: {
|
|
196
|
-
placeholder: string;
|
|
197
|
-
children: (query: string) => ReactNode;
|
|
198
|
-
}) {
|
|
199
|
-
const [query, setQuery] = useState("");
|
|
200
|
-
return (
|
|
201
|
-
<>
|
|
202
|
-
<ComposerContextMenuSearch
|
|
203
|
-
placeholder={placeholder}
|
|
204
|
-
value={query}
|
|
205
|
-
onValueChange={setQuery}
|
|
206
|
-
/>
|
|
207
|
-
{children(query)}
|
|
208
|
-
</>
|
|
209
|
-
);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
function matchesEntry(entry: ComposerContextMenuItem, query: string): boolean {
|
|
213
|
-
const terms = query.trim().toLocaleLowerCase().split(/\s+/).filter(Boolean);
|
|
214
|
-
const text = [entry.label, ...(entry.keywords ?? [])]
|
|
215
|
-
.join(" ")
|
|
216
|
-
.toLocaleLowerCase();
|
|
217
|
-
return (
|
|
218
|
-
terms.every((term) => text.includes(term)) ||
|
|
219
|
-
Boolean(entry.children?.some((child) => matchesEntry(child, query)))
|
|
220
|
-
);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
191
|
function LegacyContextPage({ children }: { children: ReactNode }) {
|
|
224
192
|
const element = useRef<HTMLDivElement>(null);
|
|
225
193
|
useEffect(() => {
|
|
@@ -274,9 +242,6 @@ export function ComposerContextMenu({
|
|
|
274
242
|
const label = t("agentChat.composer.addContext", {
|
|
275
243
|
defaultValue: "Add context",
|
|
276
244
|
});
|
|
277
|
-
const searchContext = t("agentChat.composer.searchContext", {
|
|
278
|
-
defaultValue: "Search context…",
|
|
279
|
-
});
|
|
280
245
|
const uploadLabel = t("agentChat.composer.menu.uploadFile", {
|
|
281
246
|
defaultValue: "Upload File",
|
|
282
247
|
});
|
|
@@ -399,18 +364,7 @@ export function ComposerContextMenu({
|
|
|
399
364
|
}}
|
|
400
365
|
>
|
|
401
366
|
{entry.children ? (
|
|
402
|
-
|
|
403
|
-
placeholder={entry.searchPlaceholder ?? searchContext}
|
|
404
|
-
>
|
|
405
|
-
{(query) =>
|
|
406
|
-
renderEntries(
|
|
407
|
-
entry.children.filter((child) =>
|
|
408
|
-
matchesEntry(child, query),
|
|
409
|
-
),
|
|
410
|
-
branch,
|
|
411
|
-
)
|
|
412
|
-
}
|
|
413
|
-
</ContextMenuPanel>
|
|
367
|
+
renderEntries(entry.children, branch)
|
|
414
368
|
) : entry.picker ? (
|
|
415
369
|
<ComposerContextPicker
|
|
416
370
|
key={JSON.stringify([entry.id, entry.picker.scopeKey])}
|
|
@@ -522,59 +476,35 @@ export function ComposerContextMenu({
|
|
|
522
476
|
restoreFocusOnClose.current = true;
|
|
523
477
|
}}
|
|
524
478
|
>
|
|
525
|
-
<
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
<DropdownMenuItem
|
|
537
|
-
onSelect={() => {
|
|
538
|
-
changeOpen(false);
|
|
539
|
-
inputRef.current?.click();
|
|
540
|
-
}}
|
|
541
|
-
>
|
|
542
|
-
<IconFile size={16} />
|
|
543
|
-
{uploadLabel}
|
|
544
|
-
</DropdownMenuItem>
|
|
545
|
-
)}
|
|
546
|
-
{items.length > 0 &&
|
|
547
|
-
(label
|
|
548
|
-
.toLocaleLowerCase()
|
|
549
|
-
.includes(query.trim().toLocaleLowerCase()) ||
|
|
550
|
-
items.some((item) => matchesEntry(item, query))) && (
|
|
551
|
-
<ContextSubmenu
|
|
552
|
-
label={label}
|
|
553
|
-
icon={<IconTextRecognition size={16} />}
|
|
554
|
-
open={contextOpen}
|
|
555
|
-
onOpenChange={(next) => {
|
|
556
|
-
setContextOpen(next);
|
|
557
|
-
if (!next) {
|
|
558
|
-
dismissPage();
|
|
559
|
-
updatePath([]);
|
|
560
|
-
}
|
|
561
|
-
}}
|
|
562
|
-
>
|
|
563
|
-
<ContextMenuPanel placeholder={searchContext}>
|
|
564
|
-
{(contextQuery) =>
|
|
565
|
-
renderEntries(
|
|
566
|
-
items.filter((item) =>
|
|
567
|
-
matchesEntry(item, contextQuery),
|
|
568
|
-
),
|
|
569
|
-
[],
|
|
570
|
-
)
|
|
571
|
-
}
|
|
572
|
-
</ContextMenuPanel>
|
|
573
|
-
</ContextSubmenu>
|
|
574
|
-
)}
|
|
575
|
-
</DropdownMenuGroup>
|
|
479
|
+
<DropdownMenuGroup>
|
|
480
|
+
{addAttachment && (
|
|
481
|
+
<DropdownMenuItem
|
|
482
|
+
onSelect={() => {
|
|
483
|
+
changeOpen(false);
|
|
484
|
+
inputRef.current?.click();
|
|
485
|
+
}}
|
|
486
|
+
>
|
|
487
|
+
<IconFile size={16} />
|
|
488
|
+
{uploadLabel}
|
|
489
|
+
</DropdownMenuItem>
|
|
576
490
|
)}
|
|
577
|
-
|
|
491
|
+
{items.length > 0 ? (
|
|
492
|
+
<ContextSubmenu
|
|
493
|
+
label={label}
|
|
494
|
+
icon={<IconTextRecognition size={16} />}
|
|
495
|
+
open={contextOpen}
|
|
496
|
+
onOpenChange={(next) => {
|
|
497
|
+
setContextOpen(next);
|
|
498
|
+
if (!next) {
|
|
499
|
+
dismissPage();
|
|
500
|
+
updatePath([]);
|
|
501
|
+
}
|
|
502
|
+
}}
|
|
503
|
+
>
|
|
504
|
+
{renderEntries(items, [])}
|
|
505
|
+
</ContextSubmenu>
|
|
506
|
+
) : null}
|
|
507
|
+
</DropdownMenuGroup>
|
|
578
508
|
</DropdownMenuContent>
|
|
579
509
|
</DropdownMenu>
|
|
580
510
|
{dialog &&
|
|
@@ -242,7 +242,7 @@ describe("declarative context picker", () => {
|
|
|
242
242
|
expect(menus()).toHaveLength(4);
|
|
243
243
|
expect(menus().every((menu) => menu.classList.contains("w-64"))).toBe(true);
|
|
244
244
|
const searches = document.querySelectorAll('input[role="searchbox"]');
|
|
245
|
-
expect(searches).toHaveLength(
|
|
245
|
+
expect(searches).toHaveLength(1);
|
|
246
246
|
expect(document.querySelector('[role="combobox"]')).toBeNull();
|
|
247
247
|
for (const input of searches)
|
|
248
248
|
expect(input.hasAttribute("aria-controls")).toBe(false);
|
|
@@ -44,7 +44,7 @@ describe("controlled composer context", () => {
|
|
|
44
44
|
),
|
|
45
45
|
);
|
|
46
46
|
const menu = document.querySelector('[role="menu"]')!;
|
|
47
|
-
expect(menu.querySelector('[role="searchbox"]')).
|
|
47
|
+
expect(menu.querySelector('[role="searchbox"]')).toBeNull();
|
|
48
48
|
expect(menu.textContent).toBe("Upload File");
|
|
49
49
|
await act(async () =>
|
|
50
50
|
document.dispatchEvent(
|