@arbidocs/blocks 0.3.128 → 0.3.129

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.d.cts CHANGED
@@ -537,19 +537,19 @@ interface WorkspaceCardProps {
537
537
  * place of the count and drops the avatar stack, rather than lying with a `0`.
538
538
  */
539
539
  membersHidden?: boolean;
540
- /** ISO timestamp — renders a centred "Updated {relative} ago" on the footer
541
- * line at rest, which gives way to the Open button on hover. */
540
+ /** ISO timestamp — renders "Updated {relative} ago" at the footer's right edge. */
542
541
  updatedAt?: string;
543
- /** Marks this as the current workspace: a ring on the card, and the footer says
544
- * so in words instead of offering an Open button. */
542
+ /** Marks this as the current workspace: an accented card surface and a footer label. */
545
543
  active?: boolean;
546
- /** Shows a spinner in the Open button while a switch is in flight. */
544
+ /** Shows a spinner in the Open affordance while a switch is in flight. */
547
545
  busy?: boolean;
548
546
  onOpen?: () => void;
549
547
  /** Icon in the header tile. Defaults to a lock/folder glyph. */
550
548
  icon?: LucideIcon;
551
549
  /** Replaces the whole header icon tile — for a richer, app-supplied glyph. */
552
550
  iconSlot?: ReactNode;
551
+ /** Canonical workspace entity pill shown at the top of the description tooltip. */
552
+ tooltipEntitySlot?: ReactNode;
553
553
  /**
554
554
  * Secondary context for the card (the ARBI app puts the owning project here).
555
555
  * Sits top-right and is revealed on hover/focus, so the resting card stays
@@ -559,14 +559,14 @@ interface WorkspaceCardProps {
559
559
  /**
560
560
  * Accent as a theme colour-token key (e.g. `emerald`, or a firm's own brand
561
561
  * token), resolved to `var(--color-<accent>)` at render — same contract as
562
- * MetricCard. Tints the icon tile and the Open button, so a firm can accent
562
+ * MetricCard. Tints the icon tile and the Open affordance, so a firm can accent
563
563
  * the card without its brand classes leaking into the kit. `'default'` (or
564
564
  * omitted) uses the semantic `primary` token.
565
565
  */
566
566
  accent?: string;
567
- /** Stable id for the card root; the footer button gets `${testId}-open`. */
567
+ /** Stable id for the card root; the footer action gets `${testId}-open`. */
568
568
  testId?: string;
569
- /** Overrides the footer button's test id when a caller needs a specific one. */
569
+ /** Overrides the footer action's test id when a caller needs a specific one. */
570
570
  buttonTestId?: string;
571
571
  className?: string;
572
572
  }
