@iloveagents/foundry-web-ui 0.1.0 → 0.1.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/CHANGELOG.md +36 -0
- package/package.json +3 -3
- package/src/components/__tests__/context-bar.test.ts +112 -0
- package/src/components/app-brand.tsx +1 -1
- package/src/components/assistant-chat.tsx +60 -22
- package/src/components/chat-bubble.tsx +48 -14
- package/src/components/composer-submit-bridge.tsx +19 -0
- package/src/components/context-badges.tsx +25 -13
- package/src/components/context-bar.tsx +38 -2
- package/src/components/global-selection-popover.tsx +165 -34
- package/src/components/markdown-text-citations.test.tsx +108 -0
- package/src/components/markdown-text.tsx +155 -26
- package/src/components/selection-popover.tsx +3 -3
- package/src/components/sidebar.test.tsx +144 -0
- package/src/components/sidebar.tsx +207 -41
- package/src/components/theme-runtime-provider.tsx +1 -1
- package/src/components/tool-panel.tsx +3 -3
- package/src/components/user-menu.tsx +1 -1
- package/src/index.ts +11 -1
- package/src/lib/__tests__/ag-ui-adapter.test.ts +94 -3
- package/src/lib/__tests__/app-store.test.ts +75 -0
- package/src/lib/__tests__/selection-context.test.ts +114 -0
- package/src/lib/ag-ui-adapter.ts +64 -14
- package/src/lib/app-store.ts +68 -1
- package/src/lib/composer-submit-store.ts +32 -0
- package/src/lib/nav-config.ts +5 -0
- package/src/lib/selection-context.ts +65 -0
- package/src/lib/theme-runtime.ts +2 -2
- package/src/lib/use-new-conversation.test.tsx +38 -0
- package/src/lib/use-new-conversation.ts +24 -3
- package/src/ui/dropdown-menu.tsx +5 -1
|
@@ -39,6 +39,18 @@ function Trigger() {
|
|
|
39
39
|
);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
function PreserveNavigationTrigger() {
|
|
43
|
+
const handleNewConversation = useNewConversation({
|
|
44
|
+
navigateToChat: false,
|
|
45
|
+
preserveNavigation: true,
|
|
46
|
+
});
|
|
47
|
+
return (
|
|
48
|
+
<button type="button" onClick={handleNewConversation}>
|
|
49
|
+
New Bubble Thread
|
|
50
|
+
</button>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
42
54
|
describe("useNewConversation", () => {
|
|
43
55
|
let container: HTMLDivElement;
|
|
44
56
|
let root: Root;
|
|
@@ -121,4 +133,30 @@ describe("useNewConversation", () => {
|
|
|
121
133
|
expect(citationStore.getState().results).toEqual([]);
|
|
122
134
|
expect(citationStore.getState().handler).toBeNull();
|
|
123
135
|
});
|
|
136
|
+
|
|
137
|
+
it("can reset the thread without leaving the current page", async () => {
|
|
138
|
+
await act(async () => {
|
|
139
|
+
root.render(
|
|
140
|
+
<MemoryRouter initialEntries={["/spaces/demo"]}>
|
|
141
|
+
<PreserveNavigationTrigger />
|
|
142
|
+
<LocationProbe />
|
|
143
|
+
</MemoryRouter>,
|
|
144
|
+
);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
const button = container.querySelector("button");
|
|
148
|
+
expect(button).toBeTruthy();
|
|
149
|
+
|
|
150
|
+
await act(async () => {
|
|
151
|
+
button?.dispatchEvent(new MouseEvent("click", { bubbles: true }));
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
expect(container.querySelector('[data-testid="location"]')?.textContent).toBe("/spaces/demo");
|
|
155
|
+
expect(switchToNewThread).toHaveBeenCalledTimes(1);
|
|
156
|
+
expect(resetThread).toHaveBeenCalledTimes(1);
|
|
157
|
+
expect(useAppStore.getState().currentPage).toBe("/spaces/demo");
|
|
158
|
+
expect(useAppStore.getState().navContext.label).toBe("Demo");
|
|
159
|
+
expect(useAppStore.getState().threadActive).toBe(false);
|
|
160
|
+
expect(useAppStore.getState().contextItems).toEqual([]);
|
|
161
|
+
});
|
|
124
162
|
});
|
|
@@ -12,7 +12,7 @@ import { useSidebarStore } from "./sidebar-store.ts";
|
|
|
12
12
|
* Shared hook for starting a new conversation.
|
|
13
13
|
* Used by ChatHeader and Sidebar to keep behavior in sync.
|
|
14
14
|
*/
|
|
15
|
-
export function useNewConversation() {
|
|
15
|
+
export function useNewConversation(options?: { navigateToChat?: boolean; preserveNavigation?: boolean }) {
|
|
16
16
|
const aui = useAui();
|
|
17
17
|
const { resetThread } = useAGUIAdapter();
|
|
18
18
|
const navigate = useNavigate();
|
|
@@ -22,12 +22,33 @@ export function useNewConversation() {
|
|
|
22
22
|
const clearCitations = useStore(citationStore, (s) => s.clear);
|
|
23
23
|
|
|
24
24
|
return useCallback(() => {
|
|
25
|
+
const preserved = options?.preserveNavigation
|
|
26
|
+
? {
|
|
27
|
+
currentPage: useAppStore.getState().currentPage,
|
|
28
|
+
navContext: useAppStore.getState().navContext,
|
|
29
|
+
}
|
|
30
|
+
: null;
|
|
25
31
|
closePanel();
|
|
26
32
|
resetApp();
|
|
33
|
+
if (preserved) {
|
|
34
|
+
useAppStore.setState(preserved);
|
|
35
|
+
}
|
|
27
36
|
closeMobile();
|
|
28
37
|
clearCitations();
|
|
29
38
|
resetThread();
|
|
30
39
|
aui.threads().switchToNewThread();
|
|
31
|
-
|
|
32
|
-
|
|
40
|
+
if (options?.navigateToChat ?? true) {
|
|
41
|
+
navigate("/");
|
|
42
|
+
}
|
|
43
|
+
}, [
|
|
44
|
+
closePanel,
|
|
45
|
+
resetApp,
|
|
46
|
+
options?.preserveNavigation,
|
|
47
|
+
closeMobile,
|
|
48
|
+
clearCitations,
|
|
49
|
+
resetThread,
|
|
50
|
+
aui,
|
|
51
|
+
options?.navigateToChat,
|
|
52
|
+
navigate,
|
|
53
|
+
]);
|
|
33
54
|
}
|
package/src/ui/dropdown-menu.tsx
CHANGED
|
@@ -36,7 +36,11 @@ export const DropdownMenuItem = forwardRef<
|
|
|
36
36
|
<DropdownMenuPrimitive.Item
|
|
37
37
|
ref={ref}
|
|
38
38
|
className={cn(
|
|
39
|
-
|
|
39
|
+
// ``gap-2`` is the same icon-to-text spacing the framework's
|
|
40
|
+
// Button primitive uses, so a ``<lucide-icon /> Label`` pattern
|
|
41
|
+
// inside any menu item renders consistently everywhere without
|
|
42
|
+
// the consumer needing to remember the override.
|
|
43
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none",
|
|
40
44
|
"transition-colors focus:bg-accent focus:text-accent-foreground",
|
|
41
45
|
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
42
46
|
className,
|