@handled-ai/design-system 0.18.1 → 0.18.3

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 (58) hide show
  1. package/dist/charts/index.d.ts +0 -1
  2. package/dist/charts/index.js +0 -1
  3. package/dist/charts/index.js.map +1 -1
  4. package/dist/charts/pipeline-overview.d.ts +1 -2
  5. package/dist/charts/pipeline-overview.js +1 -29
  6. package/dist/charts/pipeline-overview.js.map +1 -1
  7. package/dist/components/insights-filter-bar.d.ts +1 -2
  8. package/dist/components/insights-filter-bar.js +5 -13
  9. package/dist/components/insights-filter-bar.js.map +1 -1
  10. package/dist/components/metric-card.d.ts +1 -14
  11. package/dist/components/metric-card.js +0 -86
  12. package/dist/components/metric-card.js.map +1 -1
  13. package/dist/components/timeline-activity.d.ts +16 -1
  14. package/dist/components/timeline-activity.js +69 -1
  15. package/dist/components/timeline-activity.js.map +1 -1
  16. package/dist/index.d.ts +2 -8
  17. package/dist/index.js +0 -5
  18. package/dist/index.js.map +1 -1
  19. package/dist/prototype/prototype-inbox-view.d.ts +11 -1
  20. package/dist/prototype/prototype-inbox-view.js +101 -33
  21. package/dist/prototype/prototype-inbox-view.js.map +1 -1
  22. package/package.json +1 -1
  23. package/src/charts/index.ts +0 -1
  24. package/src/charts/pipeline-overview.tsx +1 -38
  25. package/src/components/__tests__/timeline-activity.test.tsx +137 -0
  26. package/src/components/insights-filter-bar.tsx +4 -13
  27. package/src/components/metric-card.tsx +0 -82
  28. package/src/components/timeline-activity.tsx +112 -1
  29. package/src/index.ts +0 -5
  30. package/src/prototype/__tests__/detail-view-attention.test.tsx +2 -2
  31. package/src/prototype/__tests__/detail-view-timeline-system-events.test.tsx +322 -0
  32. package/src/prototype/prototype-inbox-view.tsx +131 -30
  33. package/dist/charts/empty-chart-state.d.ts +0 -11
  34. package/dist/charts/empty-chart-state.js +0 -70
  35. package/dist/charts/empty-chart-state.js.map +0 -1
  36. package/dist/components/days-open-cell.d.ts +0 -16
  37. package/dist/components/days-open-cell.js +0 -73
  38. package/dist/components/days-open-cell.js.map +0 -1
  39. package/dist/components/detail-drawer.d.ts +0 -16
  40. package/dist/components/detail-drawer.js +0 -45
  41. package/dist/components/detail-drawer.js.map +0 -1
  42. package/dist/components/linked-entity-cell.d.ts +0 -14
  43. package/dist/components/linked-entity-cell.js +0 -96
  44. package/dist/components/linked-entity-cell.js.map +0 -1
  45. package/dist/components/pill.d.ts +0 -26
  46. package/dist/components/pill.js +0 -77
  47. package/dist/components/pill.js.map +0 -1
  48. package/dist/components/quick-segment.d.ts +0 -13
  49. package/dist/components/quick-segment.js +0 -96
  50. package/dist/components/quick-segment.js.map +0 -1
  51. package/src/charts/__tests__/insights-charts.test.tsx +0 -62
  52. package/src/charts/empty-chart-state.tsx +0 -44
  53. package/src/components/__tests__/insights-primitives.test.tsx +0 -117
  54. package/src/components/days-open-cell.tsx +0 -50
  55. package/src/components/detail-drawer.tsx +0 -60
  56. package/src/components/linked-entity-cell.tsx +0 -74
  57. package/src/components/pill.tsx +0 -67
  58. package/src/components/quick-segment.tsx +0 -68
@@ -150,6 +150,16 @@ export interface DetailViewProps {
150
150
  onRequestApproval?: () => Promise<void>
151
151
  /** Number of important/attention-worthy events to highlight on the collapsed timeline header. */
152
152
  attentionCount?: number
153
+ /** Label for the system-events toggle button (e.g. "Score changes"). */
154
+ timelineSystemEventsToggleLabel?: string
155
+ /** localStorage key for persisting the system-events toggle state. */
156
+ timelineSystemEventsStorageKey?: string
157
+ /** Whether system-noise events are visible by default. @default false */
158
+ timelineSystemEventsDefaultVisible?: boolean
159
+ /** Hint text shown below the timeline when system events are hidden. */
160
+ timelineSystemEventsHiddenHint?: string
161
+ /** Hint text shown below the timeline when system events are visible. Uses {count} as placeholder. */
162
+ timelineSystemEventsVisibleHint?: string
153
163
  }
