@handled-ai/design-system 0.18.22 → 0.18.23

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.
Files changed (70) hide show
  1. package/dist/components/case-panel-activity-timeline.d.ts +100 -0
  2. package/dist/components/case-panel-activity-timeline.js +270 -0
  3. package/dist/components/case-panel-activity-timeline.js.map +1 -0
  4. package/dist/components/case-panel-detail.d.ts +60 -0
  5. package/dist/components/case-panel-detail.js +129 -0
  6. package/dist/components/case-panel-detail.js.map +1 -0
  7. package/dist/components/case-panel-email-composer.d.ts +61 -0
  8. package/dist/components/case-panel-email-composer.js +304 -0
  9. package/dist/components/case-panel-email-composer.js.map +1 -0
  10. package/dist/components/case-panel-why.d.ts +35 -0
  11. package/dist/components/case-panel-why.js +149 -0
  12. package/dist/components/case-panel-why.js.map +1 -0
  13. package/dist/components/contextual-quick-action-launcher.d.ts +7 -3
  14. package/dist/components/contextual-quick-action-launcher.js +99 -27
  15. package/dist/components/contextual-quick-action-launcher.js.map +1 -1
  16. package/dist/components/data-table.js +0 -1
  17. package/dist/components/data-table.js.map +1 -1
  18. package/dist/components/pill.d.ts +1 -1
  19. package/dist/components/score-analysis-modal.d.ts +2 -8
  20. package/dist/components/score-analysis-modal.js +6 -19
  21. package/dist/components/score-analysis-modal.js.map +1 -1
  22. package/dist/components/score-breakdown.d.ts +1 -3
  23. package/dist/components/score-breakdown.js +6 -5
  24. package/dist/components/score-breakdown.js.map +1 -1
  25. package/dist/components/score-ring.d.ts +3 -6
  26. package/dist/components/score-ring.js +14 -11
  27. package/dist/components/score-ring.js.map +1 -1
  28. package/dist/components/score-why-chips.d.ts +2 -3
  29. package/dist/components/score-why-chips.js +21 -10
  30. package/dist/components/score-why-chips.js.map +1 -1
  31. package/dist/components/signal-priority-popover.d.ts +0 -1
  32. package/dist/components/signal-priority-popover.js +20 -20
  33. package/dist/components/signal-priority-popover.js.map +1 -1
  34. package/dist/index.d.ts +7 -4
  35. package/dist/index.js +4 -1
  36. package/dist/index.js.map +1 -1
  37. package/dist/prototype/index.d.ts +0 -1
  38. package/dist/prototype/prototype-accounts-view.d.ts +0 -1
  39. package/dist/prototype/prototype-admin-view.d.ts +0 -1
  40. package/dist/prototype/prototype-config.d.ts +0 -1
  41. package/dist/prototype/prototype-inbox-view.d.ts +0 -1
  42. package/dist/prototype/prototype-insights-view.d.ts +0 -1
  43. package/dist/prototype/prototype-shell.d.ts +0 -1
  44. package/package.json +1 -1
  45. package/src/components/__tests__/case-panel-activity-timeline.test.tsx +152 -0
  46. package/src/components/__tests__/case-panel-detail.test.tsx +138 -0
  47. package/src/components/__tests__/case-panel-email-composer.test.tsx +171 -0
  48. package/src/components/__tests__/case-panel-why.test.tsx +152 -0
  49. package/src/components/__tests__/contextual-quick-action-launcher.test.tsx +87 -0
  50. package/src/components/__tests__/signal-priority-popover.test.tsx +5 -7
  51. package/src/components/case-panel-activity-timeline.tsx +414 -0
  52. package/src/components/case-panel-detail.tsx +228 -0
  53. package/src/components/case-panel-email-composer.tsx +341 -0
  54. package/src/components/case-panel-why.tsx +214 -0
  55. package/src/components/contextual-quick-action-launcher.tsx +92 -15
  56. package/src/components/data-table.tsx +0 -1
  57. package/src/components/score-analysis-modal.tsx +5 -22
  58. package/src/components/score-breakdown.tsx +6 -7
  59. package/src/components/score-ring.tsx +13 -11
  60. package/src/components/score-why-chips.tsx +23 -12
  61. package/src/components/signal-priority-popover.tsx +21 -21
  62. package/src/index.ts +4 -1
  63. package/dist/components/score-semantics.d.ts +0 -27
  64. package/dist/components/score-semantics.js +0 -173
  65. package/dist/components/score-semantics.js.map +0 -1
  66. package/src/components/__tests__/score-analysis-modal.test.tsx +0 -55
  67. package/src/components/__tests__/score-breakdown-intent.test.tsx +0 -47
  68. package/src/components/__tests__/score-ring.test.tsx +0 -43
  69. package/src/components/__tests__/score-semantics.test.ts +0 -107
  70. package/src/components/score-semantics.ts +0 -187
@@ -21,26 +21,26 @@ import {
21
21
  } from "lucide-react";
22
22
  import { cn } from "../lib/utils.js";
23
23
  import { FeedbackFooter, InlineFeedbackControl } from "./feedback-primitives.js";
24
- import { SCORE_TONE_CLASSES, URGENCY_SCORE_CLASSES, getUrgencyLevel, getUrgencyRange } from "./score-semantics.js";
24
+ import { getSignalScoreUrgencyLabel, scoreRangeForUrgency, SIGNAL_TONE_CLASSES } from "./score-why-chips.js";
25
25
  const URGENCY_TRIGGER_DEFAULT = {
26
- Urgent: URGENCY_SCORE_CLASSES.Urgent.trigger,
27
- High: URGENCY_SCORE_CLASSES.High.trigger,
28
- Medium: URGENCY_SCORE_CLASSES.Medium.trigger,
29
- Low: URGENCY_SCORE_CLASSES.Low.trigger
26
+ Urgent: "border-red-200 bg-red-50 text-red-700",
27
+ High: "border-orange-200 bg-orange-50 text-orange-700",
28
+ Medium: "border-amber-200 bg-amber-50 text-amber-700",
29
+ Low: "border-blue-200 bg-blue-50 text-blue-700"
30
30
  };
31
31
  const URGENCY_TRIGGER_HOVER = {
32
- Urgent: URGENCY_SCORE_CLASSES.Urgent.hover,
33
- High: URGENCY_SCORE_CLASSES.High.hover,
34
- Medium: URGENCY_SCORE_CLASSES.Medium.hover,
35
- Low: URGENCY_SCORE_CLASSES.Low.hover
32
+ Urgent: "hover:bg-red-100",
33
+ High: "hover:bg-orange-100",
34
+ Medium: "hover:bg-amber-100",
35
+ Low: "hover:bg-blue-100"
36
36
  };
37
37
  const URGENCY_TRIGGER_OPEN = {
38
- Urgent: URGENCY_SCORE_CLASSES.Urgent.open,
39
- High: URGENCY_SCORE_CLASSES.High.open,
40
- Medium: URGENCY_SCORE_CLASSES.Medium.open,
41
- Low: URGENCY_SCORE_CLASSES.Low.open
38
+ Urgent: "bg-red-100",
39
+ High: "bg-orange-100",
40
+ Medium: "bg-amber-100",
41
+ Low: "bg-blue-100"
42
42
  };
