@handled-ai/design-system 0.18.1 → 0.18.2

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 (73) hide show
  1. package/dist/charts/chart.d.ts +1 -1
  2. package/dist/charts/index.d.ts +0 -1
  3. package/dist/charts/index.js +0 -1
  4. package/dist/charts/index.js.map +1 -1
  5. package/dist/charts/pipeline-overview.d.ts +1 -2
  6. package/dist/charts/pipeline-overview.js +1 -29
  7. package/dist/charts/pipeline-overview.js.map +1 -1
  8. package/dist/components/feedback-primitives.d.ts +21 -2
  9. package/dist/components/feedback-primitives.js +90 -6
  10. package/dist/components/feedback-primitives.js.map +1 -1
  11. package/dist/components/insights-filter-bar.d.ts +1 -2
  12. package/dist/components/insights-filter-bar.js +5 -13
  13. package/dist/components/insights-filter-bar.js.map +1 -1
  14. package/dist/components/metric-card.d.ts +1 -14
  15. package/dist/components/metric-card.js +0 -86
  16. package/dist/components/metric-card.js.map +1 -1
  17. package/dist/components/score-why-chips.d.ts +1 -1
  18. package/dist/components/score-why-chips.js +26 -5
  19. package/dist/components/score-why-chips.js.map +1 -1
  20. package/dist/components/signal-priority-popover.d.ts +1 -1
  21. package/dist/components/signal-priority-popover.js +172 -7
  22. package/dist/components/signal-priority-popover.js.map +1 -1
  23. package/dist/index.d.ts +3 -9
  24. package/dist/index.js +0 -5
  25. package/dist/index.js.map +1 -1
  26. package/dist/prototype/index.d.ts +1 -1
  27. package/dist/prototype/prototype-accounts-view.d.ts +1 -1
  28. package/dist/prototype/prototype-admin-view.d.ts +1 -1
  29. package/dist/prototype/prototype-config.d.ts +1 -1
  30. package/dist/prototype/prototype-inbox-view.d.ts +1 -1
  31. package/dist/prototype/prototype-inbox-view.js +4 -1
  32. package/dist/prototype/prototype-inbox-view.js.map +1 -1
  33. package/dist/prototype/prototype-insights-view.d.ts +1 -1
  34. package/dist/prototype/prototype-shell.d.ts +1 -1
  35. package/dist/{signal-priority-popover-DQ_VuHac.d.ts → signal-priority-popover-DWaAMhPI.d.ts} +26 -2
  36. package/package.json +3 -1
  37. package/src/charts/index.ts +0 -1
  38. package/src/charts/pipeline-overview.tsx +1 -38
  39. package/src/components/__tests__/wit-636-feedback-states.test.tsx +546 -0
  40. package/src/components/feedback-primitives.tsx +148 -26
  41. package/src/components/insights-filter-bar.tsx +4 -13
  42. package/src/components/metric-card.tsx +0 -82
  43. package/src/components/score-why-chips.tsx +28 -2
  44. package/src/components/signal-priority-popover.tsx +194 -3
  45. package/src/index.ts +1 -6
  46. package/src/prototype/prototype-config.ts +11 -1
  47. package/src/prototype/prototype-inbox-view.tsx +3 -0
  48. package/dist/charts/empty-chart-state.d.ts +0 -11
  49. package/dist/charts/empty-chart-state.js +0 -70
  50. package/dist/charts/empty-chart-state.js.map +0 -1
  51. package/dist/components/days-open-cell.d.ts +0 -16
  52. package/dist/components/days-open-cell.js +0 -73
  53. package/dist/components/days-open-cell.js.map +0 -1
  54. package/dist/components/detail-drawer.d.ts +0 -16
  55. package/dist/components/detail-drawer.js +0 -45
  56. package/dist/components/detail-drawer.js.map +0 -1
  57. package/dist/components/linked-entity-cell.d.ts +0 -14
  58. package/dist/components/linked-entity-cell.js +0 -96
  59. package/dist/components/linked-entity-cell.js.map +0 -1
  60. package/dist/components/pill.d.ts +0 -26
  61. package/dist/components/pill.js +0 -77
  62. package/dist/components/pill.js.map +0 -1
  63. package/dist/components/quick-segment.d.ts +0 -13
  64. package/dist/components/quick-segment.js +0 -96
  65. package/dist/components/quick-segment.js.map +0 -1
  66. package/src/charts/__tests__/insights-charts.test.tsx +0 -62
  67. package/src/charts/empty-chart-state.tsx +0 -44
  68. package/src/components/__tests__/insights-primitives.test.tsx +0 -117
  69. package/src/components/days-open-cell.tsx +0 -50
  70. package/src/components/detail-drawer.tsx +0 -60
  71. package/src/components/linked-entity-cell.tsx +0 -74
  72. package/src/components/pill.tsx +0 -67
  73. package/src/components/quick-segment.tsx +0 -68
@@ -17,10 +17,14 @@ import {
17
17
  ChevronDown,
18
18
  ChevronUp,
19
19
  Info,
20
+ ThumbsUp,
21
+ ThumbsDown,
22
+ Check,
23
+ Pencil,
20
24
  } from "lucide-react"
