@agent-native/toolkit 0.208.0 → 0.209.0-nightly-20261014070126

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 (46) hide show
  1. package/dist/app/chat/MultiTabAssistantChat.d.ts.map +1 -1
  2. package/dist/app/chat/MultiTabAssistantChat.js +12 -1
  3. package/dist/app/chat/MultiTabAssistantChat.js.map +1 -1
  4. package/dist/app/chat/agentkit-chat/guided-questions.d.ts +12 -0
  5. package/dist/app/chat/agentkit-chat/guided-questions.d.ts.map +1 -1
  6. package/dist/app/chat/agentkit-chat/guided-questions.js +32 -4
  7. package/dist/app/chat/agentkit-chat/guided-questions.js.map +1 -1
  8. package/dist/app/chat/agentkit-chat/index.d.ts +1 -1
  9. package/dist/app/chat/agentkit-chat/index.d.ts.map +1 -1
  10. package/dist/app/chat/agentkit-chat/index.js +1 -1
  11. package/dist/app/chat/agentkit-chat/index.js.map +1 -1
  12. package/dist/app/chat/chat/run-recovery.d.ts.map +1 -1
  13. package/dist/app/chat/chat/run-recovery.js +15 -8
  14. package/dist/app/chat/chat/run-recovery.js.map +1 -1
  15. package/dist/app/sharing/ShareButton.d.ts.map +1 -1
  16. package/dist/app/sharing/ShareButton.js +66 -73
  17. package/dist/app/sharing/ShareButton.js.map +1 -1
  18. package/dist/app/sharing/ShareDialog.d.ts.map +1 -1
  19. package/dist/app/sharing/ShareDialog.js +4 -12
  20. package/dist/app/sharing/ShareDialog.js.map +1 -1
  21. package/dist/sharing/ShareControls.d.ts +19 -1
  22. package/dist/sharing/ShareControls.d.ts.map +1 -1
  23. package/dist/sharing/ShareControls.js +14 -7
  24. package/dist/sharing/ShareControls.js.map +1 -1
  25. package/dist/sharing/SharePrimitives.js +1 -1
  26. package/dist/sharing/SharePrimitives.js.map +1 -1
  27. package/dist/sharing/index.d.ts +1 -1
  28. package/dist/sharing/index.d.ts.map +1 -1
  29. package/dist/sharing/index.js +1 -1
  30. package/dist/sharing/index.js.map +1 -1
  31. package/package.json +4 -4
  32. package/src/app/chat/MultiTabAssistantChat.spec.tsx +101 -2
  33. package/src/app/chat/MultiTabAssistantChat.tsx +14 -1
  34. package/src/app/chat/agentkit-chat/guided-questions.flow.spec.tsx +168 -0
  35. package/src/app/chat/agentkit-chat/guided-questions.tsx +54 -9
  36. package/src/app/chat/agentkit-chat/index.ts +2 -0
  37. package/src/app/chat/chat/run-recovery.spec.tsx +64 -0
  38. package/src/app/chat/chat/run-recovery.tsx +14 -8
  39. package/src/app/sharing/ShareButton.spec.tsx +125 -32
  40. package/src/app/sharing/ShareButton.tsx +119 -149
  41. package/src/app/sharing/ShareDialog.spec.tsx +31 -0
  42. package/src/app/sharing/ShareDialog.tsx +46 -71
  43. package/src/sharing/ShareControls.spec.tsx +86 -1
  44. package/src/sharing/ShareControls.tsx +83 -27
  45. package/src/sharing/SharePrimitives.tsx +1 -1
  46. package/src/sharing/index.ts +4 -0
@@ -3,6 +3,7 @@ import {
3
3
  type ResourceShare,
4
4
  type ShareDialogController,
5
5
  type ShareDialogPerson,
6
+ type ShareDialogTab,
6
7
  type ShareVisibility,
7
8
  } from "@agent-native/core/client/sharing/useShareDialogController";
