@arbidocs/blocks 0.3.154 → 0.3.155

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.js CHANGED
@@ -1,8 +1,8 @@
1
- import { formatPageRefs, tid, initials, fromNow, fmtDate, assetRefId, applyStoredTheme, AssetResolverProvider, ThemeEditor, applyThemeVars, SectionHeading, PricingTable, Tabs as Tabs$1, Accordion, Gallery, VideoEmbed, ContactForm, Banner, MediaText, TeamGrid, Steps, TestimonialGrid, Columns, Spacer, Container, Hero, FeatureGrid, Testimonial, CTABanner, LogoCloud, FAQ, Timeline, RichTextBlock, Callout, BlockImage, AvatarBlock, Navbar, Footer, ListBlock, isAssetRef, asAssetRef } from './chunk-4QUW423J.js';
2
- export { ASSET_REF_PREFIX, Accordion, AssetResolverProvider, AvatarBlock, Banner, BlockImage, BlockLink, CTABanner, Callout, Columns, ContactForm, Container, FAQ, FONT_PAIRINGS, FeatureGrid, Footer, Gallery, Hero, ListBlock, LogoCloud, MediaText, Navbar, PricingTable, RichTextBlock, SectionHeading, Spacer, Steps, THEME_STYLE_ID, Tabs, TeamGrid, Testimonial, TestimonialGrid, ThemeEditor, Timeline, TimelineCalendar, TimelineGantt, VideoEmbed, applyFontVars, applyStoredTheme, applyThemeVars, asAssetRef, assetRefId, clearFontVars, clearThemeVars, createThemeStore, dayKey, daysUntil, fmtDate, fmtDateTime, fontPackages, formatPageRefs, formatSpan, fromNow, gbp, getFontPairing, hrs, initials, isAssetRef, matchFontPairing, monthLabel, parseIso, pct, tid, toEmbedUrl, toHslTriplet, useAssetRenderer, useAssetResolverActive, utcDay } from './chunk-4QUW423J.js';
1
+ import { formatPageRefs, tid, initials, fromNow, fmtDate, assetRefId, applyStoredTheme, AssetResolverProvider, ThemeEditor, applyThemeVars, SectionHeading, PricingTable, Tabs as Tabs$1, Accordion, Gallery, VideoEmbed, ContactForm, Banner, MediaText, TeamGrid, Steps, TestimonialGrid, Columns, Spacer, Container, Hero, FeatureGrid, Testimonial, CTABanner, LogoCloud, FAQ, Timeline, RichTextBlock, Callout, BlockImage, AvatarBlock, Navbar, Footer, ListBlock, isAssetRef, asAssetRef } from './chunk-27Q4AST5.js';
2
+ export { ASSET_REF_PREFIX, Accordion, AssetResolverProvider, AvatarBlock, Banner, BlockImage, BlockLink, CTABanner, Callout, Columns, ContactForm, Container, FAQ, FONT_PAIRINGS, FeatureGrid, Footer, Gallery, Hero, ListBlock, LogoCloud, MediaText, Navbar, PricingTable, RichTextBlock, SectionHeading, Spacer, Steps, THEME_STYLE_ID, Tabs, TeamGrid, Testimonial, TestimonialGrid, ThemeEditor, Timeline, TimelineCalendar, TimelineGantt, VideoEmbed, applyFontVars, applyStoredTheme, applyThemeVars, asAssetRef, assetRefId, clearFontVars, clearThemeVars, createThemeStore, dayKey, daysUntil, fmtDate, fmtDateTime, fontPackages, formatPageRefs, formatSpan, fromNow, gbp, getFontPairing, hrs, initials, isAssetRef, matchFontPairing, monthLabel, parseIso, pct, tid, toEmbedUrl, toHslTriplet, useAssetRenderer, useAssetResolverActive, utcDay } from './chunk-27Q4AST5.js';
3
3
  import { createContext, useState, useRef, useEffect, useMemo, useCallback, useContext } from 'react';