21
25
  import { cn } from "../lib/utils"
22
26
  import { FeedbackFooter } from "./feedback-primitives"
23
- import type { FeedbackChipTree, FeedbackSubmitData } from "./feedback-primitives"
27
+ import type { FeedbackChipTree, FeedbackSubmitData, PersistedFeedbackData } from "./feedback-primitives"
24
28
  import type { SignalScoreUrgencyLabel } from "../prototype/prototype-config"
25
29
  import { getSignalScoreUrgencyLabel, scoreRangeForUrgency, SIGNAL_TONE_CLASSES } from "./score-why-chips"
26
30
 
@@ -58,6 +62,12 @@ export interface SignalPriorityPopoverProps {
58
62
  feedbackChips?: FeedbackChipTree[]
59
63
  onFeedbackSubmit?: (data: FeedbackSubmitData) => void
60
64
  className?: string
65
+ /** Persisted factor-level feedback (keyed by factor key). */
66
+ initialFactorFeedback?: Record<string, { type: "up" | "down"; detail: string; ownershipLabel?: string }>
67
+ /** Callback when user submits factor-level feedback. */
68
+ onFactorFeedback?: (factorKey: string, type: "up" | "down" | null, detail?: string) => void
69
+ /** Persisted priority-level feedback for the footer. */
70
+ initialPriorityFeedback?: PersistedFeedbackData | null
61
71
  }
62
72
 
63
73
  // ---------------------------------------------------------------------------