8
9
  import { writeClipboardText } from "@agent-native/toolkit/clipboard";
@@ -15,7 +16,8 @@ import {
15
16
  Status,
16
17
  TextArea,
17
18
  } from "@agent-native/toolkit/design-system";
18
- import { ShareCopyRow } from "@agent-native/toolkit/sharing";
19
+ import { ShareCopyRow, ShareTabList } from "@agent-native/toolkit/sharing";
20
+ import { Tabs, TabsContent } from "@agent-native/toolkit/ui/tabs";
19
21
  import { cn } from "@agent-native/toolkit/utils";
20
22
  import {
21
23
  IconCheck,
@@ -118,81 +120,54 @@ export function ShareDialog({
118
120
  </div>
119
121
  ) : null}
120
122
 
121
- {controller.tabsEnabled && showTabList ? (
122
- <div
123
- role="tablist"
124
- aria-label={controller.labels.shareOptions}
125
- className="mx-5 mt-10 flex gap-1 rounded-xl bg-muted/70 p-1"
126
- >
127
- {controller.tabs.map((tab) => {
128
- return (
129
- <TabTrigger
130
- key={tab.value}
131
- active={controller.activeTab === tab.value}
132
- onClick={() => controller.setActiveTab(tab.value)}
133
- label={tab.label}
134
- />
135
- );
136
- })}
137
- </div>
138
- ) : null}
139
-
140
- <div className="px-5 py-4">
141
- {controller.tabsEnabled && controller.activeTab === "link" ? (
142
- <LinkTab
143
- controller={controller}
144
- extras={linkTabExtras}
145
- accessRequests={accessRequests}
123
+ <Tabs
124
+ value={controller.activeTab}
125
+ onValueChange={(value) =>
126
+ controller.setActiveTab(value as ShareDialogTab)
127
+ }
128
+ >
129
+ {controller.tabsEnabled && showTabList ? (
130
+ <ShareTabList
131
+ tabs={controller.tabs}
132
+ aria-label={controller.labels.shareOptions}
133
+ className="mx-5 mt-10 w-auto"
146
134
  />
147
135
  ) : null}
148
- {!controller.tabsEnabled || controller.activeTab === "invite" ? (
149
- <InviteTab
150
- controller={controller}
151
- showVisibility={!controller.tabsEnabled}
152
- accessRequests={accessRequests}
136
+
137
+ <div className="px-5 py-4">
138
+ {controller.tabsEnabled ? (
139
+ <TabsContent value="link" className="m-0">
140
+ <LinkTab
141
+ controller={controller}
142
+ extras={linkTabExtras}
143
+ accessRequests={accessRequests}
144
+ />
145
+ </TabsContent>
146
+ ) : null}
147
+ {!controller.tabsEnabled || controller.activeTab === "invite" ? (
148
+ <InviteTab
149
+ controller={controller}
150
+ showVisibility={!controller.tabsEnabled}
151
+ accessRequests={accessRequests}
152
+ />
153
+ ) : null}
154
+ {controller.tabsEnabled ? (
155
+ <TabsContent value="embed" className="m-0">
156
+ {embedTabContent ?? <DefaultEmbedBody controller={controller} />}
157
+ </TabsContent>
158
+ ) : null}
159
+ <AgentShareSection
160
+ enabled={controller.agentReadable}
161
+ resourceType={resourceType}
162
+ resourceId={resourceId}
163
+ className="mt-4"
153
164
  />
154
- ) : null}
155
- {controller.tabsEnabled && controller.activeTab === "embed"
156
- ? (embedTabContent ?? <DefaultEmbedBody controller={controller} />)
157
- : null}
158
- <AgentShareSection
159
- enabled={controller.agentReadable}
160
- resourceType={resourceType}
161
- resourceId={resourceId}
162
- className="mt-4"
163
- />
164
- </div>
165
+ </div>
166
+ </Tabs>
165
167
  </DesignSystemDialog>
166
168
  );
167
169
  }
168
170
 
169
- function TabTrigger({
170
- active,
171
- onClick,
172
- label,
173
- }: {
174
- active: boolean;
175
- onClick: () => void;
176
- label: string;
177
- }) {
178
- return (
179
- <ActionButton
180
- type="button"
181
- emphasis="ghost"
182
- aria-pressed={active}
183
- onPress={onClick}
184
- className={cn(
185
- "min-w-0 flex-1 !rounded-lg !px-3 !py-2 text-sm font-medium transition-colors hover:!bg-background/70 active:!scale-100 focus-visible:!ring-0 focus-visible:!ring-offset-0",
186
- active
187
- ? "bg-background text-foreground shadow-sm ring-1 ring-border"
188
- : "text-muted-foreground hover:text-foreground",
189
- )}
190
- >
191
- <span className="block truncate">{label}</span>
192
- </ActionButton>
193
- );
194
- }
195
-
196
171
  function LinkTab({
197
172
  controller,
198
173
  extras,
@@ -256,7 +231,7 @@ function InviteTab({
256
231
  <div className="space-y-4">
257
232
  {showVisibility ? (
258
233
  <div>
259
- <div className="mb-2 text-sm font-semibold">
234
+ <div className="mb-2 text-xs font-medium text-muted-foreground">
260
235
  {controller.labels.generalAccess}
261
236
  </div>
262
237
  <div className="flex items-center gap-3">
@@ -279,7 +254,7 @@ function InviteTab({
279
254
  {accessRequests}
280
255
 
281
256
  <div className="space-y-4">
282
- <div className="text-sm font-semibold">
257
+ <div className="text-xs font-medium text-muted-foreground">
283
258
  {controller.labels.peopleWithAccess}
284
259
  </div>
285
260
  {controller.canManage ? (
@@ -5,7 +5,11 @@ import { createRoot } from "react-dom/client";
5
5
  import { afterEach, describe, expect, it, vi } from "vitest";
6
6
 
7
7
  import { TooltipProvider } from "../ui/tooltip.js";
8
- import { JoinedShareControl, ShareModeTabs } from "./ShareControls.js";
8
+ import {
9
+ JoinedShareControl,
10
+ ShareModeTabs,
11
+ ShareTabs,
12
+ } from "./ShareControls.js";
9
13
 
10
14
  describe("JoinedShareControl", () => {
11
15
  const roots: ReturnType<typeof createRoot>[] = [];
@@ -86,6 +90,87 @@ describe("JoinedShareControl", () => {
86
90
  );
87
91
  });
88
92
 
93
+ it("renders underline tabs and shows only the selected tab's panel", async () => {
94
+ const container = document.createElement("div");
95
+ document.body.append(container);
96
+ containers.push(container);
97
+ const root = createRoot(container);
98
+ roots.push(root);
99
+ const onValueChange = vi.fn();
100
+
101
+ await act(async () => {
102
+ root.render(
103
+ <ShareTabs
104
+ value="link"
105
+ onValueChange={onValueChange}
106
+ listLabel="Share options"
107
+ tabs={[
108
+ { value: "link", label: "Link", content: <div>Link body</div> },
109
+ { value: "embed", label: "Embed", content: <div>Embed body</div> },
110
+ ]}
111
+ />,
112
+ );
113
+ });
114
+
115
+ const list = container.querySelector('[role="tablist"]');
116
+ expect(list?.getAttribute("aria-label")).toBe("Share options");
117
+ expect(list?.className).toContain("bg-transparent");
118
+ expect(list?.className).not.toContain("bg-muted");
119
+ const tabs = Array.from(
120
+ container.querySelectorAll<HTMLElement>('[role="tab"]'),
121
+ );
122
+ for (const tab of tabs) {
123
+ expect(tab.className).toContain("after:bg-foreground");
124
+ expect(tab.className).toContain("data-[state=active]:bg-transparent");
125
+ }
126
+ expect(container.textContent).toContain("Link body");
127
+ expect(container.textContent).not.toContain("Embed body");
128
+
129
+ await act(async () => {
130
+ tabs[1].dispatchEvent(
131
+ new MouseEvent("mousedown", { bubbles: true, button: 0 }),
132
+ );
133
+ });
134
+ expect(onValueChange).toHaveBeenCalledWith("embed");
135
+ });
136
+
137
+ it("builds People and Agents on the same underline tabs", async () => {
138
+ const container = document.createElement("div");
139
+ document.body.append(container);
140
+ containers.push(container);
141
+ const root = createRoot(container);
142
+ roots.push(root);
143
+
144
+ await act(async () => {
145
+ root.render(
146
+ <ShareModeTabs
147
+ value="agents"
148
+ onValueChange={() => {}}
149
+ peopleLabel="People"
150
+ agentsLabel="Agents"
151
+ people={<div>Access</div>}
152
+ agents={<div>Prompt</div>}
153
+ extraTabs={[
154
+ { value: "context", label: "Context", content: <div>Ctx</div> },
155
+ ]}
156
+ />,
157
+ );
158
+ });
159
+
160
+ const tabs = Array.from(
161
+ container.querySelectorAll<HTMLElement>('[role="tab"]'),
162
+ );
163
+ expect(tabs.map((tab) => tab.textContent)).toEqual([
164
+ "People",
165
+ "Agents",
166
+ "Context",
167
+ ]);
168
+ expect(tabs[1].getAttribute("aria-selected")).toBe("true");
169
+ for (const tab of tabs) expect(tab.className).toContain("after:h-0.5");
170
+ expect(container.textContent).toContain("Prompt");
171
+ expect(container.textContent).not.toContain("Access");
172
+ });
173
+
89
174
  it("keeps disabled extra share tabs unavailable", async () => {
90
175
  const container = document.createElement("div");
91
176
  document.body.append(container);
@@ -105,6 +105,78 @@ export interface ShareModeTab {
105
105
  disabled?: boolean;
106
106
  }
107
107
 
108
+ export interface ShareTabListProps {
109
+ tabs: Pick<ShareModeTab, "value" | "label" | "disabled">[];
110
+ className?: string;
111
+ "aria-label"?: string;
112
+ }
113
+
114
+ /** The underline tab strip every share surface uses. Render inside `Tabs`. */
115
+ export function ShareTabList({
116
+ tabs,
117
+ className,
118
+ "aria-label": ariaLabel,
119
+ }: ShareTabListProps) {
120
+ return (
121
+ <TabsList
122
+ aria-label={ariaLabel}
123
+ className={cn(
124
+ "h-8 w-full justify-start gap-1 overflow-x-auto rounded-none bg-transparent px-0 py-0 [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
125
+ className,
126
+ )}
127
+ >
128
+ {tabs.map((tab) => (
129
+ <TabsTrigger
130
+ key={tab.value}
131
+ value={tab.value}
132
+ disabled={tab.disabled}
133
+ className="relative h-8 min-w-0 flex-none rounded-none bg-transparent px-2 py-0 text-sm font-normal shadow-none after:absolute after:bottom-0 after:inset-x-2 after:h-0.5 after:bg-foreground after:opacity-0 focus-visible:ring-inset focus-visible:ring-offset-0 data-[state=active]:bg-transparent data-[state=active]:font-medium data-[state=active]:shadow-none data-[state=active]:after:opacity-100"
134
+ >
135
+ {tab.label}
136
+ </TabsTrigger>
137
+ ))}
138
+ </TabsList>
139
+ );
140
+ }
141
+
142
+ export interface ShareTabsProps {
143
+ value: string;
144
+ onValueChange: (value: string) => void;
145
+ tabs: ShareModeTab[];
146
+ listLabel?: string;
147
+ className?: string;
148
+ listClassName?: string;
149
+ }
150
+
151
+ /** Underline tabs for a share surface; each tab owns its panel. */
152
+ export function ShareTabs({
153
+ value,
154
+ onValueChange,
155
+ tabs,
156
+ listLabel,
157
+ className,
158
+ listClassName,
159
+ }: ShareTabsProps) {
160
+ return (
161
+ <Tabs
162
+ value={value}
163
+ onValueChange={onValueChange}
164
+ className={cn("flex flex-col gap-3", className)}
165
+ >
166
+ <ShareTabList
167
+ tabs={tabs}
168
+ aria-label={listLabel}
169
+ className={listClassName}
170
+ />
171
+ {tabs.map((tab) => (
172
+ <TabsContent key={tab.value} value={tab.value} className="m-0">
173
+ {tab.content}
174
+ </TabsContent>
175
+ ))}
176
+ </Tabs>
177
+ );
178
+ }
179
+
108
180
  export interface ShareModeTabsProps {
109
181
  value: string;
110
182
  onValueChange: (value: string) => void;
@@ -113,6 +185,7 @@ export interface ShareModeTabsProps {
113
185
  people: ReactNode;
114
186
  agents: ReactNode;
115
187
  extraTabs?: ShareModeTab[];
188
+ listLabel?: string;
116
189
  className?: string;
117
190
  }
118
191
 
@@ -125,38 +198,21 @@ export function ShareModeTabs({
125
198
  people,
126
199
  agents,
127
200
  extraTabs = [],
201
+ listLabel,
128
202
  className,
129
203
  }: ShareModeTabsProps) {
130
- const tabs = [
131
- { value: "people", label: peopleLabel, content: people },
132
- { value: "agents", label: agentsLabel, content: agents },
133
- ...extraTabs,
134
- ];
135
-
136
204
  return (
137
- <Tabs
205
+ <ShareTabs
138
206
  value={value}
139
207
  onValueChange={onValueChange}
140
- className={cn("flex flex-col gap-3", className)}
141
- >
142
- <TabsList className="h-8 w-full justify-start gap-1 rounded-none bg-transparent px-0 py-0">
143
- {tabs.map((tab) => (
144
- <TabsTrigger
145
- key={tab.value}
146
- value={tab.value}
147
- disabled={tab.disabled}
148
- className="relative h-8 min-w-0 flex-none rounded-none bg-transparent px-2 py-0 text-sm font-normal shadow-none after:absolute after:bottom-0 after:inset-x-2 after:h-0.5 after:bg-foreground after:opacity-0 data-[state=active]:bg-transparent data-[state=active]:font-medium data-[state=active]:shadow-none data-[state=active]:after:opacity-100"
149
- >
150
- {tab.label}
151
- </TabsTrigger>
152
- ))}
153
- </TabsList>
154
- {tabs.map((tab) => (
155
- <TabsContent key={tab.value} value={tab.value} className="m-0">
156
- {tab.content}
157
- </TabsContent>
158
- ))}
159
- </Tabs>
208
+ listLabel={listLabel}
209
+ className={className}
210
+ tabs={[
211
+ { value: "people", label: peopleLabel, content: people },
212
+ { value: "agents", label: agentsLabel, content: agents },
213
+ ...extraTabs,
214
+ ]}
215
+ />
160
216
  );
161
217
  }
162
218
 
@@ -113,7 +113,7 @@ export function ShareCopyRow({
113
113
  : accessibleLabel(copyLabel, "Copy")
114
114
  }
115
115
  onPress={() => void handleCopy()}
116
- className="h-9 shrink-0"
116
+ className="shrink-0"
117
117
  >
118
118
  {copied ? copiedLabel : copyLabel}
119
119
  </ActionButton>
@@ -14,6 +14,10 @@ export {
14
14
  ShareModeTabs,
15
15
  type ShareModeTab,
16
16
  type ShareModeTabsProps,
17
+ ShareTabList,
18
+ type ShareTabListProps,
19
+ ShareTabs,
20
+ type ShareTabsProps,
17
21
  } from "./ShareControls.js";
18
22
  export {
19
23
  ShareAgentsSection,