@agent-native/toolkit 0.198.5 → 0.198.6
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/agentkit/react/components.d.ts +2 -1
- package/dist/app/agentkit/react/components.d.ts.map +1 -1
- package/dist/app/agentkit/react/components.js +86 -62
- package/dist/app/agentkit/react/components.js.map +1 -1
- package/dist/app/agentkit/react/styles.css +36 -24
- package/dist/app/chat/AgentKitAssistantChat.js +14 -7
- package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
- package/dist/app/chat/AgentPanel.d.ts +1 -1
- package/dist/app/chat/AgentPanel.d.ts.map +1 -1
- package/dist/app/chat/AgentPanel.js +11 -38
- package/dist/app/chat/AgentPanel.js.map +1 -1
- package/dist/app/chat/AgentSidebar.d.ts.map +1 -1
- package/dist/app/chat/AgentSidebar.js +3 -11
- package/dist/app/chat/AgentSidebar.js.map +1 -1
- package/dist/app/chat/chat/tool-call-display.d.ts +2 -1
- package/dist/app/chat/chat/tool-call-display.d.ts.map +1 -1
- package/dist/app/chat/chat/tool-call-display.js +83 -55
- package/dist/app/chat/chat/tool-call-display.js.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.js +1 -0
- package/dist/app/i18n/catalogs/ar-SA.js.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.js +1 -0
- package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
- package/dist/app/i18n/catalogs/en-US.d.ts +1 -0
- package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/en-US.js +1 -0
- package/dist/app/i18n/catalogs/en-US.js.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.js +1 -0
- package/dist/app/i18n/catalogs/es-ES.js.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.js +1 -0
- package/dist/app/i18n/catalogs/fr-FR.js.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.js +1 -0
- package/dist/app/i18n/catalogs/hi-IN.js.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.js +1 -0
- package/dist/app/i18n/catalogs/ja-JP.js.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.js +1 -0
- package/dist/app/i18n/catalogs/ko-KR.js.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.js +1 -0
- package/dist/app/i18n/catalogs/pt-BR.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.js +1 -0
- package/dist/app/i18n/catalogs/zh-CN.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.js +1 -0
- package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
- package/dist/composer/TiptapComposer.d.ts +1 -1
- package/dist/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/composer/TiptapComposer.js +26 -23
- package/dist/composer/TiptapComposer.js.map +1 -1
- package/dist/ui/sonner.js +1 -1
- package/dist/ui/sonner.js.map +1 -1
- package/package.json +3 -3
- package/src/app/agentkit/react/components.tsx +156 -128
- package/src/app/agentkit/react/lifecycle.spec.tsx +556 -39
- package/src/app/agentkit/react/styles.css +36 -24
- package/src/app/chat/AgentKitAssistantChat.spec.tsx +22 -0
- package/src/app/chat/AgentKitAssistantChat.tsx +19 -9
- package/src/app/chat/AgentPanel.overlay.spec.tsx +28 -4
- package/src/app/chat/AgentPanel.tsx +51 -168
- package/src/app/chat/AgentSidebar.spec.tsx +19 -19
- package/src/app/chat/AgentSidebar.tsx +59 -94
- package/src/app/chat/chat/tool-call-display.spec.tsx +371 -15
- package/src/app/chat/chat/tool-call-display.tsx +154 -80
- package/src/app/i18n/catalogs/ar-SA.ts +1 -0
- package/src/app/i18n/catalogs/de-DE.ts +1 -0
- package/src/app/i18n/catalogs/en-US.ts +1 -0
- package/src/app/i18n/catalogs/es-ES.ts +1 -0
- package/src/app/i18n/catalogs/fr-FR.ts +1 -0
- package/src/app/i18n/catalogs/hi-IN.ts +1 -0
- package/src/app/i18n/catalogs/ja-JP.ts +1 -0
- package/src/app/i18n/catalogs/ko-KR.ts +1 -0
- package/src/app/i18n/catalogs/pt-BR.ts +1 -0
- package/src/app/i18n/catalogs/zh-CN.ts +1 -0
- package/src/app/i18n/catalogs/zh-TW.ts +1 -0
- package/src/app-shell/sidebar-overflow.spec.tsx +2 -1
- package/src/composer/PromptComposer.context.spec.tsx +28 -15
- package/src/composer/TiptapComposer.spec.ts +14 -2
- package/src/composer/TiptapComposer.tsx +77 -86
- package/src/ui/sonner.spec.ts +15 -0
- package/src/ui/sonner.tsx +1 -1
|
@@ -791,19 +791,16 @@ describe("controlled composer context", () => {
|
|
|
791
791
|
expect(option).toBeDefined();
|
|
792
792
|
await act(async () => option.click());
|
|
793
793
|
expect(onSelect).toHaveBeenCalledOnce();
|
|
794
|
+
const contextRow = container.querySelector('[data-context-key="brief"]');
|
|
795
|
+
expect(contextRow?.querySelectorAll("button")).toHaveLength(1);
|
|
794
796
|
await act(async () => {
|
|
795
|
-
container
|
|
796
|
-
.querySelector<HTMLButtonElement>(
|
|
797
|
-
'button[aria-label="Retry Brief context"]',
|
|
798
|
-
)!
|
|
799
|
-
.click();
|
|
800
797
|
container
|
|
801
798
|
.querySelector<HTMLButtonElement>(
|
|
802
799
|
'button[aria-label="Remove Brief context"]',
|
|
803
800
|
)!
|
|
804
801
|
.click();
|
|
805
802
|
});
|
|
806
|
-
expect(onRetry).
|
|
803
|
+
expect(onRetry).not.toHaveBeenCalled();
|
|
807
804
|
expect(onRemove).toHaveBeenCalledWith("brief");
|
|
808
805
|
expect(onDisabledClick).not.toHaveBeenCalled();
|
|
809
806
|
const send = container.querySelector<HTMLButtonElement>(
|
|
@@ -1456,7 +1453,7 @@ describe("controlled composer context", () => {
|
|
|
1456
1453
|
expect(remove).not.toHaveBeenCalled();
|
|
1457
1454
|
},
|
|
1458
1455
|
);
|
|
1459
|
-
it("renders context
|
|
1456
|
+
it("renders a noninteractive context chip with only removal and blocks submission until ready", async () => {
|
|
1460
1457
|
const onSubmit = vi.fn();
|
|
1461
1458
|
const onRemoveContextItem = vi.fn();
|
|
1462
1459
|
const onInspectContextItem = vi.fn();
|
|
@@ -1522,25 +1519,41 @@ describe("controlled composer context", () => {
|
|
|
1522
1519
|
await pressEnter();
|
|
1523
1520
|
expect(onSubmit).not.toHaveBeenCalled();
|
|
1524
1521
|
const contextRow = container.querySelector('[data-context-key="brief"]')!;
|
|
1522
|
+
expect(contextRow.className).toContain("py-0.5");
|
|
1523
|
+
expect(contextRow.querySelector("span")?.textContent).toBe("Brief");
|
|
1524
|
+
expect(contextRow.querySelectorAll("button")).toHaveLength(1);
|
|
1525
|
+
expect(
|
|
1526
|
+
contextRow.querySelector('[aria-label="Context failed"]'),
|
|
1527
|
+
).not.toBeNull();
|
|
1528
|
+
const retryContext = container.querySelector<HTMLButtonElement>(
|
|
1529
|
+
'button[aria-label="Retry Brief context"]',
|
|
1530
|
+
);
|
|
1531
|
+
expect(retryContext).not.toBeNull();
|
|
1532
|
+
expect(contextRow.contains(retryContext)).toBe(false);
|
|
1533
|
+
await act(async () => retryContext!.click());
|
|
1534
|
+
expect(onRetryContextItem).toHaveBeenCalledWith("brief");
|
|
1525
1535
|
await act(async () => {
|
|
1526
|
-
contextRow.querySelector<HTMLButtonElement>("button")!.click();
|
|
1527
|
-
contextRow
|
|
1528
|
-
.querySelector<HTMLButtonElement>(
|
|
1529
|
-
'button[aria-label="Retry Brief context"]',
|
|
1530
|
-
)!
|
|
1531
|
-
.click();
|
|
1532
1536
|
contextRow
|
|
1533
1537
|
.querySelector<HTMLButtonElement>(
|
|
1534
1538
|
'button[aria-label="Remove Brief context"]',
|
|
1535
1539
|
)!
|
|
1536
1540
|
.click();
|
|
1537
1541
|
});
|
|
1538
|
-
expect(onInspectContextItem).
|
|
1539
|
-
expect(onRetryContextItem).
|
|
1542
|
+
expect(onInspectContextItem).not.toHaveBeenCalled();
|
|
1543
|
+
expect(onRetryContextItem).toHaveBeenCalledOnce();
|
|
1540
1544
|
expect(onRemoveContextItem).toHaveBeenCalledWith("brief");
|
|
1541
1545
|
expect(
|
|
1542
1546
|
container.querySelector('[data-context-key="brief"]'),
|
|
1543
1547
|
).not.toBeNull();
|
|
1548
|
+
item.removable = false;
|
|
1549
|
+
await render();
|
|
1550
|
+
const nonremovableContextRow = container.querySelector(
|
|
1551
|
+
'[data-context-key="brief"]',
|
|
1552
|
+
)!;
|
|
1553
|
+
expect(nonremovableContextRow.querySelectorAll("button")).toHaveLength(0);
|
|
1554
|
+
expect(
|
|
1555
|
+
container.querySelector('button[aria-label="Retry Brief context"]'),
|
|
1556
|
+
).not.toBeNull();
|
|
1544
1557
|
item.status = "ready";
|
|
1545
1558
|
await render();
|
|
1546
1559
|
await clickSend();
|
|
@@ -1581,10 +1581,16 @@ describe("createTiptapComposerExtensions", () => {
|
|
|
1581
1581
|
availableModels: [
|
|
1582
1582
|
{
|
|
1583
1583
|
engine: "builder",
|
|
1584
|
-
label: "Builder.io
|
|
1584
|
+
label: "OpenAI · Builder.io",
|
|
1585
1585
|
models,
|
|
1586
1586
|
configured: true,
|
|
1587
1587
|
},
|
|
1588
|
+
{
|
|
1589
|
+
engine: "claude",
|
|
1590
|
+
label: "Claude · Builder.io",
|
|
1591
|
+
models: ["claude-haiku-4-5"],
|
|
1592
|
+
configured: true,
|
|
1593
|
+
},
|
|
1588
1594
|
],
|
|
1589
1595
|
selectedModel: "gpt-6-luna",
|
|
1590
1596
|
selectedEngine: "builder",
|
|
@@ -1619,6 +1625,9 @@ describe("createTiptapComposerExtensions", () => {
|
|
|
1619
1625
|
expect(picker?.textContent).toContain("GPT-6 Luna");
|
|
1620
1626
|
expect(picker?.textContent).toContain("Claude Opus 5.5");
|
|
1621
1627
|
expect(picker?.textContent).toContain("Gemini 3.8 Flash");
|
|
1628
|
+
expect(picker?.textContent).toContain("OpenAI");
|
|
1629
|
+
expect(picker?.textContent).toContain("Claude");
|
|
1630
|
+
expect(picker?.textContent).not.toContain("Builder.io");
|
|
1622
1631
|
});
|
|
1623
1632
|
|
|
1624
1633
|
it("chooses the newest tier version regardless of catalog order", () => {
|
|
@@ -1983,8 +1992,11 @@ describe("TiptapComposer slash commands", () => {
|
|
|
1983
1992
|
'[data-agent-composer-slot="send-button"]',
|
|
1984
1993
|
);
|
|
1985
1994
|
expect(sendButton?.disabled).toBe(true);
|
|
1986
|
-
expect(sendButton?.getAttribute("aria-label")).toMatch(/loading/i);
|
|
1995
|
+
expect(sendButton?.getAttribute("aria-label")).not.toMatch(/loading/i);
|
|
1987
1996
|
expect(sendButton?.getAttribute("aria-label")).not.toMatch(/checking/i);
|
|
1997
|
+
expect(sendButton?.getAttribute("aria-busy")).toBeNull();
|
|
1998
|
+
expect(sendButton?.querySelector(".animate-spin")).toBeNull();
|
|
1999
|
+
expect(sendButton?.querySelector(".tabler-icon-arrow-up")).not.toBeNull();
|
|
1988
2000
|
});
|
|
1989
2001
|
|
|
1990
2002
|
it("keeps the editor focused after a successful submission", async () => {
|
|
@@ -14,9 +14,9 @@ import {
|
|
|
14
14
|
IconPencil,
|
|
15
15
|
IconPlugConnected,
|
|
16
16
|
IconHelpCircle,
|
|
17
|
-
IconRefresh,
|
|
18
17
|
IconAlertCircle,
|
|
19
18
|
IconLoader2,
|
|
19
|
+
IconRefresh,
|
|
20
20
|
} from "@tabler/icons-react";
|
|
21
21
|
import Placeholder from "@tiptap/extension-placeholder";
|
|
22
22
|
import { TextSelection } from "@tiptap/pm/state";
|
|
@@ -2384,7 +2384,7 @@ function ModelSelector({
|
|
|
2384
2384
|
{showProviderLabels && (
|
|
2385
2385
|
<div className="group flex items-center px-2 py-1">
|
|
2386
2386
|
<span className="shrink-0 text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
|
|
2387
|
-
{group.label}
|
|
2387
|
+
{group.label.replace(/ · Builder\.io$/i, "")}
|
|
2388
2388
|
</span>
|
|
2389
2389
|
{!group.configured && statusLabel && (
|
|
2390
2390
|
<button
|
|
@@ -2607,7 +2607,6 @@ export function TiptapComposer({
|
|
|
2607
2607
|
draftScope,
|
|
2608
2608
|
contextItems: providedContextItems,
|
|
2609
2609
|
onRemoveContextItem,
|
|
2610
|
-
onInspectContextItem,
|
|
2611
2610
|
onRetryContextItem,
|
|
2612
2611
|
contextMenuItems,
|
|
2613
2612
|
plusMenuMode = "full",
|
|
@@ -5151,7 +5150,7 @@ export function TiptapComposer({
|
|
|
5151
5150
|
{slotReferences.map((ref) => (
|
|
5152
5151
|
<span
|
|
5153
5152
|
key={ref.slotKey}
|
|
5154
|
-
className="inline-flex max-w-full items-center gap-1.5 rounded-md border border-border bg-background px-2 py-
|
|
5153
|
+
className="inline-flex max-w-full items-center gap-1.5 rounded-md border border-border bg-background px-2 py-0.5 text-[11px] font-medium text-foreground shadow-sm"
|
|
5155
5154
|
>
|
|
5156
5155
|
<MentionItemMedia
|
|
5157
5156
|
media={ref.media}
|
|
@@ -5185,79 +5184,80 @@ export function TiptapComposer({
|
|
|
5185
5184
|
</span>
|
|
5186
5185
|
))}
|
|
5187
5186
|
{contextItems.map((item) => (
|
|
5188
|
-
<
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
{onInspectContextItem ? (
|
|
5220
|
-
<button
|
|
5221
|
-
type="button"
|
|
5222
|
-
onClick={() => onInspectContextItem(item.key)}
|
|
5223
|
-
className="min-w-0 truncate hover:underline"
|
|
5224
|
-
>
|
|
5225
|
-
{item.title}
|
|
5226
|
-
</button>
|
|
5227
|
-
) : (
|
|
5187
|
+
<React.Fragment key={item.key}>
|
|
5188
|
+
<span
|
|
5189
|
+
data-context-key={item.key}
|
|
5190
|
+
data-context-status={item.status ?? "ready"}
|
|
5191
|
+
title={item.statusMessage}
|
|
5192
|
+
data-state={
|
|
5193
|
+
selectedContextItemKey === item.key ? "selected" : undefined
|
|
5194
|
+
}
|
|
5195
|
+
className={`inline-flex max-w-full items-center gap-1.5 rounded-md border px-2 py-0.5 text-[11px] font-medium text-foreground ${
|
|
5196
|
+
selectedContextItemKey === item.key
|
|
5197
|
+
? "border-ring bg-accent ring-2 ring-ring/40"
|
|
5198
|
+
: "border-border bg-muted/50"
|
|
5199
|
+
}`}
|
|
5200
|
+
>
|
|
5201
|
+
{item.status === "pending" ? (
|
|
5202
|
+
<IconLoader2
|
|
5203
|
+
aria-label={t("agentChat.composer.contextPending", {
|
|
5204
|
+
defaultValue: "Context pending",
|
|
5205
|
+
})}
|
|
5206
|
+
className="size-3 shrink-0 animate-spin motion-reduce:animate-none text-muted-foreground"
|
|
5207
|
+
/>
|
|
5208
|
+
) : item.status === "error" ? (
|
|
5209
|
+
<IconAlertCircle
|
|
5210
|
+
aria-label={t("agentChat.composer.contextError", {
|
|
5211
|
+
defaultValue: "Context failed",
|
|
5212
|
+
})}
|
|
5213
|
+
className="size-3 shrink-0 text-destructive"
|
|
5214
|
+
/>
|
|
5215
|
+
) : (
|
|
5216
|
+
<IconClipboardList className="h-3 w-3 shrink-0 text-muted-foreground" />
|
|
5217
|
+
)}
|
|
5228
5218
|
<span className="min-w-0 truncate">{item.title}</span>
|
|
5229
|
-
|
|
5219
|
+
{onRemoveContextItem && item.removable !== false ? (
|
|
5220
|
+
<button
|
|
5221
|
+
type="button"
|
|
5222
|
+
onClick={() => {
|
|
5223
|
+
selectedContextItemKeyRef.current = null;
|
|
5224
|
+
setSelectedContextItemKey(null);
|
|
5225
|
+
onRemoveContextItem?.(item.key);
|
|
5226
|
+
}}
|
|
5227
|
+
aria-label={t("agentChat.composer.removeContext", {
|
|
5228
|
+
defaultValue: "Remove {{name}} context",
|
|
5229
|
+
name: item.title,
|
|
5230
|
+
})}
|
|
5231
|
+
className="ms-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground"
|
|
5232
|
+
>
|
|
5233
|
+
<IconX className="h-3 w-3" />
|
|
5234
|
+
</button>
|
|
5235
|
+
) : null}
|
|
5236
|
+
</span>
|
|
5230
5237
|
{item.status === "error" && onRetryContextItem ? (
|
|
5231
|
-
<
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
5245
|
-
|
|
5246
|
-
|
|
5247
|
-
|
|
5248
|
-
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
defaultValue: "Remove {{name}} context",
|
|
5253
|
-
name: item.title,
|
|
5254
|
-
})}
|
|
5255
|
-
className="ms-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground"
|
|
5256
|
-
>
|
|
5257
|
-
<IconX className="h-3 w-3" />
|
|
5258
|
-
</button>
|
|
5238
|
+
<Tooltip>
|
|
5239
|
+
<TooltipTrigger asChild>
|
|
5240
|
+
<button
|
|
5241
|
+
type="button"
|
|
5242
|
+
onClick={() => onRetryContextItem(item.key)}
|
|
5243
|
+
aria-label={t("agentChat.composer.retryContext", {
|
|
5244
|
+
defaultValue: "Retry {{name}} context",
|
|
5245
|
+
name: item.title,
|
|
5246
|
+
})}
|
|
5247
|
+
className="flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground"
|
|
5248
|
+
>
|
|
5249
|
+
<IconRefresh aria-hidden="true" className="size-3.5" />
|
|
5250
|
+
</button>
|
|
5251
|
+
</TooltipTrigger>
|
|
5252
|
+
<TooltipContent>
|
|
5253
|
+
{t("agentChat.composer.retryContext", {
|
|
5254
|
+
defaultValue: "Retry {{name}} context",
|
|
5255
|
+
name: item.title,
|
|
5256
|
+
})}
|
|
5257
|
+
</TooltipContent>
|
|
5258
|
+
</Tooltip>
|
|
5259
5259
|
) : null}
|
|
5260
|
-
</
|
|
5260
|
+
</React.Fragment>
|
|
5261
5261
|
))}
|
|
5262
5262
|
</div>
|
|
5263
5263
|
)}
|
|
@@ -5401,23 +5401,14 @@ export function TiptapComposer({
|
|
|
5401
5401
|
type="button"
|
|
5402
5402
|
onClick={() => void submitComposer("immediate")}
|
|
5403
5403
|
disabled={!canSend || sendButtonDisabled}
|
|
5404
|
-
aria-label={
|
|
5405
|
-
submitting ? t("common.loading") : sendButtonTooltip
|
|
5406
|
-
}
|
|
5407
|
-
aria-busy={submitting || undefined}
|
|
5404
|
+
aria-label={sendButtonTooltip}
|
|
5408
5405
|
data-agent-composer-slot="send-button"
|
|
5409
5406
|
className="agent-composer-send-button shrink-0 flex h-7 w-7 items-center justify-center rounded-full bg-primary text-primary-foreground hover:opacity-90 transition-[opacity,transform] duration-150 active:scale-[0.97] disabled:opacity-30 disabled:cursor-not-allowed"
|
|
5410
5407
|
>
|
|
5411
|
-
|
|
5412
|
-
<IconLoader2 className="size-3.5 animate-spin motion-reduce:animate-none" />
|
|
5413
|
-
) : (
|
|
5414
|
-
<IconArrowUp className="h-3.5 w-3.5" />
|
|
5415
|
-
)}
|
|
5408
|
+
<IconArrowUp className="h-3.5 w-3.5" />
|
|
5416
5409
|
</button>
|
|
5417
5410
|
</TooltipTrigger>
|
|
5418
|
-
<TooltipContent>
|
|
5419
|
-
{submitting ? t("common.loading") : sendButtonTooltip}
|
|
5420
|
-
</TooltipContent>
|
|
5411
|
+
<TooltipContent>{sendButtonTooltip}</TooltipContent>
|
|
5421
5412
|
</Tooltip>
|
|
5422
5413
|
)}
|
|
5423
5414
|
</>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
|
|
3
|
+
import { describe, expect, it } from "vitest";
|
|
4
|
+
|
|
5
|
+
const source = readFileSync(new URL("./sonner.tsx", import.meta.url), "utf8");
|
|
6
|
+
|
|
7
|
+
describe("Sonner toast layout", () => {
|
|
8
|
+
it("allows toast content to shrink beside an action", () => {
|
|
9
|
+
expect(source).toContain("group-[.toast]:!min-w-0");
|
|
10
|
+
expect(source).not.toContain(
|
|
11
|
+
"group-[.toast]:!min-w-[min(16rem,calc(100vw_-_14rem))]",
|
|
12
|
+
);
|
|
13
|
+
expect(source).toContain("group-[.toast]:!shrink-0");
|
|
14
|
+
});
|
|
15
|
+
});
|
package/src/ui/sonner.tsx
CHANGED
|
@@ -8,7 +8,7 @@ type ToasterProps = React.ComponentProps<typeof Sonner>;
|
|
|
8
8
|
const toastWidthClasses =
|
|
9
9
|
"group-[.toaster]:!w-[var(--width)] group-[.toaster]:!min-w-[min(20rem,calc(100vw_-_2rem))] group-[.toaster]:!max-w-[var(--width)] group-[.toaster]:!gap-3 group-[.toaster]:!break-normal";
|
|
10
10
|
const toastContentClasses =
|
|
11
|
-
"group-[.toast]:!min-w-
|
|
11
|
+
"group-[.toast]:!min-w-0 group-[.toast]:!flex-1 group-[.toast]:!basis-auto group-[.toast]:break-words";
|
|
12
12
|
const toastButtonClasses =
|
|
13
13
|
"group-[.toast]:!shrink-0 group-[.toast]:!whitespace-nowrap";
|
|
14
14
|
|