@@ -152,7 +162,13 @@ function DirectionIcon({ direction }: { direction: PriorityFactor["direction"] }
152
162
  // PriorityFactorRow
153
163
  // ---------------------------------------------------------------------------
154
164
 
155
- function PriorityFactorRow({ factor }: { factor: PriorityFactor }) {
165
+ interface PriorityFactorRowProps {
166
+ factor: PriorityFactor
167
+ initialFeedback?: { type: "up" | "down"; detail: string; ownershipLabel?: string }
168
+ onFactorFeedback?: (factorKey: string, type: "up" | "down" | null, detail?: string) => void
169
+ }
170
+
171
+ function PriorityFactorRow({ factor, initialFeedback, onFactorFeedback }: PriorityFactorRowProps) {
156
172
  const IconComponent = FACTOR_ICONS[factor.icon] ?? Activity
157
173
  const toneClasses = TONE_ICON_CLASSES[factor.tone]
158
174
  const directionClasses = DIRECTION_CLASSES[factor.direction]
@@ -163,6 +179,50 @@ function PriorityFactorRow({ factor }: { factor: PriorityFactor }) {
163
179
  ? "Lowers"
164
180
  : "Neutral"
165
181
 
182
+ const [thumbState, setThumbState] = React.useState<"up" | "down" | null>(
183
+ initialFeedback?.type ?? null,
184
+ )
185
+ const [showInput, setShowInput] = React.useState(false)
186
+ const [detailText, setDetailText] = React.useState(initialFeedback?.detail ?? "")
187
+ const [saved, setSaved] = React.useState(!!initialFeedback)
188
+ const [savedDetail, setSavedDetail] = React.useState(initialFeedback?.detail ?? "")
189
+ const ownershipLabel = initialFeedback?.ownershipLabel ?? "Your feedback"
190
+
191
+ // Sync with initialFeedback prop changes
192
+ React.useEffect(() => {
193
+ if (initialFeedback) {
194
+ setThumbState(initialFeedback.type)
195
+ setSaved(true)
196
+ setSavedDetail(initialFeedback.detail)
197
+ }
198
+ }, [initialFeedback])
199
+
200
+ const handleThumbClick = React.useCallback(
201
+ (type: "up" | "down") => {
202
+ if (thumbState === type) {
203
+ // Toggle off
204
+ setThumbState(null)
205
+ setShowInput(false)
206
+ setSaved(false)
207
+ onFactorFeedback?.(factor.key, null)
208
+ } else {
209
+ setThumbState(type)
210
+ setShowInput(true)
211
+ setSaved(false)
212
+ }
213
+ },
214
+ [thumbState, factor.key, onFactorFeedback],
215
+ )
216
+
217
+ const handleSubmitDetail = React.useCallback(() => {
218
+ if (!thumbState) return
219
+ const text = detailText.trim()
220
+ onFactorFeedback?.(factor.key, thumbState, text)
221
+ setSaved(true)
222
+ setSavedDetail(text)
223
+ setShowInput(false)
224
+ }, [thumbState, detailText, factor.key, onFactorFeedback])
225
+
166
226
  return (
167
227
  <div
168
228
  className="grid grid-cols-[20px_1fr_auto] gap-x-3 gap-y-1 px-4 py-3"
@@ -224,6 +284,124 @@ function PriorityFactorRow({ factor }: { factor: PriorityFactor }) {
224
284
 
225
285
  {/* empty grid cell under score column */}
226
286
  <div />
287
+
288
+ {/* Factor-level feedback row (spans icon + content columns) */}
289
+ {onFactorFeedback && (
290
+ <>
291
+ <div />
292
+ <div className="col-span-2 mt-1">
293
+ {saved && !showInput ? (
294
+ /* Persisted / saved indicator */
295
+ <button
296
+ type="button"
297
+ onClick={() => {
298
+ setDetailText(savedDetail)
299
+ setShowInput(true)
300
+ setSaved(false)
301
+ }}
302
+ className="group flex items-center gap-1.5 text-[11px] text-muted-foreground hover:text-foreground transition-colors"
303
+ data-testid={`factor-feedback-persisted-${factor.key}`}
304
+ >
305
+ <span className="font-medium">{ownershipLabel}:</span>
306
+ {thumbState === "up" ? (
307
+ <ThumbsUp className="h-[10px] w-[10px]" />
308
+ ) : (
309
+ <ThumbsDown className="h-[10px] w-[10px]" />
310
+ )}
311
+ {savedDetail && (
312
+ <span className="max-w-[180px] truncate text-muted-foreground/70">
313
+ {savedDetail}
314
+ </span>
315
+ )}
316
+ <Pencil className="h-[9px] w-[9px] opacity-0 group-hover:opacity-100 transition-opacity" />
317
+ </button>
318
+ ) : (
319
+ <div className="flex items-center gap-1.5">
320
+ {/* Inline thumb buttons */}
321
+ <button
322
+ type="button"
323
+ onClick={() => handleThumbClick("up")}
324
+ className={cn(
325
+ "p-1 rounded transition-colors",
326
+ thumbState === "up"
327
+ ? "text-foreground bg-muted"
328
+ : "text-muted-foreground/40 hover:text-foreground hover:bg-muted/50",
329
+ )}
330
+ title="This factor is accurate"
331
+ data-testid={`factor-thumb-up-${factor.key}`}
332
+ >
333
+ <ThumbsUp className="h-[10px] w-[10px]" />
334
+ </button>
335
+ <button
336
+ type="button"
337
+ onClick={() => handleThumbClick("down")}
338
+ className={cn(
339
+ "p-1 rounded transition-colors",
340
+ thumbState === "down"
341
+ ? "text-red-600 bg-red-50"
342
+ : "text-muted-foreground/40 hover:text-red-600 hover:bg-red-50/50",
343
+ )}
344
+ title="Report issue with this factor"
345
+ data-testid={`factor-thumb-down-${factor.key}`}
346
+ >
347
+ <ThumbsDown className="h-[10px] w-[10px]" />
348
+ </button>
349
+
350
+ {/* Transient "Saved" pill */}
351
+ {saved && (
352
+ <span
353
+ className="inline-flex items-center gap-1 text-[11px] font-medium text-emerald-600"
354
+ role="status"
355
+ data-testid={`factor-saved-${factor.key}`}
356
+ >
357
+ <Check className="h-[10px] w-[10px]" />
358
+ Saved
359
+ </span>
360
+ )}
361
+ </div>
362
+ )}
363
+
364
+ {/* Inline detail input */}
365
+ {showInput && thumbState && (
366
+ <div className="mt-1.5">
367
+ <input
368
+ type="text"
369
+ value={detailText}
370
+ onChange={(e) => setDetailText(e.target.value)}
371
+ onKeyDown={(e) => {
372
+ if (e.key === "Enter") handleSubmitDetail()
373
+ if (e.key === "Escape") setShowInput(false)
374
+ }}
375
+ placeholder={
376
+ thumbState === "up"
377
+ ? "What\u2019s accurate? (optional)"
378
+ : "What\u2019s wrong? (optional)"
379
+ }
380
+ className="w-full h-6 rounded border border-border bg-background px-2 text-[11px] text-foreground placeholder:text-muted-foreground/50 focus:outline-none focus:ring-1 focus:ring-ring"
381
+ data-testid={`factor-detail-input-${factor.key}`}
382
+ />
383
+ <div className="mt-1 flex items-center gap-1.5">
384
+ <button
385
+ type="button"
386
+ onClick={handleSubmitDetail}
387
+ className="bg-foreground text-background rounded px-2 py-0.5 text-[10px] font-semibold"
388
+ data-testid={`factor-submit-${factor.key}`}
389
+ >
390
+ Submit
391
+ </button>
392
+ <button
393
+ type="button"
394
+ onClick={() => setShowInput(false)}
395
+ className="border border-border rounded px-2 py-0.5 text-[10px] font-medium"
396
+ >
397
+ Cancel
398
+ </button>
399
+ </div>
400
+ </div>
401
+ )}
402
+ </div>
403
+ </>
404
+ )}
227
405
  </div>
228
406
  )
229
407
  }
@@ -241,6 +419,9 @@ export function SignalPriorityPopover({
241
419
  feedbackChips,
242
420
  onFeedbackSubmit,
243
421
  className,
422
+ initialFactorFeedback,
423
+ onFactorFeedback,
424
+ initialPriorityFeedback,
244
425
  }: SignalPriorityPopoverProps) {
245
426
  const urgencyLabel = getSignalScoreUrgencyLabel(score, providedLabel)
246
427
  const scoreRange = scoreRangeForUrgency(urgencyLabel)
@@ -252,6 +433,9 @@ export function SignalPriorityPopover({
252
433
  const triggerHover = URGENCY_TRIGGER_HOVER[urgencyLabel]
253
434
  const triggerOpen = URGENCY_TRIGGER_OPEN[urgencyLabel]
254
435
 
436
+ // Derive a stable feedbackKey for the footer from score + urgencyLabel
437
+ const footerFeedbackKey = `priority-${score}-${urgencyLabel}`
438
+
255
439
  return (
256
440
  <PopoverPrimitive.Root open={open} onOpenChange={setOpen}>
257
441
  <PopoverPrimitive.Trigger asChild>
@@ -332,7 +516,12 @@ export function SignalPriorityPopover({
332
516
  {/* Factor rows */}
333
517
  <div className="divide-y divide-border/40">
334
518
  {factors.map((factor) => (
335
- <PriorityFactorRow key={factor.key} factor={factor} />
519
+ <PriorityFactorRow
520
+ key={factor.key}
521
+ factor={factor}
522
+ initialFeedback={initialFactorFeedback?.[factor.key]}
523
+ onFactorFeedback={onFactorFeedback}
524
+ />
336
525
  ))}
337
526
  </div>
338
527
  </>
@@ -349,6 +538,8 @@ export function SignalPriorityPopover({
349
538
  negativeChips={feedbackChips ?? DEFAULT_PRIORITY_FEEDBACK_CHIPS}
350
539
  positivePrompt="Thanks. Anything to keep about this score?"
351
540
  className="px-4 py-3"
541
+ initialFeedback={initialPriorityFeedback}
542
+ feedbackKey={footerFeedbackKey}
352
543
  />
353
544
  </div>
354
545
  )}
package/src/index.ts CHANGED
@@ -33,13 +33,12 @@ export * from "./components/data-table-filter"
33
33
  export * from "./components/data-table-quick-views"
34
34
  export * from "./components/data-table-toolbar"
35
35
  export * from "./components/detail-view"
36
- export * from "./components/detail-drawer"
37
36
  export * from "./components/dialog"
38
37
  export * from "./components/dropdown-menu"
39
38
  export * from "./components/empty-state"
40
39
  export * from "./components/entity-panel"
41
40
  export { FeedbackFooter, FeedbackChipGroup, FeedbackInput, FeedbackActions } from "./components/feedback-primitives"
42
- export type { FeedbackFooterProps, FeedbackChipTree, FeedbackChipGroupProps, FeedbackInputProps, FeedbackActionsProps, FeedbackSubmitData } from "./components/feedback-primitives"
41
+ export type { FeedbackFooterProps, FeedbackChipTree, FeedbackChipGroupProps, FeedbackInputProps, FeedbackActionsProps, FeedbackSubmitData, PersistedFeedbackData } from "./components/feedback-primitives"
43
42
  export { SignalPriorityPopover } from "./components/signal-priority-popover"
44
43
  export type { SignalPriorityPopoverProps, PriorityFactor } from "./components/signal-priority-popover"
45
44
  export * from "./components/filter-chip"
@@ -48,8 +47,6 @@ export * from "./components/inbox-toolbar"
48
47
  export * from "./components/inline-banner"
49
48
  export * from "./components/input"
50
49
  export * from "./components/insights-filter-bar"
51
- export * from "./components/days-open-cell"
52
- export * from "./components/linked-entity-cell"
53
50
  export * from "./components/item-list"
54
51
  export * from "./components/item-list-display"
55
52
  export * from "./components/item-list-filter"
@@ -59,11 +56,9 @@ export * from "./components/label"
59
56
  export * from "./components/message"
60
57
  export * from "./components/metric-card"
61
58
  export * from "./components/performance-metrics-table"
62
- export * from "./components/pill"
63
59
  export * from "./components/preview-list"
64
60
  export * from "./components/progress"
65
61
  export * from "./components/quick-action-chat-area"
66
- export * from "./components/quick-segment"
67
62
  export {
68
63
  QuickActionModal,
69
64
  type QuickActionPriority,
@@ -16,7 +16,7 @@ import type { TimelineEvent } from "../components/timeline-activity"
16
16
  import type { ApprovalState } from "../components/signal-feedback-inline"
17
17
  import type { LucideIcon } from "lucide-react"
18
18
  import type { PriorityFactor } from "../components/signal-priority-popover"
19
- import type { FeedbackChipTree, FeedbackSubmitData } from "../components/feedback-primitives"
19
+ import type { FeedbackChipTree, FeedbackSubmitData, PersistedFeedbackData } from "../components/feedback-primitives"
20
20
 
21
21
  // ---------------------------------------------------------------------------
22
22
  // Shared
@@ -57,6 +57,10 @@ export interface SignalScoreExplanationSignal {
57
57
  counterparty?: string
58
58
  /** Component breakdown for combined signals. */
59
59
  components?: Array<{ type: string; count: number }>
60
+ /** Current balance value (e.g., "$3.0M") for balance context strip. */
61
+ currentBalance?: string
62
+ /** Additional balance context text (e.g., "down from $23M"). */
63
+ balanceContext?: string
60
64
  }
61
65
 
62
66
  export interface SignalScoreExplanationBucket {
@@ -97,6 +101,12 @@ export interface SignalScoreData {
97
101
  /** @deprecated The compact score UX no longer renders score-level thumbs by default. */
98
102
  initialScoreFeedback?: { type: "up" | "down"; pills: string[]; detail: string } | null
99
103
  initialFactorFeedback?: Record<string, { type: "up" | "down"; detail: string }>
104
+ /** Factor-level feedback for the priority popover rows (keyed by factor key). */
105
+ initialFactorPopoverFeedback?: Record<string, { type: "up" | "down"; detail: string; ownershipLabel?: string }>
106
+ /** Persisted bucket-level feedback, keyed by bucket key. */
107
+ initialBucketFeedback?: Record<string, PersistedFeedbackData>
108
+ /** Persisted priority-level feedback for the popover footer. */
109
+ initialPriorityFeedback?: PersistedFeedbackData | null
100
110
  /** Priority factors for the popover breakdown. */
101
111
  priorityFactors?: PriorityFactor[]
102
112
  /** Negative feedback chip tree for the priority popover. */
@@ -272,6 +272,9 @@ export function DetailView({
272
272
  metaText={undefined}
273
273
  feedbackChips={signalData.priorityFeedbackChips}
274
274
  onFeedbackSubmit={signalData.onPriorityFeedback}
275
+ initialFactorFeedback={signalData.initialFactorPopoverFeedback}
276
+ onFactorFeedback={signalData.onFactorFeedback}
277
+ initialPriorityFeedback={signalData.initialPriorityFeedback}
275
278
  />
276
279
  {signalData.timeChipLabel && (
277
280
  <Badge variant="outline" title={signalData.timeChipDetail ?? undefined}>
@@ -1,11 +0,0 @@
1
- import * as React from 'react';
2
-
3
- interface EmptyChartStateProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "title"> {
4
- title?: React.ReactNode;
5
- description?: React.ReactNode;
6
- icon?: React.ReactNode;
7
- action?: React.ReactNode;
8
- }
9
- declare function EmptyChartState({ title, description, icon, action, className, ...props }: EmptyChartStateProps): React.JSX.Element;
10
-
11
- export { EmptyChartState, type EmptyChartStateProps };
@@ -1,70 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __defProps = Object.defineProperties;
3
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
- var __spreadValues = (a, b) => {
9
- for (var prop in b || (b = {}))
10
- if (__hasOwnProp.call(b, prop))
11
- __defNormalProp(a, prop, b[prop]);
12
- if (__getOwnPropSymbols)
13
- for (var prop of __getOwnPropSymbols(b)) {
14
- if (__propIsEnum.call(b, prop))
15
- __defNormalProp(a, prop, b[prop]);
16
- }
17
- return a;
18
- };
19
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
- var __objRest = (source, exclude) => {
21
- var target = {};
22
- for (var prop in source)
23
- if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
24
- target[prop] = source[prop];
25
- if (source != null && __getOwnPropSymbols)
26
- for (var prop of __getOwnPropSymbols(source)) {
27
- if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
28
- target[prop] = source[prop];
29
- }
30
- return target;
31
- };
32
- import { jsx, jsxs } from "react/jsx-runtime";
33
- import { BarChart3 } from "lucide-react";
34
- import { cn } from "../lib/utils.js";
35
- function EmptyChartState(_a) {
36
- var _b = _a, {
37
- title = "No chart data",
38
- description = "Try adjusting filters or selecting a different time range.",
39
- icon,
40
- action,
41
- className
42
- } = _b, props = __objRest(_b, [
43
- "title",
44
- "description",
45
- "icon",
46
- "action",
47
- "className"
48
- ]);
49
- return /* @__PURE__ */ jsxs(
50
- "div",
51
- __spreadProps(__spreadValues({
52
- "data-slot": "empty-chart-state",
53
- className: cn(
54
- "flex min-h-[240px] flex-col items-center justify-center rounded-xl border border-dashed border-border bg-muted/30 p-8 text-center",
55
- className
56
- )
57
- }, props), {
58
- children: [
59
- /* @__PURE__ */ jsx("div", { "data-slot": "empty-chart-state-icon", className: "mb-3 text-muted-foreground [&>svg]:h-10 [&>svg]:w-10", children: icon != null ? icon : /* @__PURE__ */ jsx(BarChart3, { "aria-hidden": "true" }) }),
60
- /* @__PURE__ */ jsx("div", { "data-slot": "empty-chart-state-title", className: "text-sm font-semibold text-foreground", children: title }),
61
- description ? /* @__PURE__ */ jsx("div", { "data-slot": "empty-chart-state-description", className: "mt-1 max-w-sm text-sm text-muted-foreground", children: description }) : null,
62
- action ? /* @__PURE__ */ jsx("div", { "data-slot": "empty-chart-state-action", className: "mt-4", children: action }) : null
63
- ]
64
- })
65
- );
66
- }
67
- export {
68
- EmptyChartState
69
- };
70
- //# sourceMappingURL=empty-chart-state.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/charts/empty-chart-state.tsx"],"sourcesContent":["import * as React from \"react\"\nimport { BarChart3 } from \"lucide-react\"\n\nimport { cn } from \"../lib/utils\"\n\nexport interface EmptyChartStateProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"title\"> {\n title?: React.ReactNode\n description?: React.ReactNode\n icon?: React.ReactNode\n action?: React.ReactNode\n}\n\nexport function EmptyChartState({\n title = \"No chart data\",\n description = \"Try adjusting filters or selecting a different time range.\",\n icon,\n action,\n className,\n ...props\n}: EmptyChartStateProps) {\n return (\n <div\n data-slot=\"empty-chart-state\"\n className={cn(\n \"flex min-h-[240px] flex-col items-center justify-center rounded-xl border border-dashed border-border bg-muted/30 p-8 text-center\",\n className\n )}\n {...props}\n >\n <div data-slot=\"empty-chart-state-icon\" className=\"mb-3 text-muted-foreground [&>svg]:h-10 [&>svg]:w-10\">\n {icon ?? <BarChart3 aria-hidden=\"true\" />}\n </div>\n <div data-slot=\"empty-chart-state-title\" className=\"text-sm font-semibold text-foreground\">\n {title}\n </div>\n {description ? (\n <div data-slot=\"empty-chart-state-description\" className=\"mt-1 max-w-sm text-sm text-muted-foreground\">\n {description}\n </div>\n ) : null}\n {action ? <div data-slot=\"empty-chart-state-action\" className=\"mt-4\">{action}</div> : null}\n </div>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqBI,SASa,KATb;AApBJ,SAAS,iBAAiB;AAE1B,SAAS,UAAU;AASZ,SAAS,gBAAgB,IAOP;AAPO,eAC9B;AAAA,YAAQ;AAAA,IACR,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,EAjBF,IAYgC,IAM3B,kBAN2B,IAM3B;AAAA,IALH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAGA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,OACI,QANL;AAAA,MAQC;AAAA,4BAAC,SAAI,aAAU,0BAAyB,WAAU,wDAC/C,gCAAQ,oBAAC,aAAU,eAAY,QAAO,GACzC;AAAA,QACA,oBAAC,SAAI,aAAU,2BAA0B,WAAU,yCAChD,iBACH;AAAA,QACC,cACC,oBAAC,SAAI,aAAU,iCAAgC,WAAU,+CACtD,uBACH,IACE;AAAA,QACH,SAAS,oBAAC,SAAI,aAAU,4BAA2B,WAAU,QAAQ,kBAAO,IAAS;AAAA;AAAA;AAAA,EACxF;AAEJ;","names":[]}
@@ -1,16 +0,0 @@
1
- import * as React from 'react';
2
- import { PillStatus } from './pill.js';
3
- import 'class-variance-authority/types';
4
- import 'class-variance-authority';
5
-
6
- interface DaysOpenCellProps extends React.HTMLAttributes<HTMLDivElement> {
7
- days: number | null | undefined;
8
- warningAt?: number;
9
- criticalAt?: number;
10
- emptyLabel?: string;
11
- suffix?: string;
12
- }
13
- declare function getDaysOpenIntent(days: number, warningAt: number, criticalAt: number): PillStatus;
14
- declare function DaysOpenCell({ days, warningAt, criticalAt, emptyLabel, suffix, className, ...props }: DaysOpenCellProps): React.JSX.Element;
15
-
16
- export { DaysOpenCell, type DaysOpenCellProps, getDaysOpenIntent };
@@ -1,73 +0,0 @@
1
- "use client"
2
-
3
- "use client";
4
- var __defProp = Object.defineProperty;
5
- var __defProps = Object.defineProperties;
6
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
7
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
10
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
- var __spreadValues = (a, b) => {
12
- for (var prop in b || (b = {}))
13
- if (__hasOwnProp.call(b, prop))
14
- __defNormalProp(a, prop, b[prop]);
15
- if (__getOwnPropSymbols)
16
- for (var prop of __getOwnPropSymbols(b)) {
17
- if (__propIsEnum.call(b, prop))
18
- __defNormalProp(a, prop, b[prop]);
19
- }
20
- return a;
21
- };
22
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
23
- var __objRest = (source, exclude) => {
24
- var target = {};
25
- for (var prop in source)
26
- if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
27
- target[prop] = source[prop];
28
- if (source != null && __getOwnPropSymbols)
29
- for (var prop of __getOwnPropSymbols(source)) {
30
- if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
31
- target[prop] = source[prop];
32
- }
33
- return target;
34
- };
35
- import { jsx, jsxs } from "react/jsx-runtime";
36
- import { cn } from "../lib/utils.js";
37
- import { StatusPill } from "./pill.js";
38
- function getDaysOpenIntent(days, warningAt, criticalAt) {
39
- if (days >= criticalAt) return "error";
40
- if (days >= warningAt) return "warning";
41
- return "success";
42
- }
43
- function DaysOpenCell(_a) {
44
- var _b = _a, {
45
- days,
46
- warningAt = 7,
47
- criticalAt = 30,
48
- emptyLabel = "\u2014",
49
- suffix = "d open",
50
- className
51
- } = _b, props = __objRest(_b, [
52
- "days",
53
- "warningAt",
54
- "criticalAt",
55
- "emptyLabel",
56
- "suffix",
57
- "className"
58
- ]);
59
- if (days === null || days === void 0) {
60
- return /* @__PURE__ */ jsx("div", __spreadProps(__spreadValues({ "data-slot": "days-open-cell", className: cn("text-sm text-muted-foreground", className) }, props), { children: emptyLabel }));
61
- }
62
- const intent = getDaysOpenIntent(days, warningAt, criticalAt);
63
- return /* @__PURE__ */ jsx("div", __spreadProps(__spreadValues({ "data-slot": "days-open-cell", className: cn("inline-flex items-center", className) }, props), { children: /* @__PURE__ */ jsxs(StatusPill, { "data-testid": "days-open-pill", status: `${days} ${suffix}`, intent, children: [
64
- days,
65
- " ",
66
- suffix
67
- ] }) }));
68
- }
69
- export {
70
- DaysOpenCell,
71
- getDaysOpenIntent
72
- };
73
- //# sourceMappingURL=days-open-cell.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/components/days-open-cell.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"../lib/utils\"\nimport { StatusPill, type PillStatus } from \"./pill\"\n\nexport interface DaysOpenCellProps extends React.HTMLAttributes<HTMLDivElement> {\n days: number | null | undefined\n warningAt?: number\n criticalAt?: number\n emptyLabel?: string\n suffix?: string\n}\n\nfunction getDaysOpenIntent(days: number, warningAt: number, criticalAt: number): PillStatus {\n if (days >= criticalAt) return \"error\"\n if (days >= warningAt) return \"warning\"\n return \"success\"\n}\n\nexport function DaysOpenCell({\n days,\n warningAt = 7,\n criticalAt = 30,\n emptyLabel = \"—\",\n suffix = \"d open\",\n className,\n ...props\n}: DaysOpenCellProps) {\n if (days === null || days === undefined) {\n return (\n <div data-slot=\"days-open-cell\" className={cn(\"text-sm text-muted-foreground\", className)} {...props}>\n {emptyLabel}\n </div>\n )\n }\n\n const intent = getDaysOpenIntent(days, warningAt, criticalAt)\n\n return (\n <div data-slot=\"days-open-cell\" className={cn(\"inline-flex items-center\", className)} {...props}>\n <StatusPill data-testid=\"days-open-pill\" status={`${days} ${suffix}`} intent={intent}>\n {days} {suffix}\n </StatusPill>\n </div>\n )\n}\n\nexport { getDaysOpenIntent }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCM,cAUA,YAVA;AA5BN,SAAS,UAAU;AACnB,SAAS,kBAAmC;AAU5C,SAAS,kBAAkB,MAAc,WAAmB,YAAgC;AAC1F,MAAI,QAAQ,WAAY,QAAO;AAC/B,MAAI,QAAQ,UAAW,QAAO;AAC9B,SAAO;AACT;AAEO,SAAS,aAAa,IAQP;AARO,eAC3B;AAAA;AAAA,IACA,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,SAAS;AAAA,IACT;AAAA,EA3BF,IAqB6B,IAOxB,kBAPwB,IAOxB;AAAA,IANH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAGA,MAAI,SAAS,QAAQ,SAAS,QAAW;AACvC,WACE,oBAAC,sCAAI,aAAU,kBAAiB,WAAW,GAAG,iCAAiC,SAAS,KAAO,QAA9F,EACE,uBACH;AAAA,EAEJ;AAEA,QAAM,SAAS,kBAAkB,MAAM,WAAW,UAAU;AAE5D,SACE,oBAAC,sCAAI,aAAU,kBAAiB,WAAW,GAAG,4BAA4B,SAAS,KAAO,QAAzF,EACC,+BAAC,cAAW,eAAY,kBAAiB,QAAQ,GAAG,IAAI,IAAI,MAAM,IAAI,QACnE;AAAA;AAAA,IAAK;AAAA,IAAE;AAAA,KACV,IACF;AAEJ;","names":[]}
@@ -1,16 +0,0 @@
1
- import * as React from 'react';
2
-
3
- interface DetailDrawerProps {
4
- open: boolean;
5
- onOpenChange: (open: boolean) => void;
6
- title: React.ReactNode;
7
- description?: React.ReactNode;
8
- children: React.ReactNode;
9
- footer?: React.ReactNode;
10
- side?: "right" | "left";
11
- className?: string;
12
- contentClassName?: string;
13
- }
14
- declare function DetailDrawer({ open, onOpenChange, title, description, children, footer, side, className, contentClassName, }: DetailDrawerProps): React.JSX.Element;
15
-
16
- export { DetailDrawer, type DetailDrawerProps };
@@ -1,45 +0,0 @@
1
- "use client"
2
-
3
- "use client";
4
- import { jsx, jsxs } from "react/jsx-runtime";
5
- import { cn } from "../lib/utils.js";
6
- import {
7
- Sheet,
8
- SheetContent,
9
- SheetDescription,
10
- SheetFooter,
11
- SheetHeader,
12
- SheetTitle
13
- } from "./sheet.js";
14
- function DetailDrawer({
15
- open,
16
- onOpenChange,
17
- title,
18
- description,
19
- children,
20
- footer,
21
- side = "right",
22
- className,
23
- contentClassName
24
- }) {
25
- return /* @__PURE__ */ jsx(Sheet, { open, onOpenChange, children: /* @__PURE__ */ jsxs(
26
- SheetContent,
27
- {
28
- "data-slot": "detail-drawer",
29
- side,
30
- className: cn("w-full gap-0 p-0 sm:max-w-xl", className),
31
- children: [
32
- /* @__PURE__ */ jsxs(SheetHeader, { "data-slot": "detail-drawer-header", className: "border-b border-border p-5", children: [
33
- /* @__PURE__ */ jsx(SheetTitle, { children: title }),
34
- description ? /* @__PURE__ */ jsx(SheetDescription, { children: description }) : null
35
- ] }),
36
- /* @__PURE__ */ jsx("div", { "data-slot": "detail-drawer-content", className: cn("flex-1 overflow-y-auto p-5", contentClassName), children }),
37
- footer ? /* @__PURE__ */ jsx(SheetFooter, { "data-slot": "detail-drawer-footer", className: "border-t border-border p-5", children: footer }) : null
38
- ]
39
- }
40
- ) });
41
- }
42
- export {
43
- DetailDrawer
44
- };
45
- //# sourceMappingURL=detail-drawer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/components/detail-drawer.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"../lib/utils\"\nimport {\n Sheet,\n SheetContent,\n SheetDescription,\n SheetFooter,\n SheetHeader,\n SheetTitle,\n} from \"./sheet\"\n\nexport interface DetailDrawerProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n title: React.ReactNode\n description?: React.ReactNode\n children: React.ReactNode\n footer?: React.ReactNode\n side?: \"right\" | \"left\"\n className?: string\n contentClassName?: string\n}\n\nexport function DetailDrawer({\n open,\n onOpenChange,\n title,\n description,\n children,\n footer,\n side = \"right\",\n className,\n contentClassName,\n}: DetailDrawerProps) {\n return (\n <Sheet open={open} onOpenChange={onOpenChange}>\n <SheetContent\n data-slot=\"detail-drawer\"\n side={side}\n className={cn(\"w-full gap-0 p-0 sm:max-w-xl\", className)}\n >\n <SheetHeader data-slot=\"detail-drawer-header\" className=\"border-b border-border p-5\">\n <SheetTitle>{title}</SheetTitle>\n {description ? <SheetDescription>{description}</SheetDescription> : null}\n </SheetHeader>\n <div data-slot=\"detail-drawer-content\" className={cn(\"flex-1 overflow-y-auto p-5\", contentClassName)}>\n {children}\n </div>\n {footer ? (\n <SheetFooter data-slot=\"detail-drawer-footer\" className=\"border-t border-border p-5\">\n {footer}\n </SheetFooter>\n ) : null}\n </SheetContent>\n </Sheet>\n )\n}\n"],"mappings":";AA4CQ,SACE,KADF;AAxCR,SAAS,UAAU;AACnB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAcA,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AACF,GAAsB;AACpB,SACE,oBAAC,SAAM,MAAY,cACjB;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV;AAAA,MACA,WAAW,GAAG,gCAAgC,SAAS;AAAA,MAEvD;AAAA,6BAAC,eAAY,aAAU,wBAAuB,WAAU,8BACtD;AAAA,8BAAC,cAAY,iBAAM;AAAA,UAClB,cAAc,oBAAC,oBAAkB,uBAAY,IAAsB;AAAA,WACtE;AAAA,QACA,oBAAC,SAAI,aAAU,yBAAwB,WAAW,GAAG,8BAA8B,gBAAgB,GAChG,UACH;AAAA,QACC,SACC,oBAAC,eAAY,aAAU,wBAAuB,WAAU,8BACrD,kBACH,IACE;AAAA;AAAA;AAAA,EACN,GACF;AAEJ;","names":[]}
@@ -1,14 +0,0 @@
1
- import * as React from 'react';
2
-
3
- interface LinkedEntityCellProps extends React.HTMLAttributes<HTMLDivElement> {
4
- name: React.ReactNode;
5
- href?: string;
6
- subtitle?: React.ReactNode;
7
- meta?: React.ReactNode;
8
- icon?: React.ReactNode;
9
- external?: boolean;
10
- onNavigate?: () => void;
11
- }
12
- declare function LinkedEntityCell({ name, href, subtitle, meta, icon, external, onNavigate, className, ...props }: LinkedEntityCellProps): React.JSX.Element;
13
-
14
- export { LinkedEntityCell, type LinkedEntityCellProps };