@invana/ui 0.0.23 → 0.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +876 -93
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +478 -12
- package/dist/index.d.ts +478 -12
- package/dist/index.js +871 -94
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -3115,27 +3115,214 @@ function ChatSessionMessage({
|
|
|
3115
3115
|
footer
|
|
3116
3116
|
] });
|
|
3117
3117
|
}
|
|
3118
|
+
var NONE = Object.freeze([]);
|
|
3119
|
+
function same(a, b) {
|
|
3120
|
+
if (a.length !== b.length) return false;
|
|
3121
|
+
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
3122
|
+
return true;
|
|
3123
|
+
}
|
|
3124
|
+
function useOverflowItems({
|
|
3125
|
+
count,
|
|
3126
|
+
enabled = true,
|
|
3127
|
+
pinnedIndex,
|
|
3128
|
+
reserve = 32
|
|
3129
|
+
}) {
|
|
3130
|
+
const containerEl = React23__namespace.useRef(null);
|
|
3131
|
+
const itemEls = React23__namespace.useRef([]);
|
|
3132
|
+
const widths = React23__namespace.useRef([]);
|
|
3133
|
+
const itemRefs = React23__namespace.useRef([]);
|
|
3134
|
+
const [hidden, setHidden] = React23__namespace.useState(NONE);
|
|
3135
|
+
const fit = React23__namespace.useCallback(() => {
|
|
3136
|
+
const el = containerEl.current;
|
|
3137
|
+
if (!el || !enabled) {
|
|
3138
|
+
setHidden((prev) => prev === NONE ? prev : NONE);
|
|
3139
|
+
return;
|
|
3140
|
+
}
|
|
3141
|
+
const gap = Number.parseFloat(getComputedStyle(el).columnGap) || 0;
|
|
3142
|
+
for (let i = 0; i < count; i++) {
|
|
3143
|
+
const item = itemEls.current[i];
|
|
3144
|
+
if (item && item.offsetParent !== null) widths.current[i] = item.offsetWidth + gap;
|
|
3145
|
+
}
|
|
3146
|
+
const budget = el.clientWidth;
|
|
3147
|
+
if (budget <= 0) return;
|
|
3148
|
+
let total = 0;
|
|
3149
|
+
for (let i = 0; i < count; i++) total += widths.current[i] ?? 0;
|
|
3150
|
+
if (total <= budget + gap) {
|
|
3151
|
+
setHidden((prev) => prev === NONE ? prev : NONE);
|
|
3152
|
+
return;
|
|
3153
|
+
}
|
|
3154
|
+
const next = [];
|
|
3155
|
+
let used = pinnedIndex != null ? widths.current[pinnedIndex] ?? 0 : 0;
|
|
3156
|
+
for (let i = 0; i < count; i++) {
|
|
3157
|
+
if (i === pinnedIndex) continue;
|
|
3158
|
+
const w = widths.current[i] ?? 0;
|
|
3159
|
+
if (used + w <= budget - reserve) used += w;
|
|
3160
|
+
else next.push(i);
|
|
3161
|
+
}
|
|
3162
|
+
setHidden((prev) => same(prev, next) ? prev : next);
|
|
3163
|
+
}, [count, enabled, pinnedIndex, reserve]);
|
|
3164
|
+
React23__namespace.useLayoutEffect(() => {
|
|
3165
|
+
widths.current = [];
|
|
3166
|
+
itemEls.current.length = count;
|
|
3167
|
+
setHidden((prev) => prev === NONE ? prev : NONE);
|
|
3168
|
+
}, [count]);
|
|
3169
|
+
React23__namespace.useLayoutEffect(() => {
|
|
3170
|
+
fit();
|
|
3171
|
+
if (!enabled || typeof ResizeObserver === "undefined") return;
|
|
3172
|
+
const observer = new ResizeObserver(() => fit());
|
|
3173
|
+
if (containerEl.current) observer.observe(containerEl.current);
|
|
3174
|
+
for (const item of itemEls.current) if (item) observer.observe(item);
|
|
3175
|
+
return () => observer.disconnect();
|
|
3176
|
+
}, [fit, enabled, hidden]);
|
|
3177
|
+
const containerRef = React23__namespace.useCallback((el) => {
|
|
3178
|
+
containerEl.current = el;
|
|
3179
|
+
}, []);
|
|
3180
|
+
const itemRef = React23__namespace.useCallback((index) => {
|
|
3181
|
+
let fn = itemRefs.current[index];
|
|
3182
|
+
if (!fn) {
|
|
3183
|
+
fn = (el) => {
|
|
3184
|
+
itemEls.current[index] = el;
|
|
3185
|
+
};
|
|
3186
|
+
itemRefs.current[index] = fn;
|
|
3187
|
+
}
|
|
3188
|
+
return fn;
|
|
3189
|
+
}, []);
|
|
3190
|
+
const isHidden = React23__namespace.useCallback(
|
|
3191
|
+
(index) => hidden.includes(index),
|
|
3192
|
+
[hidden]
|
|
3193
|
+
);
|
|
3194
|
+
return { containerRef, itemRef, hiddenIndices: hidden, isHidden };
|
|
3195
|
+
}
|
|
3196
|
+
var VARIANT = {
|
|
3197
|
+
/** The capsule: a filled, ringed chip. Toolbars, rails, header actions. */
|
|
3198
|
+
nav: {
|
|
3199
|
+
item: "rounded-control ring-1 ring-transparent",
|
|
3200
|
+
hover: "hover:bg-primary/10 hover:text-primary hover:ring-primary/25",
|
|
3201
|
+
open: "data-[state=open]:bg-primary/15 data-[state=open]:text-primary data-[state=open]:ring-primary/25",
|
|
3202
|
+
active: "bg-primary/15 text-primary ring-primary/25",
|
|
3203
|
+
strip: ""
|
|
3204
|
+
},
|
|
3205
|
+
/** The panel tab: accented fill with a rule under it, merging into the body. */
|
|
3206
|
+
underline: {
|
|
3207
|
+
item: "h-full rounded-none px-3 py-2",
|
|
3208
|
+
hover: "hover:text-foreground",
|
|
3209
|
+
open: "data-[state=open]:text-foreground",
|
|
3210
|
+
active: "bg-primary/10 text-primary border-b-2 border-primary mb-[-1px]",
|
|
3211
|
+
strip: "items-stretch"
|
|
3212
|
+
},
|
|
3213
|
+
/**
|
|
3214
|
+
* The workbook tab: boxed on top / left / right with an *open bottom*, so it
|
|
3215
|
+
* punches through the strip's own rule — the classic folder-tab notch.
|
|
3216
|
+
*/
|
|
3217
|
+
folder: {
|
|
3218
|
+
item: "h-full rounded-none px-3 py-2 gap-1.5",
|
|
3219
|
+
hover: "hover:text-foreground",
|
|
3220
|
+
open: "data-[state=open]:text-foreground",
|
|
3221
|
+
active: "mb-[-1px] rounded-t-md border border-b-0 border-primary text-primary",
|
|
3222
|
+
strip: "items-stretch"
|
|
3223
|
+
}
|
|
3224
|
+
};
|
|
3225
|
+
var keyOf = (item) => item.key ?? item.name;
|
|
3118
3226
|
var NavItems = ({
|
|
3119
3227
|
items,
|
|
3120
3228
|
orientation = "horizontal",
|
|
3121
3229
|
tooltipSide = orientation === "vertical" ? "right" : "bottom",
|
|
3122
|
-
iconClassName = orientation === "vertical" ? "w-5 h-5" : "w-4 h-4 flex-shrink-0"
|
|
3230
|
+
iconClassName = orientation === "vertical" ? "w-5 h-5" : "w-4 h-4 flex-shrink-0",
|
|
3231
|
+
variant = "nav",
|
|
3232
|
+
activeKey,
|
|
3233
|
+
onActiveChange,
|
|
3234
|
+
selectionMode = "none",
|
|
3235
|
+
panelId,
|
|
3236
|
+
overflow = false,
|
|
3237
|
+
overflowLabel = "More",
|
|
3238
|
+
className
|
|
3123
3239
|
}) => {
|
|
3124
3240
|
const isVertical = orientation === "vertical";
|
|
3125
|
-
const
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3241
|
+
const isTabs = selectionMode === "tabs";
|
|
3242
|
+
const V = VARIANT[variant];
|
|
3243
|
+
const [internalActive, setInternalActive] = React23__namespace.default.useState(
|
|
3244
|
+
null
|
|
3245
|
+
);
|
|
3246
|
+
const isControlled = activeKey !== void 0;
|
|
3247
|
+
const currentKey = isControlled ? activeKey : internalActive;
|
|
3248
|
+
const activeIndex = items.findIndex((item) => keyOf(item) === currentKey);
|
|
3249
|
+
const nodes = React23__namespace.default.useRef({});
|
|
3250
|
+
const pendingFocus = React23__namespace.default.useRef(null);
|
|
3251
|
+
React23__namespace.default.useEffect(() => {
|
|
3252
|
+
const key = pendingFocus.current;
|
|
3253
|
+
if (!key) return;
|
|
3254
|
+
const node = nodes.current[key];
|
|
3255
|
+
if (!node) return;
|
|
3256
|
+
pendingFocus.current = null;
|
|
3257
|
+
node.focus();
|
|
3258
|
+
});
|
|
3259
|
+
const { containerRef, itemRef, hiddenIndices, isHidden } = useOverflowItems({
|
|
3260
|
+
count: items.length,
|
|
3261
|
+
enabled: overflow && !isVertical,
|
|
3262
|
+
pinnedIndex: activeIndex >= 0 ? activeIndex : void 0
|
|
3263
|
+
});
|
|
3264
|
+
const select = React23__namespace.default.useCallback(
|
|
3265
|
+
(item) => {
|
|
3266
|
+
if (item.disabled) return;
|
|
3267
|
+
const key = keyOf(item);
|
|
3268
|
+
item.onClick?.();
|
|
3269
|
+
if (!isControlled) {
|
|
3270
|
+
setInternalActive((prev) => isTabs ? key : prev === key ? null : key);
|
|
3271
|
+
}
|
|
3272
|
+
onActiveChange?.(key);
|
|
3273
|
+
},
|
|
3274
|
+
[isControlled, isTabs, onActiveChange]
|
|
3275
|
+
);
|
|
3276
|
+
const step = (from, delta) => {
|
|
3277
|
+
if (items.length === 0) return -1;
|
|
3278
|
+
let i = from < 0 ? delta > 0 ? -1 : 0 : from;
|
|
3279
|
+
for (let n = 0; n < items.length; n++) {
|
|
3280
|
+
i = (i + delta + items.length) % items.length;
|
|
3281
|
+
if (!items[i]?.disabled) return i;
|
|
3282
|
+
}
|
|
3283
|
+
return -1;
|
|
3284
|
+
};
|
|
3285
|
+
const edge = (delta) => {
|
|
3286
|
+
const start = delta > 0 ? -1 : items.length;
|
|
3287
|
+
return step(start, delta);
|
|
3288
|
+
};
|
|
3289
|
+
const handleKeyDown = (event) => {
|
|
3290
|
+
if (!isTabs) return;
|
|
3291
|
+
const next = isVertical ? "ArrowDown" : "ArrowRight";
|
|
3292
|
+
const prev = isVertical ? "ArrowUp" : "ArrowLeft";
|
|
3293
|
+
let target = -1;
|
|
3294
|
+
if (event.key === next) target = step(activeIndex, 1);
|
|
3295
|
+
else if (event.key === prev) target = step(activeIndex, -1);
|
|
3296
|
+
else if (event.key === "Home") target = edge(1);
|
|
3297
|
+
else if (event.key === "End") target = edge(-1);
|
|
3298
|
+
else return;
|
|
3299
|
+
const item = items[target];
|
|
3300
|
+
if (!item) return;
|
|
3301
|
+
event.preventDefault();
|
|
3302
|
+
pendingFocus.current = keyOf(item);
|
|
3303
|
+
select(item);
|
|
3304
|
+
};
|
|
3305
|
+
const renderItem = (item, index) => {
|
|
3306
|
+
const key = keyOf(item);
|
|
3307
|
+
const isActive = key === currentKey;
|
|
3129
3308
|
const hasMenu = !item.href && Boolean(item.menuItems?.length);
|
|
3130
|
-
const
|
|
3131
|
-
const
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3309
|
+
const asCaret = hasMenu && item.menuTrigger === "caret";
|
|
3310
|
+
const isInteractive = Boolean(
|
|
3311
|
+
item.href || item.onClick || hasMenu || isTabs
|
|
3312
|
+
);
|
|
3313
|
+
const padding = variant === "nav" ? item.label ? "px-3 py-1.5" : "px-2 py-2" : "";
|
|
3314
|
+
const itemClass = cn(
|
|
3315
|
+
`relative inline-flex border-0 items-center justify-center gap-2
|
|
3316
|
+
whitespace-nowrap transition-colors
|
|
3317
|
+
ring-1 ring-transparent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring`,
|
|
3318
|
+
V.item,
|
|
3319
|
+
padding,
|
|
3320
|
+
isInteractive && !item.disabled && `cursor-pointer ${V.hover}`,
|
|
3321
|
+
hasMenu && !asCaret && V.open,
|
|
3322
|
+
item.disabled && "pointer-events-none opacity-50",
|
|
3323
|
+
isActive && cn(V.active, item.activeClass),
|
|
3324
|
+
item.className
|
|
3325
|
+
);
|
|
3139
3326
|
const icon = item.icon && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3140
3327
|
item.icon,
|
|
3141
3328
|
{
|
|
@@ -3143,41 +3330,79 @@ var NavItems = ({
|
|
|
3143
3330
|
className: item.iconClassName || iconClassName
|
|
3144
3331
|
}
|
|
3145
3332
|
);
|
|
3146
|
-
const label = item.label && /* @__PURE__ */ jsxRuntime.jsx("span", { children: item.label });
|
|
3333
|
+
const label = item.label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: item.labelClassName, children: item.label });
|
|
3147
3334
|
const badge = item.badge != null && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3148
3335
|
"span",
|
|
3149
3336
|
{
|
|
3150
|
-
className: "pointer-events-none absolute -right-0.5 -top-0.5 inline-flex h-3.5\n
|
|
3337
|
+
className: "pointer-events-none absolute -right-0.5 -top-0.5 inline-flex h-3.5\n min-w-3.5 items-center justify-center rounded-full bg-primary px-1\n text-[9px] font-semibold leading-none text-primary-foreground",
|
|
3151
3338
|
children: item.badge
|
|
3152
3339
|
}
|
|
3153
3340
|
);
|
|
3341
|
+
const tabProps = isTabs ? {
|
|
3342
|
+
role: "tab",
|
|
3343
|
+
"aria-selected": isActive,
|
|
3344
|
+
"aria-controls": panelId?.(key),
|
|
3345
|
+
tabIndex: isActive || activeIndex < 0 && index === 0 ? 0 : -1
|
|
3346
|
+
} : {};
|
|
3347
|
+
const setNode = (el) => {
|
|
3348
|
+
nodes.current[key] = el;
|
|
3349
|
+
itemRef(index)(el);
|
|
3350
|
+
};
|
|
3351
|
+
const caret = asCaret && /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3352
|
+
"span",
|
|
3353
|
+
{
|
|
3354
|
+
role: "button",
|
|
3355
|
+
tabIndex: -1,
|
|
3356
|
+
"aria-label": `${item.name} menu`,
|
|
3357
|
+
onClick: (e) => e.stopPropagation(),
|
|
3358
|
+
className: "ml-0.5 grid size-4 shrink-0 cursor-pointer place-items-center\n rounded-control text-muted-foreground hover:bg-accent hover:text-foreground",
|
|
3359
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "size-3" })
|
|
3360
|
+
}
|
|
3361
|
+
) });
|
|
3154
3362
|
const inner = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3155
3363
|
icon,
|
|
3156
3364
|
label,
|
|
3365
|
+
caret,
|
|
3157
3366
|
badge
|
|
3158
3367
|
] });
|
|
3159
|
-
const control =
|
|
3368
|
+
const control = asCaret ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3369
|
+
"div",
|
|
3370
|
+
{
|
|
3371
|
+
ref: setNode,
|
|
3372
|
+
...tabProps,
|
|
3373
|
+
style: item.style,
|
|
3374
|
+
onClick: () => select(item),
|
|
3375
|
+
className: itemClass,
|
|
3376
|
+
children: inner
|
|
3377
|
+
}
|
|
3378
|
+
) : item.href ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3160
3379
|
"a",
|
|
3161
3380
|
{
|
|
3381
|
+
ref: setNode,
|
|
3162
3382
|
href: item.href,
|
|
3163
|
-
|
|
3383
|
+
style: item.style,
|
|
3384
|
+
onClick: () => select(item),
|
|
3164
3385
|
className: itemClass,
|
|
3165
3386
|
children: inner
|
|
3166
3387
|
}
|
|
3167
|
-
) : item.onClick || hasMenu ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3388
|
+
) : item.onClick || hasMenu || isTabs ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3168
3389
|
"button",
|
|
3169
3390
|
{
|
|
3391
|
+
ref: setNode,
|
|
3170
3392
|
type: "button",
|
|
3393
|
+
disabled: item.disabled,
|
|
3394
|
+
...tabProps,
|
|
3395
|
+
style: item.style,
|
|
3171
3396
|
onClick: () => {
|
|
3172
|
-
item.onClick?.();
|
|
3173
|
-
|
|
3397
|
+
if (hasMenu) item.onClick?.();
|
|
3398
|
+
else select(item);
|
|
3174
3399
|
},
|
|
3175
3400
|
className: itemClass,
|
|
3176
3401
|
children: inner
|
|
3177
3402
|
}
|
|
3178
|
-
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: itemClass, children: inner });
|
|
3403
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { ref: setNode, style: item.style, className: itemClass, children: inner });
|
|
3179
3404
|
const withTooltip = /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
3180
|
-
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: hasMenu ? /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: control }) : control }),
|
|
3405
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: hasMenu && !asCaret ? /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: control }) : control }),
|
|
3181
3406
|
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: item.tooltipSide || tooltipSide, children: item.tooltip || item.name })
|
|
3182
3407
|
] });
|
|
3183
3408
|
return /* @__PURE__ */ jsxRuntime.jsxs(React23__namespace.default.Fragment, { children: [
|
|
@@ -3188,28 +3413,7 @@ var NavItems = ({
|
|
|
3188
3413
|
{
|
|
3189
3414
|
side: isVertical ? "right" : "bottom",
|
|
3190
3415
|
align: isVertical ? "start" : "end",
|
|
3191
|
-
children: item.menuItems
|
|
3192
|
-
const MenuIcon = menuItem.icon;
|
|
3193
|
-
const gutter = item.menuItems?.some((m) => m.icon);
|
|
3194
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(React23__namespace.default.Fragment, { children: [
|
|
3195
|
-
menuItem.separatorBefore && /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
|
|
3196
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3197
|
-
DropdownMenuItem,
|
|
3198
|
-
{
|
|
3199
|
-
disabled: menuItem.disabled,
|
|
3200
|
-
onSelect: () => menuItem.onSelect?.(),
|
|
3201
|
-
className: cn(
|
|
3202
|
-
menuItem.destructive && "text-destructive focus:bg-destructive/15 focus:text-destructive hover:bg-destructive/10 hover:text-destructive"
|
|
3203
|
-
),
|
|
3204
|
-
children: [
|
|
3205
|
-
MenuIcon ? /* @__PURE__ */ jsxRuntime.jsx(MenuIcon, {}) : gutter ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "size-4 shrink-0" }) : null,
|
|
3206
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: menuItem.label }),
|
|
3207
|
-
menuItem.shortcut && /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuShortcut, { children: menuItem.shortcut })
|
|
3208
|
-
]
|
|
3209
|
-
}
|
|
3210
|
-
)
|
|
3211
|
-
] }, menuItem.id);
|
|
3212
|
-
})
|
|
3416
|
+
children: renderMenuRows(item.menuItems)
|
|
3213
3417
|
}
|
|
3214
3418
|
)
|
|
3215
3419
|
] }) : withTooltip,
|
|
@@ -3221,22 +3425,132 @@ var NavItems = ({
|
|
|
3221
3425
|
}
|
|
3222
3426
|
)
|
|
3223
3427
|
] }, item.key || item.name);
|
|
3224
|
-
}
|
|
3428
|
+
};
|
|
3429
|
+
const rendered = items.map(
|
|
3430
|
+
(item, index) => isHidden(index) ? null : renderItem(item, index)
|
|
3431
|
+
);
|
|
3432
|
+
const overflowTrigger = hiddenIndices.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
|
|
3433
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
3434
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3435
|
+
"button",
|
|
3436
|
+
{
|
|
3437
|
+
type: "button",
|
|
3438
|
+
"aria-label": overflowLabel,
|
|
3439
|
+
className: cn(
|
|
3440
|
+
`relative inline-flex shrink-0 items-center justify-center border-0
|
|
3441
|
+
transition-colors ring-1 ring-transparent focus-visible:outline-none
|
|
3442
|
+
focus-visible:ring-2 focus-visible:ring-ring cursor-pointer`,
|
|
3443
|
+
V.item,
|
|
3444
|
+
variant === "nav" && "px-2 py-2",
|
|
3445
|
+
V.hover,
|
|
3446
|
+
V.open
|
|
3447
|
+
),
|
|
3448
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MoreHorizontal, { className: iconClassName })
|
|
3449
|
+
}
|
|
3450
|
+
) }) }),
|
|
3451
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: tooltipSide, children: overflowLabel })
|
|
3452
|
+
] }),
|
|
3453
|
+
/* @__PURE__ */ jsxRuntime.jsx(DropdownMenuContent, { align: "end", children: hiddenIndices.map((index) => {
|
|
3454
|
+
const item = items[index];
|
|
3455
|
+
if (!item) return null;
|
|
3456
|
+
const Icon = item.icon;
|
|
3457
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3458
|
+
DropdownMenuItem,
|
|
3459
|
+
{
|
|
3460
|
+
disabled: item.disabled,
|
|
3461
|
+
onSelect: () => select(item),
|
|
3462
|
+
children: [
|
|
3463
|
+
Icon ? /* @__PURE__ */ jsxRuntime.jsx(Icon, {}) : /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "size-4 shrink-0" }),
|
|
3464
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: item.label ?? item.name })
|
|
3465
|
+
]
|
|
3466
|
+
},
|
|
3467
|
+
keyOf(item)
|
|
3468
|
+
);
|
|
3469
|
+
}) })
|
|
3470
|
+
] });
|
|
3471
|
+
if (!isTabs && !overflow) {
|
|
3472
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { delayDuration: 0, children: rendered });
|
|
3473
|
+
}
|
|
3474
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3475
|
+
"div",
|
|
3476
|
+
{
|
|
3477
|
+
ref: containerRef,
|
|
3478
|
+
role: isTabs ? "tablist" : void 0,
|
|
3479
|
+
"aria-orientation": isTabs ? orientation : void 0,
|
|
3480
|
+
onKeyDown: handleKeyDown,
|
|
3481
|
+
className: cn(
|
|
3482
|
+
"flex min-w-0",
|
|
3483
|
+
isVertical ? "flex-col items-center gap-1" : "items-center gap-1",
|
|
3484
|
+
V.strip,
|
|
3485
|
+
className
|
|
3486
|
+
),
|
|
3487
|
+
children: [
|
|
3488
|
+
rendered,
|
|
3489
|
+
overflowTrigger
|
|
3490
|
+
]
|
|
3491
|
+
}
|
|
3492
|
+
) });
|
|
3225
3493
|
};
|
|
3226
|
-
|
|
3494
|
+
function renderMenuRows(menuItems) {
|
|
3495
|
+
const gutter = menuItems?.some((m) => m.icon);
|
|
3496
|
+
return menuItems?.map((menuItem) => {
|
|
3497
|
+
const MenuIcon = menuItem.icon;
|
|
3498
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React23__namespace.default.Fragment, { children: [
|
|
3499
|
+
menuItem.separatorBefore && /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
|
|
3500
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3501
|
+
DropdownMenuItem,
|
|
3502
|
+
{
|
|
3503
|
+
disabled: menuItem.disabled,
|
|
3504
|
+
onSelect: () => menuItem.onSelect?.(),
|
|
3505
|
+
className: cn(
|
|
3506
|
+
menuItem.destructive && "text-destructive focus:bg-destructive/15 focus:text-destructive hover:bg-destructive/10 hover:text-destructive"
|
|
3507
|
+
),
|
|
3508
|
+
children: [
|
|
3509
|
+
MenuIcon ? /* @__PURE__ */ jsxRuntime.jsx(MenuIcon, {}) : gutter ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "size-4 shrink-0" }) : null,
|
|
3510
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: menuItem.label }),
|
|
3511
|
+
menuItem.shortcut && /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuShortcut, { children: menuItem.shortcut })
|
|
3512
|
+
]
|
|
3513
|
+
}
|
|
3514
|
+
)
|
|
3515
|
+
] }, menuItem.id);
|
|
3516
|
+
});
|
|
3517
|
+
}
|
|
3518
|
+
var NavBase = ({
|
|
3519
|
+
className = "",
|
|
3520
|
+
orientation,
|
|
3521
|
+
sections
|
|
3522
|
+
}) => {
|
|
3227
3523
|
const isVertical = orientation === "vertical";
|
|
3228
3524
|
const containerClass = isVertical ? `flex flex-col items-center h-full ${className}` : `flex items-center w-full ${className}`;
|
|
3229
3525
|
const sectionWrapperClass = isVertical ? "flex flex-col items-center gap-1" : "flex items-center gap-1 ";
|
|
3230
3526
|
return /* @__PURE__ */ jsxRuntime.jsxs("nav", { className: containerClass, children: [
|
|
3231
|
-
sections.start?.content && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3232
|
-
|
|
3527
|
+
sections.start?.content && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3528
|
+
"div",
|
|
3529
|
+
{
|
|
3530
|
+
className: `${sectionWrapperClass} ${sections.start.className || ""}`,
|
|
3531
|
+
children: sections.start.content
|
|
3532
|
+
}
|
|
3533
|
+
),
|
|
3534
|
+
sections.center?.content ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3535
|
+
"div",
|
|
3536
|
+
{
|
|
3537
|
+
className: `flex-1 ${isVertical ? "" : "flex justify-center items-center gap-1"} ${sections.center.className || ""}`,
|
|
3538
|
+
children: sections.center.content
|
|
3539
|
+
}
|
|
3540
|
+
) : (
|
|
3233
3541
|
// Empty spacer to push end section to the bottom/right
|
|
3234
3542
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1" })
|
|
3235
3543
|
),
|
|
3236
|
-
sections.end?.content && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3544
|
+
sections.end?.content && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3545
|
+
"div",
|
|
3546
|
+
{
|
|
3547
|
+
className: `${sectionWrapperClass} ${isVertical ? "" : "ml-auto"} ${sections.end.className || ""}`,
|
|
3548
|
+
children: sections.end.content
|
|
3549
|
+
}
|
|
3550
|
+
)
|
|
3237
3551
|
] });
|
|
3238
3552
|
};
|
|
3239
|
-
var NavHorizontalItems = (
|
|
3553
|
+
var NavHorizontalItems = (props) => /* @__PURE__ */ jsxRuntime.jsx(NavItems, { ...props, orientation: "horizontal" });
|
|
3240
3554
|
var NavHorizontal = ({
|
|
3241
3555
|
left,
|
|
3242
3556
|
leftNavItems,
|
|
@@ -3670,6 +3984,56 @@ var CitationRow = React23__namespace.forwardRef(
|
|
|
3670
3984
|
)
|
|
3671
3985
|
);
|
|
3672
3986
|
CitationRow.displayName = "CitationRow";
|
|
3987
|
+
var ClampedText = React23__namespace.forwardRef(
|
|
3988
|
+
({
|
|
3989
|
+
lines = 3,
|
|
3990
|
+
moreLabel = "Show more",
|
|
3991
|
+
lessLabel = "Show less",
|
|
3992
|
+
className,
|
|
3993
|
+
children,
|
|
3994
|
+
...props
|
|
3995
|
+
}, ref) => {
|
|
3996
|
+
const [expanded, setExpanded] = React23__namespace.useState(false);
|
|
3997
|
+
const [clipped, setClipped] = React23__namespace.useState(false);
|
|
3998
|
+
const bodyRef = React23__namespace.useRef(null);
|
|
3999
|
+
React23__namespace.useLayoutEffect(() => {
|
|
4000
|
+
const el = bodyRef.current;
|
|
4001
|
+
if (!el || expanded) return;
|
|
4002
|
+
const measure = () => setClipped(el.scrollHeight - el.clientHeight > 1);
|
|
4003
|
+
measure();
|
|
4004
|
+
const observer = new ResizeObserver(measure);
|
|
4005
|
+
observer.observe(el);
|
|
4006
|
+
return () => observer.disconnect();
|
|
4007
|
+
}, [expanded, children, lines]);
|
|
4008
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: cn("min-w-0", className), ...props, children: [
|
|
4009
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4010
|
+
"p",
|
|
4011
|
+
{
|
|
4012
|
+
ref: bodyRef,
|
|
4013
|
+
className: cn(
|
|
4014
|
+
"whitespace-pre-line",
|
|
4015
|
+
!expanded && "overflow-hidden [-webkit-box-orient:vertical] [-webkit-line-clamp:var(--clamped-lines)] [display:-webkit-box]"
|
|
4016
|
+
),
|
|
4017
|
+
style: { "--clamped-lines": lines },
|
|
4018
|
+
children
|
|
4019
|
+
}
|
|
4020
|
+
),
|
|
4021
|
+
clipped ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4022
|
+
Button,
|
|
4023
|
+
{
|
|
4024
|
+
type: "button",
|
|
4025
|
+
variant: "link",
|
|
4026
|
+
size: "sm",
|
|
4027
|
+
className: "h-auto p-0",
|
|
4028
|
+
"aria-expanded": expanded,
|
|
4029
|
+
onClick: () => setExpanded((open) => !open),
|
|
4030
|
+
children: expanded ? lessLabel : moreLabel
|
|
4031
|
+
}
|
|
4032
|
+
) : null
|
|
4033
|
+
] });
|
|
4034
|
+
}
|
|
4035
|
+
);
|
|
4036
|
+
ClampedText.displayName = "ClampedText";
|
|
3673
4037
|
var ClarifyCard = React23__namespace.forwardRef(
|
|
3674
4038
|
({
|
|
3675
4039
|
step,
|
|
@@ -4270,7 +4634,7 @@ var MetricGrid = React23__namespace.forwardRef(
|
|
|
4270
4634
|
)
|
|
4271
4635
|
);
|
|
4272
4636
|
MetricGrid.displayName = "MetricGrid";
|
|
4273
|
-
var NavVerticalItems = (
|
|
4637
|
+
var NavVerticalItems = (props) => /* @__PURE__ */ jsxRuntime.jsx(NavItems, { ...props, orientation: "vertical" });
|
|
4274
4638
|
var NavVertical = ({
|
|
4275
4639
|
className = "",
|
|
4276
4640
|
top,
|
|
@@ -4878,6 +5242,27 @@ var SearchInput = ({
|
|
|
4878
5242
|
}
|
|
4879
5243
|
);
|
|
4880
5244
|
};
|
|
5245
|
+
var Eyebrow = React23__namespace.forwardRef(
|
|
5246
|
+
({ aside, tone = "muted", className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5247
|
+
"div",
|
|
5248
|
+
{
|
|
5249
|
+
ref,
|
|
5250
|
+
className: cn(
|
|
5251
|
+
"flex items-baseline gap-2 text-meta font-semibold uppercase tracking-wide",
|
|
5252
|
+
tone === "muted" && "text-muted-foreground",
|
|
5253
|
+
tone === "foreground" && "text-foreground",
|
|
5254
|
+
tone === "accent" && "text-primary",
|
|
5255
|
+
className
|
|
5256
|
+
),
|
|
5257
|
+
...props,
|
|
5258
|
+
children: [
|
|
5259
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 truncate", children }),
|
|
5260
|
+
aside != null ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto shrink-0 font-normal normal-case tracking-normal text-muted-foreground", children: aside }) : null
|
|
5261
|
+
]
|
|
5262
|
+
}
|
|
5263
|
+
)
|
|
5264
|
+
);
|
|
5265
|
+
Eyebrow.displayName = "Eyebrow";
|
|
4881
5266
|
var SectionHeader = React23__namespace.forwardRef(({ icon, title, count, actions, bare, className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4882
5267
|
"div",
|
|
4883
5268
|
{
|
|
@@ -4975,6 +5360,9 @@ function TabbedPanel({
|
|
|
4975
5360
|
activeTab,
|
|
4976
5361
|
onTabChange,
|
|
4977
5362
|
headerActions,
|
|
5363
|
+
overflow = false,
|
|
5364
|
+
overflowLabel = "More panels",
|
|
5365
|
+
keepMounted = false,
|
|
4978
5366
|
className,
|
|
4979
5367
|
headerClassName,
|
|
4980
5368
|
bodyClassName,
|
|
@@ -4989,35 +5377,358 @@ function TabbedPanel({
|
|
|
4989
5377
|
}
|
|
4990
5378
|
onTabChange?.(value);
|
|
4991
5379
|
};
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
|
|
4995
|
-
|
|
5380
|
+
const uid = React23__namespace.default.useId();
|
|
5381
|
+
const panelId = (value) => `${uid}-panel-${value}`;
|
|
5382
|
+
const items = React23__namespace.default.useMemo(
|
|
5383
|
+
() => tabs.map((tab) => ({
|
|
5384
|
+
key: tab.value,
|
|
5385
|
+
name: tab.name ?? (typeof tab.label === "string" ? tab.label : tab.value),
|
|
5386
|
+
label: tab.label,
|
|
5387
|
+
icon: tab.icon,
|
|
5388
|
+
disabled: tab.disabled
|
|
5389
|
+
})),
|
|
5390
|
+
[tabs]
|
|
5391
|
+
);
|
|
5392
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: cn("flex h-full min-h-0 flex-col border rounded-none", className), children: [
|
|
5393
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5394
|
+
"div",
|
|
5395
|
+
{
|
|
5396
|
+
className: cn(
|
|
5397
|
+
"flex h-[30px] shrink-0 flex-row items-stretch border-b",
|
|
5398
|
+
headerClassName
|
|
5399
|
+
),
|
|
5400
|
+
children: [
|
|
5401
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5402
|
+
NavItems,
|
|
5403
|
+
{
|
|
5404
|
+
items,
|
|
5405
|
+
variant: "underline",
|
|
5406
|
+
selectionMode: "tabs",
|
|
5407
|
+
activeKey: currentTab,
|
|
5408
|
+
onActiveChange: handleTabChange,
|
|
5409
|
+
panelId,
|
|
5410
|
+
overflow,
|
|
5411
|
+
overflowLabel,
|
|
5412
|
+
className: "min-w-0 flex-1 gap-0",
|
|
5413
|
+
iconClassName: "h-3.5 w-3.5 shrink-0"
|
|
5414
|
+
}
|
|
5415
|
+
),
|
|
5416
|
+
headerActions && headerActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-auto flex h-full shrink-0 items-center gap-1 pr-1", children: /* @__PURE__ */ jsxRuntime.jsx(NavHorizontalItems, { items: headerActions }) })
|
|
5417
|
+
]
|
|
5418
|
+
}
|
|
5419
|
+
),
|
|
5420
|
+
tabs.map((tab) => {
|
|
5421
|
+
const active = tab.value === currentTab;
|
|
5422
|
+
if (!keepMounted && !active) return null;
|
|
5423
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5424
|
+
"div",
|
|
4996
5425
|
{
|
|
4997
|
-
|
|
4998
|
-
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
|
|
5003
|
-
]
|
|
5426
|
+
id: panelId(tab.value),
|
|
5427
|
+
role: "tabpanel",
|
|
5428
|
+
"aria-label": tab.name ?? (typeof tab.label === "string" ? tab.label : tab.value),
|
|
5429
|
+
hidden: !active,
|
|
5430
|
+
className: cn("m-0 min-h-0 flex-1 overflow-y-auto", bodyClassName),
|
|
5431
|
+
children: tab.content
|
|
5004
5432
|
},
|
|
5005
5433
|
tab.value
|
|
5006
|
-
)
|
|
5007
|
-
|
|
5434
|
+
);
|
|
5435
|
+
}),
|
|
5436
|
+
footerContent && /* @__PURE__ */ jsxRuntime.jsx(CardFooter, { className: cn("shrink-0", footerClassName), children: footerContent })
|
|
5437
|
+
] }) }) });
|
|
5438
|
+
}
|
|
5439
|
+
var BAR = {
|
|
5440
|
+
succeeded: "bg-success",
|
|
5441
|
+
running: "bg-info",
|
|
5442
|
+
failed: "bg-destructive",
|
|
5443
|
+
needs_input: "bg-warning",
|
|
5444
|
+
stopped: "bg-muted-foreground",
|
|
5445
|
+
skipped: "bg-transparent",
|
|
5446
|
+
queued: "bg-transparent"
|
|
5447
|
+
};
|
|
5448
|
+
var DOT = {
|
|
5449
|
+
succeeded: "success",
|
|
5450
|
+
running: "running",
|
|
5451
|
+
failed: "error",
|
|
5452
|
+
needs_input: "warning",
|
|
5453
|
+
stopped: "muted",
|
|
5454
|
+
skipped: "muted",
|
|
5455
|
+
queued: "queued"
|
|
5456
|
+
};
|
|
5457
|
+
var STATUS_LABEL = {
|
|
5458
|
+
succeeded: "succeeded",
|
|
5459
|
+
running: "running",
|
|
5460
|
+
failed: "failed",
|
|
5461
|
+
needs_input: "needs input",
|
|
5462
|
+
stopped: "stopped",
|
|
5463
|
+
skipped: "never ran",
|
|
5464
|
+
queued: "not started"
|
|
5465
|
+
};
|
|
5466
|
+
function renderResult(result) {
|
|
5467
|
+
if (result == null) return null;
|
|
5468
|
+
if (React23__namespace.isValidElement(result)) return result;
|
|
5469
|
+
if (typeof result !== "object") {
|
|
5470
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-meta", children: String(result) });
|
|
5471
|
+
}
|
|
5472
|
+
const entries = Object.entries(result);
|
|
5473
|
+
const scalars = entries.filter(([, v]) => v == null || typeof v !== "object");
|
|
5474
|
+
const nested = entries.filter(([, v]) => v != null && typeof v === "object");
|
|
5475
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5476
|
+
scalars.length ? /* @__PURE__ */ jsxRuntime.jsx(PropertyList, { labelWidth: 96, children: scalars.map(([k, v]) => /* @__PURE__ */ jsxRuntime.jsx(PropertyRow, { label: k, mono: true, className: "py-0.5", children: v == null ? "\u2014" : String(v) }, k)) }) : null,
|
|
5477
|
+
nested.map(([k, v]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [
|
|
5478
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-meta text-muted-foreground", children: k }),
|
|
5479
|
+
/* @__PURE__ */ jsxRuntime.jsx("pre", { className: "max-h-40 overflow-auto border border-border bg-muted/40 p-1.5 font-mono text-meta", children: JSON.stringify(v, null, 2) })
|
|
5480
|
+
] }, k))
|
|
5481
|
+
] });
|
|
5482
|
+
}
|
|
5483
|
+
var TaskGanttDetailCard = React23__namespace.forwardRef(({ task, elapsedMs, formatDuration = defaultFormatDuration, className, ...props }, ref) => {
|
|
5484
|
+
const status = task.status ?? "succeeded";
|
|
5485
|
+
const ms = task.durationMs ?? elapsedMs;
|
|
5486
|
+
const duration = task.duration ?? (ms != null ? formatDuration(ms) : "\u2014");
|
|
5487
|
+
const attempts = task.attempts ?? [];
|
|
5488
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: cn("flex flex-col gap-2", className), ...props, children: [
|
|
5489
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-2", children: [
|
|
5490
|
+
/* @__PURE__ */ jsxRuntime.jsx(StatusDot, { tone: DOT[status], size: "md", className: "translate-y-px" }),
|
|
5491
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate font-mono text-meta font-medium", children: task.key }),
|
|
5492
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 font-mono text-meta text-muted-foreground tabular-nums", children: duration })
|
|
5493
|
+
] }),
|
|
5494
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-meta text-muted-foreground", children: [
|
|
5495
|
+
STATUS_LABEL[status],
|
|
5496
|
+
task.summary != null ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5497
|
+
" \xB7 ",
|
|
5498
|
+
task.summary
|
|
5499
|
+
] }) : null
|
|
5008
5500
|
] }),
|
|
5009
|
-
|
|
5010
|
-
|
|
5501
|
+
attempts.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-0.5", children: attempts.map((a, i) => /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-meta text-muted-foreground", children: [
|
|
5502
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium text-warning", children: [
|
|
5503
|
+
"attempt ",
|
|
5504
|
+
i + 1
|
|
5505
|
+
] }),
|
|
5506
|
+
" ",
|
|
5507
|
+
a.title ?? `${a.status ?? "failed"}${a.durationMs != null ? ` \xB7 ${formatDuration(a.durationMs)}` : ""}`
|
|
5508
|
+
] }, i)) }) : null,
|
|
5509
|
+
task.error != null ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5510
|
+
"div",
|
|
5011
5511
|
{
|
|
5012
|
-
|
|
5013
|
-
className:
|
|
5014
|
-
children:
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5512
|
+
style: { borderColor: "var(--color-destructive)" },
|
|
5513
|
+
className: "border-l-2 bg-destructive/10 px-2 py-1.5",
|
|
5514
|
+
children: [
|
|
5515
|
+
task.error.code != null ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-mono text-meta font-medium text-destructive", children: task.error.code }) : null,
|
|
5516
|
+
task.error.message != null ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-meta", children: task.error.message }) : null,
|
|
5517
|
+
task.error.detail != null ? /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "mt-1 max-h-32 overflow-auto whitespace-pre-wrap font-mono text-meta text-muted-foreground", children: task.error.detail }) : null
|
|
5518
|
+
]
|
|
5519
|
+
}
|
|
5520
|
+
) : null,
|
|
5521
|
+
task.result != null ? renderResult(task.result) : null,
|
|
5522
|
+
task.log != null ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-border pt-1.5 font-mono text-meta text-muted-foreground", children: task.log }) : null
|
|
5523
|
+
] });
|
|
5524
|
+
});
|
|
5525
|
+
TaskGanttDetailCard.displayName = "TaskGanttDetailCard";
|
|
5526
|
+
var toMs = (t) => t instanceof Date ? t.getTime() : typeof t === "number" ? t : Date.parse(t);
|
|
5527
|
+
var defaultFormatDuration = (ms) => {
|
|
5528
|
+
if (ms < 100) return `${Math.round(ms)}ms`;
|
|
5529
|
+
const s = ms / 1e3;
|
|
5530
|
+
return s < 10 ? `${(Math.round(s * 10) / 10).toFixed(1)}s` : `${Math.round(s)}s`;
|
|
5531
|
+
};
|
|
5532
|
+
var defaultFormatTick = (ms) => {
|
|
5533
|
+
if (ms === 0) return "0s";
|
|
5534
|
+
const s = ms / 1e3;
|
|
5535
|
+
return Number.isInteger(s) ? `${s}s` : `${(Math.round(s * 10) / 10).toFixed(1)}s`;
|
|
5536
|
+
};
|
|
5537
|
+
function place(seg, origin) {
|
|
5538
|
+
let start = seg.startMs;
|
|
5539
|
+
if (start == null && seg.startedAt != null && origin != null) {
|
|
5540
|
+
start = toMs(seg.startedAt) - origin;
|
|
5541
|
+
}
|
|
5542
|
+
if (start == null || Number.isNaN(start)) return null;
|
|
5543
|
+
let duration = seg.durationMs;
|
|
5544
|
+
if (duration == null && seg.startedAt != null && seg.finishedAt != null) {
|
|
5545
|
+
duration = toMs(seg.finishedAt) - toMs(seg.startedAt);
|
|
5546
|
+
}
|
|
5547
|
+
return { start, duration: duration != null && duration > 0 ? duration : 0 };
|
|
5020
5548
|
}
|
|
5549
|
+
var TaskGantt = React23__namespace.forwardRef(
|
|
5550
|
+
({
|
|
5551
|
+
tasks,
|
|
5552
|
+
origin,
|
|
5553
|
+
spanMs,
|
|
5554
|
+
nowMs,
|
|
5555
|
+
openEnded,
|
|
5556
|
+
ticks = 4,
|
|
5557
|
+
formatTick = defaultFormatTick,
|
|
5558
|
+
formatDuration = defaultFormatDuration,
|
|
5559
|
+
labelWidth = 112,
|
|
5560
|
+
density = "comfortable",
|
|
5561
|
+
showDetail = true,
|
|
5562
|
+
renderDetail,
|
|
5563
|
+
detailProps,
|
|
5564
|
+
selectedKey,
|
|
5565
|
+
onSelectTask,
|
|
5566
|
+
className,
|
|
5567
|
+
...props
|
|
5568
|
+
}, ref) => {
|
|
5569
|
+
const barHeight = density === "compact" ? 11 : 13;
|
|
5570
|
+
const durationWidth = 40;
|
|
5571
|
+
const rows = React23__namespace.useMemo(() => {
|
|
5572
|
+
const stamps = [];
|
|
5573
|
+
for (const t of [...tasks, ...tasks.flatMap((t2) => t2.attempts ?? [])]) {
|
|
5574
|
+
if (t.startedAt != null) stamps.push(toMs(t.startedAt));
|
|
5575
|
+
}
|
|
5576
|
+
const zero = origin != null ? toMs(origin) : stamps.length ? Math.min(...stamps) : void 0;
|
|
5577
|
+
return tasks.map((task) => {
|
|
5578
|
+
const segments = [...task.attempts ?? [], task].map((seg) => {
|
|
5579
|
+
const at = place(seg, zero);
|
|
5580
|
+
return at ? { ...at, status: seg.status ?? task.status ?? "succeeded", title: seg.title } : null;
|
|
5581
|
+
}).filter((s) => s !== null);
|
|
5582
|
+
const last = segments[segments.length - 1];
|
|
5583
|
+
return { task, segments, end: last ? last.start + last.duration : 0 };
|
|
5584
|
+
});
|
|
5585
|
+
}, [tasks, origin]);
|
|
5586
|
+
const span = Math.max(
|
|
5587
|
+
spanMs ?? Math.max(nowMs ?? 0, ...rows.map((r) => r.end)),
|
|
5588
|
+
1
|
|
5589
|
+
);
|
|
5590
|
+
const pct = (ms) => `${Math.max(0, Math.min(100, ms / span * 100))}%`;
|
|
5591
|
+
const axis = Array.from(
|
|
5592
|
+
{ length: ticks + 1 },
|
|
5593
|
+
(_, i) => formatTick(span / ticks * i)
|
|
5594
|
+
);
|
|
5595
|
+
const lastLabel = openEnded ? `${axis[axis.length - 1]}+` : axis[axis.length - 1];
|
|
5596
|
+
const detailFor = (task, elapsedMs) => {
|
|
5597
|
+
if (!showDetail) return null;
|
|
5598
|
+
if (renderDetail) return renderDetail(task);
|
|
5599
|
+
if (task.detail != null) return task.detail;
|
|
5600
|
+
const hasBody = task.result != null || task.error != null || task.log != null || task.summary != null || (task.attempts?.length ?? 0) > 0;
|
|
5601
|
+
if (!hasBody) return null;
|
|
5602
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5603
|
+
TaskGanttDetailCard,
|
|
5604
|
+
{
|
|
5605
|
+
task,
|
|
5606
|
+
elapsedMs,
|
|
5607
|
+
formatDuration
|
|
5608
|
+
}
|
|
5609
|
+
);
|
|
5610
|
+
};
|
|
5611
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: cn("flex flex-col", className), ...props, children: [
|
|
5612
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 pt-0.5 pb-1", "aria-hidden": true, children: [
|
|
5613
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0", style: { width: labelWidth } }),
|
|
5614
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex flex-1", children: axis.slice(0, -1).map((label, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5615
|
+
"span",
|
|
5616
|
+
{
|
|
5617
|
+
className: "flex-1 border-l border-border pl-1 text-meta text-muted-foreground tabular-nums",
|
|
5618
|
+
children: label
|
|
5619
|
+
},
|
|
5620
|
+
i
|
|
5621
|
+
)) }),
|
|
5622
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5623
|
+
"span",
|
|
5624
|
+
{
|
|
5625
|
+
className: "shrink-0 text-right text-meta text-muted-foreground tabular-nums",
|
|
5626
|
+
style: { width: durationWidth },
|
|
5627
|
+
children: lastLabel
|
|
5628
|
+
}
|
|
5629
|
+
)
|
|
5630
|
+
] }),
|
|
5631
|
+
rows.map(({ task, segments }) => {
|
|
5632
|
+
const neverRan = segments.length === 0;
|
|
5633
|
+
const selected = selectedKey != null && selectedKey === task.key;
|
|
5634
|
+
const pickable = onSelectTask != null;
|
|
5635
|
+
const elapsed = task.durationMs ?? segments[segments.length - 1]?.duration;
|
|
5636
|
+
const duration = task.duration ?? (neverRan || elapsed == null ? "\u2014" : formatDuration(elapsed));
|
|
5637
|
+
const detail = detailFor(task, elapsed);
|
|
5638
|
+
const row = /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 py-[3px]", children: [
|
|
5639
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5640
|
+
"span",
|
|
5641
|
+
{
|
|
5642
|
+
className: cn(
|
|
5643
|
+
"shrink-0 truncate font-mono text-meta",
|
|
5644
|
+
neverRan && "text-muted-foreground"
|
|
5645
|
+
),
|
|
5646
|
+
style: { width: labelWidth },
|
|
5647
|
+
title: task.key,
|
|
5648
|
+
children: task.label ?? task.key
|
|
5649
|
+
}
|
|
5650
|
+
),
|
|
5651
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5652
|
+
"span",
|
|
5653
|
+
{
|
|
5654
|
+
className: "relative min-w-0 flex-1 bg-muted/55",
|
|
5655
|
+
style: { height: barHeight },
|
|
5656
|
+
children: [
|
|
5657
|
+
neverRan ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute inset-0 border border-dashed border-border" }) : segments.map((seg, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5658
|
+
"span",
|
|
5659
|
+
{
|
|
5660
|
+
title: seg.title ?? `${task.key} \xB7 ${seg.status} \xB7 ${formatDuration(seg.duration)}`,
|
|
5661
|
+
className: cn("absolute inset-y-0 rounded-[1px]", BAR[seg.status]),
|
|
5662
|
+
style: {
|
|
5663
|
+
left: pct(seg.start),
|
|
5664
|
+
width: pct(seg.duration),
|
|
5665
|
+
minWidth: 2
|
|
5666
|
+
}
|
|
5667
|
+
},
|
|
5668
|
+
i
|
|
5669
|
+
)),
|
|
5670
|
+
nowMs != null ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5671
|
+
"span",
|
|
5672
|
+
{
|
|
5673
|
+
className: "absolute -top-0.5 -bottom-0.5 w-px bg-info/70",
|
|
5674
|
+
style: { left: pct(nowMs) },
|
|
5675
|
+
"aria-hidden": true
|
|
5676
|
+
}
|
|
5677
|
+
) : null
|
|
5678
|
+
]
|
|
5679
|
+
}
|
|
5680
|
+
),
|
|
5681
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5682
|
+
"span",
|
|
5683
|
+
{
|
|
5684
|
+
className: "shrink-0 text-right font-mono text-meta text-muted-foreground tabular-nums",
|
|
5685
|
+
style: { width: durationWidth },
|
|
5686
|
+
children: duration
|
|
5687
|
+
}
|
|
5688
|
+
)
|
|
5689
|
+
] }) });
|
|
5690
|
+
const trigger = pickable ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5691
|
+
"button",
|
|
5692
|
+
{
|
|
5693
|
+
type: "button",
|
|
5694
|
+
"aria-pressed": selected,
|
|
5695
|
+
onClick: () => onSelectTask(task.key),
|
|
5696
|
+
className: cn(
|
|
5697
|
+
"w-full cursor-pointer text-left focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50",
|
|
5698
|
+
"hover:bg-accent/60",
|
|
5699
|
+
selected && "bg-accent"
|
|
5700
|
+
),
|
|
5701
|
+
children: row
|
|
5702
|
+
}
|
|
5703
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(detail != null && "hover:bg-accent/60"), children: row });
|
|
5704
|
+
if (detail == null) return /* @__PURE__ */ jsxRuntime.jsx("div", { children: trigger }, task.key);
|
|
5705
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5706
|
+
HoverCard,
|
|
5707
|
+
{
|
|
5708
|
+
openDelay: detailProps?.openDelay ?? 200,
|
|
5709
|
+
closeDelay: detailProps?.closeDelay ?? 80,
|
|
5710
|
+
children: [
|
|
5711
|
+
/* @__PURE__ */ jsxRuntime.jsx(HoverCardTrigger, { asChild: true, children: trigger }),
|
|
5712
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5713
|
+
HoverCardContent,
|
|
5714
|
+
{
|
|
5715
|
+
side: detailProps?.side ?? "right",
|
|
5716
|
+
align: detailProps?.align ?? "start",
|
|
5717
|
+
sideOffset: detailProps?.sideOffset ?? 8,
|
|
5718
|
+
style: detailProps?.width != null ? { width: detailProps.width } : void 0,
|
|
5719
|
+
className: cn("w-72 p-3", detailProps?.className),
|
|
5720
|
+
children: detail
|
|
5721
|
+
}
|
|
5722
|
+
)
|
|
5723
|
+
]
|
|
5724
|
+
},
|
|
5725
|
+
task.key
|
|
5726
|
+
);
|
|
5727
|
+
})
|
|
5728
|
+
] });
|
|
5729
|
+
}
|
|
5730
|
+
);
|
|
5731
|
+
TaskGantt.displayName = "TaskGantt";
|
|
5021
5732
|
var TemplatePicker = React23__namespace.forwardRef(({ heading, options, value, onSelect, footnote, className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5022
5733
|
"div",
|
|
5023
5734
|
{
|
|
@@ -5128,27 +5839,93 @@ var TerminalLine = React23__namespace.forwardRef(
|
|
|
5128
5839
|
)
|
|
5129
5840
|
);
|
|
5130
5841
|
TerminalLine.displayName = "TerminalLine";
|
|
5131
|
-
var
|
|
5842
|
+
var TimelineVariantContext = React23__namespace.createContext("columns");
|
|
5843
|
+
var RAIL_MARKER_OFFSET = "h-[0.692rem]";
|
|
5844
|
+
var RAIL_FOOTER_TAIL = "h-[1.067rem]";
|
|
5845
|
+
var TimelineList = React23__namespace.forwardRef(({ className, variant = "columns", children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(TimelineVariantContext.Provider, { value: variant, children: /* @__PURE__ */ jsxRuntime.jsx("ol", { ref, className: cn("flex flex-col", className), ...props, children }) }));
|
|
5132
5846
|
TimelineList.displayName = "TimelineList";
|
|
5133
|
-
|
|
5134
|
-
"
|
|
5135
|
-
|
|
5136
|
-
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
|
|
5147
|
-
|
|
5148
|
-
|
|
5847
|
+
function RailGutter({ marker }) {
|
|
5848
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex w-2.5 shrink-0 flex-col items-center", children: [
|
|
5849
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5850
|
+
"span",
|
|
5851
|
+
{
|
|
5852
|
+
"aria-hidden": true,
|
|
5853
|
+
className: cn(
|
|
5854
|
+
"w-px shrink-0 bg-border group-first/entry:bg-transparent",
|
|
5855
|
+
RAIL_MARKER_OFFSET
|
|
5856
|
+
)
|
|
5857
|
+
}
|
|
5858
|
+
),
|
|
5859
|
+
marker,
|
|
5860
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5861
|
+
"span",
|
|
5862
|
+
{
|
|
5863
|
+
"aria-hidden": true,
|
|
5864
|
+
className: "w-px flex-1 bg-border group-last/entry:bg-transparent"
|
|
5865
|
+
}
|
|
5866
|
+
)
|
|
5867
|
+
] });
|
|
5868
|
+
}
|
|
5869
|
+
var TimelineEntry = React23__namespace.forwardRef(({ when, title, marker, className, children, ...props }, ref) => {
|
|
5870
|
+
const variant = React23__namespace.useContext(TimelineVariantContext);
|
|
5871
|
+
if (variant === "rail") {
|
|
5872
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5873
|
+
"li",
|
|
5874
|
+
{
|
|
5875
|
+
ref,
|
|
5876
|
+
className: cn("group/entry flex gap-2.5", className),
|
|
5877
|
+
...props,
|
|
5878
|
+
children: [
|
|
5879
|
+
/* @__PURE__ */ jsxRuntime.jsx(RailGutter, { marker }),
|
|
5880
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5 pb-4 group-last/entry:pb-0", children: [
|
|
5881
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-meta text-muted-foreground", children: when }),
|
|
5882
|
+
title != null ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: title }) : null,
|
|
5883
|
+
children
|
|
5884
|
+
] })
|
|
5885
|
+
]
|
|
5886
|
+
}
|
|
5887
|
+
);
|
|
5149
5888
|
}
|
|
5150
|
-
|
|
5889
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5890
|
+
"li",
|
|
5891
|
+
{
|
|
5892
|
+
ref,
|
|
5893
|
+
className: cn("flex gap-2 border-b border-border py-1.5 last:border-b-0", className),
|
|
5894
|
+
...props,
|
|
5895
|
+
children: [
|
|
5896
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex w-[72px] shrink-0 items-baseline gap-1.5 text-meta text-muted-foreground", children: [
|
|
5897
|
+
marker ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "translate-y-1", children: marker }) : null,
|
|
5898
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: when })
|
|
5899
|
+
] }),
|
|
5900
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
|
|
5901
|
+
title != null ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: title }) : null,
|
|
5902
|
+
children
|
|
5903
|
+
] })
|
|
5904
|
+
]
|
|
5905
|
+
}
|
|
5906
|
+
);
|
|
5907
|
+
});
|
|
5151
5908
|
TimelineEntry.displayName = "TimelineEntry";
|
|
5909
|
+
var TimelineFooter = React23__namespace.forwardRef(({ className, children, ...props }, ref) => {
|
|
5910
|
+
const variant = React23__namespace.useContext(TimelineVariantContext);
|
|
5911
|
+
if (variant === "rail") {
|
|
5912
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5913
|
+
"li",
|
|
5914
|
+
{
|
|
5915
|
+
ref,
|
|
5916
|
+
role: "presentation",
|
|
5917
|
+
className: cn("flex gap-2.5", className),
|
|
5918
|
+
...props,
|
|
5919
|
+
children: [
|
|
5920
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex w-2.5 shrink-0 justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: cn("w-px bg-border", RAIL_FOOTER_TAIL) }) }),
|
|
5921
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 flex-1 pt-1.5", children })
|
|
5922
|
+
]
|
|
5923
|
+
}
|
|
5924
|
+
);
|
|
5925
|
+
}
|
|
5926
|
+
return /* @__PURE__ */ jsxRuntime.jsx("li", { ref, role: "presentation", className: cn("pt-1.5", className), ...props, children });
|
|
5927
|
+
});
|
|
5928
|
+
TimelineFooter.displayName = "TimelineFooter";
|
|
5152
5929
|
var Toolbar = () => {
|
|
5153
5930
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-5 items-center space-x-2", children: [
|
|
5154
5931
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -5802,6 +6579,7 @@ exports.ChatSessionTaskRow = ChatSessionTaskRow;
|
|
|
5802
6579
|
exports.CitationList = CitationList;
|
|
5803
6580
|
exports.CitationMarker = CitationMarker;
|
|
5804
6581
|
exports.CitationRow = CitationRow;
|
|
6582
|
+
exports.ClampedText = ClampedText;
|
|
5805
6583
|
exports.ClarifyCard = ClarifyCard;
|
|
5806
6584
|
exports.Command = Command;
|
|
5807
6585
|
exports.CommandDialog = CommandDialog;
|
|
@@ -5848,6 +6626,7 @@ exports.EmissionHeader = EmissionHeader;
|
|
|
5848
6626
|
exports.EmptyState = EmptyState;
|
|
5849
6627
|
exports.EmptyStateLock = EmptyStateLock;
|
|
5850
6628
|
exports.ErrorBoundary = ErrorBoundary;
|
|
6629
|
+
exports.Eyebrow = Eyebrow;
|
|
5851
6630
|
exports.FilterBar = FilterBar;
|
|
5852
6631
|
exports.FilterChip = FilterChip;
|
|
5853
6632
|
exports.HeatStrip = HeatStrip;
|
|
@@ -5980,10 +6759,13 @@ exports.Tabs = Tabs;
|
|
|
5980
6759
|
exports.TabsContent = TabsContent;
|
|
5981
6760
|
exports.TabsList = TabsList;
|
|
5982
6761
|
exports.TabsTrigger = TabsTrigger;
|
|
6762
|
+
exports.TaskGantt = TaskGantt;
|
|
6763
|
+
exports.TaskGanttDetailCard = TaskGanttDetailCard;
|
|
5983
6764
|
exports.TemplatePicker = TemplatePicker;
|
|
5984
6765
|
exports.Terminal = Terminal;
|
|
5985
6766
|
exports.TerminalLine = TerminalLine;
|
|
5986
6767
|
exports.TimelineEntry = TimelineEntry;
|
|
6768
|
+
exports.TimelineFooter = TimelineFooter;
|
|
5987
6769
|
exports.TimelineList = TimelineList;
|
|
5988
6770
|
exports.Toaster = Toaster;
|
|
5989
6771
|
exports.Toggle = Toggle;
|
|
@@ -6023,6 +6805,7 @@ exports.cn = cn;
|
|
|
6023
6805
|
exports.navigationMenuTriggerStyle = navigationMenuTriggerStyle;
|
|
6024
6806
|
exports.statusDotVariants = statusDotVariants;
|
|
6025
6807
|
exports.toggleVariants = toggleVariants;
|
|
6808
|
+
exports.useOverflowItems = useOverflowItems;
|
|
6026
6809
|
exports.useSidebar = useSidebar;
|
|
6027
6810
|
exports.useTour = useTour;
|
|
6028
6811
|
//# sourceMappingURL=index.cjs.map
|