@vvedantb/ui 0.39.0 → 0.39.1
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/package.json +4 -3
- package/src/ai-elements/__snapshots__/queue.test.tsx.snap +3 -3
- package/src/ai-elements/activity-shared.tsx +1 -103
- package/src/ai-elements/activity-step-label.ts +1 -1
- package/src/ai-elements/activity-step-types.ts +107 -0
- package/src/ai-elements/activity-tasks-utils.ts +1 -1
- package/src/ai-elements/queue.tsx +1 -1
- package/src/ai-elements/trace.tsx +3 -2
- package/src/icons/nav-icon-base.tsx +1 -1
- package/src/ui/__snapshots__/alt-wrappers.test.tsx.snap +3 -3
- package/src/ui/__snapshots__/sonner-dom.test.tsx.snap +1 -1
- package/src/ui/button.tsx +1 -1
- package/src/ui/clear-input.tsx +1 -1
- package/src/ui/command.tsx +1 -1
- package/src/ui/input.tsx +1 -1
- package/src/ui/search-input.tsx +1 -1
- package/src/ui/select.tsx +1 -1
- package/src/ui/sonner.tsx +11 -0
- package/src/ui/textarea.tsx +1 -1
- package/tokens/src/css/base.css +23 -0
- package/tokens/src/css/markdown.css +4 -2
- package/tokens/src/css/marquee.css +8 -5
- package/tokens/src/css/nav-icons.css +121 -152
- package/tokens/src/css/scrollbar-thin.css +17 -13
- package/tokens/src/css/tabs-pills.css +9 -7
- package/tokens/src/css/tabs.css +5 -1
- package/tokens/src/css/utilities.css +2 -2
- package/tokens/src/tokens.css +8 -6
package/package.json
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vvedantb/ui",
|
|
3
|
-
"version": "0.39.
|
|
3
|
+
"version": "0.39.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Shared React 19 UI for web apps: one main JavaScript entry (primitives, shell pieces, app helpers including the Convex and Clerk provider, VITE env parsing and ensure-user, artifact viewers over the @vvedantb/server artifacts core, native tokens), third-party brand logos (also @vvedantb/ui/logos), motion-driven animated SVG icons (@vvedantb/ui/icons/animated), a client entry without @vvedantb/server, convex or Clerk for Chrome extensions, design-token CSS, shared Tailwind v4 CSS, a Tailwind preset and packaged Instrument Sans fonts.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"publishConfig": {
|
|
8
|
-
"access": "public"
|
|
8
|
+
"access": "public",
|
|
9
|
+
"provenance": true
|
|
9
10
|
},
|
|
10
11
|
"repository": {
|
|
11
12
|
"type": "git",
|
|
12
|
-
"url": "git+https://github.com/vvedantb/
|
|
13
|
+
"url": "git+https://github.com/vvedantb/packages.git",
|
|
13
14
|
"directory": "packages/ui"
|
|
14
15
|
},
|
|
15
16
|
"exports": {
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
exports[`vibot Queue widget DOM > renders the closed widget 1`] = `"<div class="w-full overflow-hidden" style="height: auto; opacity: 1;"><button type="button" class="flex items-center justify-between w-full px-4 py-2.5 bg-surface-secondary text-foreground border-0 shadow-none backdrop-blur-none transition-[background-color,transform] duration-150 ease-out active:scale-[0.99] hover:bg-surface-tertiary rounded-t-2xl group"><div class="flex items-center gap-2"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-stack-2 text-muted-foreground"><path d="M12 4l-8 4l8 4l8 -4l-8 -4"></path><path d="M4 12l8 4l8 -4"></path><path d="M4 16l8 4l8 -4"></path></svg><span class="text-sm font-medium text-foreground">Queued Messages</span><div class="inline-flex items-center gap-1 rounded-full border px-2.5 py-1 font-medium tracking-normal transition-colors focus:outline-none focus:ring-2 focus:ring-focus-ring focus:ring-offset-2 focus:ring-offset-background border-separator bg-default text-default-foreground text-xs">3</div></div><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-chevron-down text-muted-foreground transition-transform duration-200 ease-out"><path d="M6 9l6 6l6 -6"></path></svg></button></div>"`;
|
|
4
4
|
|
|
5
|
-
exports[`vibot Queue widget DOM > renders the editing state, then saves the trimmed text 1`] = `"<div class="group relative p-2.5 rounded-lg transition-[background-color,transform] duration-150 ease-out active:scale-[0.99] hover:bg-surface-secondary"><div class="flex flex-col gap-2"><textarea class="flex w-full max-sm:min-w-0 rounded-field border border-border bg-field-background px-3.5 py-2.5 sm:text-sm placeholder:text-field-placeholder disabled:cursor-not-allowed disabled:opacity-50 focus-visible:outline-hidden focus-visible:border-focus-border focus-visible:ring-1 focus-visible:ring-focus-ring min-h-[60px]
|
|
5
|
+
exports[`vibot Queue widget DOM > renders the editing state, then saves the trimmed text 1`] = `"<div class="group relative p-2.5 rounded-lg transition-[background-color,transform] duration-150 ease-out active:scale-[0.99] hover:bg-surface-secondary"><div class="flex flex-col gap-2"><textarea class="flex w-full max-sm:min-w-0 rounded-field border border-border bg-field-background px-3.5 py-2.5 text-base sm:pointer-fine:text-sm placeholder:text-field-placeholder disabled:cursor-not-allowed disabled:opacity-50 focus-visible:outline-hidden focus-visible:border-focus-border focus-visible:ring-1 focus-visible:ring-focus-ring min-h-[60px]">Draft</textarea><div class="flex justify-end gap-2"><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] active:duration-[var(--motion-fast,150ms)] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 text-muted-foreground hover:bg-surface-tertiary hover:text-foreground text-xs max-sm:hit-target rounded-full h-7 px-2"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-x"><path d="M18 6l-12 12"></path><path d="M6 6l12 12"></path></svg><span class="ml-1 text-xs">Cancel</span></button><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] active:duration-[var(--motion-fast,150ms)] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 bg-primary text-primary-foreground hover:-translate-y-0.5 hover:opacity-90 text-xs max-sm:hit-target rounded-full h-7 px-2"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-check"><path d="M5 12l5 5l10 -10"></path></svg><span class="ml-1 text-xs">Save</span></button></div></div></div>"`;
|
|
6
6
|
|
|
7
|
-
exports[`vibot Queue widget DOM > renders the editing state, then saves the trimmed text 2`] = `"<div class="group relative p-2.5 rounded-lg transition-[background-color,transform] duration-150 ease-out active:scale-[0.99] hover:bg-surface-secondary"><div class="flex items-center gap-2"><p class="text-sm text-foreground/90 flex-1 truncate">Draft</p><div class="flex items-center gap-1.5 shrink-0"></div><div class="flex items-center gap-1 shrink-0 opacity-0 group-hover:opacity-100 transition-opacity"><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 text-muted-foreground hover:bg-surface-tertiary hover:text-foreground text-xs max-sm:hit-target rounded-full h-6 w-6 p-0"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-edit"><path d="M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1"></path><path d="M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415"></path><path d="M16 5l3 3"></path></svg></button><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 hover:bg-surface-tertiary text-xs max-sm:hit-target rounded-full h-6 w-6 p-0 text-danger hover:text-danger"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-trash"><path d="M4 7l16 0"></path><path d="M10 11l0 6"></path><path d="M14 11l0 6"></path><path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12"></path><path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3"></path></svg></button></div></div></div>"`;
|
|
7
|
+
exports[`vibot Queue widget DOM > renders the editing state, then saves the trimmed text 2`] = `"<div class="group relative p-2.5 rounded-lg transition-[background-color,transform] duration-150 ease-out active:scale-[0.99] hover:bg-surface-secondary"><div class="flex items-center gap-2"><p class="text-sm text-foreground/90 flex-1 truncate">Draft</p><div class="flex items-center gap-1.5 shrink-0"></div><div class="flex items-center gap-1 shrink-0 opacity-0 group-hover:opacity-100 transition-opacity"><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] active:duration-[var(--motion-fast,150ms)] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 text-muted-foreground hover:bg-surface-tertiary hover:text-foreground text-xs max-sm:hit-target rounded-full h-6 w-6 p-0"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-edit"><path d="M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1"></path><path d="M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415"></path><path d="M16 5l3 3"></path></svg></button><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] active:duration-[var(--motion-fast,150ms)] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 hover:bg-surface-tertiary text-xs max-sm:hit-target rounded-full h-6 w-6 p-0 text-danger hover:text-danger"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-trash"><path d="M4 7l16 0"></path><path d="M10 11l0 6"></path><path d="M14 11l0 6"></path><path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12"></path><path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3"></path></svg></button></div></div></div>"`;
|
|
8
8
|
|
|
9
9
|
exports[`vibot Queue widget DOM > renders the header with a custom class 1`] = `"<button type="button" class="flex items-center justify-between w-full px-4 py-2.5 bg-surface-secondary text-foreground border-0 shadow-none backdrop-blur-none transition-[background-color,transform] duration-150 ease-out active:scale-[0.99] hover:bg-surface-tertiary rounded-t-2xl group x"><div class="flex items-center gap-2"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-stack-2 text-muted-foreground"><path d="M12 4l-8 4l8 4l8 -4l-8 -4"></path><path d="M4 12l8 4l8 -4"></path><path d="M4 16l8 4l8 -4"></path></svg><span class="text-sm font-medium text-foreground">Queued Messages</span><div class="inline-flex items-center gap-1 rounded-full border px-2.5 py-1 font-medium tracking-normal transition-colors focus:outline-none focus:ring-2 focus:ring-focus-ring focus:ring-offset-2 focus:ring-offset-background border-separator bg-default text-default-foreground text-xs">1</div></div><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-chevron-down text-muted-foreground transition-transform duration-200 ease-out"><path d="M6 9l6 6l6 -6"></path></svg></button>"`;
|
|
10
10
|
|
|
11
|
-
exports[`vibot Queue widget DOM > renders the open widget 1`] = `"<div class="w-full overflow-hidden mb-2" style="height: auto; opacity: 1;"><button type="button" class="flex items-center justify-between w-full px-4 py-2.5 bg-surface-secondary text-foreground border-0 shadow-none backdrop-blur-none transition-[background-color,transform] duration-150 ease-out active:scale-[0.99] hover:bg-surface-tertiary rounded-t-2xl group"><div class="flex items-center gap-2"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-stack-2 text-muted-foreground"><path d="M12 4l-8 4l8 4l8 -4l-8 -4"></path><path d="M4 12l8 4l8 -4"></path><path d="M4 16l8 4l8 -4"></path></svg><span class="text-sm font-medium text-foreground">Queued Messages</span><div class="inline-flex items-center gap-1 rounded-full border px-2.5 py-1 font-medium tracking-normal transition-colors focus:outline-none focus:ring-2 focus:ring-focus-ring focus:ring-offset-2 focus:ring-offset-background border-separator bg-default text-default-foreground text-xs">3</div></div><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-chevron-down text-muted-foreground transition-transform duration-200 ease-out rotate-180"><path d="M6 9l6 6l6 -6"></path></svg></button><div class="overflow-hidden" style="height: auto; opacity: 1;"><div class="bg-surface-secondary text-foreground border-0 shadow-none backdrop-blur-none rounded-b-2xl"><div dir="ltr" data-slot="scroll-area" class="relative max-h-[240px]" style="position: relative; --radix-scroll-area-corner-width: 0px; --radix-scroll-area-corner-height: 0px;"><style>[data-radix-scroll-area-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-scroll-area-viewport]::-webkit-scrollbar{display:none}</style><div data-radix-scroll-area-viewport="" data-slot="scroll-area-viewport" class="size-full rounded-[inherit] outline-hidden" style="overflow-x: hidden; overflow-y: scroll;"><div style="min-width: 100%; display: table;"><div class="p-2 space-y-1.5"><div class="group relative p-2.5 rounded-lg transition-[background-color,transform] duration-150 ease-out active:scale-[0.99] hover:bg-surface-secondary"><div class="flex items-center gap-2"><img alt="Ada" class="size-5 rounded-full shrink-0" src="https://example.com/ada.png"><p class="text-sm text-foreground/90 flex-1 truncate">Fix the build</p><div class="flex items-center gap-1.5 shrink-0"><div class="inline-flex items-center gap-1 rounded-full border py-1 font-medium tracking-normal transition-colors focus:outline-none focus:ring-2 focus:ring-focus-ring focus:ring-offset-2 focus:ring-offset-background border-separator bg-transparent text-muted-foreground text-xs h-5 px-1.5">claude-sonnet</div><div class="inline-flex items-center gap-1 rounded-full border py-1 font-medium tracking-normal transition-colors focus:outline-none focus:ring-2 focus:ring-focus-ring focus:ring-offset-2 focus:ring-offset-background border-separator bg-transparent text-muted-foreground text-xs h-5 px-1.5">Terse</div></div><div class="flex items-center gap-1 shrink-0 opacity-0 group-hover:opacity-100 transition-opacity"><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 text-muted-foreground hover:bg-surface-tertiary hover:text-foreground text-xs max-sm:hit-target rounded-full h-6 w-6 p-0"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-edit"><path d="M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1"></path><path d="M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415"></path><path d="M16 5l3 3"></path></svg></button><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 hover:bg-surface-tertiary text-xs max-sm:hit-target rounded-full h-6 w-6 p-0 text-danger hover:text-danger"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-trash"><path d="M4 7l16 0"></path><path d="M10 11l0 6"></path><path d="M14 11l0 6"></path><path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12"></path><path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3"></path></svg></button></div></div></div><div class="group relative p-2.5 rounded-lg transition-[background-color,transform] duration-150 ease-out active:scale-[0.99] hover:bg-surface-secondary extra"><div class="flex items-center gap-2"><p class="text-sm text-foreground/90 flex-1 truncate">Plain</p><div class="flex items-center gap-1.5 shrink-0"><div class="inline-flex items-center gap-1 rounded-full border py-1 font-medium tracking-normal transition-colors focus:outline-none focus:ring-2 focus:ring-focus-ring focus:ring-offset-2 focus:ring-offset-background border-separator bg-transparent text-muted-foreground text-xs h-5 px-1.5">Bob</div></div><div class="flex items-center gap-1 shrink-0 opacity-0 group-hover:opacity-100 transition-opacity"><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 text-muted-foreground hover:bg-surface-tertiary hover:text-foreground text-xs max-sm:hit-target rounded-full h-6 w-6 p-0"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-edit"><path d="M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1"></path><path d="M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415"></path><path d="M16 5l3 3"></path></svg></button><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 hover:bg-surface-tertiary text-xs max-sm:hit-target rounded-full h-6 w-6 p-0 text-danger hover:text-danger"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-trash"><path d="M4 7l16 0"></path><path d="M10 11l0 6"></path><path d="M14 11l0 6"></path><path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12"></path><path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3"></path></svg></button></div></div></div><div class="group relative p-2.5 rounded-lg transition-[background-color,transform] duration-150 ease-out active:scale-[0.99] hover:bg-surface-secondary"><div class="flex items-center gap-2"><p class="text-sm text-foreground/90 flex-1 truncate">Bare</p><div class="flex items-center gap-1.5 shrink-0"></div><div class="flex items-center gap-1 shrink-0 opacity-0 group-hover:opacity-100 transition-opacity"><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 text-muted-foreground hover:bg-surface-tertiary hover:text-foreground text-xs max-sm:hit-target rounded-full h-6 w-6 p-0"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-edit"><path d="M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1"></path><path d="M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415"></path><path d="M16 5l3 3"></path></svg></button><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 hover:bg-surface-tertiary text-xs max-sm:hit-target rounded-full h-6 w-6 p-0 text-danger hover:text-danger"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-trash"><path d="M4 7l16 0"></path><path d="M10 11l0 6"></path><path d="M14 11l0 6"></path><path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12"></path><path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3"></path></svg></button></div></div></div></div></div></div></div></div></div></div>"`;
|
|
11
|
+
exports[`vibot Queue widget DOM > renders the open widget 1`] = `"<div class="w-full overflow-hidden mb-2" style="height: auto; opacity: 1;"><button type="button" class="flex items-center justify-between w-full px-4 py-2.5 bg-surface-secondary text-foreground border-0 shadow-none backdrop-blur-none transition-[background-color,transform] duration-150 ease-out active:scale-[0.99] hover:bg-surface-tertiary rounded-t-2xl group"><div class="flex items-center gap-2"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-stack-2 text-muted-foreground"><path d="M12 4l-8 4l8 4l8 -4l-8 -4"></path><path d="M4 12l8 4l8 -4"></path><path d="M4 16l8 4l8 -4"></path></svg><span class="text-sm font-medium text-foreground">Queued Messages</span><div class="inline-flex items-center gap-1 rounded-full border px-2.5 py-1 font-medium tracking-normal transition-colors focus:outline-none focus:ring-2 focus:ring-focus-ring focus:ring-offset-2 focus:ring-offset-background border-separator bg-default text-default-foreground text-xs">3</div></div><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-chevron-down text-muted-foreground transition-transform duration-200 ease-out rotate-180"><path d="M6 9l6 6l6 -6"></path></svg></button><div class="overflow-hidden" style="height: auto; opacity: 1;"><div class="bg-surface-secondary text-foreground border-0 shadow-none backdrop-blur-none rounded-b-2xl"><div dir="ltr" data-slot="scroll-area" class="relative max-h-[240px]" style="position: relative; --radix-scroll-area-corner-width: 0px; --radix-scroll-area-corner-height: 0px;"><style>[data-radix-scroll-area-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-scroll-area-viewport]::-webkit-scrollbar{display:none}</style><div data-radix-scroll-area-viewport="" data-slot="scroll-area-viewport" class="size-full rounded-[inherit] outline-hidden" style="overflow-x: hidden; overflow-y: scroll;"><div style="min-width: 100%; display: table;"><div class="p-2 space-y-1.5"><div class="group relative p-2.5 rounded-lg transition-[background-color,transform] duration-150 ease-out active:scale-[0.99] hover:bg-surface-secondary"><div class="flex items-center gap-2"><img alt="Ada" class="size-5 rounded-full shrink-0" src="https://example.com/ada.png"><p class="text-sm text-foreground/90 flex-1 truncate">Fix the build</p><div class="flex items-center gap-1.5 shrink-0"><div class="inline-flex items-center gap-1 rounded-full border py-1 font-medium tracking-normal transition-colors focus:outline-none focus:ring-2 focus:ring-focus-ring focus:ring-offset-2 focus:ring-offset-background border-separator bg-transparent text-muted-foreground text-xs h-5 px-1.5">claude-sonnet</div><div class="inline-flex items-center gap-1 rounded-full border py-1 font-medium tracking-normal transition-colors focus:outline-none focus:ring-2 focus:ring-focus-ring focus:ring-offset-2 focus:ring-offset-background border-separator bg-transparent text-muted-foreground text-xs h-5 px-1.5">Terse</div></div><div class="flex items-center gap-1 shrink-0 opacity-0 group-hover:opacity-100 transition-opacity"><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] active:duration-[var(--motion-fast,150ms)] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 text-muted-foreground hover:bg-surface-tertiary hover:text-foreground text-xs max-sm:hit-target rounded-full h-6 w-6 p-0"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-edit"><path d="M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1"></path><path d="M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415"></path><path d="M16 5l3 3"></path></svg></button><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] active:duration-[var(--motion-fast,150ms)] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 hover:bg-surface-tertiary text-xs max-sm:hit-target rounded-full h-6 w-6 p-0 text-danger hover:text-danger"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-trash"><path d="M4 7l16 0"></path><path d="M10 11l0 6"></path><path d="M14 11l0 6"></path><path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12"></path><path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3"></path></svg></button></div></div></div><div class="group relative p-2.5 rounded-lg transition-[background-color,transform] duration-150 ease-out active:scale-[0.99] hover:bg-surface-secondary extra"><div class="flex items-center gap-2"><p class="text-sm text-foreground/90 flex-1 truncate">Plain</p><div class="flex items-center gap-1.5 shrink-0"><div class="inline-flex items-center gap-1 rounded-full border py-1 font-medium tracking-normal transition-colors focus:outline-none focus:ring-2 focus:ring-focus-ring focus:ring-offset-2 focus:ring-offset-background border-separator bg-transparent text-muted-foreground text-xs h-5 px-1.5">Bob</div></div><div class="flex items-center gap-1 shrink-0 opacity-0 group-hover:opacity-100 transition-opacity"><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] active:duration-[var(--motion-fast,150ms)] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 text-muted-foreground hover:bg-surface-tertiary hover:text-foreground text-xs max-sm:hit-target rounded-full h-6 w-6 p-0"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-edit"><path d="M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1"></path><path d="M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415"></path><path d="M16 5l3 3"></path></svg></button><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] active:duration-[var(--motion-fast,150ms)] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 hover:bg-surface-tertiary text-xs max-sm:hit-target rounded-full h-6 w-6 p-0 text-danger hover:text-danger"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-trash"><path d="M4 7l16 0"></path><path d="M10 11l0 6"></path><path d="M14 11l0 6"></path><path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12"></path><path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3"></path></svg></button></div></div></div><div class="group relative p-2.5 rounded-lg transition-[background-color,transform] duration-150 ease-out active:scale-[0.99] hover:bg-surface-secondary"><div class="flex items-center gap-2"><p class="text-sm text-foreground/90 flex-1 truncate">Bare</p><div class="flex items-center gap-1.5 shrink-0"></div><div class="flex items-center gap-1 shrink-0 opacity-0 group-hover:opacity-100 transition-opacity"><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] active:duration-[var(--motion-fast,150ms)] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 text-muted-foreground hover:bg-surface-tertiary hover:text-foreground text-xs max-sm:hit-target rounded-full h-6 w-6 p-0"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-edit"><path d="M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1"></path><path d="M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415"></path><path d="M16 5l3 3"></path></svg></button><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] active:duration-[var(--motion-fast,150ms)] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 hover:bg-surface-tertiary text-xs max-sm:hit-target rounded-full h-6 w-6 p-0 text-danger hover:text-danger"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-trash"><path d="M4 7l16 0"></path><path d="M10 11l0 6"></path><path d="M14 11l0 6"></path><path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12"></path><path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3"></path></svg></button></div></div></div></div></div></div></div></div></div></div>"`;
|
|
@@ -50,109 +50,7 @@ export interface ActivityTasksConfig {
|
|
|
50
50
|
thinkingIcon?: { src: string; alt: string };
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
export interface ActivityTodoItem {
|
|
55
|
-
content: string;
|
|
56
|
-
status: "pending" | "in_progress" | "completed";
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export interface ActivityStepOutput {
|
|
60
|
-
text: string;
|
|
61
|
-
exitCode?: number;
|
|
62
|
-
truncated?: boolean;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export interface ActivityStepEdit {
|
|
66
|
-
oldText: string;
|
|
67
|
-
newText: string;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/** One choice offered by an AskUserQuestion prompt. */
|
|
71
|
-
export interface ActivityQuestionOption {
|
|
72
|
-
label: string;
|
|
73
|
-
description?: string;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/** One question of an AskUserQuestion prompt, with the choices shown. */
|
|
77
|
-
export interface ActivityQuestion {
|
|
78
|
-
question: string;
|
|
79
|
-
header?: string;
|
|
80
|
-
multiSelect?: boolean;
|
|
81
|
-
options: ActivityQuestionOption[];
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export interface ActivityStep {
|
|
85
|
-
type:
|
|
86
|
-
| "read"
|
|
87
|
-
| "edit"
|
|
88
|
-
| "write"
|
|
89
|
-
| "bash"
|
|
90
|
-
| "search_files"
|
|
91
|
-
| "search_code"
|
|
92
|
-
| "web_fetch"
|
|
93
|
-
| "web_search"
|
|
94
|
-
| "subtask"
|
|
95
|
-
| "notebook"
|
|
96
|
-
| "thinking"
|
|
97
|
-
| "reasoning"
|
|
98
|
-
| "response"
|
|
99
|
-
| "question"
|
|
100
|
-
| "todos"
|
|
101
|
-
| "tool"
|
|
102
|
-
| "notice"
|
|
103
|
-
| "hook"
|
|
104
|
-
| "status"
|
|
105
|
-
/** A queued user message the agent took into this live turn (Steer). */
|
|
106
|
-
| "steer";
|
|
107
|
-
label: string;
|
|
108
|
-
detail?: string;
|
|
109
|
-
/** Full, unshortened path for file-type steps. Powers the chat File Viewer. */
|
|
110
|
-
path?: string;
|
|
111
|
-
/** `pending`: a planned step that has not started (sandbox startup stages). */
|
|
112
|
-
status: "complete" | "active" | "pending";
|
|
113
|
-
/** The tool_use id that produced this step (Claude only). */
|
|
114
|
-
toolUseId?: string;
|
|
115
|
-
/** Parent `Agent` tool_use id — set on steps that ran inside a subagent. */
|
|
116
|
-
parentToolUseId?: string;
|
|
117
|
-
/** Todo checklist snapshot (type "todos" only). */
|
|
118
|
-
todos?: ActivityTodoItem[];
|
|
119
|
-
/** Bash command (fuller than detail, capped). */
|
|
120
|
-
command?: string;
|
|
121
|
-
/** Tool result transcript (tail-capped). */
|
|
122
|
-
output?: ActivityStepOutput;
|
|
123
|
-
/** Edit before/after snippets. */
|
|
124
|
-
edits?: ActivityStepEdit[];
|
|
125
|
-
/** Codex file_change paths. */
|
|
126
|
-
files?: string[];
|
|
127
|
-
/** Write tool content head preview. */
|
|
128
|
-
contentPreview?: string;
|
|
129
|
-
/** True when the tool failed or exited non-zero. */
|
|
130
|
-
isError?: boolean;
|
|
131
|
-
/** Wall time from push → complete (ms). */
|
|
132
|
-
durationMs?: number;
|
|
133
|
-
/** AskUserQuestion prompt (type "question" only): the questions and options shown to the user. */
|
|
134
|
-
questions?: ActivityQuestion[];
|
|
135
|
-
/** AskUserQuestion answers keyed by question text. Absent when the turn ended without a structured answer. */
|
|
136
|
-
answers?: Record<string, string>;
|
|
137
|
-
/**
|
|
138
|
-
* The transcript query stripped this step's expanded-only fields (`output`,
|
|
139
|
-
* `edits`, `contentPreview`) to keep the chat subscription small. The row
|
|
140
|
-
* still opens; the body fills in once the full payload is fetched.
|
|
141
|
-
*/
|
|
142
|
-
hasHiddenDetail?: boolean;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/** True when the step has expandable rich detail to show. */
|
|
146
|
-
export function activityStepHasRichDetail(step: ActivityStep): boolean {
|
|
147
|
-
return Boolean(
|
|
148
|
-
step.command ||
|
|
149
|
-
step.output ||
|
|
150
|
-
(step.edits && step.edits.length > 0) ||
|
|
151
|
-
(step.files && step.files.length > 0) ||
|
|
152
|
-
step.contentPreview ||
|
|
153
|
-
step.hasHiddenDetail,
|
|
154
|
-
);
|
|
155
|
-
}
|
|
53
|
+
export * from "./activity-step-types";
|
|
156
54
|
|
|
157
55
|
/** Glyph for thinking steps: the app's mark from `UiConfig.ActivityTasks.thinkingIcon`, or a brain. */
|
|
158
56
|
export function ActivityThinkingIcon({ className }: { className?: string }) {
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// Pure step types for the activity timeline: no React, so `@vvedantb/native-ui`
|
|
2
|
+
// keeps a byte-identical copy (`src/ai/activity-step-types.ts`), with the step
|
|
3
|
+
// labels and grouping that read them.
|
|
4
|
+
|
|
5
|
+
/** One item in a todo checklist step (type "todos"). */
|
|
6
|
+
export interface ActivityTodoItem {
|
|
7
|
+
content: string;
|
|
8
|
+
status: "pending" | "in_progress" | "completed";
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ActivityStepOutput {
|
|
12
|
+
text: string;
|
|
13
|
+
exitCode?: number;
|
|
14
|
+
truncated?: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface ActivityStepEdit {
|
|
18
|
+
oldText: string;
|
|
19
|
+
newText: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** One choice offered by an AskUserQuestion prompt. */
|
|
23
|
+
export interface ActivityQuestionOption {
|
|
24
|
+
label: string;
|
|
25
|
+
description?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** One question of an AskUserQuestion prompt, with the choices shown. */
|
|
29
|
+
export interface ActivityQuestion {
|
|
30
|
+
question: string;
|
|
31
|
+
header?: string;
|
|
32
|
+
multiSelect?: boolean;
|
|
33
|
+
options: ActivityQuestionOption[];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface ActivityStep {
|
|
37
|
+
type:
|
|
38
|
+
| "read"
|
|
39
|
+
| "edit"
|
|
40
|
+
| "write"
|
|
41
|
+
| "bash"
|
|
42
|
+
| "search_files"
|
|
43
|
+
| "search_code"
|
|
44
|
+
| "web_fetch"
|
|
45
|
+
| "web_search"
|
|
46
|
+
| "subtask"
|
|
47
|
+
| "notebook"
|
|
48
|
+
| "thinking"
|
|
49
|
+
| "reasoning"
|
|
50
|
+
| "response"
|
|
51
|
+
| "question"
|
|
52
|
+
| "todos"
|
|
53
|
+
| "tool"
|
|
54
|
+
| "notice"
|
|
55
|
+
| "hook"
|
|
56
|
+
| "status"
|
|
57
|
+
/** A queued user message the agent took into this live turn (Steer). */
|
|
58
|
+
| "steer";
|
|
59
|
+
label: string;
|
|
60
|
+
detail?: string;
|
|
61
|
+
/** Full, unshortened path for file-type steps. Powers the chat File Viewer. */
|
|
62
|
+
path?: string;
|
|
63
|
+
/** `pending`: a planned step that has not started (sandbox startup stages). */
|
|
64
|
+
status: "complete" | "active" | "pending";
|
|
65
|
+
/** The tool_use id that produced this step (Claude only). */
|
|
66
|
+
toolUseId?: string;
|
|
67
|
+
/** Parent `Agent` tool_use id — set on steps that ran inside a subagent. */
|
|
68
|
+
parentToolUseId?: string;
|
|
69
|
+
/** Todo checklist snapshot (type "todos" only). */
|
|
70
|
+
todos?: ActivityTodoItem[];
|
|
71
|
+
/** Bash command (fuller than detail, capped). */
|
|
72
|
+
command?: string;
|
|
73
|
+
/** Tool result transcript (tail-capped). */
|
|
74
|
+
output?: ActivityStepOutput;
|
|
75
|
+
/** Edit before/after snippets. */
|
|
76
|
+
edits?: ActivityStepEdit[];
|
|
77
|
+
/** Codex file_change paths. */
|
|
78
|
+
files?: string[];
|
|
79
|
+
/** Write tool content head preview. */
|
|
80
|
+
contentPreview?: string;
|
|
81
|
+
/** True when the tool failed or exited non-zero. */
|
|
82
|
+
isError?: boolean;
|
|
83
|
+
/** Wall time from push → complete (ms). */
|
|
84
|
+
durationMs?: number;
|
|
85
|
+
/** AskUserQuestion prompt (type "question" only): the questions and options shown to the user. */
|
|
86
|
+
questions?: ActivityQuestion[];
|
|
87
|
+
/** AskUserQuestion answers keyed by question text. Absent when the turn ended without a structured answer. */
|
|
88
|
+
answers?: Record<string, string>;
|
|
89
|
+
/**
|
|
90
|
+
* The transcript query stripped this step's expanded-only fields (`output`,
|
|
91
|
+
* `edits`, `contentPreview`) to keep the chat subscription small. The row
|
|
92
|
+
* still opens; the body fills in once the full payload is fetched.
|
|
93
|
+
*/
|
|
94
|
+
hasHiddenDetail?: boolean;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** True when the step has expandable rich detail to show. */
|
|
98
|
+
export function activityStepHasRichDetail(step: ActivityStep): boolean {
|
|
99
|
+
return Boolean(
|
|
100
|
+
step.command ||
|
|
101
|
+
step.output ||
|
|
102
|
+
(step.edits && step.edits.length > 0) ||
|
|
103
|
+
(step.files && step.files.length > 0) ||
|
|
104
|
+
step.contentPreview ||
|
|
105
|
+
step.hasHiddenDetail,
|
|
106
|
+
);
|
|
107
|
+
}
|
|
@@ -47,8 +47,9 @@ export function AgentTraceLine({
|
|
|
47
47
|
data-status={status}
|
|
48
48
|
className={merge(
|
|
49
49
|
"flex w-fit max-w-full min-w-0 items-center gap-2 text-muted-foreground text-sm transition-colors",
|
|
50
|
-
|
|
51
|
-
"
|
|
50
|
+
// Gated like `hover:` plus a fine pointer, so a tap on a phone does not leave it lit.
|
|
51
|
+
"[@media(hover:hover)_and_(pointer:fine)]:in-[button:hover]:text-foreground",
|
|
52
|
+
"data-[status=error]:text-destructive data-[status=error]:[@media(hover:hover)_and_(pointer:fine)]:in-[button:hover]:text-destructive",
|
|
52
53
|
"data-[status=pending]:opacity-60",
|
|
53
54
|
className,
|
|
54
55
|
)}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useId, type CSSProperties, type ReactNode, type SVGProps } from "react";
|
|
2
2
|
import { cn } from "../utils/cn";
|
|
3
3
|
|
|
4
|
-
/** `"hover"`: animate while an ancestor with the `group` class is hovered. `true`: always. `false`: never. */
|
|
4
|
+
/** `"hover"`: animate while an ancestor with the `group` class is hovered by a mouse (fine pointer). `true`: always. `false`: never. */
|
|
5
5
|
export type IconAnimate = boolean | "hover";
|
|
6
6
|
|
|
7
7
|
export type IconProps = Omit<SVGProps<SVGSVGElement>, "children" | "color" | "height" | "width" | "strokeWidth"> & {
|
|
@@ -12,8 +12,8 @@ exports[`ClearInputAlt markup > every prop 1`] = `"<div class="relative w-40"><s
|
|
|
12
12
|
|
|
13
13
|
exports[`ClearInputAlt markup > filled 1`] = `"<div class="relative"><input class="flex h-10 w-full rounded-field border border-border bg-field-background px-3.5 py-2 text-sm transition-[border-color,background-color] duration-200 ease-smooth placeholder:text-field-placeholder disabled:cursor-not-allowed disabled:opacity-50 focus-visible:outline-hidden focus-visible:border-focus-border focus-visible:ring-1 focus-visible:ring-focus-ring pr-9" type="text" value="abc"><button type="button" tabindex="0" class="absolute right-2 top-1/2 inline-flex h-6 w-6 -translate-y-1/2 items-center justify-center rounded-md text-muted-foreground transition-[opacity,background-color,color,transform] duration-150 ease-out active:duration-100 active:ease-out active:scale-[0.97] hover:bg-surface-tertiary hover:text-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-focus-ring before:absolute before:inset-[-8px] before:content-[''] opacity-100" aria-hidden="false" aria-label="Clear"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-x"><path d="M18 6l-12 12"></path><path d="M6 6l12 12"></path></svg></button></div>"`;
|
|
14
14
|
|
|
15
|
-
exports[`InputGroupAlt markup > input className and props 1`] = `"<div data-input-group="" class="flex h-10 flex-wrap rounded-field border border-border bg-field-background text-sm transition-[border-color,box-shadow] duration-200 ease-smooth has-[textarea]:h-auto has-data-[slot=input-group-control]:h-auto has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-focus-visible:outline-hidden has-focus-visible:border-focus-border has-focus-visible:ring-1 has-focus-visible:ring-focus-ring"><input class="flex w-full max-sm:min-w-0 border-border text-base sm:text-sm transition-[border-color,box-shadow,background-color] duration-200 ease-smooth file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-field-placeholder disabled:cursor-not-allowed disabled:opacity-50 focus-visible:outline-hidden focus-visible:border-focus-border focus-visible:ring-focus-ring h-full flex-1 rounded-none border-0 bg-transparent px-3 py-2 shadow-none focus-visible:border-0 focus-visible:ring-0 in-x" id="i" disabled=""></div>"`;
|
|
15
|
+
exports[`InputGroupAlt markup > input className and props 1`] = `"<div data-input-group="" class="flex h-10 flex-wrap rounded-field border border-border bg-field-background text-sm transition-[border-color,box-shadow] duration-200 ease-smooth has-[textarea]:h-auto has-data-[slot=input-group-control]:h-auto has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-focus-visible:outline-hidden has-focus-visible:border-focus-border has-focus-visible:ring-1 has-focus-visible:ring-focus-ring"><input class="flex w-full max-sm:min-w-0 border-border text-base sm:pointer-fine:text-sm transition-[border-color,box-shadow,background-color] duration-200 ease-smooth file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-field-placeholder disabled:cursor-not-allowed disabled:opacity-50 focus-visible:outline-hidden focus-visible:border-focus-border focus-visible:ring-focus-ring h-full flex-1 rounded-none border-0 bg-transparent px-3 py-2 shadow-none focus-visible:border-0 focus-visible:ring-0 in-x" id="i" disabled=""></div>"`;
|
|
16
16
|
|
|
17
|
-
exports[`InputGroupAlt markup > input with every addon align and button size 1`] = `"<div data-input-group="" class="flex h-10 flex-wrap rounded-field border border-border bg-field-background text-sm transition-[border-color,box-shadow] duration-200 ease-smooth has-[textarea]:h-auto has-data-[slot=input-group-control]:h-auto has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-focus-visible:outline-hidden has-focus-visible:border-focus-border has-focus-visible:ring-1 has-focus-visible:ring-focus-ring"><div class="flex items-center flex-row ps-3"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-search"><path d="M3 10a7 7 0 1 0 14 0a7 7 0 1 0 -14 0"></path><path d="M21 21l-6 -6"></path></svg></div><div data-align="inline-start" class="flex items-center flex-row ps-3"><span class="flex items-center text-sm text-muted-foreground/95">https://</span></div><input class="flex w-full max-sm:min-w-0 border-border text-base sm:text-sm transition-[border-color,box-shadow,background-color] duration-200 ease-smooth file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-field-placeholder disabled:cursor-not-allowed disabled:opacity-50 focus-visible:outline-hidden focus-visible:border-focus-border focus-visible:ring-focus-ring h-full flex-1 rounded-none border-0 bg-transparent px-3 py-2 shadow-none focus-visible:border-0 focus-visible:ring-0" placeholder="Search"><div data-align="inline-end" class="flex items-center flex-row pe-3"><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 text-muted-foreground hover:bg-surface-tertiary hover:text-foreground py-2 shrink-0 shadow-none h-7 rounded-lg px-2 text-xs">Go</button><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 text-muted-foreground hover:bg-surface-tertiary hover:text-foreground py-2 shrink-0 shadow-none h-8 rounded-lg px-2.5 text-xs">Small</button><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 text-muted-foreground hover:bg-surface-tertiary hover:text-foreground px-4 py-2 shrink-0 shadow-none h-7 w-7 rounded-lg" aria-label="A"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-search"><path d="M3 10a7 7 0 1 0 14 0a7 7 0 1 0 -14 0"></path><path d="M21 21l-6 -6"></path></svg></button><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 bg-primary text-primary-foreground hover:-translate-y-0.5 hover:opacity-90 px-4 py-2 shrink-0 shadow-none h-8 w-8 rounded-lg" type="submit" aria-label="B"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-search"><path d="M3 10a7 7 0 1 0 14 0a7 7 0 1 0 -14 0"></path><path d="M21 21l-6 -6"></path></svg></button></div></div>"`;
|
|
17
|
+
exports[`InputGroupAlt markup > input with every addon align and button size 1`] = `"<div data-input-group="" class="flex h-10 flex-wrap rounded-field border border-border bg-field-background text-sm transition-[border-color,box-shadow] duration-200 ease-smooth has-[textarea]:h-auto has-data-[slot=input-group-control]:h-auto has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-focus-visible:outline-hidden has-focus-visible:border-focus-border has-focus-visible:ring-1 has-focus-visible:ring-focus-ring"><div class="flex items-center flex-row ps-3"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-search"><path d="M3 10a7 7 0 1 0 14 0a7 7 0 1 0 -14 0"></path><path d="M21 21l-6 -6"></path></svg></div><div data-align="inline-start" class="flex items-center flex-row ps-3"><span class="flex items-center text-sm text-muted-foreground/95">https://</span></div><input class="flex w-full max-sm:min-w-0 border-border text-base sm:pointer-fine:text-sm transition-[border-color,box-shadow,background-color] duration-200 ease-smooth file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-field-placeholder disabled:cursor-not-allowed disabled:opacity-50 focus-visible:outline-hidden focus-visible:border-focus-border focus-visible:ring-focus-ring h-full flex-1 rounded-none border-0 bg-transparent px-3 py-2 shadow-none focus-visible:border-0 focus-visible:ring-0" placeholder="Search"><div data-align="inline-end" class="flex items-center flex-row pe-3"><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] active:duration-[var(--motion-fast,150ms)] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 text-muted-foreground hover:bg-surface-tertiary hover:text-foreground py-2 shrink-0 shadow-none h-7 rounded-lg px-2 text-xs">Go</button><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] active:duration-[var(--motion-fast,150ms)] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 text-muted-foreground hover:bg-surface-tertiary hover:text-foreground py-2 shrink-0 shadow-none h-8 rounded-lg px-2.5 text-xs">Small</button><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] active:duration-[var(--motion-fast,150ms)] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 text-muted-foreground hover:bg-surface-tertiary hover:text-foreground px-4 py-2 shrink-0 shadow-none h-7 w-7 rounded-lg" aria-label="A"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-search"><path d="M3 10a7 7 0 1 0 14 0a7 7 0 1 0 -14 0"></path><path d="M21 21l-6 -6"></path></svg></button><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] active:duration-[var(--motion-fast,150ms)] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 bg-primary text-primary-foreground hover:-translate-y-0.5 hover:opacity-90 px-4 py-2 shrink-0 shadow-none h-8 w-8 rounded-lg" type="submit" aria-label="B"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-search"><path d="M3 10a7 7 0 1 0 14 0a7 7 0 1 0 -14 0"></path><path d="M21 21l-6 -6"></path></svg></button></div></div>"`;
|
|
18
18
|
|
|
19
|
-
exports[`InputGroupAlt markup > textarea with block addons, error and classNames 1`] = `"<div data-input-group="" class="flex h-10 flex-wrap rounded-field border bg-field-background text-sm transition-[border-color,box-shadow] duration-200 ease-smooth has-[textarea]:h-auto has-data-[slot=input-group-control]:h-auto has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-focus-visible:outline-hidden has-focus-visible:ring-1 border-danger-border has-focus-visible:border-danger has-focus-visible:ring-danger-ring root-x" id="g"><div data-align="block-start" class="flex items-center w-full flex-row border-b border-separator px-3 py-2 addon-x"><span class="flex items-center text-sm text-x">Title</span></div><textarea class="flex min-h-20 w-full max-sm:min-w-0 border-border text-base sm:text-sm placeholder:text-field-placeholder disabled:cursor-not-allowed disabled:opacity-50 focus-visible:outline-hidden focus-visible:border-focus-border focus-visible:ring-focus-ring flex-1 resize-none rounded-none border-0 bg-transparent px-3 py-2.5 shadow-none focus-visible:border-0 focus-visible:ring-0 field-sizing-content ta-x" rows="2">v</textarea><div data-align="block-end" class="flex items-center w-full flex-row px-3 py-2"><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 text-muted-foreground hover:bg-surface-tertiary hover:text-foreground py-2 shrink-0 shadow-none h-7 rounded-lg px-2 text-xs btn-x" disabled="" data-loading="true"><svg class="h-4 w-4 animate-spin" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg>Send</button></div></div>"`;
|
|
19
|
+
exports[`InputGroupAlt markup > textarea with block addons, error and classNames 1`] = `"<div data-input-group="" class="flex h-10 flex-wrap rounded-field border bg-field-background text-sm transition-[border-color,box-shadow] duration-200 ease-smooth has-[textarea]:h-auto has-data-[slot=input-group-control]:h-auto has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-focus-visible:outline-hidden has-focus-visible:ring-1 border-danger-border has-focus-visible:border-danger has-focus-visible:ring-danger-ring root-x" id="g"><div data-align="block-start" class="flex items-center w-full flex-row border-b border-separator px-3 py-2 addon-x"><span class="flex items-center text-sm text-x">Title</span></div><textarea class="flex min-h-20 w-full max-sm:min-w-0 border-border text-base sm:pointer-fine:text-sm placeholder:text-field-placeholder disabled:cursor-not-allowed disabled:opacity-50 focus-visible:outline-hidden focus-visible:border-focus-border focus-visible:ring-focus-ring flex-1 resize-none rounded-none border-0 bg-transparent px-3 py-2.5 shadow-none focus-visible:border-0 focus-visible:ring-0 field-sizing-content ta-x" rows="2">v</textarea><div data-align="block-end" class="flex items-center w-full flex-row px-3 py-2"><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] active:duration-[var(--motion-fast,150ms)] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 text-muted-foreground hover:bg-surface-tertiary hover:text-foreground py-2 shrink-0 shadow-none h-7 rounded-lg px-2 text-xs btn-x" disabled="" data-loading="true"><svg class="h-4 w-4 animate-spin" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg>Send</button></div></div>"`;
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
|
|
3
3
|
exports[`SonnerToaster DOM > renders the toaster and a toast 1`] = `"<section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false" data-react-aria-top-layer="true"></section>"`;
|
|
4
4
|
|
|
5
|
-
exports[`SonnerToaster DOM > renders the toaster and a toast 2`] = `"<section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false" data-react-aria-top-layer="true"><ol dir="ltr" tabindex="-1" class="toaster group !font-sans" data-sonner-toaster="true" data-sonner-theme="light" data-y-position="top" data-x-position="right" style="--front-toast-height: 0px; --width: 356px; --gap: 12px; --offset-top: 24px; --offset-right: 24px; --offset-bottom: 24px; --offset-left: 24px; --mobile-offset-top: 16px; --mobile-offset-right: 16px; --mobile-offset-bottom: 16px; --mobile-offset-left: 16px;"><li tabindex="0" class="group toast glass-panel-strong flex w-full items-center gap-3 rounded-lg px-4 py-3 text-sm text-foreground smooth-shadow-ring-md" data-sonner-toast="" data-styled="false" data-mounted="true" data-promise="false" data-swiped="false" data-removed="false" data-visible="true" data-y-position="top" data-x-position="right" data-index="0" data-front="true" data-swiping="false" data-dismissible="true" data-swipe-out="false" data-expanded="false" style="--index: 0; --toasts-before: 0; --z-index: 1; --offset: 0px; --initial-height: 0px;"><div data-content="" class="flex min-w-0 grow flex-col"><div data-title="" class="font-medium leading-snug">Saved</div><div data-description="" class="text-[13px] leading-snug text-muted-foreground">All changes stored</div></div></li></ol></section>"`;
|
|
5
|
+
exports[`SonnerToaster DOM > renders the toaster and a toast 2`] = `"<section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false" data-react-aria-top-layer="true"><ol dir="ltr" tabindex="-1" class="toaster group !font-sans" data-sonner-toaster="true" data-sonner-theme="light" data-y-position="top" data-x-position="right" style="--front-toast-height: 0px; --width: 356px; --gap: 12px; --offset-top: 24px; --offset-right: 24px; --offset-bottom: 24px; --offset-left: 24px; --mobile-offset-top: calc(16px + env(safe-area-inset-top, 0px)); --mobile-offset-right: 16px; --mobile-offset-bottom: calc(16px + env(safe-area-inset-bottom, 0px)); --mobile-offset-left: 16px;"><li tabindex="0" class="group toast glass-panel-strong flex w-full items-center gap-3 rounded-lg px-4 py-3 text-sm text-foreground smooth-shadow-ring-md" data-sonner-toast="" data-styled="false" data-mounted="true" data-promise="false" data-swiped="false" data-removed="false" data-visible="true" data-y-position="top" data-x-position="right" data-index="0" data-front="true" data-swiping="false" data-dismissible="true" data-swipe-out="false" data-expanded="false" style="--index: 0; --toasts-before: 0; --z-index: 1; --offset: 0px; --initial-height: 0px;"><div data-content="" class="flex min-w-0 grow flex-col"><div data-title="" class="font-medium leading-snug">Saved</div><div data-description="" class="text-[13px] leading-snug text-muted-foreground">All changes stored</div></div></li></ol></section>"`;
|
package/src/ui/button.tsx
CHANGED
|
@@ -8,7 +8,7 @@ const ghostClass =
|
|
|
8
8
|
"text-muted-foreground hover:bg-surface-tertiary hover:text-foreground";
|
|
9
9
|
|
|
10
10
|
const buttonBaseClasses =
|
|
11
|
-
"inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0";
|
|
11
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm font-medium tracking-normal transition-[transform,background-color,box-shadow,opacity,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.96] active:duration-[var(--motion-fast,150ms)] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0";
|
|
12
12
|
|
|
13
13
|
const buttonVariantClasses = {
|
|
14
14
|
default:
|
package/src/ui/clear-input.tsx
CHANGED
|
@@ -49,7 +49,7 @@ export interface ClearInputProps extends Omit<
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
const inputClasses =
|
|
52
|
-
"flex h-10 w-full max-sm:min-w-0 rounded-field border border-border bg-field-background px-3.5 py-2 text-base sm:text-sm transition-[border-color,box-shadow,background-color] duration-200 ease-smooth placeholder:text-field-placeholder disabled:cursor-not-allowed disabled:opacity-50";
|
|
52
|
+
"flex h-10 w-full max-sm:min-w-0 rounded-field border border-border bg-field-background px-3.5 py-2 text-base sm:pointer-fine:text-sm transition-[border-color,box-shadow,background-color] duration-200 ease-smooth placeholder:text-field-placeholder disabled:cursor-not-allowed disabled:opacity-50";
|
|
53
53
|
|
|
54
54
|
const buttonClasses =
|
|
55
55
|
"absolute right-2 top-1/2 z-4 inline-flex h-6 w-6 -translate-y-1/2 items-center justify-center rounded-md text-muted-foreground transition-[background-color,color,transform] duration-100 ease-out active:scale-[0.92] hover:bg-surface-tertiary/50 hover:text-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-focus-ring max-sm:hit-target";
|
package/src/ui/command.tsx
CHANGED
|
@@ -131,7 +131,7 @@ const CommandInput = React.forwardRef<
|
|
|
131
131
|
ref={ref}
|
|
132
132
|
className={merge(
|
|
133
133
|
config?.classes?.input ??
|
|
134
|
-
"flex h-11 w-full max-sm:min-w-0 bg-transparent text-base sm:text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
|
134
|
+
"flex h-11 w-full max-sm:min-w-0 bg-transparent text-base sm:pointer-fine:text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
|
135
135
|
className,
|
|
136
136
|
)}
|
|
137
137
|
{...props}
|
package/src/ui/input.tsx
CHANGED
|
@@ -16,7 +16,7 @@ const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
|
|
|
16
16
|
type={type}
|
|
17
17
|
className={merge(
|
|
18
18
|
base ?? [
|
|
19
|
-
"flex h-10 w-full max-sm:min-w-0 rounded-field border border-border bg-field-background px-3.5 py-2 text-base sm:text-sm transition-[border-color,box-shadow,background-color] duration-200 ease-smooth file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-field-placeholder disabled:cursor-not-allowed disabled:opacity-50",
|
|
19
|
+
"flex h-10 w-full max-sm:min-w-0 rounded-field border border-border bg-field-background px-3.5 py-2 text-base sm:pointer-fine:text-sm transition-[border-color,box-shadow,background-color] duration-200 ease-smooth file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-field-placeholder disabled:cursor-not-allowed disabled:opacity-50",
|
|
20
20
|
fieldFocusClass,
|
|
21
21
|
],
|
|
22
22
|
className,
|
package/src/ui/search-input.tsx
CHANGED
|
@@ -7,7 +7,7 @@ import { Kbd } from "./kbd";
|
|
|
7
7
|
import { useCn, useUiConfig } from "./ui-config";
|
|
8
8
|
|
|
9
9
|
const sizeClasses = {
|
|
10
|
-
sm: { input: "h-8 pl-8 text-base sm:text-sm", icon: "left-2" },
|
|
10
|
+
sm: { input: "h-8 pl-8 text-base sm:pointer-fine:text-sm", icon: "left-2" },
|
|
11
11
|
md: { input: "h-10 pl-9", icon: "left-3" },
|
|
12
12
|
};
|
|
13
13
|
|
package/src/ui/select.tsx
CHANGED
|
@@ -55,7 +55,7 @@ const SelectTrigger = React.forwardRef<
|
|
|
55
55
|
data-slot={(config?.triggerSlot ?? true) ? "select-trigger" : undefined}
|
|
56
56
|
className={merge(
|
|
57
57
|
config?.classes?.trigger ?? [
|
|
58
|
-
"flex h-10 w-full max-sm:min-w-0 items-center justify-between whitespace-nowrap rounded-field border border-border bg-field-background px-3.5 py-2 text-base sm:text-sm ring-offset-background placeholder:text-field-placeholder transition-[border-color,box-shadow,background-color] duration-200 ease-smooth disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
|
|
58
|
+
"flex h-10 w-full max-sm:min-w-0 items-center justify-between whitespace-nowrap rounded-field border border-border bg-field-background px-3.5 py-2 text-base sm:pointer-fine:text-sm ring-offset-background placeholder:text-field-placeholder transition-[border-color,box-shadow,background-color] duration-200 ease-smooth disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
|
|
59
59
|
fieldFocusClass,
|
|
60
60
|
],
|
|
61
61
|
className,
|
package/src/ui/sonner.tsx
CHANGED
|
@@ -16,6 +16,7 @@ import "./sonner.css";
|
|
|
16
16
|
//
|
|
17
17
|
// Position: `top-right` by default (sonner's own default is `bottom-right`), as
|
|
18
18
|
// apps mount it. A `position` prop or `UiConfig.SonnerToaster.position` wins.
|
|
19
|
+
// `mobileOffset` adds the safe-area insets to sonner's 16px; a prop or config replaces it.
|
|
19
20
|
//
|
|
20
21
|
// Stacking: `expand={false}` keeps toasts collapsed (offset + scale). Hovering
|
|
21
22
|
// the stack expands them. `sonner.css` hides back-toast content while collapsed
|
|
@@ -100,6 +101,14 @@ const defaultCancelButtonClassName =
|
|
|
100
101
|
|
|
101
102
|
const defaultToasterPosition = "top-right" satisfies ToasterProps["position"];
|
|
102
103
|
|
|
104
|
+
// Sonner's 16px phone offset (viewport up to 600px) plus the safe-area inset, so
|
|
105
|
+
// toasts clear the notch and home indicator under a translucent status bar
|
|
106
|
+
// (`viewport-fit=cover`). `env()` is 0 without it. Left and right keep 16px.
|
|
107
|
+
const defaultMobileOffset = {
|
|
108
|
+
top: "calc(16px + env(safe-area-inset-top, 0px))",
|
|
109
|
+
bottom: "calc(16px + env(safe-area-inset-bottom, 0px))",
|
|
110
|
+
} satisfies ToasterProps["mobileOffset"];
|
|
111
|
+
|
|
103
112
|
const toastRadiusClasses = {
|
|
104
113
|
lg: "rounded-lg",
|
|
105
114
|
surface: "rounded-surface",
|
|
@@ -220,6 +229,7 @@ function SonnerToaster(props: ToasterProps & SonnerToasterOptions) {
|
|
|
220
229
|
// Defaulted here, not by spreading after a literal, so `position={undefined}`
|
|
221
230
|
// still gets top-right rather than sonner's bottom-right.
|
|
222
231
|
position = defaultToasterPosition,
|
|
232
|
+
mobileOffset = defaultMobileOffset,
|
|
223
233
|
toastRadius,
|
|
224
234
|
density,
|
|
225
235
|
toastIcons = "default",
|
|
@@ -252,6 +262,7 @@ function SonnerToaster(props: ToasterProps & SonnerToasterOptions) {
|
|
|
252
262
|
gap={12}
|
|
253
263
|
{...rest}
|
|
254
264
|
position={position}
|
|
265
|
+
mobileOffset={mobileOffset}
|
|
255
266
|
closeButton={closeButton ?? (closeButtonStyle === "hoverChip" ? true : undefined)}
|
|
256
267
|
className={
|
|
257
268
|
toasterClassName && className
|
package/src/ui/textarea.tsx
CHANGED
|
@@ -17,7 +17,7 @@ const Textarea = React.forwardRef<
|
|
|
17
17
|
<textarea
|
|
18
18
|
className={merge(
|
|
19
19
|
base ?? [
|
|
20
|
-
"flex min-h-20 w-full max-sm:min-w-0 rounded-field border border-border bg-field-background px-3.5 py-2.5 text-base sm:text-sm placeholder:text-field-placeholder disabled:cursor-not-allowed disabled:opacity-50",
|
|
20
|
+
"flex min-h-20 w-full max-sm:min-w-0 rounded-field border border-border bg-field-background px-3.5 py-2.5 text-base sm:pointer-fine:text-sm placeholder:text-field-placeholder disabled:cursor-not-allowed disabled:opacity-50",
|
|
21
21
|
fieldFocusClass,
|
|
22
22
|
],
|
|
23
23
|
className,
|
package/tokens/src/css/base.css
CHANGED
|
@@ -14,6 +14,29 @@
|
|
|
14
14
|
accent-color: var(--accent);
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
/* No double-tap-zoom wait on controls, so a tap fires `click` at once.
|
|
18
|
+
touch-action is not inherited and the `html` value stops at the first
|
|
19
|
+
scroll container, so controls inside scroll areas need their own. In
|
|
20
|
+
`@layer base`, so a `touch-*` utility (e.g. `touch-pan-y`) still wins. */
|
|
21
|
+
button,
|
|
22
|
+
a[href],
|
|
23
|
+
summary,
|
|
24
|
+
label,
|
|
25
|
+
[role="button"],
|
|
26
|
+
[role="link"],
|
|
27
|
+
[role="tab"],
|
|
28
|
+
[role="option"],
|
|
29
|
+
[role="menuitem"],
|
|
30
|
+
[role="menuitemcheckbox"],
|
|
31
|
+
[role="menuitemradio"],
|
|
32
|
+
[role="checkbox"],
|
|
33
|
+
[role="radio"],
|
|
34
|
+
[role="switch"],
|
|
35
|
+
input[type="checkbox"],
|
|
36
|
+
input[type="radio"] {
|
|
37
|
+
touch-action: manipulation;
|
|
38
|
+
}
|
|
39
|
+
|
|
17
40
|
::selection {
|
|
18
41
|
background-color: color-mix(in oklch, var(--accent) 18%, transparent);
|
|
19
42
|
color: var(--foreground);
|