4
- import { MessageSquare, Cpu, Code, Cloud, Layers, Target, Award, MapPin, Phone, Mail, Lock, Globe, Heart, Star, Rocket, Shield, Zap, Sparkles, Gavel, Scale, Bell, Activity, BarChart3, DollarSign, TrendingUp, Info, AlertCircle, CheckCircle, Clock, Calendar, Briefcase, Users, Folder, FileText, X, Loader2, UploadCloud, Search, ArrowUpRight, ArrowDownRight, FolderLock, CheckCircle2, ArrowLeftRight, MessagesSquare, Menu, ArrowLeft, Palette, RotateCcw, ChevronUp, ChevronDown, BrainCircuit, Bot, LayoutGrid, FileJson, Download, Crop, ImagePlus, Upload, Link2, Check } from 'lucide-react';
5
- import { cn, DocumentEntity, useArbi, ArbiProvider, useAiTask, useWorkspaceDocs as useWorkspaceDocs$1, useSemanticSearch as useSemanticSearch$1, Table, TableHeader, TableRow, TableHead, TableBody, TableCell, Input, Card, CardHeader, CardTitle, CardDescription, CardContent, Tooltip, TooltipTrigger, TooltipContent, CardFooter, Avatar, AvatarImage, AvatarFallback, TooltipProvider, Button, NotificationBell, UserMenu, useThumbnails, Badge, Switch, useConfigs, useAgents, Checkbox, Tabs, TabsList, TabsTrigger, TabsContent, Separator, ArbiWebSocketProvider, useDocuments, ImageCropModal, DEFAULT_ASPECT_OPTIONS, useConversations } from '@arbidocs/react';
4
+ import { MessageSquare, Cpu, Code, Cloud, Layers, Target, Award, MapPin, Phone, Mail, Lock, Globe, Heart, Star, Rocket, Shield, Zap, Sparkles, Gavel, Scale, Bell, Activity, BarChart3, DollarSign, TrendingUp, Info, AlertCircle, CheckCircle, Clock, Calendar, Briefcase, Users, Folder, FileText, X, Loader2, UploadCloud, Search, Pencil, ChevronDown, ArrowUpRight, ArrowDownRight, ChevronRight, Plus, FolderLock, CheckCircle2, ArrowLeftRight, MessagesSquare, Menu, ArrowLeft, Palette, RotateCcw, ChevronUp, BrainCircuit, Bot, LayoutGrid, FileJson, Download, Crop, ImagePlus, Upload, Link2, Check } from 'lucide-react';
5
+ import { cn, DocumentEntity, useArbi, ArbiProvider, useAiTask, useWorkspaceDocs as useWorkspaceDocs$1, useSemanticSearch as useSemanticSearch$1, Table, TableHeader, TableRow, TableHead, TableBody, TableCell, Input, Textarea, Avatar, AvatarImage, AvatarFallback, Card, Button, CardHeader, CardTitle, CardDescription, CardContent, Tooltip, TooltipTrigger, TooltipContent, CardFooter, TooltipProvider, NotificationBell, UserMenu, useThumbnails, Badge, Switch, useConfigs, useAgents, Checkbox, Tabs, TabsList, TabsTrigger, TabsContent, Separator, ArbiWebSocketProvider, useDocuments, ImageCropModal, DEFAULT_ASPECT_OPTIONS, useConversations } from '@arbidocs/react';
6
6
  export { DocumentCard, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, redlineStats, textToArtifact, toRedlineMarkdown } from '@arbidocs/react';
7
7
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
8
8
  import { QueryClient, QueryClientProvider, useQuery, useQueryClient } from '@tanstack/react-query';
@@ -1179,6 +1179,203 @@ function Toolbar({
1179
1179
  }
1180
1180
  );
1181
1181
  }
