@agent-native/toolkit 0.13.8 → 0.13.10
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/chat-history/ChatHistoryList.js +1 -1
- package/dist/chat-history/ChatHistoryList.js.map +1 -1
- package/dist/chat-history.css +46 -1
- package/dist/collab-ui/PresenceBar.d.ts +4 -1
- package/dist/collab-ui/PresenceBar.d.ts.map +1 -1
- package/dist/collab-ui/PresenceBar.js +19 -12
- package/dist/collab-ui/PresenceBar.js.map +1 -1
- package/dist/composer/PromptComposer.d.ts +1 -1
- package/dist/composer/PromptComposer.d.ts.map +1 -1
- package/dist/composer/PromptComposer.js +1 -1
- package/dist/composer/PromptComposer.js.map +1 -1
- package/dist/composer/TiptapComposer.d.ts +3 -3
- package/dist/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/composer/TiptapComposer.js +14 -7
- package/dist/composer/TiptapComposer.js.map +1 -1
- package/dist/composer/TiptapComposer.spec.js +1 -1
- package/dist/composer/TiptapComposer.spec.js.map +1 -1
- package/dist/composer/runtime-adapters.d.ts.map +1 -1
- package/dist/composer/runtime-adapters.js +2 -2
- package/dist/composer/runtime-adapters.js.map +1 -1
- package/dist/editor.css +2 -0
- package/dist/ui/dropdown-menu.d.ts.map +1 -1
- package/dist/ui/dropdown-menu.js +8 -2
- package/dist/ui/dropdown-menu.js.map +1 -1
- package/package.json +1 -1
- package/src/chat-history/ChatHistoryList.tsx +2 -0
- package/src/chat-history.css +46 -1
- package/src/collab-ui/PresenceBar.tsx +44 -17
- package/src/composer/PromptComposer.tsx +2 -2
- package/src/composer/TiptapComposer.spec.ts +1 -1
- package/src/composer/TiptapComposer.tsx +21 -15
- package/src/composer/runtime-adapters.tsx +2 -2
- package/src/editor.css +2 -0
- package/src/ui/dropdown-menu.tsx +4 -0
|
@@ -358,6 +358,8 @@ const ChatHistoryRow = React.memo(function ChatHistoryRow({
|
|
|
358
358
|
"an-chat-history-row",
|
|
359
359
|
active && "an-chat-history-row--active",
|
|
360
360
|
item.pinned && "an-chat-history-row--pinned",
|
|
361
|
+
hasMenu && "an-chat-history-row--has-menu",
|
|
362
|
+
menuOpen && "an-chat-history-row--menu-open",
|
|
361
363
|
isRenaming && "an-chat-history-row--renaming",
|
|
362
364
|
item.disabled && "an-chat-history-row--disabled",
|
|
363
365
|
)}
|
package/src/chat-history.css
CHANGED
|
@@ -234,7 +234,7 @@
|
|
|
234
234
|
.an-chat-history--rail .an-chat-history-row__button {
|
|
235
235
|
min-height: 32px;
|
|
236
236
|
padding-block: 6px;
|
|
237
|
-
padding-inline: 10px
|
|
237
|
+
padding-inline: 10px;
|
|
238
238
|
border-radius: inherit;
|
|
239
239
|
color: hsl(var(--muted-foreground));
|
|
240
240
|
}
|
|
@@ -290,6 +290,15 @@
|
|
|
290
290
|
.an-chat-history--rail .an-chat-history-row__timestamp {
|
|
291
291
|
font-size: 11px;
|
|
292
292
|
color: hsl(var(--muted-foreground) / 0.62);
|
|
293
|
+
transition: opacity 100ms ease;
|
|
294
|
+
}
|
|
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;
|
|
293
302
|
}
|
|
294
303
|
|
|
295
304
|
.an-chat-history--rail
|
|
@@ -298,6 +307,23 @@
|
|
|
298
307
|
color: hsl(var(--accent-foreground));
|
|
299
308
|
}
|
|
300
309
|
|
|
310
|
+
/* The menu overlays this fixed trailing slot so its hover state never changes
|
|
311
|
+
the title's available width or moves the rest of the rail. */
|
|
312
|
+
.an-chat-history--rail
|
|
313
|
+
.an-chat-history-row--has-menu:hover
|
|
314
|
+
.an-chat-history-row__timestamp,
|
|
315
|
+
.an-chat-history--rail
|
|
316
|
+
.an-chat-history-row--has-menu:focus-within
|
|
317
|
+
.an-chat-history-row__timestamp,
|
|
318
|
+
.an-chat-history--rail
|
|
319
|
+
.an-chat-history-row--has-menu.an-chat-history-row--menu-open
|
|
320
|
+
.an-chat-history-row__timestamp,
|
|
321
|
+
.an-chat-history--rail
|
|
322
|
+
.an-chat-history-row--has-menu.an-chat-history-row--pinned
|
|
323
|
+
.an-chat-history-row__timestamp {
|
|
324
|
+
opacity: 0;
|
|
325
|
+
}
|
|
326
|
+
|
|
301
327
|
.an-chat-history-row__subtitle {
|
|
302
328
|
margin-top: 2px;
|
|
303
329
|
overflow: hidden;
|
|
@@ -351,6 +377,10 @@
|
|
|
351
377
|
inset-inline-end: 4px;
|
|
352
378
|
}
|
|
353
379
|
|
|
380
|
+
.an-chat-history--rail .an-chat-history-row__menu {
|
|
381
|
+
inset-inline-end: 10px;
|
|
382
|
+
}
|
|
383
|
+
|
|
354
384
|
.an-chat-history-row__menu-trigger {
|
|
355
385
|
display: inline-flex;
|
|
356
386
|
align-items: center;
|
|
@@ -369,6 +399,10 @@
|
|
|
369
399
|
opacity 100ms ease;
|
|
370
400
|
}
|
|
371
401
|
|
|
402
|
+
.an-chat-history--rail .an-chat-history-row__menu-trigger {
|
|
403
|
+
pointer-events: none;
|
|
404
|
+
}
|
|
405
|
+
|
|
372
406
|
.an-chat-history-row:hover .an-chat-history-row__menu-trigger,
|
|
373
407
|
.an-chat-history-row:focus-within .an-chat-history-row__menu-trigger,
|
|
374
408
|
.an-chat-history-row__menu-trigger[aria-expanded="true"],
|
|
@@ -376,6 +410,17 @@
|
|
|
376
410
|
opacity: 1;
|
|
377
411
|
}
|
|
378
412
|
|
|
413
|
+
.an-chat-history--rail
|
|
414
|
+
.an-chat-history-row:hover
|
|
415
|
+
.an-chat-history-row__menu-trigger,
|
|
416
|
+
.an-chat-history--rail
|
|
417
|
+
.an-chat-history-row:focus-within
|
|
418
|
+
.an-chat-history-row__menu-trigger,
|
|
419
|
+
.an-chat-history--rail .an-chat-history-row__menu-trigger[aria-expanded="true"],
|
|
420
|
+
.an-chat-history--rail .an-chat-history-row__menu-trigger--pinned {
|
|
421
|
+
pointer-events: auto;
|
|
422
|
+
}
|
|
423
|
+
|
|
379
424
|
.an-chat-history-row__menu-trigger:hover,
|
|
380
425
|
.an-chat-history-row__menu-trigger[aria-expanded="true"] {
|
|
381
426
|
background: hsl(var(--accent));
|
|
@@ -20,6 +20,9 @@ export interface PresenceBarProps {
|
|
|
20
20
|
agentPresent?: boolean;
|
|
21
21
|
/** Whether the agent is actively making edits right now. */
|
|
22
22
|
agentActive?: boolean;
|
|
23
|
+
/** Whether to show the status dot beside the active agent label. When false,
|
|
24
|
+
* the label is integrated with the avatar pill. */
|
|
25
|
+
showAgentEditingDot?: boolean;
|
|
23
26
|
/** Current user's email (to exclude from the list). */
|
|
24
27
|
currentUserEmail?: string;
|
|
25
28
|
/** Max visible avatars before "+N" overflow. Default: 5 */
|
|
@@ -151,12 +154,15 @@ function AgentAvatar({
|
|
|
151
154
|
active,
|
|
152
155
|
onClick,
|
|
153
156
|
isFollowing,
|
|
157
|
+
showAgentEditingDot,
|
|
154
158
|
}: {
|
|
155
159
|
active: boolean;
|
|
156
160
|
onClick?: () => void;
|
|
157
161
|
isFollowing?: boolean;
|
|
162
|
+
showAgentEditingDot: boolean;
|
|
158
163
|
}) {
|
|
159
164
|
injectStyles();
|
|
165
|
+
const integratedEditingBadge = active && !isFollowing && !showAgentEditingDot;
|
|
160
166
|
|
|
161
167
|
return (
|
|
162
168
|
<div
|
|
@@ -164,6 +170,12 @@ function AgentAvatar({
|
|
|
164
170
|
display: "flex",
|
|
165
171
|
alignItems: "center",
|
|
166
172
|
gap: 4,
|
|
173
|
+
...(integratedEditingBadge && {
|
|
174
|
+
height: AVATAR_SIZE,
|
|
175
|
+
paddingRight: 8,
|
|
176
|
+
borderRadius: 9999,
|
|
177
|
+
backgroundColor: `${AGENT_COLOR}20`,
|
|
178
|
+
}),
|
|
167
179
|
}}
|
|
168
180
|
>
|
|
169
181
|
<div
|
|
@@ -193,7 +205,12 @@ function AgentAvatar({
|
|
|
193
205
|
>
|
|
194
206
|
A
|
|
195
207
|
</div>
|
|
196
|
-
{active && !isFollowing &&
|
|
208
|
+
{active && !isFollowing && (
|
|
209
|
+
<AgentEditingChip
|
|
210
|
+
showDot={showAgentEditingDot}
|
|
211
|
+
integrated={integratedEditingBadge}
|
|
212
|
+
/>
|
|
213
|
+
)}
|
|
197
214
|
{isFollowing && (
|
|
198
215
|
<span
|
|
199
216
|
style={{
|
|
@@ -216,33 +233,41 @@ function AgentAvatar({
|
|
|
216
233
|
);
|
|
217
234
|
}
|
|
218
235
|
|
|
219
|
-
function AgentEditingChip(
|
|
236
|
+
function AgentEditingChip({
|
|
237
|
+
showDot,
|
|
238
|
+
integrated,
|
|
239
|
+
}: {
|
|
240
|
+
showDot: boolean;
|
|
241
|
+
integrated: boolean;
|
|
242
|
+
}) {
|
|
220
243
|
return (
|
|
221
244
|
<span
|
|
222
245
|
style={{
|
|
223
246
|
display: "inline-flex",
|
|
224
247
|
alignItems: "center",
|
|
225
|
-
gap: 4,
|
|
226
|
-
height: 20,
|
|
227
|
-
padding: "0 8px",
|
|
228
|
-
borderRadius: 9999,
|
|
229
|
-
backgroundColor: `${AGENT_COLOR}20`,
|
|
248
|
+
gap: showDot ? 4 : 0,
|
|
249
|
+
height: integrated ? "auto" : 20,
|
|
250
|
+
padding: integrated ? 0 : "0 8px",
|
|
251
|
+
borderRadius: integrated ? 0 : 9999,
|
|
252
|
+
backgroundColor: integrated ? "transparent" : `${AGENT_COLOR}20`,
|
|
230
253
|
color: AGENT_COLOR,
|
|
231
254
|
fontSize: 11,
|
|
232
255
|
fontWeight: 600,
|
|
233
256
|
whiteSpace: "nowrap",
|
|
234
257
|
}}
|
|
235
258
|
>
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
259
|
+
{showDot && (
|
|
260
|
+
<span
|
|
261
|
+
style={{
|
|
262
|
+
width: 6,
|
|
263
|
+
height: 6,
|
|
264
|
+
borderRadius: "50%",
|
|
265
|
+
backgroundColor: AGENT_COLOR,
|
|
266
|
+
animation: "_anPresencePulse 2s infinite",
|
|
267
|
+
flexShrink: 0,
|
|
268
|
+
}}
|
|
269
|
+
/>
|
|
270
|
+
)}
|
|
246
271
|
AI editing
|
|
247
272
|
</span>
|
|
248
273
|
);
|
|
@@ -275,6 +300,7 @@ export function PresenceBar({
|
|
|
275
300
|
activeUsers,
|
|
276
301
|
agentPresent,
|
|
277
302
|
agentActive,
|
|
303
|
+
showAgentEditingDot = true,
|
|
278
304
|
currentUserEmail,
|
|
279
305
|
maxVisible = 5,
|
|
280
306
|
className,
|
|
@@ -313,6 +339,7 @@ export function PresenceBar({
|
|
|
313
339
|
active={!!agentActive}
|
|
314
340
|
onClick={onAvatarClick ? () => onAvatarClick(null) : undefined}
|
|
315
341
|
isFollowing={isFollowingAgent}
|
|
342
|
+
showAgentEditingDot={showAgentEditingDot}
|
|
316
343
|
/>
|
|
317
344
|
)}
|
|
318
345
|
{visibleUsers.length > 0 && (
|
|
@@ -81,7 +81,7 @@ export interface PromptComposerProps {
|
|
|
81
81
|
files: PromptComposerFile[],
|
|
82
82
|
references: Reference[],
|
|
83
83
|
options: PromptComposerSubmitOptions,
|
|
84
|
-
) => void
|
|
84
|
+
) => void | Promise<void>;
|
|
85
85
|
placeholder?: string;
|
|
86
86
|
disabled?: boolean;
|
|
87
87
|
/** Override the generic document attachment cap for a multipart host. */
|
|
@@ -587,7 +587,7 @@ function PromptComposerInner({
|
|
|
587
587
|
text,
|
|
588
588
|
attachments,
|
|
589
589
|
});
|
|
590
|
-
onSubmit(finalText, files, references, {
|
|
590
|
+
await onSubmit(finalText, files, references, {
|
|
591
591
|
intent: submitOptions?.intent ?? "immediate",
|
|
592
592
|
model: composerModel,
|
|
593
593
|
engine: composerEngine,
|
|
@@ -44,7 +44,7 @@ describe("createTiptapComposerExtensions", () => {
|
|
|
44
44
|
}).not.toThrow();
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
-
it("offers explicit
|
|
47
|
+
it("offers explicit effort levels without legacy Auto", () => {
|
|
48
48
|
expect(getComposerReasoningEffortOptions("auto")).toEqual([
|
|
49
49
|
"low",
|
|
50
50
|
"medium",
|
|
@@ -580,7 +580,7 @@ export interface TiptapComposerProps {
|
|
|
580
580
|
references: Reference[],
|
|
581
581
|
attachments?: ReadonlyArray<unknown>,
|
|
582
582
|
options?: TiptapComposerSubmitOptions,
|
|
583
|
-
) => void
|
|
583
|
+
) => void | Promise<void>;
|
|
584
584
|
/** Return false to stop a submit before it enters the chat runtime. */
|
|
585
585
|
onBeforeSubmit?: () => boolean | Promise<boolean>;
|
|
586
586
|
/**
|
|
@@ -631,7 +631,7 @@ export interface TiptapComposerProps {
|
|
|
631
631
|
voiceEnabled?: boolean;
|
|
632
632
|
/** Selected model override for this conversation */
|
|
633
633
|
selectedModel?: string;
|
|
634
|
-
/** Selected
|
|
634
|
+
/** Selected effort override for this conversation */
|
|
635
635
|
selectedEffort?: ReasoningEffort;
|
|
636
636
|
/** Show the legacy provider-level Auto model option (default: true). */
|
|
637
637
|
showAutoModelOption?: boolean;
|
|
@@ -648,7 +648,7 @@ export interface TiptapComposerProps {
|
|
|
648
648
|
modelListLoading?: boolean;
|
|
649
649
|
/** Callback when user picks a model */
|
|
650
650
|
onModelChange?: (model: string, engine: string) => void;
|
|
651
|
-
/** Callback when user picks
|
|
651
|
+
/** Callback when user picks an effort */
|
|
652
652
|
onEffortChange?: (effort: ReasoningEffort) => void;
|
|
653
653
|
/**
|
|
654
654
|
* Disable Builder/provider status polling for hosts that supply provider
|
|
@@ -963,7 +963,7 @@ function latestModelsOnly(models: string[]): string[] {
|
|
|
963
963
|
return true;
|
|
964
964
|
}
|
|
965
965
|
// GPT: family = gpt-{major} (e.g. gpt-5.6-sol and gpt-5.6-luna are different)
|
|
966
|
-
// OpenAI
|
|
966
|
+
// OpenAI effort: each is its own family
|
|
967
967
|
// Gemini: family = gemini-{major} + variant
|
|
968
968
|
const gemini = m.match(/^gemini-(\d+(?:\.\d+)?)-(.+?)(?:-preview)?$/);
|
|
969
969
|
if (gemini) {
|
|
@@ -1133,12 +1133,12 @@ function ModelSelector({
|
|
|
1133
1133
|
});
|
|
1134
1134
|
}, []);
|
|
1135
1135
|
|
|
1136
|
-
// The
|
|
1136
|
+
// The effort list is collapsed by default — it's a secondary
|
|
1137
1137
|
// control most users don't touch, so it stays tucked behind a header that
|
|
1138
1138
|
// reveals the current effort at a glance. Reset to collapsed on each open.
|
|
1139
|
-
const [
|
|
1139
|
+
const [effortExpanded, setEffortExpanded] = useState(false);
|
|
1140
1140
|
useEffect(() => {
|
|
1141
|
-
if (open)
|
|
1141
|
+
if (open) setEffortExpanded(false);
|
|
1142
1142
|
}, [open]);
|
|
1143
1143
|
|
|
1144
1144
|
// The optional image-model section follows the same collapsed-by-default
|
|
@@ -1202,7 +1202,7 @@ function ModelSelector({
|
|
|
1202
1202
|
data-agent-composer-slot="model-button"
|
|
1203
1203
|
aria-label={`Model: ${friendlyModelName(model)}${
|
|
1204
1204
|
effortOptions.length > 0
|
|
1205
|
-
? `.
|
|
1205
|
+
? `. Effort: ${effortLabel(selectedEffort)}`
|
|
1206
1206
|
: ""
|
|
1207
1207
|
}`}
|
|
1208
1208
|
className="agent-composer-model-button flex min-w-0 max-w-[10.5rem] shrink items-center gap-1 rounded-md px-2 py-1 text-[12px] font-medium text-muted-foreground hover:bg-accent/50 hover:text-foreground"
|
|
@@ -1466,26 +1466,26 @@ function ModelSelector({
|
|
|
1466
1466
|
<div className="flex items-center hover:bg-accent/30">
|
|
1467
1467
|
<button
|
|
1468
1468
|
type="button"
|
|
1469
|
-
aria-expanded={
|
|
1470
|
-
onClick={() =>
|
|
1469
|
+
aria-expanded={effortExpanded}
|
|
1470
|
+
onClick={() => setEffortExpanded((prev) => !prev)}
|
|
1471
1471
|
className="flex flex-1 min-w-0 items-center gap-1.5 px-2 py-1.5 cursor-pointer text-start"
|
|
1472
1472
|
>
|
|
1473
|
-
{
|
|
1473
|
+
{effortExpanded ? (
|
|
1474
1474
|
<IconChevronDown className="h-3 w-3 shrink-0 text-muted-foreground" />
|
|
1475
1475
|
) : (
|
|
1476
1476
|
<IconChevronRight className="h-3 w-3 shrink-0 text-muted-foreground rtl:-scale-x-100" />
|
|
1477
1477
|
)}
|
|
1478
1478
|
<span className="text-[11px] font-medium text-muted-foreground uppercase tracking-wide shrink-0">
|
|
1479
|
-
|
|
1479
|
+
Effort
|
|
1480
1480
|
</span>
|
|
1481
|
-
{!
|
|
1481
|
+
{!effortExpanded && (
|
|
1482
1482
|
<span className="text-[11px] text-muted-foreground/80 truncate">
|
|
1483
1483
|
{effortLabel(selectedEffort)}
|
|
1484
1484
|
</span>
|
|
1485
1485
|
)}
|
|
1486
1486
|
</button>
|
|
1487
1487
|
</div>
|
|
1488
|
-
{
|
|
1488
|
+
{effortExpanded &&
|
|
1489
1489
|
effortOptions.map((option) => (
|
|
1490
1490
|
<button
|
|
1491
1491
|
key={option}
|
|
@@ -2651,7 +2651,13 @@ export function TiptapComposer({
|
|
|
2651
2651
|
}
|
|
2652
2652
|
|
|
2653
2653
|
if (onSubmit) {
|
|
2654
|
-
|
|
2654
|
+
try {
|
|
2655
|
+
await onSubmit(text, references, attachments, { intent });
|
|
2656
|
+
} catch {
|
|
2657
|
+
// Hosts own their submit errors. Keep the draft and attachments
|
|
2658
|
+
// available for recovery when a host rejects the submission.
|
|
2659
|
+
return;
|
|
2660
|
+
}
|
|
2655
2661
|
// Clear any pending attachments now that the host has them.
|
|
2656
2662
|
void composerRuntime.clearAttachments().catch(() => {});
|
|
2657
2663
|
if (!clearOnSubmit) {
|
|
@@ -184,7 +184,7 @@ const fallbackModels = {
|
|
|
184
184
|
useChatModels: () => ({
|
|
185
185
|
selectedModel: "auto",
|
|
186
186
|
selectedEngine: "auto",
|
|
187
|
-
selectedEffort: "
|
|
187
|
+
selectedEffort: "high" as ReasoningEffort,
|
|
188
188
|
availableModels: [],
|
|
189
189
|
isLoading: false,
|
|
190
190
|
onModelChange: () => {},
|
|
@@ -281,7 +281,7 @@ export function useComposerRuntimeAdapters() {
|
|
|
281
281
|
return useContext(ComposerRuntimeAdaptersContext);
|
|
282
282
|
}
|
|
283
283
|
|
|
284
|
-
export const DEFAULT_REASONING_EFFORT: ReasoningEffort = "
|
|
284
|
+
export const DEFAULT_REASONING_EFFORT: ReasoningEffort = "high";
|
|
285
285
|
export function getReasoningEffortOptionsForModel(
|
|
286
286
|
_model?: string,
|
|
287
287
|
): ReasoningEffort[] {
|
package/src/editor.css
CHANGED
package/src/ui/dropdown-menu.tsx
CHANGED
|
@@ -54,6 +54,8 @@ const DropdownMenuSubContent = React.forwardRef<
|
|
|
54
54
|
<DropdownMenuPrimitive.SubContent
|
|
55
55
|
ref={ref}
|
|
56
56
|
className={cn(
|
|
57
|
+
// compositing-ok: Radix content mounts on open and unmounts on close,
|
|
58
|
+
// so the promoted layer is retired with it.
|
|
57
59
|
"z-[290] min-w-[8rem] origin-[var(--radix-dropdown-menu-content-transform-origin)] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg will-change-[transform,opacity] data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:duration-100 data-[state=open]:duration-150 data-[state=closed]:ease-out data-[state=open]:ease-out data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1 motion-reduce:data-[state=open]:zoom-in-100 motion-reduce:data-[state=closed]:zoom-out-100 motion-reduce:data-[side=bottom]:slide-in-from-top-0 motion-reduce:data-[side=left]:slide-in-from-right-0 motion-reduce:data-[side=right]:slide-in-from-left-0 motion-reduce:data-[side=top]:slide-in-from-bottom-0",
|
|
58
60
|
className,
|
|
59
61
|
)}
|
|
@@ -83,6 +85,8 @@ const DropdownMenuContent = React.forwardRef<
|
|
|
83
85
|
ref={ref}
|
|
84
86
|
sideOffset={sideOffset}
|
|
85
87
|
className={cn(
|
|
88
|
+
// compositing-ok: Radix content mounts on open and unmounts on close,
|
|
89
|
+
// so the promoted layer is retired with it.
|
|
86
90
|
"z-[290] min-w-[8rem] origin-[var(--radix-dropdown-menu-content-transform-origin)] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md will-change-[transform,opacity] data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:duration-100 data-[state=open]:duration-150 data-[state=closed]:ease-out data-[state=open]:ease-out data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1 motion-reduce:data-[state=open]:zoom-in-100 motion-reduce:data-[state=closed]:zoom-out-100 motion-reduce:data-[side=bottom]:slide-in-from-top-0 motion-reduce:data-[side=left]:slide-in-from-right-0 motion-reduce:data-[side=right]:slide-in-from-left-0 motion-reduce:data-[side=top]:slide-in-from-bottom-0",
|
|
87
91
|
className,
|
|
88
92
|
)}
|