ai-design-system 0.1.96 → 0.1.98
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/components/composites/SessionHeader/SessionHeader.tsx +46 -40
- package/components/composites/StoriesBar/StoriesBar.tsx +16 -19
- package/components/features/ChatPanel/ChatPanel.tsx +13 -0
- package/dist/index.cjs +37 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +5 -28
- package/dist/index.d.ts +207 -196
- package/dist/index.js +37 -35
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -20,12 +20,14 @@ import type { FileDownloadResult } from '@/components/composites/FileTreeExplore
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
export interface SessionHeaderProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
23
|
+
title?: string;
|
|
23
24
|
sessions?: ChatSessionInfo[];
|
|
24
25
|
activeSessionId?: string | null;
|
|
25
26
|
onNewSession?: () => void;
|
|
26
27
|
onCloseSession?: (id: string) => void;
|
|
27
28
|
onSelectSession?: (id: string) => void;
|
|
28
29
|
onDownloadSession?: () => Promise<FileDownloadResult | undefined>;
|
|
30
|
+
showActions?: boolean;
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
/**
|
|
@@ -35,7 +37,7 @@ export interface SessionHeaderProps extends React.HTMLAttributes<HTMLDivElement>
|
|
|
35
37
|
* and a dropdown history of past sessions.
|
|
36
38
|
*/
|
|
37
39
|
export const SessionHeader = React.forwardRef<HTMLDivElement, SessionHeaderProps>(
|
|
38
|
-
({ sessions, activeSessionId, onNewSession, onCloseSession, onSelectSession, onDownloadSession, className, ...props }, ref) => {
|
|
40
|
+
({ title, sessions, activeSessionId, onNewSession, onCloseSession, onSelectSession, onDownloadSession, showActions = true, className, ...props }, ref) => {
|
|
39
41
|
const activeSession = sessions?.find(s => s.id === activeSessionId);
|
|
40
42
|
const downloadRef = React.useRef<HTMLAnchorElement>(null);
|
|
41
43
|
|
|
@@ -53,6 +55,10 @@ export const SessionHeader = React.forwardRef<HTMLDivElement, SessionHeaderProps
|
|
|
53
55
|
URL.revokeObjectURL(url);
|
|
54
56
|
}, [onDownloadSession]);
|
|
55
57
|
|
|
58
|
+
const displayTitle = title || (activeSessionId
|
|
59
|
+
? (activeSession?.title || 'Untitled Session')
|
|
60
|
+
: 'New Session');
|
|
61
|
+
|
|
56
62
|
return (
|
|
57
63
|
<div
|
|
58
64
|
ref={ref}
|
|
@@ -61,48 +67,48 @@ export const SessionHeader = React.forwardRef<HTMLDivElement, SessionHeaderProps
|
|
|
61
67
|
>
|
|
62
68
|
<div className="flex items-center space-x-2 overflow-hidden">
|
|
63
69
|
<span className="text-sm font-medium truncate">
|
|
64
|
-
{
|
|
65
|
-
? (activeSession?.title || 'Untitled Session')
|
|
66
|
-
: 'New Session'}
|
|
70
|
+
{displayTitle}
|
|
67
71
|
</span>
|
|
68
72
|
</div>
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
<
|
|
73
|
-
|
|
74
|
-
)}
|
|
75
|
-
<Button variant="ghost" size="icon" onClick={onNewSession} className="h-8 w-8" title="New Session">
|
|
76
|
-
<Icon name="plus" className="h-4 w-4" />
|
|
77
|
-
</Button>
|
|
78
|
-
|
|
79
|
-
<DropdownMenu>
|
|
80
|
-
<DropdownMenuTrigger asChild>
|
|
81
|
-
<Button variant="ghost" size="icon" className="h-8 w-8">
|
|
82
|
-
<Icon name="clock" className="h-4 w-4" />
|
|
73
|
+
{showActions && (
|
|
74
|
+
<div className="flex items-center space-x-1 flex-none">
|
|
75
|
+
{onDownloadSession && (
|
|
76
|
+
<Button variant="ghost" size="icon" onClick={handleDownloadClick} className="h-8 w-8" title="Download Chat History">
|
|
77
|
+
<Icon name="download" className="h-4 w-4" />
|
|
83
78
|
</Button>
|
|
84
|
-
|
|
85
|
-
<
|
|
86
|
-
<
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
79
|
+
)}
|
|
80
|
+
<Button variant="ghost" size="icon" onClick={onNewSession} className="h-8 w-8" title="New Session">
|
|
81
|
+
<Icon name="plus" className="h-4 w-4" />
|
|
82
|
+
</Button>
|
|
83
|
+
|
|
84
|
+
<DropdownMenu>
|
|
85
|
+
<DropdownMenuTrigger asChild>
|
|
86
|
+
<Button variant="ghost" size="icon" className="h-8 w-8">
|
|
87
|
+
<Icon name="clock" className="h-4 w-4" />
|
|
88
|
+
</Button>
|
|
89
|
+
</DropdownMenuTrigger>
|
|
90
|
+
<DropdownMenuContent align="end" className="w-64 max-h-80 overflow-y-auto">
|
|
91
|
+
<DropdownMenuLabel>Chat History</DropdownMenuLabel>
|
|
92
|
+
<DropdownMenuSeparator />
|
|
93
|
+
{sessions && sessions.length > 0 ? (
|
|
94
|
+
sessions.map((session) => (
|
|
95
|
+
<DropdownMenuItem
|
|
96
|
+
key={session.id}
|
|
97
|
+
onClick={() => onSelectSession?.(session.id)}
|
|
98
|
+
className="flex flex-col items-start py-2 cursor-pointer"
|
|
99
|
+
>
|
|
100
|
+
<span className="text-sm font-medium truncate w-full">{session.title || 'Untitled Session'}</span>
|
|
101
|
+
<span className="text-xs text-muted-foreground">{new Date(session.created_at).toLocaleString()}</span>
|
|
102
|
+
</DropdownMenuItem>
|
|
103
|
+
))
|
|
104
|
+
) : (
|
|
105
|
+
<div className="p-4 text-sm text-center text-muted-foreground">No previous sessions</div>
|
|
106
|
+
)}
|
|
107
|
+
</DropdownMenuContent>
|
|
108
|
+
</DropdownMenu>
|
|
109
|
+
<a ref={downloadRef} style={{ display: 'none' }} />
|
|
110
|
+
</div>
|
|
111
|
+
)}
|
|
106
112
|
</div>
|
|
107
113
|
);
|
|
108
114
|
}
|
|
@@ -31,20 +31,17 @@ function getStoryStatusStyle(status?: StoryItem["status"]) {
|
|
|
31
31
|
case "generating":
|
|
32
32
|
return {
|
|
33
33
|
iconColor: "text-amber-500",
|
|
34
|
-
ringClass: "ring-2 ring-amber-500 animate-pulse",
|
|
35
34
|
badgeBg: "bg-amber-500",
|
|
36
35
|
};
|
|
37
36
|
case "ready":
|
|
38
37
|
return {
|
|
39
38
|
iconColor: "text-emerald-500",
|
|
40
|
-
ringClass: "ring-1 ring-emerald-500/70 group-hover:ring-emerald-500",
|
|
41
39
|
badgeBg: "bg-emerald-500",
|
|
42
40
|
};
|
|
43
41
|
case "draft":
|
|
44
42
|
default:
|
|
45
43
|
return {
|
|
46
44
|
iconColor: "text-muted-foreground",
|
|
47
|
-
ringClass: "ring-1 ring-border group-hover:ring-primary/60",
|
|
48
45
|
badgeBg: "bg-muted-foreground",
|
|
49
46
|
};
|
|
50
47
|
}
|
|
@@ -55,11 +52,11 @@ export const StoriesBar = React.forwardRef<HTMLDivElement, StoriesBarProps>(
|
|
|
55
52
|
return (
|
|
56
53
|
<div
|
|
57
54
|
ref={ref}
|
|
58
|
-
className={cn("w-full border-b shrink-0", className)}
|
|
55
|
+
className={cn("w-full border-b border-border bg-background shrink-0", className)}
|
|
59
56
|
data-testid="stories-bar"
|
|
60
57
|
{...props}
|
|
61
58
|
>
|
|
62
|
-
<div className="flex items-center gap-3 overflow-x-auto no-scrollbar scroll-smooth">
|
|
59
|
+
<div className="flex items-center gap-2.5 px-3 py-1.5 overflow-x-auto no-scrollbar scroll-smooth">
|
|
63
60
|
{stories.map((story) => {
|
|
64
61
|
const isActive = story.id === activeStoryId;
|
|
65
62
|
const isGenerating = story.status === "generating";
|
|
@@ -75,15 +72,15 @@ export const StoriesBar = React.forwardRef<HTMLDivElement, StoriesBarProps>(
|
|
|
75
72
|
data-testid={`btn-story-${story.id}`}
|
|
76
73
|
aria-label={`Open story: ${story.title}`}
|
|
77
74
|
>
|
|
78
|
-
<div
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
75
|
+
<div className="relative w-9 h-9 shrink-0 aspect-square rounded-full transition-transform group-hover:scale-105">
|
|
76
|
+
<div
|
|
77
|
+
className={cn(
|
|
78
|
+
"w-full h-full rounded-full flex items-center justify-center border transition-colors overflow-hidden select-none",
|
|
79
|
+
isActive
|
|
80
|
+
? "border-primary bg-muted/60"
|
|
81
|
+
: "border-border/50 bg-muted/40"
|
|
82
|
+
)}
|
|
83
|
+
>
|
|
87
84
|
{story.thumbnailUrl ? (
|
|
88
85
|
<img
|
|
89
86
|
src={story.thumbnailUrl}
|
|
@@ -93,20 +90,20 @@ export const StoriesBar = React.forwardRef<HTMLDivElement, StoriesBarProps>(
|
|
|
93
90
|
) : (
|
|
94
91
|
<Icon
|
|
95
92
|
name={iconName}
|
|
96
|
-
className={cn("w-
|
|
93
|
+
className={cn("w-4 h-4 transition-colors", statusStyle.iconColor)}
|
|
97
94
|
/>
|
|
98
95
|
)}
|
|
99
96
|
</div>
|
|
100
97
|
|
|
101
98
|
{isGenerating ? (
|
|
102
|
-
<span className="absolute bottom-0 right-0 flex h-2
|
|
99
|
+
<span className="absolute bottom-0 right-0 flex h-2 w-2">
|
|
103
100
|
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-amber-500 opacity-75" />
|
|
104
|
-
<span className="relative inline-flex rounded-full h-2
|
|
101
|
+
<span className="relative inline-flex rounded-full h-2 w-2 bg-amber-500" />
|
|
105
102
|
</span>
|
|
106
103
|
) : (
|
|
107
104
|
<span
|
|
108
105
|
className={cn(
|
|
109
|
-
"absolute bottom-0 right-0 inline-flex rounded-full h-2
|
|
106
|
+
"absolute bottom-0 right-0 inline-flex rounded-full h-2 w-2 ring-1.5 ring-background",
|
|
110
107
|
statusStyle.badgeBg
|
|
111
108
|
)}
|
|
112
109
|
/>
|
|
@@ -115,7 +112,7 @@ export const StoriesBar = React.forwardRef<HTMLDivElement, StoriesBarProps>(
|
|
|
115
112
|
|
|
116
113
|
<span
|
|
117
114
|
className={cn(
|
|
118
|
-
"text-
|
|
115
|
+
"text-[10px] leading-tight truncate max-w-[56px] text-center",
|
|
119
116
|
isActive
|
|
120
117
|
? "font-semibold text-foreground"
|
|
121
118
|
: "text-muted-foreground group-hover:text-foreground"
|
|
@@ -204,6 +204,15 @@ export interface ChatPanelProps {
|
|
|
204
204
|
* @default true
|
|
205
205
|
*/
|
|
206
206
|
showHeader?: boolean;
|
|
207
|
+
/**
|
|
208
|
+
* Title override for the session header
|
|
209
|
+
*/
|
|
210
|
+
sessionTitle?: string;
|
|
211
|
+
/**
|
|
212
|
+
* Whether to show action buttons in the session header
|
|
213
|
+
* @default true
|
|
214
|
+
*/
|
|
215
|
+
showSessionActions?: boolean;
|
|
207
216
|
}
|
|
208
217
|
|
|
209
218
|
/**
|
|
@@ -249,6 +258,8 @@ export const ChatPanel = React.memo<ChatPanelProps>(
|
|
|
249
258
|
onTaskClick,
|
|
250
259
|
enableSpeech = true,
|
|
251
260
|
showHeader = true,
|
|
261
|
+
sessionTitle,
|
|
262
|
+
showSessionActions = true,
|
|
252
263
|
}) => {
|
|
253
264
|
// File change queue state
|
|
254
265
|
const [fileChangeState, setFileChangeState] = React.useState<
|
|
@@ -405,6 +416,8 @@ export const ChatPanel = React.memo<ChatPanelProps>(
|
|
|
405
416
|
{/* Chat Session Header */}
|
|
406
417
|
{showHeader && (
|
|
407
418
|
<SessionHeader
|
|
419
|
+
title={sessionTitle}
|
|
420
|
+
showActions={showSessionActions}
|
|
408
421
|
sessions={sessions}
|
|
409
422
|
activeSessionId={activeSessionId}
|
|
410
423
|
onNewSession={onNewSession}
|
package/dist/index.cjs
CHANGED
|
@@ -7786,7 +7786,7 @@ var ApprovalCard = React3__namespace.memo(
|
|
|
7786
7786
|
ApprovalCard.displayName = "ApprovalCard";
|
|
7787
7787
|
var SessionHeader = React3__namespace.forwardRef(
|
|
7788
7788
|
(_a, ref) => {
|
|
7789
|
-
var _b = _a, { sessions, activeSessionId, onNewSession, onCloseSession, onSelectSession, onDownloadSession, className } = _b, props = __objRest(_b, ["sessions", "activeSessionId", "onNewSession", "onCloseSession", "onSelectSession", "onDownloadSession", "className"]);
|
|
7789
|
+
var _b = _a, { title, sessions, activeSessionId, onNewSession, onCloseSession, onSelectSession, onDownloadSession, showActions = true, className } = _b, props = __objRest(_b, ["title", "sessions", "activeSessionId", "onNewSession", "onCloseSession", "onSelectSession", "onDownloadSession", "showActions", "className"]);
|
|
7790
7790
|
const activeSession = sessions == null ? void 0 : sessions.find((s) => s.id === activeSessionId);
|
|
7791
7791
|
const downloadRef = React3__namespace.useRef(null);
|
|
7792
7792
|
const handleDownloadClick = React3__namespace.useCallback(async () => {
|
|
@@ -7802,6 +7802,7 @@ var SessionHeader = React3__namespace.forwardRef(
|
|
|
7802
7802
|
}
|
|
7803
7803
|
URL.revokeObjectURL(url);
|
|
7804
7804
|
}, [onDownloadSession]);
|
|
7805
|
+
const displayTitle = title || (activeSessionId ? (activeSession == null ? void 0 : activeSession.title) || "Untitled Session" : "New Session");
|
|
7805
7806
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7806
7807
|
"div",
|
|
7807
7808
|
__spreadProps(__spreadValues({
|
|
@@ -7809,8 +7810,8 @@ var SessionHeader = React3__namespace.forwardRef(
|
|
|
7809
7810
|
className: `flex flex-none items-center justify-between px-4 py-2 border-b border-border bg-background ${className || ""}`
|
|
7810
7811
|
}, props), {
|
|
7811
7812
|
children: [
|
|
7812
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center space-x-2 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium truncate", children:
|
|
7813
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-1 flex-none", children: [
|
|
7813
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center space-x-2 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium truncate", children: displayTitle }) }),
|
|
7814
|
+
showActions && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-1 flex-none", children: [
|
|
7814
7815
|
onDownloadSession && /* @__PURE__ */ jsxRuntime.jsx(Button2, { variant: "ghost", size: "icon", onClick: handleDownloadClick, className: "h-8 w-8", title: "Download Chat History", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "download", className: "h-4 w-4" }) }),
|
|
7815
7816
|
/* @__PURE__ */ jsxRuntime.jsx(Button2, { variant: "ghost", size: "icon", onClick: onNewSession, className: "h-8 w-8", title: "New Session", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "plus", className: "h-4 w-4" }) }),
|
|
7816
7817
|
/* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu2, { children: [
|
|
@@ -8039,7 +8040,9 @@ var ChatPanel = React3__namespace.memo(
|
|
|
8039
8040
|
onTaskStopAll,
|
|
8040
8041
|
onTaskClick,
|
|
8041
8042
|
enableSpeech = true,
|
|
8042
|
-
showHeader = true
|
|
8043
|
+
showHeader = true,
|
|
8044
|
+
sessionTitle,
|
|
8045
|
+
showSessionActions = true
|
|
8043
8046
|
}) => {
|
|
8044
8047
|
const [fileChangeState, setFileChangeState] = React3__namespace.useState("approval-requested");
|
|
8045
8048
|
const [approval, setApproval] = React3__namespace.useState({});
|
|
@@ -8161,6 +8164,8 @@ var ChatPanel = React3__namespace.memo(
|
|
|
8161
8164
|
showHeader && /* @__PURE__ */ jsxRuntime.jsx(
|
|
8162
8165
|
SessionHeader,
|
|
8163
8166
|
{
|
|
8167
|
+
title: sessionTitle,
|
|
8168
|
+
showActions: showSessionActions,
|
|
8164
8169
|
sessions,
|
|
8165
8170
|
activeSessionId,
|
|
8166
8171
|
onNewSession,
|
|
@@ -14398,20 +14403,17 @@ function getStoryStatusStyle(status) {
|
|
|
14398
14403
|
case "generating":
|
|
14399
14404
|
return {
|
|
14400
14405
|
iconColor: "text-amber-500",
|
|
14401
|
-
ringClass: "ring-2 ring-amber-500 animate-pulse",
|
|
14402
14406
|
badgeBg: "bg-amber-500"
|
|
14403
14407
|
};
|
|
14404
14408
|
case "ready":
|
|
14405
14409
|
return {
|
|
14406
14410
|
iconColor: "text-emerald-500",
|
|
14407
|
-
ringClass: "ring-1 ring-emerald-500/70 group-hover:ring-emerald-500",
|
|
14408
14411
|
badgeBg: "bg-emerald-500"
|
|
14409
14412
|
};
|
|
14410
14413
|
case "draft":
|
|
14411
14414
|
default:
|
|
14412
14415
|
return {
|
|
14413
14416
|
iconColor: "text-muted-foreground",
|
|
14414
|
-
ringClass: "ring-1 ring-border group-hover:ring-primary/60",
|
|
14415
14417
|
badgeBg: "bg-muted-foreground"
|
|
14416
14418
|
};
|
|
14417
14419
|
}
|
|
@@ -14423,10 +14425,10 @@ var StoriesBar = React3__namespace.forwardRef(
|
|
|
14423
14425
|
"div",
|
|
14424
14426
|
__spreadProps(__spreadValues({
|
|
14425
14427
|
ref,
|
|
14426
|
-
className: cn("w-full border-b shrink-0", className),
|
|
14428
|
+
className: cn("w-full border-b border-border bg-background shrink-0", className),
|
|
14427
14429
|
"data-testid": "stories-bar"
|
|
14428
14430
|
}, props), {
|
|
14429
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3 overflow-x-auto no-scrollbar scroll-smooth", children: stories.map((story) => {
|
|
14431
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2.5 px-3 py-1.5 overflow-x-auto no-scrollbar scroll-smooth", children: stories.map((story) => {
|
|
14430
14432
|
const isActive = story.id === activeStoryId;
|
|
14431
14433
|
const isGenerating = story.status === "generating";
|
|
14432
14434
|
const statusStyle = getStoryStatusStyle(story.status);
|
|
@@ -14440,15 +14442,15 @@ var StoriesBar = React3__namespace.forwardRef(
|
|
|
14440
14442
|
"data-testid": `btn-story-${story.id}`,
|
|
14441
14443
|
"aria-label": `Open story: ${story.title}`,
|
|
14442
14444
|
children: [
|
|
14443
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
14444
|
-
|
|
14445
|
-
|
|
14446
|
-
|
|
14447
|
-
|
|
14448
|
-
|
|
14449
|
-
|
|
14450
|
-
|
|
14451
|
-
|
|
14445
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-9 h-9 shrink-0 aspect-square rounded-full transition-transform group-hover:scale-105", children: [
|
|
14446
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
14447
|
+
"div",
|
|
14448
|
+
{
|
|
14449
|
+
className: cn(
|
|
14450
|
+
"w-full h-full rounded-full flex items-center justify-center border transition-colors overflow-hidden select-none",
|
|
14451
|
+
isActive ? "border-primary bg-muted/60" : "border-border/50 bg-muted/40"
|
|
14452
|
+
),
|
|
14453
|
+
children: story.thumbnailUrl ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
14452
14454
|
"img",
|
|
14453
14455
|
{
|
|
14454
14456
|
src: story.thumbnailUrl,
|
|
@@ -14459,29 +14461,29 @@ var StoriesBar = React3__namespace.forwardRef(
|
|
|
14459
14461
|
Icon,
|
|
14460
14462
|
{
|
|
14461
14463
|
name: iconName,
|
|
14462
|
-
className: cn("w-
|
|
14463
|
-
}
|
|
14464
|
-
) }),
|
|
14465
|
-
isGenerating ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute bottom-0 right-0 flex h-2.5 w-2.5", children: [
|
|
14466
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "animate-ping absolute inline-flex h-full w-full rounded-full bg-amber-500 opacity-75" }),
|
|
14467
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "relative inline-flex rounded-full h-2.5 w-2.5 bg-amber-500" })
|
|
14468
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
14469
|
-
"span",
|
|
14470
|
-
{
|
|
14471
|
-
className: cn(
|
|
14472
|
-
"absolute bottom-0 right-0 inline-flex rounded-full h-2.5 w-2.5 ring-2 ring-background",
|
|
14473
|
-
statusStyle.badgeBg
|
|
14474
|
-
)
|
|
14464
|
+
className: cn("w-4 h-4 transition-colors", statusStyle.iconColor)
|
|
14475
14465
|
}
|
|
14476
14466
|
)
|
|
14477
|
-
|
|
14478
|
-
|
|
14479
|
-
|
|
14467
|
+
}
|
|
14468
|
+
),
|
|
14469
|
+
isGenerating ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute bottom-0 right-0 flex h-2 w-2", children: [
|
|
14470
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "animate-ping absolute inline-flex h-full w-full rounded-full bg-amber-500 opacity-75" }),
|
|
14471
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "relative inline-flex rounded-full h-2 w-2 bg-amber-500" })
|
|
14472
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
14473
|
+
"span",
|
|
14474
|
+
{
|
|
14475
|
+
className: cn(
|
|
14476
|
+
"absolute bottom-0 right-0 inline-flex rounded-full h-2 w-2 ring-1.5 ring-background",
|
|
14477
|
+
statusStyle.badgeBg
|
|
14478
|
+
)
|
|
14479
|
+
}
|
|
14480
|
+
)
|
|
14481
|
+
] }),
|
|
14480
14482
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
14481
14483
|
"span",
|
|
14482
14484
|
{
|
|
14483
14485
|
className: cn(
|
|
14484
|
-
"text-
|
|
14486
|
+
"text-[10px] leading-tight truncate max-w-[56px] text-center",
|
|
14485
14487
|
isActive ? "font-semibold text-foreground" : "text-muted-foreground group-hover:text-foreground"
|
|
14486
14488
|
),
|
|
14487
14489
|
title: story.title,
|