1182
+ var IDENTITY_NAME_MAX_LENGTH = 50;
1183
+ var COUNTER_THRESHOLD = 10;
1184
+ function EntityIdentityBar({
1185
+ fields,
1186
+ extraRows = [],
1187
+ canEdit = false,
1188
+ actions,
1189
+ footer,
1190
+ className,
1191
+ testId
1192
+ }) {
1193
+ return /* @__PURE__ */ jsxs(
1194
+ "div",
1195
+ {
1196
+ className: cn("flex flex-wrap items-start justify-between gap-x-6 gap-y-3", className),
1197
+ "data-testid": testId,
1198
+ children: [
1199
+ /* @__PURE__ */ jsxs("dl", { className: "min-w-0 flex-1 space-y-1.5", children: [
1200
+ fields.map((field) => /* @__PURE__ */ jsx(IdentityFieldRow, { field, canEdit }, field.label)),
1201
+ extraRows.map((row) => /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-2", "data-testid": row.testId, children: [
1202
+ /* @__PURE__ */ jsxs("dt", { className: "w-24 shrink-0 text-xs font-medium text-muted-foreground", children: [
1203
+ row.label,
1204
+ ":"
1205
+ ] }),
1206
+ /* @__PURE__ */ jsxs("dd", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
1207
+ row.content,
1208
+ row.trailing ? /* @__PURE__ */ jsx("div", { className: "ml-auto shrink-0", children: row.trailing }) : null
1209
+ ] })
1210
+ ] }, row.label)),
1211
+ footer ? /* @__PURE__ */ jsx("div", { className: "flex items-center pt-0.5", children: footer }) : null
1212
+ ] }),
1213
+ actions ? /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center gap-2", children: actions }) : null
1214
+ ]
1215
+ }
1216
+ );
1217
+ }
1218
+ function IdentityFieldRow({ field, canEdit }) {
1219
+ const {
1220
+ label,
1221
+ value,
1222
+ placeholder,
1223
+ onSave,
1224
+ multiline = false,
1225
+ maxLength,
1226
+ valueClassName,
1227
+ trailing,
1228
+ testId
1229
+ } = field;
1230
+ const [isEditing, setIsEditing] = useState(false);
1231
+ const [draft, setDraft] = useState(value);
1232
+ useEffect(() => {
1233
+ if (!isEditing) setDraft(value);
1234
+ }, [value, isEditing]);
1235
+ const commit = () => {
1236
+ setIsEditing(false);
1237
+ const next = draft.trim();
1238
+ if (next !== value) onSave(next);
1239
+ };
1240
+ const cancel = () => {
1241
+ setDraft(value);
1242
+ setIsEditing(false);
1243
+ };
1244
+ const charsLeft = maxLength === void 0 ? null : maxLength - draft.length;
1245
+ const fieldClass = "h-auto rounded border-0 bg-muted px-1.5 py-0.5 shadow-none focus-visible:ring-0 focus-visible:ring-offset-0";
1246
+ const shared = {
1247
+ autoFocus: true,
1248
+ value: draft,
1249
+ placeholder,
1250
+ maxLength,
1251
+ "aria-label": label,
1252
+ "data-testid": testId && `${testId}-input`,
1253
+ onBlur: commit,
1254
+ onChange: (e) => setDraft(e.target.value),
1255
+ onKeyDown: (e) => {
1256
+ if (e.key === "Escape") {
1257
+ e.preventDefault();
1258
+ cancel();
1259
+ } else if (e.key === "Enter" && !multiline) {
1260
+ e.preventDefault();
1261
+ commit();
1262
+ }
1263
+ }
1264
+ };
1265
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex min-w-0 gap-2", multiline ? "items-start" : "items-center"), children: [
1266
+ /* @__PURE__ */ jsxs(
1267
+ "dt",
1268
+ {
1269
+ className: cn(
1270
+ "w-24 shrink-0 text-xs font-medium text-muted-foreground",
1271
+ multiline && "pt-1"
1272
+ ),
1273
+ children: [
1274
+ label,
1275
+ ":"
1276
+ ]
1277
+ }
1278
+ ),
1279
+ /* @__PURE__ */ jsxs("dd", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
1280
+ isEditing ? /* @__PURE__ */ jsxs("div", { className: "relative min-w-0 flex-1", children: [
1281
+ multiline ? /* @__PURE__ */ jsx(
1282
+ Textarea,
1283
+ {
1284
+ ...shared,
1285
+ rows: 2,
1286
+ className: cn(fieldClass, "min-h-0 resize-none text-sm leading-snug")
1287
+ }
1288
+ ) : /* @__PURE__ */ jsx(
1289
+ Input,
1290
+ {
1291
+ ...shared,
1292
+ className: cn(fieldClass, "pr-20 text-xl font-semibold tracking-tight")
1293
+ }
1294
+ ),
1295
+ charsLeft !== null && charsLeft <= COUNTER_THRESHOLD && /* @__PURE__ */ jsx(
1296
+ "span",
1297
+ {
1298
+ className: cn(
1299
+ "pointer-events-none absolute right-3 top-1/2 hidden -translate-y-1/2 text-sm lg:block",
1300
+ charsLeft < 0 ? "text-destructive" : "text-muted-foreground"
1301
+ ),
1302
+ "data-testid": testId && `${testId}-counter`,
1303
+ children: charsLeft < 0 ? `${-charsLeft} over` : `${charsLeft} left`
1304
+ }
1305
+ )
1306
+ ] }) : /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-1.5", children: [
1307
+ /* @__PURE__ */ jsx("span", { className: cn("px-1.5 py-0.5", valueClassName), "data-testid": testId, children: value || /* @__PURE__ */ jsx("span", { className: "italic text-muted-foreground", children: placeholder }) }),
1308
+ canEdit && /* @__PURE__ */ jsx(
1309
+ "button",
1310
+ {
1311
+ type: "button",
1312
+ onClick: () => setIsEditing(true),
1313
+ "aria-label": `Edit ${label.toLowerCase()}`,
1314
+ title: `Edit ${label.toLowerCase()}`,
1315
+ className: "shrink-0 cursor-pointer rounded p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
1316
+ "data-testid": testId && `${testId}-edit`,
1317
+ children: /* @__PURE__ */ jsx(Pencil, { className: "size-3.5" })
1318
+ }
1319
+ )
1320
+ ] }),
1321
+ trailing ? /* @__PURE__ */ jsx("div", { className: "ml-auto shrink-0", children: trailing }) : null
1322
+ ] })
1323
+ ] });
1324
+ }
1325
+ var MAX_DEFAULT = 3;
1326
+ function MemberAvatarStack({
1327
+ members,
1328
+ total,
1329
+ max = MAX_DEFAULT,
1330
+ hidden = false,
1331
+ onClick,
1332
+ expanded = false,
1333
+ ringClassName = "border-card",
1334
+ className,
1335
+ testId
1336
+ }) {
1337
+ const count = total ?? members.length;
1338
+ const shown = hidden ? [] : members.slice(0, max);
1339
+ const extra = count - shown.length;
1340
+ const faces = /* @__PURE__ */ jsxs(Fragment, { children: [
1341
+ hidden ? /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: "\u2014" }) : shown.map((m, i) => /* @__PURE__ */ jsxs(Avatar, { className: cn("size-6 border-2", ringClassName), title: m.name, children: [
1342
+ m.picture && /* @__PURE__ */ jsx(AvatarImage, { src: m.picture, alt: m.name }),
1343
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "bg-foreground text-[9px] font-medium text-background", children: initials(m.name || "?") })
1344
+ ] }, i)),
1345
+ !hidden && extra > 0 && /* @__PURE__ */ jsx(Avatar, { className: cn("size-6 border-2", ringClassName), children: /* @__PURE__ */ jsxs(AvatarFallback, { className: "bg-accent text-[9px] font-medium text-muted-foreground", children: [
1346
+ "+",
1347
+ extra
1348
+ ] }) })
1349
+ ] });
1350
+ if (!onClick) {
1351
+ return /* @__PURE__ */ jsx("div", { className: cn("flex shrink-0 -space-x-2", className), "data-testid": testId, children: faces });
1352
+ }
1353
+ return /* @__PURE__ */ jsxs(
1354
+ "button",
1355
+ {
1356
+ type: "button",
1357
+ onClick,
1358
+ "aria-expanded": expanded,
1359
+ className: cn(
1360
+ "flex shrink-0 cursor-pointer items-center gap-1.5 rounded-full py-0.5 pl-0.5 pr-1.5 transition-colors hover:bg-accent/60",
1361
+ className
1362
+ ),
1363
+ "data-testid": testId,
1364
+ children: [
1365
+ /* @__PURE__ */ jsx("span", { className: "flex -space-x-2", children: faces }),
1366
+ /* @__PURE__ */ jsx(
1367
+ ChevronDown,
1368
+ {
1369
+ className: cn(
1370
+ "size-3.5 text-muted-foreground transition-transform",
1371
+ expanded && "rotate-180"
1372
+ )
1373
+ }
1374
+ )
1375
+ ]
1376
+ }
1377
+ );
1378
+ }
1182
1379
  function MetricCard({
1183
1380
  label,
1184
1381
  value,
@@ -1221,6 +1418,142 @@ function MetricCard({
1221
1418
  ] })
1222
1419
  ] });