154
164
 
155
165
  export function DetailView({
@@ -184,10 +194,47 @@ export function DetailView({
184
194
  opportunityPreview,
185
195
  onRequestApproval,
186
196
  attentionCount,
197
+ timelineSystemEventsToggleLabel,
198
+ timelineSystemEventsStorageKey,
199
+ timelineSystemEventsDefaultVisible = false,
200
+ timelineSystemEventsHiddenHint,
201
+ timelineSystemEventsVisibleHint,
187
202
  }: DetailViewProps) {
188
203
  const [showTimeline, setShowTimeline] = React.useState(false)
189
204
  const [extraActions, setExtraActions] = React.useState<SuggestedAction[]>([])
190
205
 
206
+ // ---- System-noise toggle state ----
207
+ const [showSystemEvents, setShowSystemEvents] = React.useState(timelineSystemEventsDefaultVisible)
208
+ const initialReadDoneRef = React.useRef(false)
209
+
210
+ // Read persisted value from localStorage on mount
211
+ React.useEffect(() => {
212
+ if (!timelineSystemEventsStorageKey) {
213
+ initialReadDoneRef.current = true
214
+ return
215
+ }
216
+ try {
217
+ const stored = localStorage.getItem(timelineSystemEventsStorageKey)
218
+ if (stored !== null) {
219
+ setShowSystemEvents(stored === "true")
220
+ }
221
+ } catch {
222
+ // localStorage unavailable — ignore
223
+ }
224
+ initialReadDoneRef.current = true
225
+ }, [timelineSystemEventsStorageKey])
226
+
227
+ // Write to localStorage when the toggle changes (skip initial if matching default)
228
+ React.useEffect(() => {
229
+ if (!timelineSystemEventsStorageKey) return
230
+ if (!initialReadDoneRef.current) return
231
+ try {
232
+ localStorage.setItem(timelineSystemEventsStorageKey, String(showSystemEvents))
233
+ } catch {
234
+ // localStorage unavailable — ignore
235
+ }
236
+ }, [showSystemEvents, timelineSystemEventsStorageKey])
237
+
191
238
  React.useEffect(() => {
192
239
  setShowTimeline(false)
193
240
  setExtraActions([])
@@ -351,38 +398,92 @@ export function DetailView({
351
398
  {renderAfterScore?.(item)}
352
399
 
353
400
  {/* Activity Timeline */}
354
- {sections.timeline && timelineEvents.length > 0 && (
355
- <div className="mb-8">
356
- <button
357
- type="button"
358
- onClick={() => setShowTimeline((prev) => !prev)}
359
- className="group/timeline flex w-full items-center justify-between gap-2 py-2 rounded-md transition-colors hover:bg-muted/40 -mx-2 px-2 cursor-pointer"
360
- >
361
- <div className="flex items-center gap-2">
362
- <h3 className="text-xs font-bold text-muted-foreground uppercase tracking-wider group-hover/timeline:text-foreground transition-colors">Activity timeline</h3>
363
- {!showTimeline && attentionCount != null && attentionCount > 0 && (
364
- <span className="inline-flex items-center gap-1 rounded-full bg-destructive/10 px-1.5 py-0.5 text-[10px] font-semibold text-destructive border border-destructive/20">
365
- {attentionCount} new
366
- </span>
367
- )}
368
- {!showTimeline && (lastActivityTime || (timelineEvents.length > 0 && timelineEvents[0].time)) && (
369
- <span className="text-[11px] text-muted-foreground/60">
370
- &middot; Last activity {lastActivityTime ?? timelineEvents[0]?.time ?? ''}
371
- </span>
401
+ {sections.timeline && timelineEvents.length > 0 && (() => {
402
+ const visibleEvents = timelineEvents.filter(
403
+ (e) => !e.isSystemNoise || showSystemEvents,
404
+ )
405
+ const hiddenCount = timelineEvents.filter((e) => e.isSystemNoise).length
406
+ const hasSystemNoise = hiddenCount > 0
407
+ const showToggle =
408
+ hasSystemNoise &&
409
+ !!(timelineSystemEventsToggleLabel || timelineSystemEventsStorageKey)
410
+ const firstVisibleTime =
411
+ lastActivityTime ?? (visibleEvents.length > 0 ? visibleEvents[0].time : "")
412
+ const visibleCount = visibleEvents.length
413
+ const eventCountLabel = `${visibleCount} ${visibleCount === 1 ? "event" : "events"}`
414
+
415
+ return (
416
+ <div className="mb-8">
417
+ {/* Header outer non-interactive container */}
418
+ <div
419
+ className="group/timeline flex w-full items-center justify-between gap-2 py-2 rounded-md transition-colors hover:bg-muted/40 -mx-2 px-2"
420
+ data-testid="timeline-header"
421
+ >
422
+ {/* Left: collapse/expand button */}
423
+ <button
424
+ type="button"
425
+ onClick={() => setShowTimeline((prev) => !prev)}
426
+ className="flex items-center gap-2 cursor-pointer bg-transparent border-0 p-0"
427
+ data-testid="timeline-collapse-btn"
428
+ >
429
+ <h3 className="text-xs font-bold text-muted-foreground uppercase tracking-wider group-hover/timeline:text-foreground transition-colors">Activity timeline</h3>
430
+ {!showTimeline && attentionCount != null && attentionCount > 0 && (
431
+ <span className="inline-flex items-center gap-1 rounded-full bg-destructive/10 px-1.5 py-0.5 text-[10px] font-semibold text-destructive border border-destructive/20">
432
+ {attentionCount} new
433
+ </span>
434
+ )}
435
+ {!showTimeline && firstVisibleTime && (
436
+ <span className="text-[11px] text-muted-foreground/60" data-testid="last-activity-hint">
437
+ &middot; Last activity {firstVisibleTime}
438
+ </span>
439
+ )}
440
+ <div className="flex items-center gap-1.5">
441
+ <span className="text-[11px] font-medium text-muted-foreground" data-testid="event-count">{eventCountLabel}</span>
442
+ <ChevronDown className={`h-3.5 w-3.5 text-muted-foreground transition-transform duration-200 ${showTimeline ? "rotate-180" : ""}`} />
443
+ </div>
444
+ </button>
445
+
446
+ {/* Right: system-events toggle */}
447
+ {showToggle && (
448
+ <button
449
+ type="button"
450
+ onClick={() => setShowSystemEvents((prev) => !prev)}
451
+ className="flex shrink-0 items-center gap-1.5 rounded-full border border-border bg-background px-2.5 py-1 text-[11px] font-medium text-muted-foreground transition-colors hover:bg-muted/40 hover:text-foreground cursor-pointer"
452
+ aria-pressed={showSystemEvents}
453
+ data-testid="system-events-toggle"
454
+ >
455
+ {timelineSystemEventsToggleLabel ?? "System events"}
456
+ <span
457
+ className="inline-flex items-center justify-center rounded-full bg-muted px-1.5 text-[10px] font-semibold min-w-[18px] tabular-nums"
458
+ data-testid="hidden-count-badge"
459
+ >
460
+ {hiddenCount}
461
+ </span>
462
+ </button>
372
463
  )}
373
464
  </div>
374
- <div className="flex items-center gap-1.5">
375
- <span className="text-[11px] font-medium text-muted-foreground">{timelineEvents.length} events</span>
376
- <ChevronDown className={`h-3.5 w-3.5 text-muted-foreground transition-transform duration-200 ${showTimeline ? "rotate-180" : ""}`} />
377
- </div>
378
- </button>
379
- {showTimeline && (
380
- <div className="mt-3">
381
- <TimelineActivity events={timelineEvents} />
382
- </div>
383
- )}
384
- </div>
385
- )}
465
+
466
+ {/* Timeline body */}
467
+ {showTimeline && visibleEvents.length > 0 && (
468
+ <div className="mt-3">
469
+ <TimelineActivity events={visibleEvents} />
470
+ </div>
471
+ )}
472
+
473
+ {/* Footer hint */}
474
+ {showTimeline && !showSystemEvents && timelineSystemEventsHiddenHint && hasSystemNoise && (
475
+ <p className="mt-2 text-[11px] text-muted-foreground/60 border-t border-dashed border-border pt-2" data-testid="timeline-footer-hint">
476
+ {timelineSystemEventsHiddenHint}
477
+ </p>
478
+ )}
479
+ {showTimeline && showSystemEvents && timelineSystemEventsVisibleHint && hasSystemNoise && (
480
+ <p className="mt-2 text-[11px] text-muted-foreground/60 border-t border-dashed border-border pt-2" data-testid="timeline-footer-hint">
481
+ {timelineSystemEventsVisibleHint.replace("{count}", String(hiddenCount))}
482
+ </p>
483
+ )}
484
+ </div>
485
+ )
486
+ })()}
386
487
  </div>
387
488
 
388
489
  {/* Suggested Actions */}
@@ -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 };
@@ -1,96 +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 { Fragment, jsx, jsxs } from "react/jsx-runtime";
36
- import { ExternalLink } from "lucide-react";
37
- import { cn } from "../lib/utils.js";
38
- function LinkedEntityCell(_a) {
39
- var _b = _a, {
40
- name,
41
- href,
42
- subtitle,
43
- meta,
44
- icon,
45
- external = false,
46
- onNavigate,
47
- className
48
- } = _b, props = __objRest(_b, [
49
- "name",
50
- "href",
51
- "subtitle",
52
- "meta",
53
- "icon",
54
- "external",
55
- "onNavigate",
56
- "className"
57
- ]);
58
- const content = /* @__PURE__ */ jsxs(Fragment, { children: [
59
- /* @__PURE__ */ jsx("span", { className: "truncate", children: name }),
60
- external ? /* @__PURE__ */ jsx(ExternalLink, { className: "h-3 w-3 shrink-0 opacity-60", "aria-hidden": "true" }) : null
61
- ] });
62
- return /* @__PURE__ */ jsxs(
63
- "div",
64
- __spreadProps(__spreadValues({
65
- "data-slot": "linked-entity-cell",
66
- className: cn("flex min-w-0 items-center gap-2", className)
67
- }, props), {
68
- children: [
69
- icon ? /* @__PURE__ */ jsx("span", { "data-slot": "linked-entity-cell-icon", className: "shrink-0 text-muted-foreground", children: icon }) : null,
70
- /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
71
- href ? /* @__PURE__ */ jsx(
72
- "a",
73
- {
74
- "data-slot": "linked-entity-cell-link",
75
- href,
76
- target: external ? "_blank" : void 0,
77
- rel: external ? "noreferrer" : void 0,
78
- onClick: onNavigate,
79
- className: "inline-flex max-w-full items-center gap-1 truncate font-medium text-foreground underline-offset-4 hover:text-primary hover:underline",
80
- children: content
81
- }
82
- ) : /* @__PURE__ */ jsx("span", { "data-slot": "linked-entity-cell-name", className: "block truncate font-medium text-foreground", children: name }),
83
- subtitle || meta ? /* @__PURE__ */ jsxs("div", { "data-slot": "linked-entity-cell-meta", className: "mt-0.5 truncate text-xs text-muted-foreground", children: [
84
- subtitle,
85
- subtitle && meta ? /* @__PURE__ */ jsx("span", { className: "px-1", children: "\xB7" }) : null,
86
- meta
87
- ] }) : null
88
- ] })
89
- ]
90
- })
91
- );
92
- }
93
- export {
94
- LinkedEntityCell
95
- };
96
- //# sourceMappingURL=linked-entity-cell.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/components/linked-entity-cell.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { ExternalLink } from \"lucide-react\"\n\nimport { cn } from \"../lib/utils\"\n\nexport interface LinkedEntityCellProps extends React.HTMLAttributes<HTMLDivElement> {\n name: React.ReactNode\n href?: string\n subtitle?: React.ReactNode\n meta?: React.ReactNode\n icon?: React.ReactNode\n external?: boolean\n onNavigate?: () => void\n}\n\nexport function LinkedEntityCell({\n name,\n href,\n subtitle,\n meta,\n icon,\n external = false,\n onNavigate,\n className,\n ...props\n}: LinkedEntityCellProps) {\n const content = (\n <>\n <span className=\"truncate\">{name}</span>\n {external ? <ExternalLink className=\"h-3 w-3 shrink-0 opacity-60\" aria-hidden=\"true\" /> : null}\n </>\n )\n\n return (\n <div\n data-slot=\"linked-entity-cell\"\n className={cn(\"flex min-w-0 items-center gap-2\", className)}\n {...props}\n >\n {icon ? (\n <span data-slot=\"linked-entity-cell-icon\" className=\"shrink-0 text-muted-foreground\">\n {icon}\n </span>\n ) : null}\n <div className=\"min-w-0 flex-1\">\n {href ? (\n <a\n data-slot=\"linked-entity-cell-link\"\n href={href}\n target={external ? \"_blank\" : undefined}\n rel={external ? \"noreferrer\" : undefined}\n onClick={onNavigate}\n className=\"inline-flex max-w-full items-center gap-1 truncate font-medium text-foreground underline-offset-4 hover:text-primary hover:underline\"\n >\n {content}\n </a>\n ) : (\n <span data-slot=\"linked-entity-cell-name\" className=\"block truncate font-medium text-foreground\">\n {name}\n </span>\n )}\n {subtitle || meta ? (\n <div data-slot=\"linked-entity-cell-meta\" className=\"mt-0.5 truncate text-xs text-muted-foreground\">\n {subtitle}\n {subtitle && meta ? <span className=\"px-1\">·</span> : null}\n {meta}\n </div>\n ) : null}\n </div>\n </div>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BI,mBACE,KADF;AA1BJ,SAAS,oBAAoB;AAE7B,SAAS,UAAU;AAYZ,SAAS,iBAAiB,IAUP;AAVO,eAC/B;AAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA;AAAA,EAzBF,IAiBiC,IAS5B,kBAT4B,IAS5B;AAAA,IARH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAGA,QAAM,UACJ,iCACE;AAAA,wBAAC,UAAK,WAAU,YAAY,gBAAK;AAAA,IAChC,WAAW,oBAAC,gBAAa,WAAU,+BAA8B,eAAY,QAAO,IAAK;AAAA,KAC5F;AAGF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,mCAAmC,SAAS;AAAA,OACtD,QAHL;AAAA,MAKE;AAAA,eACC,oBAAC,UAAK,aAAU,2BAA0B,WAAU,kCACjD,gBACH,IACE;AAAA,QACJ,qBAAC,SAAI,WAAU,kBACZ;AAAA,iBACC;AAAA,YAAC;AAAA;AAAA,cACC,aAAU;AAAA,cACV;AAAA,cACA,QAAQ,WAAW,WAAW;AAAA,cAC9B,KAAK,WAAW,eAAe;AAAA,cAC/B,SAAS;AAAA,cACT,WAAU;AAAA,cAET;AAAA;AAAA,UACH,IAEA,oBAAC,UAAK,aAAU,2BAA0B,WAAU,8CACjD,gBACH;AAAA,UAED,YAAY,OACX,qBAAC,SAAI,aAAU,2BAA0B,WAAU,iDAChD;AAAA;AAAA,YACA,YAAY,OAAO,oBAAC,UAAK,WAAU,QAAO,kBAAC,IAAU;AAAA,YACrD;AAAA,aACH,IACE;AAAA,WACN;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
@@ -1,26 +0,0 @@
1
- import * as class_variance_authority_types from 'class-variance-authority/types';
2
- import * as React from 'react';
3
- import { VariantProps } from 'class-variance-authority';
4
-
5
- /**
6
- * Insights-friendly pill convenience wrappers.
7
- *
8
- * Pill and StatusPill are small, rounded wrappers for dense Insights surfaces
9
- * such as tables, KPI strips, and filter summaries. They intentionally wrap the
10
- * existing Badge/StatusBadge visual language and are not a replacement for all
11
- * Badge usage across the design system.
12
- */
13
- type PillStatus = "success" | "warning" | "error" | "neutral" | "info";
14
- declare const pillVariants: (props?: ({
15
- variant?: "default" | "secondary" | "destructive" | "outline" | "ghost" | "error" | "neutral" | "info" | "warning" | "success" | null | undefined;
16
- } & class_variance_authority_types.ClassProp) | undefined) => string;
17
- interface PillProps extends React.ComponentProps<"span">, VariantProps<typeof pillVariants> {
18
- }
19
- declare function Pill({ className, variant, ...props }: PillProps): React.JSX.Element;
20
- interface StatusPillProps extends Omit<PillProps, "variant"> {
21
- status: React.ReactNode;
22
- intent?: PillStatus;
23
- }
24
- declare function StatusPill({ status, intent, children, ...props }: StatusPillProps): React.JSX.Element;
25
-
26
- export { Pill, type PillProps, type PillStatus, StatusPill, type StatusPillProps, pillVariants };