@@ -575,11 +575,10 @@ interface WorkspaceCardProps {
575
575
  *
576
576
  * 1. header — icon + workspace name; secondary context (`cornerSlot`) hides
577
577
  * top-right until hover, keeping the resting card about the workspace.
578
- * 2. body — two-line description, then one stat line: doc/chat/member counts
579
- * on the left, the member avatar stack right-justified on the same row.
580
- * 3. footer — one centred line with the full width to itself: "Updated … ago"
581
- * at rest, swapping to the Open button on hover. The current
582
- * workspace says so in words there instead.
578
+ * 2. body — an expanded description area with the centred Open/current
579
+ * affordance layered over it only on hover or keyboard focus.
580
+ * 3. footer — doc/chat counts stay left and membership stays right, followed
581
+ * by a final left-aligned update timestamp.
583
582
  *
584
583
  * State is said once, in words. There is deliberately no status badge.
585
584
  *
@@ -587,7 +586,7 @@ interface WorkspaceCardProps {
587
586
  * primary, card, border, accent), so every firm gets it in its own colours
588
587
  * without any firm-branded classes leaking in.
589
588
  */
590
- declare function WorkspaceCard({ name, matterRef, description, docCount, chatCount, memberCount, members, membersHidden, updatedAt, active, busy, onOpen, icon: Icon, iconSlot, cornerSlot, accent, testId, buttonTestId, className, }: WorkspaceCardProps): react.JSX.Element;
589
+ declare function WorkspaceCard({ name, matterRef, description, docCount, chatCount, memberCount, members, membersHidden, updatedAt, active, busy, onOpen, icon: Icon, iconSlot, tooltipEntitySlot, cornerSlot, accent, testId, buttonTestId, className, }: WorkspaceCardProps): react.JSX.Element;
591
590
 
592
591
  interface StatItem {
593
592
  value: string;
package/dist/index.d.ts CHANGED
@@ -537,19 +537,19 @@ interface WorkspaceCardProps {
537
537
  * place of the count and drops the avatar stack, rather than lying with a `0`.
538
538
  */
539
539
  membersHidden?: boolean;
540
- /** ISO timestamp — renders a centred "Updated {relative} ago" on the footer
541
- * line at rest, which gives way to the Open button on hover. */
540
+ /** ISO timestamp — renders "Updated {relative} ago" at the footer's right edge. */
542
541
  updatedAt?: string;
543
- /** Marks this as the current workspace: a ring on the card, and the footer says
544
- * so in words instead of offering an Open button. */
542
+ /** Marks this as the current workspace: an accented card surface and a footer label. */
545
543
  active?: boolean;
546
- /** Shows a spinner in the Open button while a switch is in flight. */
544
+ /** Shows a spinner in the Open affordance while a switch is in flight. */
547
545
  busy?: boolean;
548
546
  onOpen?: () => void;
549
547
  /** Icon in the header tile. Defaults to a lock/folder glyph. */
550
548
  icon?: LucideIcon;
551
549
  /** Replaces the whole header icon tile — for a richer, app-supplied glyph. */
552
550
  iconSlot?: ReactNode;
551
+ /** Canonical workspace entity pill shown at the top of the description tooltip. */
552
+ tooltipEntitySlot?: ReactNode;
553
553
  /**
554
554
  * Secondary context for the card (the ARBI app puts the owning project here).
555
555
  * Sits top-right and is revealed on hover/focus, so the resting card stays
@@ -559,14 +559,14 @@ interface WorkspaceCardProps {
559
559
  /**
560
560
  * Accent as a theme colour-token key (e.g. `emerald`, or a firm's own brand
561
561
  * token), resolved to `var(--color-<accent>)` at render — same contract as
562
- * MetricCard. Tints the icon tile and the Open button, so a firm can accent
562
+ * MetricCard. Tints the icon tile and the Open affordance, so a firm can accent
563
563
  * the card without its brand classes leaking into the kit. `'default'` (or
564
564
  * omitted) uses the semantic `primary` token.
565
565
  */
566
566
  accent?: string;
567
- /** Stable id for the card root; the footer button gets `${testId}-open`. */
567
+ /** Stable id for the card root; the footer action gets `${testId}-open`. */
568
568
  testId?: string;
569
- /** Overrides the footer button's test id when a caller needs a specific one. */
569
+ /** Overrides the footer action's test id when a caller needs a specific one. */
570
570
  buttonTestId?: string;
571
571
  className?: string;
572
572
  }
@@ -575,11 +575,10 @@ interface WorkspaceCardProps {
575
575
  *
576
576
  * 1. header — icon + workspace name; secondary context (`cornerSlot`) hides
577
577
  * top-right until hover, keeping the resting card about the workspace.
578
- * 2. body — two-line description, then one stat line: doc/chat/member counts
579
- * on the left, the member avatar stack right-justified on the same row.
580
- * 3. footer — one centred line with the full width to itself: "Updated … ago"
581
- * at rest, swapping to the Open button on hover. The current
582
- * workspace says so in words there instead.
578
+ * 2. body — an expanded description area with the centred Open/current
579
+ * affordance layered over it only on hover or keyboard focus.
580
+ * 3. footer — doc/chat counts stay left and membership stays right, followed
581
+ * by a final left-aligned update timestamp.
583
582
  *
584
583
  * State is said once, in words. There is deliberately no status badge.
585
584
  *
@@ -587,7 +586,7 @@ interface WorkspaceCardProps {
587
586
  * primary, card, border, accent), so every firm gets it in its own colours
588
587
  * without any firm-branded classes leaking in.
589
588
  */
590
- declare function WorkspaceCard({ name, matterRef, description, docCount, chatCount, memberCount, members, membersHidden, updatedAt, active, busy, onOpen, icon: Icon, iconSlot, cornerSlot, accent, testId, buttonTestId, className, }: WorkspaceCardProps): react.JSX.Element;
589
+ declare function WorkspaceCard({ name, matterRef, description, docCount, chatCount, memberCount, members, membersHidden, updatedAt, active, busy, onOpen, icon: Icon, iconSlot, tooltipEntitySlot, cornerSlot, accent, testId, buttonTestId, className, }: WorkspaceCardProps): react.JSX.Element;
591
590
 
592
591
  interface StatItem {
593
592
  value: string;
package/dist/index.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import { 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, RichTextBlock, Callout, BlockImage, AvatarBlock, Navbar, Footer, ListBlock, isAssetRef, asAssetRef } from './chunk-L6GG4KN2.js';
2
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, VideoEmbed, applyFontVars, applyStoredTheme, applyThemeVars, asAssetRef, assetRefId, clearFontVars, clearThemeVars, createThemeStore, daysUntil, fmtDate, fmtDateTime, fontPackages, fromNow, gbp, getFontPairing, hrs, initials, isAssetRef, matchFontPairing, pct, tid, toEmbedUrl, toHslTriplet, useAssetRenderer, useAssetResolverActive } from './chunk-L6GG4KN2.js';
3
3
  import { createContext, useState, useCallback, useMemo, useContext, useRef, useEffect } from 'react';
4
- import { useArbi, ArbiProvider, useAiTask, useWorkspaceDocs as useWorkspaceDocs$1, useSemanticSearch as useSemanticSearch$1, cn, Table, TableHeader, TableRow, TableHead, TableBody, TableCell, Input, Card, CardHeader, CardTitle, CardDescription, CardContent, Avatar, AvatarImage, AvatarFallback, CardFooter, Button, TooltipProvider, 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 { useArbi, ArbiProvider, useAiTask, useWorkspaceDocs as useWorkspaceDocs$1, useSemanticSearch as useSemanticSearch$1, cn, 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';
5
5
  export { DocumentCard, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, redlineStats, textToArtifact, toRedlineMarkdown } from '@arbidocs/react';
6
6
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
7
  import { QueryClient, QueryClientProvider, useQuery, useQueryClient } from '@tanstack/react-query';
8
8
  import { AgGridReact } from 'ag-grid-react';
9
9
  import { themeQuartz, AllCommunityModule } from 'ag-grid-community';
10
- 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, Loader2, UploadCloud, Search, ArrowUpRight, ArrowDownRight, FolderLock, MessagesSquare, CheckCircle2, ArrowLeftRight, X, Menu, ArrowLeft, Palette, RotateCcw, ChevronUp, ChevronDown, BrainCircuit, Bot, LayoutGrid, FileJson, Download, Crop, ImagePlus, Upload, Link2, Check } from 'lucide-react';
10
+ 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, Loader2, UploadCloud, Search, ArrowUpRight, ArrowDownRight, FolderLock, CheckCircle2, ArrowLeftRight, MessagesSquare, X, Menu, ArrowLeft, Palette, RotateCcw, ChevronUp, ChevronDown, BrainCircuit, Bot, LayoutGrid, FileJson, Download, Crop, ImagePlus, Upload, Link2, Check } from 'lucide-react';
11
11
  import { useLocation, Link, useParams, NavLink } from 'react-router-dom';
12
12
  import { Puck, Render } from '@measured/puck';
13
13
  import { create } from 'zustand';
@@ -1058,7 +1058,7 @@ function MetricCard({
1058
1058
  ] });
1059
1059
  }
1060
1060
  var MAX_AVATARS = 3;
1061
- var ON_HOVER = "opacity-0 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100";
1061
+ var ON_HOVER = "opacity-0 transition-opacity group-hover/workspace-card:opacity-100 group-focus-within/workspace-card:opacity-100";
1062
1062
  function WorkspaceCard({
1063
1063
  name,
1064
1064
  matterRef,
@@ -1074,6 +1074,7 @@ function WorkspaceCard({
1074
1074
  onOpen,
1075
1075
  icon: Icon = FolderLock,
1076
1076
  iconSlot,
1077
+ tooltipEntitySlot,
1077
1078
  cornerSlot,
1078
1079
  accent = "default",
1079
1080
  testId,
@@ -1083,24 +1084,39 @@ function WorkspaceCard({
1083
1084
  const totalMembers = memberCount ?? members.length;
1084
1085
  const shownMembers = membersHidden ? [] : members.slice(0, MAX_AVATARS);
1085
1086
  const extraMembers = totalMembers - shownMembers.length;
1086
- const btnTestId = buttonTestId ?? (testId ? `${testId}-open` : void 0);
1087
+ const actionTestId = buttonTestId ?? (testId ? `${testId}-open` : void 0);
1088
+ const canOpen = Boolean(onOpen) && !busy;
1087
1089
  const hue = accent && accent !== "default" ? `var(--color-${accent})` : null;
1088
1090
  const tileStyle = hue ? { backgroundColor: `color-mix(in oklab, ${hue} 14%, transparent)`, color: hue } : void 0;
1089
- const buttonStyle = hue ? { backgroundColor: hue, color: "var(--color-primary-foreground)" } : void 0;
1091
+ const openStyle = hue ? { backgroundColor: hue, color: "var(--color-background)" } : void 0;
1092
+ const handleKeyDown = (event) => {
1093
+ if (!canOpen || event.target !== event.currentTarget) return;
1094
+ if (event.key === "Enter" || event.key === " ") {
1095
+ event.preventDefault();
1096
+ onOpen?.();
1097
+ }
1098
+ };
1090
1099
  return /* @__PURE__ */ jsxs(
1091
1100
  Card,
1092
1101
  {
1093
- variant: "outline",
1102
+ variant: "flat",
1094
1103
  className: cn(
1095
- "card-hover group flex flex-col gap-3 p-4",
1096
- // The current workspace is marked by a ring, not a badge — the footer
1097
- // already says "Current workspace" in words.
1098
- active && "ring-1 ring-primary",
1104
+ "card-hover group/workspace-card relative flex h-48 w-full flex-col gap-3 overflow-hidden rounded-xl bg-card p-4 shadow-sm",
1105
+ canOpen && "cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2",
1106
+ active && "bg-primary/10 shadow-md",
1099
1107
  className
1100
1108
  ),
1101
1109
  "data-testid": testId,
1110
+ "data-active": active || void 0,
1111
+ role: canOpen ? "button" : void 0,
1112
+ tabIndex: canOpen ? 0 : void 0,
1113
+ "aria-current": active ? "page" : void 0,
1114
+ "aria-label": canOpen ? `Open workspace ${name}` : void 0,
1115
+ "aria-busy": busy || void 0,
1116
+ onClick: canOpen ? onOpen : void 0,
1117
+ onKeyDown: handleKeyDown,
1102
1118
  children: [
1103
- /* @__PURE__ */ jsxs(CardHeader, { className: "flex flex-row items-start gap-3 p-0", children: [
1119
+ /* @__PURE__ */ jsxs(CardHeader, { className: "flex flex-row items-center gap-3 space-y-0 p-0", children: [
1104
1120
  iconSlot ?? /* @__PURE__ */ jsx(
1105
1121
  "div",
1106
1122
  {
@@ -1113,7 +1129,7 @@ function WorkspaceCard({
1113
1129
  /* @__PURE__ */ jsx(
1114
1130
  CardTitle,
1115
1131
  {
1116
- className: "line-clamp-2 text-base leading-tight",
1132
+ className: "line-clamp-2 text-base font-bold leading-tight",
1117
1133
  "data-testid": testId && `${testId}-title`,
1118
1134
  children: name
1119
1135
  }
@@ -1122,88 +1138,98 @@ function WorkspaceCard({
1122
1138
  ] }),
1123
1139
  cornerSlot && /* @__PURE__ */ jsx("div", { className: cn("shrink-0", ON_HOVER), children: cornerSlot })
1124
1140
  ] }),
1125
- /* @__PURE__ */ jsxs(CardContent, { className: "flex flex-1 flex-col gap-2 p-0", children: [
1126
- description && /* @__PURE__ */ jsx("p", { className: "line-clamp-2 text-sm text-muted-foreground", children: description }),
1127
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3 text-sm", children: [
1128
- /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-foreground", title: "Documents", children: [
1129
- /* @__PURE__ */ jsx(FileText, { className: "size-3.5 text-muted-foreground" }),
1130
- /* @__PURE__ */ jsx("span", { className: "font-medium tabular-nums", children: docCount.toLocaleString() })
1131
- ] }),
1132
- chatCount !== void 0 && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-foreground", title: "Chats", children: [
1133
- /* @__PURE__ */ jsx(MessagesSquare, { className: "size-3.5 text-muted-foreground" }),
1134
- /* @__PURE__ */ jsx("span", { className: "font-medium tabular-nums", children: chatCount.toLocaleString() })
1135
- ] }),
1136
- /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-foreground", title: "Members", children: [
1137
- /* @__PURE__ */ jsx(Users, { className: "size-3.5 text-muted-foreground" }),
1138
- /* @__PURE__ */ jsx(
1141
+ /* @__PURE__ */ jsxs(CardContent, { className: "relative flex min-h-0 flex-1 flex-col p-0", children: [
1142
+ description && /* @__PURE__ */ jsxs(Tooltip, { children: [
1143
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx("p", { className: "line-clamp-2 text-sm text-muted-foreground transition-opacity group-hover/workspace-card:opacity-0 group-focus-within/workspace-card:opacity-0", children: description }) }),
1144
+ /* @__PURE__ */ jsx(TooltipContent, { side: "top", className: "max-w-sm p-0", children: /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-md", children: [
1145
+ /* @__PURE__ */ jsx("div", { className: "flex items-center bg-muted/70 px-3 py-2.5", children: tooltipEntitySlot ?? /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: name }) }),
1146
+ /* @__PURE__ */ jsx("p", { className: "px-3 py-3 text-sm leading-relaxed text-foreground/90", children: description })
1147
+ ] }) })
1148
+ ] }),
1149
+ /* @__PURE__ */ jsx(
1150
+ "span",
1151
+ {
1152
+ className: cn(
1153
+ "pointer-events-none absolute inset-0 z-10 inline-flex items-center justify-center whitespace-nowrap",
1154
+ !busy && "opacity-0 transition-opacity group-hover/workspace-card:opacity-100 group-focus-within/workspace-card:opacity-100"
1155
+ ),
1156
+ "data-testid": actionTestId,
1157
+ children: /* @__PURE__ */ jsx(
1139
1158
  "span",
1140
1159
  {
1141
- className: "font-medium tabular-nums",
1142
- "data-testid": testId && `${testId}-member-count`,
1143
- children: membersHidden ? "\u2014" : totalMembers
1160
+ className: cn(
1161
+ "inline-flex w-full items-center justify-center gap-2 rounded-md px-4 py-2 text-base font-semibold shadow-md",
1162
+ active ? "bg-muted-foreground text-background" : "bg-primary text-primary-foreground"
1163
+ ),
1164
+ style: active ? void 0 : openStyle,
1165
+ children: active ? /* @__PURE__ */ jsxs(Fragment, { children: [
1166
+ /* @__PURE__ */ jsx(CheckCircle2, { className: "size-4" }),
1167
+ " Current workspace"
1168
+ ] }) : busy ? /* @__PURE__ */ jsxs(Fragment, { children: [
1169
+ /* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin" }),
1170
+ " Opening"
1171
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1172
+ /* @__PURE__ */ jsx(ArrowLeftRight, { className: "size-4" }),
1173
+ " Open"
1174
+ ] })
1144
1175
  }
1145
1176
  )
1146
- ] }),
1147
- /* @__PURE__ */ jsxs("div", { className: "ml-auto flex shrink-0 -space-x-2", children: [
1148
- shownMembers.map((m, i) => /* @__PURE__ */ jsxs(Avatar, { className: "size-6 border-2 border-card", title: m.name, children: [
1149
- m.picture && /* @__PURE__ */ jsx(AvatarImage, { src: m.picture, alt: m.name }),
1150
- /* @__PURE__ */ jsx(AvatarFallback, { className: "bg-foreground text-[9px] font-medium text-background", children: initials(m.name || "?") })
1151
- ] }, i)),
1152
- !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: [
1153
- "+",
1154
- extraMembers
1155
- ] }) })
1156
- ] })
1157
- ] })
1158
- ] }),
1159
- /* @__PURE__ */ jsx(CardFooter, { className: "grid min-h-8 place-items-center p-0", children: active ? (
1160
- // Reads as a statement, not a call to action — but stays clickable, so
1161
- // re-entering the workspace you're already in still works.
1162
- /* @__PURE__ */ jsxs(
1163
- Button,
1164
- {
1165
- variant: "ghost",
1166
- size: "sm",
1167
- className: "col-start-1 row-start-1 h-8 whitespace-nowrap px-2 text-xs font-medium text-primary hover:bg-primary/10",
1168
- onClick: onOpen,
1169
- "data-testid": btnTestId,
1170
- children: [
1171
- /* @__PURE__ */ jsx(CheckCircle2, { className: "size-3.5" }),
1172
- " Current workspace"
1173
- ]
1174
1177
  }
1175
1178
  )
1176
- ) : /* @__PURE__ */ jsxs(Fragment, { children: [
1179
+ ] }),
1180
+ /* @__PURE__ */ jsxs(CardFooter, { className: "mt-auto flex w-full min-w-0 flex-col items-stretch gap-3 overflow-hidden p-0", children: [
1181
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-x-3 text-sm", children: [
1182
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
1183
+ /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-foreground", title: "Documents", children: [
1184
+ /* @__PURE__ */ jsx(FileText, { className: "size-3.5 text-muted-foreground" }),
1185
+ /* @__PURE__ */ jsx("span", { className: "font-medium tabular-nums", children: docCount.toLocaleString() })
1186
+ ] }),
1187
+ chatCount !== void 0 && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-foreground", title: "Chats", children: [
1188
+ /* @__PURE__ */ jsx(MessagesSquare, { className: "size-3.5 text-muted-foreground" }),
1189
+ /* @__PURE__ */ jsx("span", { className: "font-medium tabular-nums", children: chatCount.toLocaleString() })
1190
+ ] }),
1191
+ /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-foreground", title: "Members", children: [
1192
+ /* @__PURE__ */ jsx(Users, { className: "size-3.5 text-muted-foreground" }),
1193
+ /* @__PURE__ */ jsx(
1194
+ "span",
1195
+ {
1196
+ className: "font-medium tabular-nums",
1197
+ "data-testid": testId && `${testId}-member-count`,
1198
+ children: membersHidden ? "\u2014" : totalMembers
1199
+ }
1200
+ )
1201
+ ] })
1202
+ ] }),
1203
+ /* @__PURE__ */ jsxs(
1204
+ "div",
1205
+ {
1206
+ className: "ml-auto flex shrink-0 -space-x-2",
1207
+ "data-testid": testId && `${testId}-member-avatars`,
1208
+ children: [
1209
+ shownMembers.map((m, i) => /* @__PURE__ */ jsxs(Avatar, { className: "size-6 border-2 border-card", title: m.name, children: [
1210
+ m.picture && /* @__PURE__ */ jsx(AvatarImage, { src: m.picture, alt: m.name }),
1211
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "bg-foreground text-[9px] font-medium text-background", children: initials(m.name || "?") })
1212
+ ] }, i)),
1213
+ !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: [
1214
+ "+",
1215
+ extraMembers
1216
+ ] }) })
1217
+ ]
1218
+ }
1219
+ )
1220
+ ] }),
1177
1221
  updatedAt && /* @__PURE__ */ jsxs(
1178
1222
  "span",
1179
1223
  {
1180
- className: cn(
1181
- "col-start-1 row-start-1 whitespace-nowrap text-xs text-muted-foreground",
1182
- "transition-opacity group-hover:opacity-0 group-focus-within:opacity-0"
1183
- ),
1224
+ className: "min-w-0 max-w-full self-start truncate text-left text-xs text-muted-foreground",
1184
1225
  title: fmtDate(updatedAt),
1185
1226
  children: [
1186
1227
  "Updated ",
1187
1228
  fromNow(updatedAt)
1188
1229
  ]
1189
1230
  }
1190
- ),
1191
- /* @__PURE__ */ jsxs(
1192
- Button,
1193
- {
1194
- size: "sm",
1195
- className: cn("col-start-1 row-start-1 whitespace-nowrap", ON_HOVER),
1196
- style: buttonStyle,
1197
- onClick: onOpen,
1198
- disabled: busy,
1199
- "data-testid": btnTestId,
1200
- children: [
1201
- busy ? /* @__PURE__ */ jsx(Loader2, { className: "size-3.5 animate-spin" }) : /* @__PURE__ */ jsx(ArrowLeftRight, { className: "size-3.5" }),
1202
- "Open"
1203
- ]
1204
- }
1205
1231
  )
1206
- ] }) })
1232
+ ] })
1207
1233
  ]
1208
1234
  }
1209
1235
  );