1223
1420
  }
1421
+ function RecentActivityCard({
1422
+ icon: Icon,
1423
+ title,
1424
+ count,
1425
+ onOpen,
1426
+ actionLabel,
1427
+ actionIcon: ActionIcon,
1428
+ onAction,
1429
+ rows,
1430
+ caption,
1431
+ emptyText,
1432
+ emptyActionLabel,
1433
+ className,
1434
+ testId
1435
+ }) {
1436
+ return /* @__PURE__ */ jsxs(
1437
+ Card,
1438
+ {
1439
+ variant: "flat",
1440
+ className: cn(
1441
+ // Grows to its content. The card must NOT scroll internally: a list
1442
+ // scrolling inside a fixed-height card puts a scrollbar in the middle
1443
+ // of the page, where every other page in the app scrolls at its outer
1444
+ // edge. The page is the scroll container; the card is just tall.
1445
+ "card-hover flex flex-col overflow-hidden rounded-xl bg-card p-0 shadow-sm",
1446
+ className
1447
+ ),
1448
+ "data-testid": testId,
1449
+ children: [
1450
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 px-2 pt-2", children: [
1451
+ /* @__PURE__ */ jsxs(
1452
+ "button",
1453
+ {
1454
+ type: "button",
1455
+ onClick: onOpen,
1456
+ disabled: !onOpen,
1457
+ className: "group flex min-w-0 flex-1 cursor-pointer items-center gap-2 rounded-lg px-2 py-1.5 text-left transition-colors hover:bg-primary/10 disabled:cursor-default disabled:hover:bg-transparent",
1458
+ "data-testid": testId && `${testId}-open`,
1459
+ children: [
1460
+ Icon && /* @__PURE__ */ jsx(Icon, { className: "size-4 shrink-0 text-muted-foreground" }),
1461
+ /* @__PURE__ */ jsx("span", { className: "whitespace-nowrap text-sm font-semibold text-foreground", children: title }),
1462
+ count !== void 0 && /* @__PURE__ */ jsx("span", { className: "text-xs tabular-nums text-muted-foreground", children: count }),
1463
+ onOpen && /* @__PURE__ */ jsx(ChevronRight, { className: "ml-auto size-4 shrink-0 text-muted-foreground/50 transition-transform group-hover:translate-x-0.5 group-hover:text-foreground" })
1464
+ ]
1465
+ }
1466
+ ),
1467
+ actionLabel ? /* @__PURE__ */ jsxs(
1468
+ Button,
1469
+ {
1470
+ variant: "ghost",
1471
+ size: "sm",
1472
+ className: "h-8 shrink-0 px-2 text-xs font-medium text-muted-foreground hover:text-foreground",
1473
+ onClick: onAction,
1474
+ title: actionLabel,
1475
+ "data-testid": testId && `${testId}-action`,
1476
+ children: [
1477
+ ActionIcon && /* @__PURE__ */ jsx(ActionIcon, { className: "size-3.5" }),
1478
+ /* @__PURE__ */ jsx("span", { className: "sr-only @md:not-sr-only @md:ml-1.5", children: actionLabel })
1479
+ ]
1480
+ }
1481
+ ) : null
1482
+ ] }),
1483
+ rows.length === 0 ? onAction ? (
1484
+ // The whole empty area is the button. A muted sentence in a big void
1485
+ // tells you the card is empty; this tells you what to do about it.
1486
+ /* @__PURE__ */ jsxs(
1487
+ "button",
1488
+ {
1489
+ type: "button",
1490
+ onClick: onAction,
1491
+ className: "group m-3 flex flex-1 cursor-pointer flex-col items-center justify-center gap-2 rounded-lg border-2 border-dashed border-border px-4 text-center transition-colors hover:border-primary/40 hover:bg-primary/5 focus-visible:border-primary/40 focus-visible:bg-primary/5 focus-visible:outline-none",
1492
+ "data-testid": testId && `${testId}-empty-action`,
1493
+ children: [
1494
+ /* @__PURE__ */ jsx("span", { className: "flex size-11 items-center justify-center rounded-full bg-primary/10 text-primary transition-colors group-hover:bg-primary group-hover:text-primary-foreground", children: ActionIcon ? /* @__PURE__ */ jsx(ActionIcon, { className: "size-5" }) : /* @__PURE__ */ jsx(Plus, { className: "size-5" }) }),
1495
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-foreground", children: emptyActionLabel ?? actionLabel }),
1496
+ /* @__PURE__ */ jsx("span", { className: "text-xs leading-relaxed text-muted-foreground", children: emptyText })
1497
+ ]
1498
+ }
1499
+ )
1500
+ ) : /* @__PURE__ */ jsx("p", { className: "flex flex-1 items-center px-4 py-6 text-xs leading-relaxed text-muted-foreground", children: emptyText }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1501
+ caption && // A caption, so the list says what it is instead of leaving you to
1502
+ // infer it from the order.
1503
+ /* @__PURE__ */ jsx(
1504
+ "p",
1505
+ {
1506
+ className: "mt-1 px-4 pb-1 text-[11px] font-medium uppercase tracking-wide text-muted-foreground",
1507
+ "data-testid": testId && `${testId}-caption`,
1508
+ children: caption
1509
+ }
1510
+ ),
1511
+ /* @__PURE__ */ jsx("ul", { className: "flex-1", children: rows.map((row) => /* @__PURE__ */ jsxs(
1512
+ "li",
1513
+ {
1514
+ className: cn(
1515
+ "group relative flex items-center border-b border-border/60 transition-colors last:border-b-0",
1516
+ // A row is a link to somewhere, so hovering it has to look
1517
+ // like one. A 40%-alpha accent wash was too faint to read as
1518
+ // an affordance at all — this is a definite tint plus an
1519
+ // accent bar down the leading edge.
1520
+ "hover:bg-primary/10 has-[button:focus-visible]:bg-primary/10",
1521
+ "before:absolute before:inset-y-0 before:left-0 before:w-0.5 before:bg-primary before:opacity-0 before:transition-opacity hover:before:opacity-100"
1522
+ ),
1523
+ children: [
1524
+ /* @__PURE__ */ jsxs(
1525
+ "button",
1526
+ {
1527
+ type: "button",
1528
+ onClick: row.onClick,
1529
+ title: row.title,
1530
+ className: cn(
1531
+ "flex min-w-0 flex-1 items-start gap-3 py-2.5 pl-4 pr-2 text-left focus-visible:outline-none",
1532
+ row.onClick && "cursor-pointer"
1533
+ ),
1534
+ "data-testid": testId && `${testId}-row`,
1535
+ children: [
1536
+ row.leading,
1537
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
1538
+ /* @__PURE__ */ jsx("span", { className: "block truncate text-sm font-semibold text-foreground group-hover:text-primary", children: row.title }),
1539
+ /* @__PURE__ */ jsxs("div", { className: "mt-0.5 flex items-center gap-1.5", children: [
1540
+ /* @__PURE__ */ jsx("p", { className: "min-w-0 flex-1 truncate text-xs text-muted-foreground", children: row.subtitle }),
1541
+ !row.trailing && row.meta && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: row.meta })
1542
+ ] })
1543
+ ] })
1544
+ ]
1545
+ }
1546
+ ),
1547
+ row.trailing ? /* @__PURE__ */ jsx("div", { className: "shrink-0 pr-3", children: row.trailing }) : null
1548
+ ]
1549
+ },
1550
+ row.id
1551
+ )) })
1552
+ ] })
1553
+ ]
1554
+ }
1555
+ );
1556
+ }
1224
1557
  var MAX_AVATARS = 3;