43
- const TONE_ICON_CLASSES = SCORE_TONE_CLASSES;
43
+ const TONE_ICON_CLASSES = SIGNAL_TONE_CLASSES;
44
44
  const DIRECTION_CLASSES = {
45
45
  raises: "text-red-600",
46
46
  lowers: "text-emerald-600",
@@ -57,10 +57,10 @@ const FACTOR_ICONS = {
57
57
  activity: Activity
58
58
  };
59
59
  const URGENCY_DOT_CLASSES = {
60
- Urgent: URGENCY_SCORE_CLASSES.Urgent.dot,
61
- High: URGENCY_SCORE_CLASSES.High.dot,
62
- Medium: URGENCY_SCORE_CLASSES.Medium.dot,
63
- Low: URGENCY_SCORE_CLASSES.Low.dot
60
+ Urgent: "bg-red-500",
61
+ High: "bg-orange-500",
62
+ Medium: "bg-amber-500",
63
+ Low: "bg-blue-500"
64
64
  };
65
65
  const DEFAULT_PRIORITY_FEEDBACK_CHIPS = [
66
66
  { label: "Wrong factor weighting" },
@@ -163,8 +163,8 @@ function SignalPriorityPopover({
163
163
  onFactorFeedback,
164
164
  initialPriorityFeedback
165
165
  }) {
166
- const urgencyLabel = providedLabel != null ? providedLabel : getUrgencyLevel(score);
167
- const scoreRange = getUrgencyRange(urgencyLabel);
166
+ const urgencyLabel = getSignalScoreUrgencyLabel(score, providedLabel);
167
+ const scoreRange = scoreRangeForUrgency(urgencyLabel);
168
168
  const [open, setOpen] = React.useState(false);
169
169
  const [feedback, setFeedback] = React.useState(null);
170
170
  const triggerDefault = URGENCY_TRIGGER_DEFAULT[urgencyLabel];
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/signal-priority-popover.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { Popover as PopoverPrimitive } from \"radix-ui\"\nimport type { LucideIcon } from \"lucide-react\"\nimport {\n Radar,\n Wallet,\n Link2,\n MessageSquare,\n TrendingDown,\n ArrowUpRight,\n ArrowDownRight,\n Clock,\n Activity,\n Minus,\n ChevronDown,\n ChevronUp,\n Info,\n} from \"lucide-react\"\nimport { cn } from \"../lib/utils\"\nimport { FeedbackFooter, InlineFeedbackControl } from \"./feedback-primitives\"\nimport type { FeedbackChipTree, FeedbackSubmitData, PersistedFeedbackData } from \"./feedback-primitives\"\nimport type { SignalScoreUrgencyLabel } from \"../prototype/prototype-config\"\nimport { SCORE_TONE_CLASSES, URGENCY_SCORE_CLASSES, getUrgencyLevel, getUrgencyRange } from \"./score-semantics\"\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * A single contributing factor in the priority popover.\n */\nexport interface PriorityFactor {\n key: string\n label: string\n /** Lucide icon name (e.g. \"radar\", \"wallet\", \"link-2\", \"message-square\"). */\n icon: string\n /** Drives icon background tint. */\n tone: \"alert\" | \"warn\" | \"info\"\n /** Explicit semantic label - NOT inferred from score+weight. */\n direction: \"raises\" | \"lowers\" | \"neutral\"\n /** Optional display label for the direction text. Keeps semantic direction icon/color unchanged. */\n directionLabel?: string\n /** 0-100 */\n score: number\n /** Optional display label rendered instead of the numeric score cell. */\n displayValueLabel?: string\n /** Evidence text (e.g. \"$3.4M moved in 8h - current treasury balance $0.00\"). */\n rationale: string\n}\n\nexport interface SignalPriorityPopoverProps {\n score: number\n urgencyLabel?: SignalScoreUrgencyLabel\n /** Synthesis sentence displayed in the popover head. */\n urgencyExplanation?: string\n factors: PriorityFactor[]\n /** e.g. \"Updated 4m ago - model v3.2\" */\n metaText?: string\n /** Negative feedback issue tree. */\n feedbackChips?: FeedbackChipTree[]\n onFeedbackSubmit?: (data: FeedbackSubmitData) => void\n className?: string\n /** Persisted factor-level feedback (keyed by factor key). */\n initialFactorFeedback?: Record<string, { type: \"up\" | \"down\"; detail: string; ownershipLabel?: string }>\n /** Callback when user submits factor-level feedback. */\n onFactorFeedback?: (factorKey: string, type: \"up\" | \"down\" | null, detail?: string) => void\n /** Persisted priority-level feedback for the footer. */\n initialPriorityFeedback?: PersistedFeedbackData | null\n}\n\n// ---------------------------------------------------------------------------\n// Static class maps (required for Tailwind v4 source scanning)\n// ---------------------------------------------------------------------------\n\nconst URGENCY_TRIGGER_DEFAULT: Record<SignalScoreUrgencyLabel, string> = {\n Urgent: URGENCY_SCORE_CLASSES.Urgent.trigger,\n High: URGENCY_SCORE_CLASSES.High.trigger,\n Medium: URGENCY_SCORE_CLASSES.Medium.trigger,\n Low: URGENCY_SCORE_CLASSES.Low.trigger,\n}\n\nconst URGENCY_TRIGGER_HOVER: Record<SignalScoreUrgencyLabel, string> = {\n Urgent: URGENCY_SCORE_CLASSES.Urgent.hover,\n High: URGENCY_SCORE_CLASSES.High.hover,\n Medium: URGENCY_SCORE_CLASSES.Medium.hover,\n Low: URGENCY_SCORE_CLASSES.Low.hover,\n}\n\nconst URGENCY_TRIGGER_OPEN: Record<SignalScoreUrgencyLabel, string> = {\n Urgent: URGENCY_SCORE_CLASSES.Urgent.open,\n High: URGENCY_SCORE_CLASSES.High.open,\n Medium: URGENCY_SCORE_CLASSES.Medium.open,\n Low: URGENCY_SCORE_CLASSES.Low.open,\n}\n\n/** Re-use shared tone classes from score-semantics. */\nconst TONE_ICON_CLASSES: Record<PriorityFactor[\"tone\"], string> = SCORE_TONE_CLASSES as Record<PriorityFactor[\"tone\"], string>\n\nconst DIRECTION_CLASSES: Record<PriorityFactor[\"direction\"], string> = {\n raises: \"text-red-600\",\n lowers: \"text-emerald-600\",\n neutral: \"text-muted-foreground\",\n}\n\n// ---------------------------------------------------------------------------\n// Icon lookup\n// ---------------------------------------------------------------------------\n\nconst FACTOR_ICONS: Record<string, LucideIcon> = {\n radar: Radar,\n wallet: Wallet,\n \"link-2\": Link2,\n \"message-square\": MessageSquare,\n \"trending-down\": TrendingDown,\n \"arrow-up-right\": ArrowUpRight,\n clock: Clock,\n activity: Activity,\n}\n\n// ---------------------------------------------------------------------------\n// Urgency dot color (static map)\n// ---------------------------------------------------------------------------\n\nconst URGENCY_DOT_CLASSES: Record<SignalScoreUrgencyLabel, string> = {\n Urgent: URGENCY_SCORE_CLASSES.Urgent.dot,\n High: URGENCY_SCORE_CLASSES.High.dot,\n Medium: URGENCY_SCORE_CLASSES.Medium.dot,\n Low: URGENCY_SCORE_CLASSES.Low.dot,\n}\n\n// ---------------------------------------------------------------------------\n// Default feedback chips\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_PRIORITY_FEEDBACK_CHIPS: FeedbackChipTree[] = [\n { label: \"Wrong factor weighting\" },\n { label: \"Missing context\" },\n { label: \"Inaccurate data\" },\n { label: \"Stale\" },\n { label: \"Other\" },\n]\n\n// ---------------------------------------------------------------------------\n// Direction icon component\n// ---------------------------------------------------------------------------\n\nfunction DirectionIcon({ direction }: { direction: PriorityFactor[\"direction\"] }) {\n const cls = \"h-2.5 w-2.5\"\n switch (direction) {\n case \"raises\":\n return <ArrowUpRight className={cls} />\n case \"lowers\":\n return <ArrowDownRight className={cls} />\n case \"neutral\":\n return <Minus className={cls} />\n }\n}\n\n// ---------------------------------------------------------------------------\n// PriorityFactorRow\n// ---------------------------------------------------------------------------\n\ninterface PriorityFactorRowProps {\n factor: PriorityFactor\n initialFeedback?: { type: \"up\" | \"down\"; detail: string; ownershipLabel?: string }\n onFactorFeedback?: (factorKey: string, type: \"up\" | \"down\" | null, detail?: string) => void\n}\n\nfunction PriorityFactorRow({ factor, initialFeedback, onFactorFeedback }: PriorityFactorRowProps) {\n const IconComponent = FACTOR_ICONS[factor.icon] ?? Activity\n const toneClasses = TONE_ICON_CLASSES[factor.tone]\n const directionClasses = DIRECTION_CLASSES[factor.direction]\n const directionLabel = factor.directionLabel ?? (\n factor.direction === \"raises\"\n ? \"Raises\"\n : factor.direction === \"lowers\"\n ? \"Lowers\"\n : \"Neutral\"\n )\n\n return (\n <div\n className=\"grid grid-cols-[20px_1fr_auto] gap-x-3 gap-y-1 px-4 py-3\"\n data-testid={`factor-row-${factor.key}`}\n >\n {/* Icon */}\n <div\n className={cn(\n \"flex h-5 w-5 items-center justify-center rounded\",\n toneClasses,\n )}\n >\n <IconComponent className=\"h-3 w-3\" />\n </div>\n\n {/* Label + direction tag */}\n <div className=\"flex items-center gap-2\">\n <span className=\"text-[13px] font-semibold text-foreground\">\n {factor.label}\n </span>\n <span\n className={cn(\n \"inline-flex items-center gap-0.5 text-[10px] font-medium\",\n directionClasses,\n )}\n >\n <DirectionIcon direction={factor.direction} />\n {directionLabel}\n </span>\n </div>\n\n {/* Score number / display label */}\n <div className=\"flex items-center text-right\">\n {factor.displayValueLabel ? (\n <span className=\"text-xs font-semibold text-foreground\">{factor.displayValueLabel}</span>\n ) : (\n <>\n <span className=\"text-sm font-bold tabular-nums\">{factor.score}</span>\n <span className=\"text-xs font-normal text-muted-foreground\">/100</span>\n </>\n )}\n </div>\n\n {/* empty grid cell under icon column */}\n <div />\n\n {/* Rationale */}\n <p className=\"text-xs leading-relaxed text-muted-foreground\">\n {factor.rationale}\n </p>\n\n {/* empty grid cell under score column */}\n <div />\n\n {/* empty grid cell under icon column */}\n <div />\n\n {/* Score track */}\n <div className=\"mt-1 h-0.5 rounded-full bg-muted\">\n <div\n className=\"h-full rounded-full bg-foreground/20\"\n style={{ width: `${Math.min(100, Math.max(0, factor.score))}%` }}\n />\n </div>\n\n {/* empty grid cell under score column */}\n <div />\n\n {/* Factor-level feedback row (spans icon + content columns) */}\n {onFactorFeedback && (\n <>\n <div />\n <div className=\"col-span-2 mt-1\">\n <InlineFeedbackControl\n feedbackKey={factor.key}\n initialFeedback={initialFeedback}\n onFeedback={onFactorFeedback}\n testIdPrefix=\"factor\"\n />\n </div>\n </>\n )}\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// SignalPriorityPopover\n// ---------------------------------------------------------------------------\n\nexport function SignalPriorityPopover({\n score,\n urgencyLabel: providedLabel,\n urgencyExplanation,\n factors,\n metaText,\n feedbackChips,\n onFeedbackSubmit,\n className,\n initialFactorFeedback,\n onFactorFeedback,\n initialPriorityFeedback,\n}: SignalPriorityPopoverProps) {\n const urgencyLabel = providedLabel ?? getUrgencyLevel(score)\n const scoreRange = getUrgencyRange(urgencyLabel)\n\n const [open, setOpen] = React.useState(false)\n const [feedback, setFeedback] = React.useState<\"positive\" | \"negative\" | null>(null)\n\n const triggerDefault = URGENCY_TRIGGER_DEFAULT[urgencyLabel]\n const triggerHover = URGENCY_TRIGGER_HOVER[urgencyLabel]\n const triggerOpen = URGENCY_TRIGGER_OPEN[urgencyLabel]\n\n // Derive a stable feedbackKey for the footer from score + urgencyLabel\n const footerFeedbackKey = `priority-${score}-${urgencyLabel}`\n\n return (\n <PopoverPrimitive.Root open={open} onOpenChange={setOpen}>\n <PopoverPrimitive.Trigger asChild>\n <button\n type=\"button\"\n className={cn(\n \"inline-flex items-center gap-1 rounded-md border px-2.5 py-1 text-xs font-semibold transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n triggerDefault,\n triggerHover,\n open && triggerOpen,\n open && \"outline-2 outline-foreground outline-offset-2\",\n className,\n )}\n data-testid=\"priority-popover-trigger\"\n >\n {urgencyLabel} Priority\n {open ? (\n <ChevronUp className=\"h-3 w-3\" />\n ) : (\n <ChevronDown className=\"h-3 w-3\" />\n )}\n </button>\n </PopoverPrimitive.Trigger>\n\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n side=\"bottom\"\n align=\"start\"\n sideOffset={8}\n onOpenAutoFocus={(e) => e.preventDefault()}\n className=\"z-50 w-[420px] rounded-lg border border-border bg-background shadow-lg p-0\"\n data-testid=\"priority-popover-content\"\n >\n {/* Head section */}\n <div className=\"p-4 pb-3\">\n <div className=\"flex items-start justify-between gap-3\">\n <p className=\"text-sm font-semibold text-foreground\">\n Why this is {urgencyLabel.toLowerCase()} priority\n </p>\n <span className=\"text-2xl font-bold tabular-nums text-foreground\">\n {score}\n <span className=\"text-sm font-normal text-muted-foreground\">/100</span>\n </span>\n </div>\n\n {/* Band indicator */}\n <div className=\"mt-1 flex items-center gap-1.5 text-[11px] text-muted-foreground\">\n <span\n className={cn(\n \"inline-block h-2 w-2 rounded-full\",\n URGENCY_DOT_CLASSES[urgencyLabel],\n )}\n />\n {urgencyLabel} range: {scoreRange}\n </div>\n\n {/* Synthesis sentence */}\n {urgencyExplanation && (\n <p className=\"mt-2 text-xs leading-relaxed text-muted-foreground\">\n {urgencyExplanation}\n </p>\n )}\n </div>\n\n {/* Section label */}\n {factors.length > 0 && (\n <>\n <div className=\"flex items-center justify-between border-t border-border px-4 py-2\">\n <span className=\"text-[10px] font-bold uppercase tracking-wider text-muted-foreground\">\n Contributing factors\n </span>\n <span className=\"flex items-center gap-1 text-[10px] text-muted-foreground\">\n <Info className=\"h-3 w-3\" />\n Score = weighted sum\n </span>\n </div>\n\n {/* Factor rows */}\n <div className=\"divide-y divide-border/40\">\n {factors.map((factor) => (\n <PriorityFactorRow\n key={factor.key}\n factor={factor}\n initialFeedback={initialFactorFeedback?.[factor.key]}\n onFactorFeedback={onFactorFeedback}\n />\n ))}\n </div>\n </>\n )}\n\n {/* Feedback footer */}\n {onFeedbackSubmit && (\n <div className=\"border-t border-border\">\n <FeedbackFooter\n feedback={feedback}\n onFeedbackChange={setFeedback}\n onSubmit={onFeedbackSubmit}\n metaText={metaText}\n negativeChips={feedbackChips ?? DEFAULT_PRIORITY_FEEDBACK_CHIPS}\n positivePrompt=\"Thanks. Anything to keep about this score?\"\n className=\"px-4 py-3\"\n initialFeedback={initialPriorityFeedback}\n feedbackKey={footerFeedbackKey}\n />\n </div>\n )}\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n )\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/signal-priority-popover.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { Popover as PopoverPrimitive } from \"radix-ui\"\nimport type { LucideIcon } from \"lucide-react\"\nimport {\n Radar,\n Wallet,\n Link2,\n MessageSquare,\n TrendingDown,\n ArrowUpRight,\n ArrowDownRight,\n Clock,\n Activity,\n Minus,\n ChevronDown,\n ChevronUp,\n Info,\n} from \"lucide-react\"\nimport { cn } from \"../lib/utils\"\nimport { FeedbackFooter, InlineFeedbackControl } from \"./feedback-primitives\"\nimport type { FeedbackChipTree, FeedbackSubmitData, PersistedFeedbackData } from \"./feedback-primitives\"\nimport type { SignalScoreUrgencyLabel } from \"../prototype/prototype-config\"\nimport { getSignalScoreUrgencyLabel, scoreRangeForUrgency, SIGNAL_TONE_CLASSES } from \"./score-why-chips\"\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * A single contributing factor in the priority popover.\n */\nexport interface PriorityFactor {\n key: string\n label: string\n /** Lucide icon name (e.g. \"radar\", \"wallet\", \"link-2\", \"message-square\"). */\n icon: string\n /** Drives icon background tint. */\n tone: \"alert\" | \"warn\" | \"info\"\n /** Explicit semantic label - NOT inferred from score+weight. */\n direction: \"raises\" | \"lowers\" | \"neutral\"\n /** Optional display label for the direction text. Keeps semantic direction icon/color unchanged. */\n directionLabel?: string\n /** 0-100 */\n score: number\n /** Optional display label rendered instead of the numeric score cell. */\n displayValueLabel?: string\n /** Evidence text (e.g. \"$3.4M moved in 8h - current treasury balance $0.00\"). */\n rationale: string\n}\n\nexport interface SignalPriorityPopoverProps {\n score: number\n urgencyLabel?: SignalScoreUrgencyLabel\n /** Synthesis sentence displayed in the popover head. */\n urgencyExplanation?: string\n factors: PriorityFactor[]\n /** e.g. \"Updated 4m ago - model v3.2\" */\n metaText?: string\n /** Negative feedback issue tree. */\n feedbackChips?: FeedbackChipTree[]\n onFeedbackSubmit?: (data: FeedbackSubmitData) => void\n className?: string\n /** Persisted factor-level feedback (keyed by factor key). */\n initialFactorFeedback?: Record<string, { type: \"up\" | \"down\"; detail: string; ownershipLabel?: string }>\n /** Callback when user submits factor-level feedback. */\n onFactorFeedback?: (factorKey: string, type: \"up\" | \"down\" | null, detail?: string) => void\n /** Persisted priority-level feedback for the footer. */\n initialPriorityFeedback?: PersistedFeedbackData | null\n}\n\n// ---------------------------------------------------------------------------\n// Static class maps (required for Tailwind v4 source scanning)\n// ---------------------------------------------------------------------------\n\nconst URGENCY_TRIGGER_DEFAULT: Record<SignalScoreUrgencyLabel, string> = {\n Urgent: \"border-red-200 bg-red-50 text-red-700\",\n High: \"border-orange-200 bg-orange-50 text-orange-700\",\n Medium: \"border-amber-200 bg-amber-50 text-amber-700\",\n Low: \"border-blue-200 bg-blue-50 text-blue-700\",\n}\n\nconst URGENCY_TRIGGER_HOVER: Record<SignalScoreUrgencyLabel, string> = {\n Urgent: \"hover:bg-red-100\",\n High: \"hover:bg-orange-100\",\n Medium: \"hover:bg-amber-100\",\n Low: \"hover:bg-blue-100\",\n}\n\nconst URGENCY_TRIGGER_OPEN: Record<SignalScoreUrgencyLabel, string> = {\n Urgent: \"bg-red-100\",\n High: \"bg-orange-100\",\n Medium: \"bg-amber-100\",\n Low: \"bg-blue-100\",\n}\n\n/** Re-use shared tone classes from score-why-chips. */\nconst TONE_ICON_CLASSES: Record<PriorityFactor[\"tone\"], string> = SIGNAL_TONE_CLASSES as Record<PriorityFactor[\"tone\"], string>\n\nconst DIRECTION_CLASSES: Record<PriorityFactor[\"direction\"], string> = {\n raises: \"text-red-600\",\n lowers: \"text-emerald-600\",\n neutral: \"text-muted-foreground\",\n}\n\n// ---------------------------------------------------------------------------\n// Icon lookup\n// ---------------------------------------------------------------------------\n\nconst FACTOR_ICONS: Record<string, LucideIcon> = {\n radar: Radar,\n wallet: Wallet,\n \"link-2\": Link2,\n \"message-square\": MessageSquare,\n \"trending-down\": TrendingDown,\n \"arrow-up-right\": ArrowUpRight,\n clock: Clock,\n activity: Activity,\n}\n\n// ---------------------------------------------------------------------------\n// Urgency dot color (static map)\n// ---------------------------------------------------------------------------\n\nconst URGENCY_DOT_CLASSES: Record<SignalScoreUrgencyLabel, string> = {\n Urgent: \"bg-red-500\",\n High: \"bg-orange-500\",\n Medium: \"bg-amber-500\",\n Low: \"bg-blue-500\",\n}\n\n// ---------------------------------------------------------------------------\n// Default feedback chips\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_PRIORITY_FEEDBACK_CHIPS: FeedbackChipTree[] = [\n { label: \"Wrong factor weighting\" },\n { label: \"Missing context\" },\n { label: \"Inaccurate data\" },\n { label: \"Stale\" },\n { label: \"Other\" },\n]\n\n// ---------------------------------------------------------------------------\n// Direction icon component\n// ---------------------------------------------------------------------------\n\nfunction DirectionIcon({ direction }: { direction: PriorityFactor[\"direction\"] }) {\n const cls = \"h-2.5 w-2.5\"\n switch (direction) {\n case \"raises\":\n return <ArrowUpRight className={cls} />\n case \"lowers\":\n return <ArrowDownRight className={cls} />\n case \"neutral\":\n return <Minus className={cls} />\n }\n}\n\n// ---------------------------------------------------------------------------\n// PriorityFactorRow\n// ---------------------------------------------------------------------------\n\ninterface PriorityFactorRowProps {\n factor: PriorityFactor\n initialFeedback?: { type: \"up\" | \"down\"; detail: string; ownershipLabel?: string }\n onFactorFeedback?: (factorKey: string, type: \"up\" | \"down\" | null, detail?: string) => void\n}\n\nfunction PriorityFactorRow({ factor, initialFeedback, onFactorFeedback }: PriorityFactorRowProps) {\n const IconComponent = FACTOR_ICONS[factor.icon] ?? Activity\n const toneClasses = TONE_ICON_CLASSES[factor.tone]\n const directionClasses = DIRECTION_CLASSES[factor.direction]\n const directionLabel = factor.directionLabel ?? (\n factor.direction === \"raises\"\n ? \"Raises\"\n : factor.direction === \"lowers\"\n ? \"Lowers\"\n : \"Neutral\"\n )\n\n return (\n <div\n className=\"grid grid-cols-[20px_1fr_auto] gap-x-3 gap-y-1 px-4 py-3\"\n data-testid={`factor-row-${factor.key}`}\n >\n {/* Icon */}\n <div\n className={cn(\n \"flex h-5 w-5 items-center justify-center rounded\",\n toneClasses,\n )}\n >\n <IconComponent className=\"h-3 w-3\" />\n </div>\n\n {/* Label + direction tag */}\n <div className=\"flex items-center gap-2\">\n <span className=\"text-[13px] font-semibold text-foreground\">\n {factor.label}\n </span>\n <span\n className={cn(\n \"inline-flex items-center gap-0.5 text-[10px] font-medium\",\n directionClasses,\n )}\n >\n <DirectionIcon direction={factor.direction} />\n {directionLabel}\n </span>\n </div>\n\n {/* Score number / display label */}\n <div className=\"flex items-center text-right\">\n {factor.displayValueLabel ? (\n <span className=\"text-xs font-semibold text-foreground\">{factor.displayValueLabel}</span>\n ) : (\n <>\n <span className=\"text-sm font-bold tabular-nums\">{factor.score}</span>\n <span className=\"text-xs font-normal text-muted-foreground\">/100</span>\n </>\n )}\n </div>\n\n {/* empty grid cell under icon column */}\n <div />\n\n {/* Rationale */}\n <p className=\"text-xs leading-relaxed text-muted-foreground\">\n {factor.rationale}\n </p>\n\n {/* empty grid cell under score column */}\n <div />\n\n {/* empty grid cell under icon column */}\n <div />\n\n {/* Score track */}\n <div className=\"mt-1 h-0.5 rounded-full bg-muted\">\n <div\n className=\"h-full rounded-full bg-foreground/20\"\n style={{ width: `${Math.min(100, Math.max(0, factor.score))}%` }}\n />\n </div>\n\n {/* empty grid cell under score column */}\n <div />\n\n {/* Factor-level feedback row (spans icon + content columns) */}\n {onFactorFeedback && (\n <>\n <div />\n <div className=\"col-span-2 mt-1\">\n <InlineFeedbackControl\n feedbackKey={factor.key}\n initialFeedback={initialFeedback}\n onFeedback={onFactorFeedback}\n testIdPrefix=\"factor\"\n />\n </div>\n </>\n )}\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// SignalPriorityPopover\n// ---------------------------------------------------------------------------\n\nexport function SignalPriorityPopover({\n score,\n urgencyLabel: providedLabel,\n urgencyExplanation,\n factors,\n metaText,\n feedbackChips,\n onFeedbackSubmit,\n className,\n initialFactorFeedback,\n onFactorFeedback,\n initialPriorityFeedback,\n}: SignalPriorityPopoverProps) {\n const urgencyLabel = getSignalScoreUrgencyLabel(score, providedLabel)\n const scoreRange = scoreRangeForUrgency(urgencyLabel)\n\n const [open, setOpen] = React.useState(false)\n const [feedback, setFeedback] = React.useState<\"positive\" | \"negative\" | null>(null)\n\n const triggerDefault = URGENCY_TRIGGER_DEFAULT[urgencyLabel]\n const triggerHover = URGENCY_TRIGGER_HOVER[urgencyLabel]\n const triggerOpen = URGENCY_TRIGGER_OPEN[urgencyLabel]\n\n // Derive a stable feedbackKey for the footer from score + urgencyLabel\n const footerFeedbackKey = `priority-${score}-${urgencyLabel}`\n\n return (\n <PopoverPrimitive.Root open={open} onOpenChange={setOpen}>\n <PopoverPrimitive.Trigger asChild>\n <button\n type=\"button\"\n className={cn(\n \"inline-flex items-center gap-1 rounded-md border px-2.5 py-1 text-xs font-semibold transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n triggerDefault,\n triggerHover,\n open && triggerOpen,\n open && \"outline-2 outline-foreground outline-offset-2\",\n className,\n )}\n data-testid=\"priority-popover-trigger\"\n >\n {urgencyLabel} Priority\n {open ? (\n <ChevronUp className=\"h-3 w-3\" />\n ) : (\n <ChevronDown className=\"h-3 w-3\" />\n )}\n </button>\n </PopoverPrimitive.Trigger>\n\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n side=\"bottom\"\n align=\"start\"\n sideOffset={8}\n onOpenAutoFocus={(e) => e.preventDefault()}\n className=\"z-50 w-[420px] rounded-lg border border-border bg-background shadow-lg p-0\"\n data-testid=\"priority-popover-content\"\n >\n {/* Head section */}\n <div className=\"p-4 pb-3\">\n <div className=\"flex items-start justify-between gap-3\">\n <p className=\"text-sm font-semibold text-foreground\">\n Why this is {urgencyLabel.toLowerCase()} priority\n </p>\n <span className=\"text-2xl font-bold tabular-nums text-foreground\">\n {score}\n <span className=\"text-sm font-normal text-muted-foreground\">/100</span>\n </span>\n </div>\n\n {/* Band indicator */}\n <div className=\"mt-1 flex items-center gap-1.5 text-[11px] text-muted-foreground\">\n <span\n className={cn(\n \"inline-block h-2 w-2 rounded-full\",\n URGENCY_DOT_CLASSES[urgencyLabel],\n )}\n />\n {urgencyLabel} range: {scoreRange}\n </div>\n\n {/* Synthesis sentence */}\n {urgencyExplanation && (\n <p className=\"mt-2 text-xs leading-relaxed text-muted-foreground\">\n {urgencyExplanation}\n </p>\n )}\n </div>\n\n {/* Section label */}\n {factors.length > 0 && (\n <>\n <div className=\"flex items-center justify-between border-t border-border px-4 py-2\">\n <span className=\"text-[10px] font-bold uppercase tracking-wider text-muted-foreground\">\n Contributing factors\n </span>\n <span className=\"flex items-center gap-1 text-[10px] text-muted-foreground\">\n <Info className=\"h-3 w-3\" />\n Score = weighted sum\n </span>\n </div>\n\n {/* Factor rows */}\n <div className=\"divide-y divide-border/40\">\n {factors.map((factor) => (\n <PriorityFactorRow\n key={factor.key}\n factor={factor}\n initialFeedback={initialFactorFeedback?.[factor.key]}\n onFactorFeedback={onFactorFeedback}\n />\n ))}\n </div>\n </>\n )}\n\n {/* Feedback footer */}\n {onFeedbackSubmit && (\n <div className=\"border-t border-border\">\n <FeedbackFooter\n feedback={feedback}\n onFeedbackChange={setFeedback}\n onSubmit={onFeedbackSubmit}\n metaText={metaText}\n negativeChips={feedbackChips ?? DEFAULT_PRIORITY_FEEDBACK_CHIPS}\n positivePrompt=\"Thanks. Anything to keep about this score?\"\n className=\"px-4 py-3\"\n initialFeedback={initialPriorityFeedback}\n feedbackKey={footerFeedbackKey}\n />\n </div>\n )}\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n )\n}\n"],"mappings":"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","names":[]}
package/dist/index.d.ts CHANGED
@@ -10,11 +10,15 @@ export { Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, Ava
10
10
  export { Badge, badgeVariants } from './components/badge.js';
11
11
  export { Button, buttonVariants } from './components/button.js';
12
12
  export { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from './components/card.js';
13
+ export { CasePanelEmailComposer, CasePanelEmailComposerChip, CasePanelEmailComposerChipProps, CasePanelEmailComposerProps, CasePanelEmailComposerRow, CasePanelEmailComposerRowProps, CasePanelEmailComposerRowState, CasePanelEmailComposerSignatureRow, CasePanelEmailComposerSignatureRowProps, CasePanelEmailComposerSlotHelpers } from './components/case-panel-email-composer.js';
14
+ export { CasePanelActivityActor, CasePanelActivityEvent, CasePanelActivityPayload, CasePanelActivityTimeline, CasePanelActivityTimelineProps, CasePanelActivityTone, CasePanelPayloadAction } from './components/case-panel-activity-timeline.js';
15
+ export { CasePanelDetail, CasePanelDetailProps, CasePanelDetailSlots, CasePanelDetailSlotsProps, CasePanelDetailWidth, CasePanelHeader, CasePanelHeaderProps, CasePanelIdentityLink, CasePanelIdentitySubline, CasePanelIdentitySublineProps, CasePanelMetadataRow, CasePanelMetadataRowProps, CasePanelSignalBrief, CasePanelSignalBriefProps } from './components/case-panel-detail.js';
16
+ export { CasePanelSignalApprovalActions, CasePanelSignalApprovalActionsProps, CasePanelWhy, CasePanelWhyItem, CasePanelWhyProps, CasePanelWhyRow, CasePanelWhyTone } from './components/case-panel-why.js';
13
17
  export { CollapsibleSection, CollapsibleSectionProps } from './components/collapsible-section.js';
14
18
  export { ComplianceBadge, ComplianceBadgeProps, ComplianceStatus } from './components/compliance-badge.js';
15
19
  export { ContactChip, ContactChipProps } from './components/contact-chip.js';
16
20
  export { ContactChannel, ContactItem, ContactList, ContactListProps } from './components/contact-list.js';
17
- export { ContextualQuickActionContextLabel, ContextualQuickActionContextLabelProps, ContextualQuickActionItem, ContextualQuickActionLauncher, ContextualQuickActionLauncherProps } from './components/contextual-quick-action-launcher.js';
21
+ export { ContextualQuickActionContextLabel, ContextualQuickActionContextLabelProps, ContextualQuickActionItem, ContextualQuickActionLauncher, ContextualQuickActionLauncherProps, ContextualQuickActionLauncherVariant } from './components/contextual-quick-action-launcher.js';
18
22
  export { CheckInsCard, RecentlyCompletedCard, TopTasksCard, UpcomingMeetingsCard } from './components/dashboard-cards.js';
19
23
  export { DataRow, DataTable, DataTableProps } from './components/data-table.js';
20
24
  export { ConditionFieldDef, ConditionFieldOption, ConditionFilterValue, ConditionOperator, ConditionOptionObject, DEFAULT_OPERATORS, DataTableConditionFilter, DataTableConditionFilterProps, OPERATOR_LABELS, generateConditionId, getOperators, shouldShowOptionSearch } from './components/data-table-condition-filter.js';
@@ -57,12 +61,11 @@ export { ActiveVariant, QuickActionSidebarNav, SidebarNavItem, SidebarNavSection
57
61
  export { RecommendedAction, RecommendedActionsSection } from './components/recommended-actions-section.js';
58
62
  export { ReportCard, ReportCardProps } from './components/report-card.js';
59
63
  export { RichTextAction, RichTextToolbar, RichTextToolbarProps } from './components/rich-text-toolbar.js';
60
- export { ScoreAnalysisModal, ScoreAnalysisModalProps, ScoreAnalysisPanel, getScoreLabel } from './components/score-analysis-modal.js';
64
+ export { ScoreAnalysisModal, ScoreAnalysisModalProps, ScoreAnalysisPanel } from './components/score-analysis-modal.js';
61
65
  export { ScoreBreakdown, ScoreBreakdownProps, ScoreFactor } from './components/score-breakdown.js';
62
66
  export { ScoreFeedback, useScoreFeedback } from './components/score-feedback.js';
63
- export { DEFAULT_SCORE_TONE_CLASS, POSITIVE_SCORE_CLASSES, PositiveLevel, RISK_SCORE_CLASSES, RiskLevel, SCORE_TONE_CLASSES, ScoreIntent, ScoreSemanticClasses, URGENCY_SCORE_CLASSES, UrgencyLevel, getPositiveLevel, getRiskLevel, getScoreToneClasses, getUrgencyLevel, getUrgencyRange } from './components/score-semantics.js';
64
67
  export { DEFAULT_TONE_CLASS, SIGNAL_TONE_CLASSES, ScoreWhyChips, ScoreWhyChipsProps, getSignalScoreUrgencyLabel, scoreRangeForUrgency } from './components/score-why-chips.js';
65
- export { ScoreRing, ScoreRingProps, getScoreColor, getScoreTrackColor } from './components/score-ring.js';
68
+ export { ScoreRing, ScoreRingProps, getScoreColor } from './components/score-ring.js';
66
69
  export { ScrollArea, ScrollBar } from './components/scroll-area.js';
67
70
  export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue } from './components/select.js';
68
71
  export { Separator } from './components/separator.js';
package/dist/index.js CHANGED
@@ -10,6 +10,10 @@ export * from "./components/avatar.js";
10
10
  export * from "./components/badge.js";
11
11
  export * from "./components/button.js";
12
12
  export * from "./components/card.js";
13
+ export * from "./components/case-panel-email-composer.js";
14
+ export * from "./components/case-panel-activity-timeline.js";
15
+ export * from "./components/case-panel-detail.js";
16
+ export * from "./components/case-panel-why.js";
13
17
  import { CollapsibleSection } from "./components/collapsible-section.js";
14
18
  export * from "./components/compliance-badge.js";
15
19
  export * from "./components/contact-chip.js";
@@ -62,7 +66,6 @@ export * from "./components/rich-text-toolbar.js";
62
66
  export * from "./components/score-analysis-modal.js";
63
67
  export * from "./components/score-breakdown.js";
64
68
  export * from "./components/score-feedback.js";
65
- export * from "./components/score-semantics.js";
66
69
  export * from "./components/score-why-chips.js";
67
70
  export * from "./components/score-ring.js";
68
71
  export * from "./components/scroll-area.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @handled-ai/design-system\n * UI components and utilities (shadcn-style, New York)\n */\n\n// Utilities\nexport { cn } from \"./lib/utils\"\nexport { BRAND_ICONS, BRAND_GRAPHICS } from \"./lib/icons\"\nexport { displayName, getInitials, shortName, type ProfileLike } from \"./lib/user-display\"\n\n// Hooks\nexport { useIsMobile } from \"./hooks/use-mobile\"\n\n// Components (light — no recharts/nivo/three transitive deps)\nexport * from \"./components/activity-detail\"\nexport * from \"./components/activity-log\"\nexport * from \"./components/agent-popover\"\nexport * from \"./components/agent-widget\"\nexport * from \"./components/avatar\"\nexport * from \"./components/badge\"\nexport * from \"./components/button\"\nexport * from \"./components/card\"\nexport { CollapsibleSection, type CollapsibleSectionProps } from \"./components/collapsible-section\"\nexport * from \"./components/compliance-badge\"\nexport * from \"./components/contact-chip\"\nexport * from \"./components/contact-list\"\nexport * from \"./components/contextual-quick-action-launcher\"\nexport * from \"./components/dashboard-cards\"\nexport * from \"./components/data-table\"\nexport * from \"./components/data-table-condition-filter\"\nexport * from \"./components/data-table-display\"\nexport * from \"./components/data-table-filter\"\nexport * from \"./components/data-table-quick-views\"\nexport * from \"./components/data-table-toolbar\"\nexport * from \"./components/detail-view\"\nexport * from \"./components/detail-drawer\"\nexport * from \"./components/dialog\"\nexport * from \"./components/dropdown-menu\"\nexport * from \"./components/empty-state\"\nexport * from \"./components/entity-panel\"\nexport { FeedbackFooter, FeedbackChipGroup, FeedbackInput, FeedbackActions, InlineFeedbackControl } from \"./components/feedback-primitives\"\nexport type { FeedbackFooterProps, FeedbackChipTree, FeedbackChipGroupProps, FeedbackInputProps, FeedbackActionsProps, FeedbackSubmitData, PersistedFeedbackData, InlineFeedbackControlProps } from \"./components/feedback-primitives\"\nexport { SignalPriorityPopover } from \"./components/signal-priority-popover\"\nexport type { SignalPriorityPopoverProps, PriorityFactor } from \"./components/signal-priority-popover\"\nexport * from \"./components/filter-chip\"\nexport * from \"./components/inbox-row\"\nexport * from \"./components/inbox-toolbar\"\nexport * from \"./components/inline-banner\"\nexport * from \"./components/input\"\nexport * from \"./components/insights-filter-bar\"\nexport * from \"./components/days-open-cell\"\nexport * from \"./components/linked-entity-cell\"\nexport * from \"./components/item-list\"\nexport * from \"./components/item-list-display\"\nexport * from \"./components/item-list-filter\"\nexport * from \"./components/item-list-toolbar\"\nexport * from \"./components/kbd-hint\"\nexport * from \"./components/label\"\nexport * from \"./components/message\"\nexport * from \"./components/metric-card\"\nexport * from \"./components/performance-metrics-table\"\nexport * from \"./components/pill\"\nexport * from \"./components/preview-list\"\nexport * from \"./components/progress\"\nexport * from \"./components/quick-action-chat-area\"\nexport * from \"./components/quick-segment\"\nexport {\n QuickActionModal,\n type QuickActionPriority,\n type QuickActionTaskDraft,\n type QuickActionTemplate,\n} from \"./components/quick-action-modal\"\nexport * from \"./components/quick-action-sidebar-nav\"\nexport * from \"./components/recommended-actions-section\"\nexport * from \"./components/report-card\"\nexport * from \"./components/rich-text-toolbar\"\nexport * from \"./components/score-analysis-modal\"\nexport * from \"./components/score-breakdown\"\nexport * from \"./components/score-feedback\"\nexport * from \"./components/score-semantics\"\nexport * from \"./components/score-why-chips\"\nexport * from \"./components/score-ring\"\nexport * from \"./components/scroll-area\"\nexport * from \"./components/select\"\nexport * from \"./components/separator\"\nexport * from \"./components/sheet\"\nexport * from \"./components/sidebar\"\nexport * from \"./components/signal-feedback-inline\"\nexport * from \"./components/simple-data-table\"\nexport * from \"./components/skeleton\"\nexport * from \"./components/status-badge\"\nexport * from \"./components/step-timeline\"\nexport * from \"./components/sticky-action-bar\"\nexport * from \"./components/styled-bar-list\"\nexport { DraftFeedbackInline } from \"./components/draft-feedback-inline\"\nexport type { DraftFeedbackInlineProps } from \"./components/draft-feedback-inline\"\nexport { AccountContactsPopover, BrandIcon } from \"./components/account-contacts-popover\"\nexport type { AccountContactsPopoverProps } from \"./components/account-contacts-popover\"\nexport * from \"./components/suggested-actions\"\nexport * from \"./components/switch\"\nexport * from \"./components/table\"\nexport * from \"./components/tabs\"\nexport * from \"./components/textarea\"\nexport * from \"./components/timeline-activity\"\nexport * from \"./components/tooltip\"\nexport * from \"./components/user-display\"\nexport * from \"./components/variable-autocomplete\"\nexport * from \"./components/view-mode-toggle\"\nexport * from \"./components/virtualized-data-table\"\nexport type { ColumnSizingState } from \"@tanstack/react-table\"\n\n// Charts (re-exported for backward compatibility with root imports)\nexport * from \"./charts/index\"\n\n// Prototype template system (re-exported for backward compatibility)\nexport * from \"./prototype/prototype-config\"\nexport * from \"./prototype/prototype-shell\"\nexport * from \"./prototype/prototype-inbox-view\"\nexport * from \"./prototype/prototype-insights-view\"\nexport * from \"./prototype/prototype-accounts-view\"\nexport * from \"./prototype/prototype-admin-view\"\nexport * from \"./prototype/prototype-work-queue-view\"\n"],"mappings":"AAMA,SAAS,UAAU;AACnB,SAAS,aAAa,sBAAsB;AAC5C,SAAS,aAAa,aAAa,iBAAmC;AAGtE,SAAS,mBAAmB;AAG5B,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAAS,0BAAwD;AACjE,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAAS,gBAAgB,mBAAmB,eAAe,iBAAiB,6BAA6B;AAEzG,SAAS,6BAA6B;AAEtC,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd;AAAA,EACE;AAAA,OAIK;AACP,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAAS,2BAA2B;AAEpC,SAAS,wBAAwB,iBAAiB;AAElD,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AAId,cAAc;AAGd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @handled-ai/design-system\n * UI components and utilities (shadcn-style, New York)\n */\n\n// Utilities\nexport { cn } from \"./lib/utils\"\nexport { BRAND_ICONS, BRAND_GRAPHICS } from \"./lib/icons\"\nexport { displayName, getInitials, shortName, type ProfileLike } from \"./lib/user-display\"\n\n// Hooks\nexport { useIsMobile } from \"./hooks/use-mobile\"\n\n// Components (light — no recharts/nivo/three transitive deps)\nexport * from \"./components/activity-detail\"\nexport * from \"./components/activity-log\"\nexport * from \"./components/agent-popover\"\nexport * from \"./components/agent-widget\"\nexport * from \"./components/avatar\"\nexport * from \"./components/badge\"\nexport * from \"./components/button\"\nexport * from \"./components/card\"\nexport * from \"./components/case-panel-email-composer\"\nexport * from \"./components/case-panel-activity-timeline\"\nexport * from \"./components/case-panel-detail\"\nexport * from \"./components/case-panel-why\"\nexport { CollapsibleSection, type CollapsibleSectionProps } from \"./components/collapsible-section\"\nexport * from \"./components/compliance-badge\"\nexport * from \"./components/contact-chip\"\nexport * from \"./components/contact-list\"\nexport * from \"./components/contextual-quick-action-launcher\"\nexport * from \"./components/dashboard-cards\"\nexport * from \"./components/data-table\"\nexport * from \"./components/data-table-condition-filter\"\nexport * from \"./components/data-table-display\"\nexport * from \"./components/data-table-filter\"\nexport * from \"./components/data-table-quick-views\"\nexport * from \"./components/data-table-toolbar\"\nexport * from \"./components/detail-view\"\nexport * from \"./components/detail-drawer\"\nexport * from \"./components/dialog\"\nexport * from \"./components/dropdown-menu\"\nexport * from \"./components/empty-state\"\nexport * from \"./components/entity-panel\"\nexport { FeedbackFooter, FeedbackChipGroup, FeedbackInput, FeedbackActions, InlineFeedbackControl } from \"./components/feedback-primitives\"\nexport type { FeedbackFooterProps, FeedbackChipTree, FeedbackChipGroupProps, FeedbackInputProps, FeedbackActionsProps, FeedbackSubmitData, PersistedFeedbackData, InlineFeedbackControlProps } from \"./components/feedback-primitives\"\nexport { SignalPriorityPopover } from \"./components/signal-priority-popover\"\nexport type { SignalPriorityPopoverProps, PriorityFactor } from \"./components/signal-priority-popover\"\nexport * from \"./components/filter-chip\"\nexport * from \"./components/inbox-row\"\nexport * from \"./components/inbox-toolbar\"\nexport * from \"./components/inline-banner\"\nexport * from \"./components/input\"\nexport * from \"./components/insights-filter-bar\"\nexport * from \"./components/days-open-cell\"\nexport * from \"./components/linked-entity-cell\"\nexport * from \"./components/item-list\"\nexport * from \"./components/item-list-display\"\nexport * from \"./components/item-list-filter\"\nexport * from \"./components/item-list-toolbar\"\nexport * from \"./components/kbd-hint\"\nexport * from \"./components/label\"\nexport * from \"./components/message\"\nexport * from \"./components/metric-card\"\nexport * from \"./components/performance-metrics-table\"\nexport * from \"./components/pill\"\nexport * from \"./components/preview-list\"\nexport * from \"./components/progress\"\nexport * from \"./components/quick-action-chat-area\"\nexport * from \"./components/quick-segment\"\nexport {\n QuickActionModal,\n type QuickActionPriority,\n type QuickActionTaskDraft,\n type QuickActionTemplate,\n} from \"./components/quick-action-modal\"\nexport * from \"./components/quick-action-sidebar-nav\"\nexport * from \"./components/recommended-actions-section\"\nexport * from \"./components/report-card\"\nexport * from \"./components/rich-text-toolbar\"\nexport * from \"./components/score-analysis-modal\"\nexport * from \"./components/score-breakdown\"\nexport * from \"./components/score-feedback\"\nexport * from \"./components/score-why-chips\"\nexport * from \"./components/score-ring\"\nexport * from \"./components/scroll-area\"\nexport * from \"./components/select\"\nexport * from \"./components/separator\"\nexport * from \"./components/sheet\"\nexport * from \"./components/sidebar\"\nexport * from \"./components/signal-feedback-inline\"\nexport * from \"./components/simple-data-table\"\nexport * from \"./components/skeleton\"\nexport * from \"./components/status-badge\"\nexport * from \"./components/step-timeline\"\nexport * from \"./components/sticky-action-bar\"\nexport * from \"./components/styled-bar-list\"\nexport { DraftFeedbackInline } from \"./components/draft-feedback-inline\"\nexport type { DraftFeedbackInlineProps } from \"./components/draft-feedback-inline\"\nexport { AccountContactsPopover, BrandIcon } from \"./components/account-contacts-popover\"\nexport type { AccountContactsPopoverProps } from \"./components/account-contacts-popover\"\nexport * from \"./components/suggested-actions\"\nexport * from \"./components/switch\"\nexport * from \"./components/table\"\nexport * from \"./components/tabs\"\nexport * from \"./components/textarea\"\nexport * from \"./components/timeline-activity\"\nexport * from \"./components/tooltip\"\nexport * from \"./components/user-display\"\nexport * from \"./components/variable-autocomplete\"\nexport * from \"./components/view-mode-toggle\"\nexport * from \"./components/virtualized-data-table\"\nexport type { ColumnSizingState } from \"@tanstack/react-table\"\n\n// Charts (re-exported for backward compatibility with root imports)\nexport * from \"./charts/index\"\n\n// Prototype template system (re-exported for backward compatibility)\nexport * from \"./prototype/prototype-config\"\nexport * from \"./prototype/prototype-shell\"\nexport * from \"./prototype/prototype-inbox-view\"\nexport * from \"./prototype/prototype-insights-view\"\nexport * from \"./prototype/prototype-accounts-view\"\nexport * from \"./prototype/prototype-admin-view\"\nexport * from \"./prototype/prototype-work-queue-view\"\n"],"mappings":"AAMA,SAAS,UAAU;AACnB,SAAS,aAAa,sBAAsB;AAC5C,SAAS,aAAa,aAAa,iBAAmC;AAGtE,SAAS,mBAAmB;AAG5B,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAAS,0BAAwD;AACjE,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAAS,gBAAgB,mBAAmB,eAAe,iBAAiB,6BAA6B;AAEzG,SAAS,6BAA6B;AAEtC,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd;AAAA,EACE;AAAA,OAIK;AACP,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAAS,2BAA2B;AAEpC,SAAS,wBAAwB,iBAAiB;AAElD,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AAId,cAAc;AAGd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
@@ -10,7 +10,6 @@ import '../components/feedback-primitives.js';
10
10
  import '../components/quick-action-sidebar-nav.js';
11
11
  import '../components/quick-action-modal.js';
12
12
  import '../components/score-breakdown.js';
13
- import '../components/score-semantics.js';
14
13
  import '../components/suggested-actions.js';
15
14
  import '../components/detail-view.js';
16
15
  import '../components/inbox-toolbar.js';
@@ -5,7 +5,6 @@ import '../components/feedback-primitives.js';
5
5
  import '../components/quick-action-sidebar-nav.js';
6
6
  import '../components/quick-action-modal.js';
7
7
  import '../components/score-breakdown.js';
8
- import '../components/score-semantics.js';
9
8
  import '../components/suggested-actions.js';
10
9
  import '../components/detail-view.js';
11
10
  import '../components/inbox-toolbar.js';
@@ -4,7 +4,6 @@ import '../components/feedback-primitives.js';
4
4
  import '../components/quick-action-sidebar-nav.js';
5
5
  import '../components/quick-action-modal.js';
6
6
  import '../components/score-breakdown.js';
7
- import '../components/score-semantics.js';
8
7
  import '../components/suggested-actions.js';
9
8
  import '../components/detail-view.js';
10
9
  import '../components/inbox-toolbar.js';
@@ -14,5 +14,4 @@ import 'lucide-react';
14
14
  export { A as AccountFilterTab, a as AccountsViewConfig, b as AdminTab, c as AdminViewConfig, B as BriefStyleVariant, E as EntityPanelConfig, d as EntityPanelSection, I as InboxDetailSections, e as InboxSortOption, f as InboxViewConfig, g as InsightsCustomTab, h as InsightsViewConfig, i as PrototypeBrandConfig, j as PrototypeConfig, Q as QueueItem, l as SignalScoreData, m as SignalScoreExplanationBucket, n as SignalScoreExplanationSignal, o as SignalScoreUrgencyLabel, T as TimelineSystemEventsConfig, W as WorkQueueViewConfig } from '../signal-priority-popover-B5b-XZ7i.js';
15
15
  import '../components/feedback-primitives.js';
16
16
  import '../components/quick-action-modal.js';
17
- import '../components/score-semantics.js';
18
17
  import '../components/data-table-condition-filter.js';
@@ -8,7 +8,6 @@ import '../components/feedback-primitives.js';
8
8
  import '../components/quick-action-sidebar-nav.js';
9
9
  import '../components/quick-action-modal.js';
10
10
  import '../components/score-breakdown.js';
11
- import '../components/score-semantics.js';
12
11
  import '../components/inbox-toolbar.js';
13
12
  import '../components/data-table-filter.js';
14
13
  import '../components/data-table-condition-filter.js';
@@ -4,7 +4,6 @@ import '../components/feedback-primitives.js';
4
4
  import '../components/quick-action-sidebar-nav.js';
5
5
  import '../components/quick-action-modal.js';
6
6
  import '../components/score-breakdown.js';
7
- import '../components/score-semantics.js';
8
7
  import '../components/suggested-actions.js';
9
8
  import '../components/detail-view.js';
10
9
  import '../components/inbox-toolbar.js';
@@ -4,7 +4,6 @@ import '../components/feedback-primitives.js';
4
4
  import '../components/quick-action-sidebar-nav.js';
5
5
  import '../components/quick-action-modal.js';
6
6
  import '../components/score-breakdown.js';
7
- import '../components/score-semantics.js';
8
7
  import '../components/suggested-actions.js';
9
8
  import '../components/detail-view.js';
10
9
  import '../components/inbox-toolbar.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@handled-ai/design-system",
3
- "version": "0.18.22",
3
+ "version": "0.18.23",
4
4
  "description": "Handled UI component library (shadcn-style, New York)",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@9.12.0",
@@ -0,0 +1,152 @@
1
+ import React from "react"
2
+ import { describe, expect, it, vi } from "vitest"
3
+ import { fireEvent, render, screen, within } from "@testing-library/react"
4
+ import {
5
+ CasePanelActivityTimeline,
6
+ type CasePanelActivityEvent,
7
+ } from "../case-panel-activity-timeline"
8
+
9
+ function event(overrides: Partial<CasePanelActivityEvent> = {}): CasePanelActivityEvent {
10
+ return {
11
+ id: "event-1",
12
+ title: "Signal detected",
13
+ timeLabel: "2h ago",
14
+ tone: "blue",
15
+ payload: { kind: "generic", description: "A case update happened" },
16
+ ...overrides,
17
+ }
18
+ }
19
+
20
+ const visibleEvent = event()
21
+ const systemNoiseEvent = event({
22
+ id: "system-1",
23
+ title: "System recalculated routing state",
24
+ timeLabel: "1h ago",
25
+ tone: "slate",
26
+ actor: { kind: "system" },
27
+ isSystemNoise: true,
28
+ payload: { kind: "generic", description: "Internal routing snapshot refreshed" },
29
+ })
30
+
31
+ describe("CasePanelActivityTimeline", () => {
32
+ it("renders collapsed by default with non-system count and last activity text", () => {
33
+ render(<CasePanelActivityTimeline events={[visibleEvent, systemNoiseEvent]} />)
34
+
35
+ expect(screen.getByRole("button", { name: /activity/i }).getAttribute("aria-expanded")).toBe("false")
36
+ expect(screen.getByText("1 event")).not.toBeNull()
37
+ expect(screen.getByText("Last activity 2h ago")).not.toBeNull()
38
+ expect(screen.queryByText("Signal detected")).toBeNull()
39
+ })
40
+
41
+ it("expands and renders visible timeline events", () => {
42
+ render(<CasePanelActivityTimeline events={[visibleEvent]} />)
43
+
44
+ fireEvent.click(screen.getByRole("button", { name: /activity/i }))
45
+
46
+ expect(screen.getByText("Signal detected")).not.toBeNull()
47
+ expect(screen.getByText("A case update happened")).not.toBeNull()
48
+ expect(screen.getByTestId("case-panel-activity-dot").className).toContain("bg-blue-50")
49
+ })
50
+
51
+ it("hides system noise until the Show system events toggle is enabled", () => {
52
+ render(<CasePanelActivityTimeline events={[visibleEvent, systemNoiseEvent]} defaultExpanded />)
53
+
54
+ expect((screen.getByLabelText("Show system events") as HTMLInputElement).checked).toBe(false)
55
+ expect(screen.getByText("Signal detected")).not.toBeNull()
56
+ expect(screen.queryByText("System recalculated routing state")).toBeNull()
57
+
58
+ fireEvent.click(screen.getByLabelText("Show system events"))
59
+
60
+ expect(screen.getByText("System recalculated routing state")).not.toBeNull()
61
+ })
62
+
63
+ it("applies actor byline rules without implying system when actor is missing", () => {
64
+ render(
65
+ <CasePanelActivityTimeline
66
+ defaultExpanded
67
+ events={[
68
+ event({ id: "missing-actor", title: "No actor event" }),
69
+ event({ id: "system-actor", title: "System actor event", actor: { kind: "system" } }),
70
+ event({ id: "integration-actor", title: "Integration actor event", actor: { kind: "integration", name: "Salesforce" } }),
71
+ event({ id: "user-actor", title: "User actor event", actor: { kind: "user", name: "Maya", verb: "approved this" } }),
72
+ ]}
73
+ />
74
+ )
75
+
76
+ const bylines = screen.getAllByTestId("case-panel-activity-byline")
77
+ expect(bylines).toHaveLength(2)
78
+ expect(bylines[0].textContent).toContain("Salesforce")
79
+ expect(bylines[0].textContent).toContain("synced this update")
80
+ expect(bylines[0].textContent).toContain("2h ago")
81
+ expect(bylines[1].textContent).toContain("Maya")
82
+ expect(bylines[1].textContent).toContain("approved this")
83
+ expect(bylines[1].textContent).toContain("2h ago")
84
+ expect(screen.queryByText("System")).toBeNull()
85
+ })
86
+
87
+ it("renders typed payload variants and dispatches typed signal actions", () => {
88
+ const onPayloadAction = vi.fn()
89
+ render(
90
+ <CasePanelActivityTimeline
91
+ defaultExpanded
92
+ onPayloadAction={onPayloadAction}
93
+ events={[
94
+ event({ id: "signal", title: "Signal", payload: { kind: "signal", key: "sig-1", summary: "Churn risk rose", detail: "Usage fell 30%." } }),
95
+ event({ id: "score", title: "Score", payload: { kind: "scoreUpdate", previousScore: 62, nextScore: 81, reason: "Executive engagement improved." } }),
96
+ event({ id: "rec", title: "Recommendation", payload: { kind: "recommendation", recommendation: "Send renewal brief", rationale: "Close date is within 14 days." } }),
97
+ event({ id: "email", title: "Email", payload: { kind: "email", from: "rep@example.com", to: "buyer@example.com", subject: "Renewal plan", preview: "Can we meet tomorrow?" } }),
98
+ event({ id: "deadline", title: "Deadline", payload: { kind: "deadline", dueLabel: "Due tomorrow", status: "due", description: "SLA response window." } }),
99
+ event({ id: "note", title: "Note", payload: { kind: "operatorNote", note: "Customer asked for legal review." } }),
100
+ event({ id: "assignment", title: "Assignment", payload: { kind: "assignment", assignee: "Jordan", from: "Maya", role: "Owner" } }),
101
+ event({ id: "opened", title: "Opened", payload: { kind: "caseOpened", source: "Gmail", openedBy: "Ari", description: "Inbound renewal request." } }),
102
+ ]}
103
+ />
104
+ )
105
+
106
+ expect(screen.getByTestId("case-panel-payload-signal").textContent).toContain("Churn risk rose")
107
+ expect(screen.getByTestId("case-panel-payload-scoreUpdate").textContent).toContain("62 → 81")
108
+ expect(screen.getByTestId("case-panel-payload-recommendation").textContent).toContain("Send renewal brief")
109
+ expect(screen.getByTestId("case-panel-payload-email").textContent).toContain("Renewal plan")
110
+ expect(screen.getByTestId("case-panel-payload-deadline").textContent).toContain("Due tomorrow")
111
+ expect(screen.getByTestId("case-panel-payload-operatorNote").textContent).toContain("Customer asked for legal review.")
112
+ expect(screen.getByTestId("case-panel-payload-assignment").textContent).toContain("Assigned to Jordan as Owner from Maya")
113
+ expect(screen.getByTestId("case-panel-payload-caseOpened").textContent).toContain("Case opened by Ari from Gmail")
114
+
115
+ fireEvent.click(screen.getByRole("button", { name: "Open signal" }))
116
+ expect(onPayloadAction).toHaveBeenCalledWith({ kind: "openSignal", key: "sig-1", eventId: "signal" })
117
+ })
118
+
119
+ it("renders the Salesforce deep-link slot", () => {
120
+ render(
121
+ <CasePanelActivityTimeline
122
+ defaultExpanded
123
+ events={[
124
+ event({
125
+ tone: "salesforce",
126
+ title: "Salesforce opportunity updated",
127
+ payload: {
128
+ kind: "salesforce",
129
+ objectLabel: "Opportunity",
130
+ recordLabel: "ACME Renewal",
131
+ changeSummary: "Stage moved to Negotiation.",
132
+ deepLink: { href: "https://salesforce.example.com/opp/123", label: "View opportunity" },
133
+ },
134
+ }),
135
+ ]}
136
+ />
137
+ )
138
+
139
+ const card = screen.getByTestId("case-panel-payload-salesforce")
140
+ expect(card.textContent).toContain("Opportunity")
141
+ expect(card.textContent).toContain("ACME Renewal")
142
+ const link = within(card).getByRole("link", { name: /view opportunity/i })
143
+ expect(link.getAttribute("href")).toBe("https://salesforce.example.com/opp/123")
144
+ expect(screen.getByTestId("case-panel-activity-dot").className).toContain("border-[#00A1E0]/25")
145
+ })
146
+
147
+ it("does not render a Detailed system log section", () => {
148
+ render(<CasePanelActivityTimeline events={[visibleEvent, systemNoiseEvent]} defaultExpanded defaultShowSystemEvents />)
149
+
150
+ expect(screen.queryByText(/detailed system log/i)).toBeNull()
151
+ })
152
+ })