@handled-ai/design-system 0.20.2 → 0.20.4

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.
@@ -58,7 +58,7 @@ export interface OwnerPerson {
58
58
 
59
59
  /* ── shared bits ─────────────────────────────────────────────────────────── */
60
60
 
61
- function SalesforceMark({ size = 14 }: { size?: number }) {
61
+ function SalesforceMark({ size = 13 }: { size?: number }) {
62
62
  return (
63
63
  // eslint-disable-next-line @next/next/no-img-element
64
64
  <img
@@ -82,8 +82,10 @@ function OwnerAvatar({ person, size = "sm" }: { person: OwnerPerson; size?: "sm"
82
82
  )
83
83
  }
84
84
 
85
+ // Component-owned compact sizing. Set directly here (not via consumer
86
+ // className) because cn()/tailwind-merge can strip conflicting overrides.
85
87
  const chipBase =
86
- "inline-flex h-8 items-center gap-1.5 rounded-lg border border-border bg-background px-2.5 text-[13px] " +
88
+ "inline-flex h-7 items-center gap-1 rounded-md border border-border bg-background px-2 text-[12px] " +
87
89
  "shadow-[0_1px_1px_rgba(0,0,0,0.03)]"
88
90
 
89
91
  /* ── Signal owner (Handled assignment, editable) ─────────────────────────── */
@@ -115,14 +117,14 @@ function SignalOwnerChip({
115
117
  {owner ? (
116
118
  <OwnerAvatar person={owner} />
117
119
  ) : (
118
- <span className="text-muted-foreground inline-flex size-[18px] items-center justify-center">
119
- <UserPlus size={13} />
120
+ <span className="text-muted-foreground inline-flex size-4 items-center justify-center">
121
+ <UserPlus size={12} />
120
122
  </span>
121
123
  )}
122
- <span className="text-muted-foreground text-[11px] font-medium tracking-wide uppercase">
124
+ <span className="text-muted-foreground text-[10px] font-medium tracking-wide uppercase">
123
125
  Signal owner
124
126
  </span>
125
- <span className="bg-border/70 mx-0.5 h-3.5 w-px" aria-hidden />
127
+ <span className="bg-border/70 mx-0.5 h-3 w-px" aria-hidden />
126
128
  <span className={cn("font-medium", owner ? "text-foreground" : "text-muted-foreground")}>
127
129
  {owner ? owner.name : "Unassigned"}
128
130
  </span>
@@ -155,7 +157,7 @@ function SignalOwnerChip({
155
157
  >
156
158
  {value}
157
159
  <span className="text-muted-foreground ml-0.5">
158
- {open ? <ChevronUp size={13} /> : <ChevronDown size={13} />}
160
+ {open ? <ChevronUp size={12} /> : <ChevronDown size={12} />}
159
161
  </span>
160
162
  </button>
161
163
  </DropdownMenuTrigger>
@@ -289,7 +291,7 @@ function AccountOwnerChip({ owners, className }: AccountOwnerChipProps) {
289
291
  <OwnerAvatar person={only} />
290
292
  <span className="text-foreground font-medium">{only.name}</span>
291
293
  <span className="text-muted-foreground ml-0.5">
292
- {open ? <ChevronUp size={13} /> : <ChevronDown size={13} />}
294
+ {open ? <ChevronUp size={12} /> : <ChevronDown size={12} />}
293
295
  </span>
294
296
  </button>
295
297
  </DropdownMenuTrigger>
@@ -327,11 +329,11 @@ function AccountOwnerChip({ owners, className }: AccountOwnerChipProps) {
327
329
  ))}
328
330
  </span>
329
331
  <span className="text-foreground font-medium">Account owners</span>
330
- <span className="bg-muted text-muted-foreground rounded px-1 text-[11px] font-semibold tabular-nums">
332
+ <span className="bg-muted text-muted-foreground rounded px-1 text-[10px] font-semibold tabular-nums">
331
333
  ×{owners.length}
332
334
  </span>
333
335
  <span className="text-muted-foreground ml-0.5">
334
- {open ? <ChevronUp size={13} /> : <ChevronDown size={13} />}
336
+ {open ? <ChevronUp size={12} /> : <ChevronDown size={12} />}
335
337
  </span>
336
338
  </button>
337
339
  </DropdownMenuTrigger>
@@ -163,21 +163,21 @@ const TIMELINE_VARIANT_CLASSES: Record<TimelineActivityVariant, TimelineVariantC
163
163
  },
164
164
  "case-panel": {
165
165
  outerRowGap: "group relative flex gap-3",
166
- connector: "absolute left-[7px] top-[18px] bottom-[-4px] w-px bg-border/60",
167
- dotWrapperSize: "relative z-10 mt-1 flex h-4 w-4 shrink-0 items-center justify-center rounded-full bg-background",
168
- dot: "flex h-3.5 w-3.5 items-center justify-center rounded-full border ring-[3px] ring-background",
169
- contentPadding: "flex-1 pb-4 pt-0.5",
170
- titleRowSpacing: "flex min-w-0 flex-col gap-0.5 sm:flex-row sm:items-start sm:justify-between",
171
- title: "pr-3 text-[13px] leading-snug text-foreground",
172
- time: "mt-0.5 shrink-0 whitespace-nowrap text-[11px] leading-snug text-muted-foreground/70",
173
- cardContainer: "overflow-hidden rounded-lg border border-border/70 bg-card shadow-sm",
174
- cardHeader: "border-b border-border/60 bg-background px-3 py-2",
175
- cardBody: "px-3 py-2.5 text-sm",
176
- cardFooter: "border-t border-border/60 bg-background/50 px-3 py-1.5",
177
- collapsedPreview: "flex items-center justify-between gap-2 px-3 py-2 text-sm text-muted-foreground",
166
+ connector: "absolute left-[11px] top-6 bottom-[-2px] w-px bg-border/50",
167
+ dotWrapperSize: "relative z-10 mt-0.5 flex h-[22px] w-[22px] shrink-0 items-center justify-center rounded-full bg-background",
168
+ dot: "flex h-[22px] w-[22px] items-center justify-center rounded-full border ring-4 ring-background [&>svg]:h-3 [&>svg]:w-3",
169
+ contentPadding: "flex-1 min-w-0 pb-5 pt-px",
170
+ titleRowSpacing: "flex min-w-0 items-start justify-between gap-3",
171
+ title: "min-w-0 pr-1 text-[13.5px] font-medium leading-tight text-foreground",
172
+ time: "shrink-0 whitespace-nowrap pt-px text-[11px] leading-tight text-muted-foreground/60",
173
+ cardContainer: "overflow-hidden rounded-lg border border-border/70 bg-card",
174
+ cardHeader: "flex items-center justify-between border-b border-border/60 bg-muted/30 px-3 py-1.5 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground/70",
175
+ cardBody: "px-3 py-2.5 text-[13px] leading-relaxed",
176
+ cardFooter: "border-t border-border/60 bg-muted/10 px-3 py-1.5",
177
+ collapsedPreview: "flex items-center justify-between gap-2 px-3 py-2 text-[13px] text-muted-foreground",
178
178
  actionLinkRow: "flex items-center justify-end gap-2 px-3 py-1.5",
179
- actionLink: "inline-flex items-center gap-1.5 text-[11px] font-medium text-muted-foreground/70 transition-colors hover:text-foreground",
180
- nonInteractiveContent: "pr-2 text-[13px] leading-snug text-muted-foreground",
179
+ actionLink: "inline-flex items-center gap-1 text-[11px] font-medium text-muted-foreground/70 transition-colors hover:text-foreground",
180
+ nonInteractiveContent: "pr-2 text-[13px] leading-relaxed text-muted-foreground",
181
181
  },
182
182
  }
183
183
 
@@ -120,8 +120,6 @@ describe("DetailView case-panel-v2 section layout", () => {
120
120
  screen.getByText("Signal brief copy: account activity needs review."),
121
121
  screen.getByText("Metadata marker"),
122
122
  screen.getByText("Before-score status marker"),
123
- screen.getByText("The why"),
124
- screen.getByText("The why copy: customer replied after the escalation window opened."),
125
123
  screen.getByText("Cash movement"),
126
124
  screen.getByText("Approve action"),
127
125
  screen.getByText("Opportunity marker"),
@@ -154,14 +152,14 @@ describe("DetailView case-panel-v2 section layout", () => {
154
152
  )
155
153
  })
156
154
 
157
- it("renders signal brief and The why separately when both copies exist", () => {
155
+ it("renders signal brief and chip-backed Why section without a separate The why block", () => {
158
156
  renderDetailView({ sectionLayout: "case-panel-v2" })
159
157
 
160
- expectInDocumentOrder(
161
- screen.getByText("Signal brief copy: account activity needs review."),
162
- screen.getByText("The why"),
163
- screen.getByText("The why copy: customer replied after the escalation window opened."),
164
- )
158
+ expect(screen.getByText("Signal brief copy: account activity needs review.")).toBeTruthy()
159
+ expect(screen.queryByText("The why")).toBeNull()
160
+ expect(screen.queryByText("The why copy: customer replied after the escalation window opened.")).toBeNull()
161
+ expect(screen.getByText("Why")).toBeTruthy()
162
+ expect(screen.getByText("Cash movement")).toBeTruthy()
165
163
  })
166
164
 
167
165
  it("falls back to whyNow in the brief and suppresses the separate The why block when signalBrief is missing", () => {
@@ -502,9 +502,6 @@ export function DetailView({
502
502
  : "hover:bg-muted/50"
503
503
 
504
504
  const isCasePanelV2 = sectionLayout === "case-panel-v2"
505
- const v2WhyText = signalData.signalBrief
506
- ? signalData.whyNow || signalData.urgencyExplanation
507
- : undefined
508
505
 
509
506
  // The metadata chips row (priority · deadline · account · renderMetadataExtra). Rendered above
510
507
  // the brief by default, or beneath it when `metadataLayout === "below-brief"` (case-panel redesign).
@@ -724,15 +721,6 @@ export function DetailView({
724
721
  {/* Before-score content slot (e.g. status/attention pills) */}
725
722
  {renderBeforeScore?.(item)}
726
723
 
727
- {v2WhyText ? (
728
- <div className="mb-8">
729
- <h3 className="text-xs font-bold text-muted-foreground uppercase tracking-wider mb-3">The why</h3>
730
- <p className="text-sm text-foreground/90 leading-relaxed mb-4">
731
- {v2WhyText}
732
- </p>
733
- </div>
734
- ) : null}
735
-
736
724
  <div className="mb-8">
737
725
  <ScoreWhyChips
738
726
  item={item}