1225
1558
  function WorkspaceCard({
1226
1559
  name,
@@ -1245,8 +1578,6 @@ function WorkspaceCard({
1245
1578
  className
1246
1579
  }) {
1247
1580
  const totalMembers = memberCount ?? members.length;
1248
- const shownMembers = membersHidden ? [] : members.slice(0, MAX_AVATARS);
1249
- const extraMembers = totalMembers - shownMembers.length;
1250
1581
  const actionTestId = buttonTestId ?? (testId ? `${testId}-open` : void 0);
1251
1582
  const canOpen = Boolean(onOpen) && !busy;
1252
1583
  const [isHoverPointerActive, setIsHoverPointerActive] = useState(false);
@@ -1399,21 +1730,15 @@ function WorkspaceCard({
1399
1730
  )
1400
1731
  ] })
1401
1732
  ] }),
1402
- /* @__PURE__ */ jsxs(
1403
- "div",
1733
+ /* @__PURE__ */ jsx(
1734
+ MemberAvatarStack,
1404
1735
  {
1405
- className: "ml-auto flex shrink-0 -space-x-2",
1406
- "data-testid": testId && `${testId}-member-avatars`,
1407
- children: [
1408
- shownMembers.map((m, i) => /* @__PURE__ */ jsxs(Avatar, { className: "size-6 border-2 border-card", title: m.name, children: [
1409
- m.picture && /* @__PURE__ */ jsx(AvatarImage, { src: m.picture, alt: m.name }),
1410
- /* @__PURE__ */ jsx(AvatarFallback, { className: "bg-foreground text-[9px] font-medium text-background", children: initials(m.name || "?") })
1411
- ] }, i)),
1412
- !membersHidden && extraMembers > 0 && /* @__PURE__ */ jsx(Avatar, { className: "size-6 border-2 border-card", children: /* @__PURE__ */ jsxs(AvatarFallback, { className: "bg-accent text-[9px] font-medium text-muted-foreground", children: [
1413
- "+",
1414
- extraMembers
1415
- ] }) })
1416
- ]
1736
+ members,
1737
+ total: totalMembers,
1738
+ max: MAX_AVATARS,
1739
+ hidden: membersHidden,
1740
+ className: "ml-auto",
1741
+ testId: testId && `${testId}-member-avatars`
1417
1742
  }
1418
1743
  )
1419
1744
  ] }),
@@ -4866,6 +5191,6 @@ function VerticalBuilder({
4866
5191
  ] });
4867
5192
  }
4868
5193
 
4869
- export { AgentsPanel, AppHeader, AppShell, AssetThumb, CitationEditor, ConnectionProvider, DataTable, DataTableBlock, EmptyState, GridView, LegalArbiProvider, LiveDataProvider, MetricCard, ModuleManager, PageHeader, PageRenderer, Section, StatGroup, StudioEditor, Toolbar, UploadDropzone, VerticalBuilder, WidgetPlaceholder, WorkspaceCard, createAgentSelectionStore, createAiFields, createArbiBlocksConfig, createArbiMaterializer, createBlockKit, createImageField, createLiveWidgets, createModuleRegistry, createModuleStore, createPromptLibrary, createSiteBlocks, createStudioPersistence, createVerticalExport, createWebsiteBlocks, iconMap, isAuthenticated, materializePageData, matterToContext, useAssetImage, useConnection, useFirmAiTask, useImageGen, useLiveDataActive, useSemanticSearch, useWorkspaceDocs };
5194
+ export { AgentsPanel, AppHeader, AppShell, AssetThumb, CitationEditor, ConnectionProvider, DataTable, DataTableBlock, EmptyState, EntityIdentityBar, GridView, IDENTITY_NAME_MAX_LENGTH, LegalArbiProvider, LiveDataProvider, MemberAvatarStack, MetricCard, ModuleManager, PageHeader, PageRenderer, RecentActivityCard, Section, StatGroup, StudioEditor, Toolbar, UploadDropzone, VerticalBuilder, WidgetPlaceholder, WorkspaceCard, createAgentSelectionStore, createAiFields, createArbiBlocksConfig, createArbiMaterializer, createBlockKit, createImageField, createLiveWidgets, createModuleRegistry, createModuleStore, createPromptLibrary, createSiteBlocks, createStudioPersistence, createVerticalExport, createWebsiteBlocks, iconMap, isAuthenticated, materializePageData, matterToContext, useAssetImage, useConnection, useFirmAiTask, useImageGen, useLiveDataActive, useSemanticSearch, useWorkspaceDocs };
4870
5195
  //# sourceMappingURL=index.js.map
4871
5196
  //# sourceMappingURL=index.js.map