@assure-one/design-system 1.14.0 → 1.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -6376,13 +6376,48 @@ var previewVariants = cva("bg-surface flex min-h-0 flex-col overflow-hidden", {
6376
6376
  },
6377
6377
  defaultVariants: { variant: "modal" }
6378
6378
  });
6379
+ var MIN_ZOOM = 0.5;
6380
+ var MAX_ZOOM = 2;
6381
+ var ZOOM_STEP = 0.25;
6382
+ var BASE_PAGE_WIDTH = 820;
6383
+ var clampZoom = (z) => Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, Math.round(z * 100) / 100));
6379
6384
  var headerAction = cn(
6380
6385
  "inline-flex size-7 shrink-0 items-center justify-center",
6381
6386
  "rounded-icon text-fg-4 transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out-quart)] motion-reduce:transition-none",
6382
6387
  "hover:bg-overlay-hover hover:text-fg",
6383
6388
  "focus-visible:[box-shadow:var(--shadow-focus-ring)] focus-visible:outline-none"
6384
6389
  );
6385
- var PdfPreview = forwardRef(function PdfPreview2({ src, pages, fileName, onDownload, onClose, variant, className, ...props }, ref) {
6390
+ var zoomAction = cn(
6391
+ "inline-flex size-7 shrink-0 items-center justify-center",
6392
+ "rounded-icon text-fg-3 transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out-quart)] motion-reduce:transition-none",
6393
+ "hover:bg-overlay-hover hover:text-fg",
6394
+ "focus-visible:[box-shadow:var(--shadow-focus-ring)] focus-visible:outline-none",
6395
+ "disabled:pointer-events-none disabled:opacity-40"
6396
+ );
6397
+ var zoomLabel = cn(
6398
+ "inline-flex h-7 min-w-[3.25rem] items-center justify-center px-2",
6399
+ "rounded-icon text-fg-3 text-xs font-medium tabular-nums",
6400
+ "transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out-quart)] motion-reduce:transition-none",
6401
+ "hover:bg-overlay-hover hover:text-fg",
6402
+ "focus-visible:[box-shadow:var(--shadow-focus-ring)] focus-visible:outline-none"
6403
+ );
6404
+ var PdfPreview = forwardRef(function PdfPreview2({
6405
+ src,
6406
+ pages,
6407
+ fileName,
6408
+ onDownload,
6409
+ onApprove,
6410
+ approved,
6411
+ onReject,
6412
+ rejected,
6413
+ onClose,
6414
+ variant,
6415
+ zoomable,
6416
+ className,
6417
+ ...props
6418
+ }, ref) {
6419
+ const [zoom, setZoom] = useState(1);
6420
+ const zoomPercent = Math.round(zoom * 100);
6386
6421
  return /* @__PURE__ */ jsxs("div", { ref, className: cn(previewVariants({ variant }), className), ...props, children: [
6387
6422
  fileName && /* @__PURE__ */ jsxs("div", { className: "border-rule bg-surface flex shrink-0 items-center gap-3 border-b px-4 py-3", children: [
6388
6423
  /* @__PURE__ */ jsx(
@@ -6394,7 +6429,56 @@ var PdfPreview = forwardRef(function PdfPreview2({ src, pages, fileName, onDownl
6394
6429
  }
6395
6430
  ),
6396
6431
  /* @__PURE__ */ jsx("span", { className: "text-fg line-clamp-1 flex-1 text-sm font-medium", children: fileName }),
6397
- onDownload && /* @__PURE__ */ jsx("button", { type: "button", onClick: onDownload, "aria-label": "Download", className: headerAction, children: /* @__PURE__ */ jsx(DownloadIcon, { className: "size-4", "aria-hidden": "true" }) }),
6432
+ onApprove && (approved ? /* @__PURE__ */ jsxs("span", { className: "bg-success-bg text-success-fg rounded-icon inline-flex h-7 shrink-0 items-center gap-1.5 px-2.5 text-xs font-semibold", children: [
6433
+ /* @__PURE__ */ jsx(CheckIcon, { className: "size-4", "aria-hidden": "true" }),
6434
+ "Approved"
6435
+ ] }) : /* @__PURE__ */ jsxs(
6436
+ "button",
6437
+ {
6438
+ type: "button",
6439
+ onClick: onApprove,
6440
+ className: cn(
6441
+ "rounded-icon inline-flex h-7 shrink-0 items-center gap-1.5 px-2.5 text-xs font-semibold",
6442
+ "bg-success-fg text-fg-on-success hover:bg-success-fg-hover active:bg-success-fg-active",
6443
+ "transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out-quart)] motion-reduce:transition-none",
6444
+ "focus-visible:[box-shadow:var(--shadow-focus-ring)] focus-visible:outline-none"
6445
+ ),
6446
+ children: [
6447
+ /* @__PURE__ */ jsx(CheckIcon, { className: "size-4", "aria-hidden": "true" }),
6448
+ "Approve"
6449
+ ]
6450
+ }
6451
+ )),
6452
+ onReject && (rejected ? /* @__PURE__ */ jsxs("span", { className: "bg-danger-bg text-danger-fg rounded-icon inline-flex h-7 shrink-0 items-center gap-1.5 px-2.5 text-xs font-semibold", children: [
6453
+ /* @__PURE__ */ jsx(AlertTriangleIcon, { className: "size-4", "aria-hidden": "true" }),
6454
+ "Rejected"
6455
+ ] }) : /* @__PURE__ */ jsxs(
6456
+ "button",
6457
+ {
6458
+ type: "button",
6459
+ onClick: onReject,
6460
+ className: cn(
6461
+ "rounded-icon inline-flex h-7 shrink-0 items-center gap-1.5 px-2.5 text-xs font-semibold",
6462
+ "bg-danger-fg text-fg-on-danger hover:bg-danger-fg-hover active:bg-danger-fg-active",
6463
+ "transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out-quart)] motion-reduce:transition-none",
6464
+ "focus-visible:[box-shadow:var(--shadow-focus-ring)] focus-visible:outline-none"
6465
+ ),
6466
+ children: [
6467
+ /* @__PURE__ */ jsx(AlertTriangleIcon, { className: "size-4", "aria-hidden": "true" }),
6468
+ "Reject"
6469
+ ]
6470
+ }
6471
+ )),
6472
+ onDownload && /* @__PURE__ */ jsx(
6473
+ "button",
6474
+ {
6475
+ type: "button",
6476
+ onClick: onDownload,
6477
+ "aria-label": "Download",
6478
+ className: headerAction,
6479
+ children: /* @__PURE__ */ jsx(DownloadIcon, { className: "size-4", "aria-hidden": "true" })
6480
+ }
6481
+ ),
6398
6482
  onClose && /* @__PURE__ */ jsx("button", { type: "button", onClick: onClose, "aria-label": "Close", className: headerAction, children: /* @__PURE__ */ jsx(XIcon, { className: "size-4", "aria-hidden": "true" }) })
6399
6483
  ] }),
6400
6484
  src ? /* @__PURE__ */ jsx(
@@ -6404,15 +6488,72 @@ var PdfPreview = forwardRef(function PdfPreview2({ src, pages, fileName, onDownl
6404
6488
  title: fileName ?? "PDF preview",
6405
6489
  className: "bg-bg-2 min-h-0 flex-1 border-0"
6406
6490
  }
6407
- ) : pages && pages.length > 0 ? /* @__PURE__ */ jsx("div", { className: "scrollbar-thin bg-bg-2 min-h-0 flex-1 overflow-auto p-4 sm:p-6", children: /* @__PURE__ */ jsx("div", { className: "mx-auto flex max-w-[820px] flex-col gap-4", children: pages.map((page, i) => /* @__PURE__ */ jsx(
6408
- "img",
6409
- {
6410
- src: page,
6411
- alt: `Page ${i + 1}`,
6412
- className: "rounded-input border-rule shadow-card bg-surface w-full border"
6413
- },
6414
- i
6415
- )) }) }) : /* @__PURE__ */ jsxs("div", { className: "bg-bg-2 text-fg-4 flex min-h-0 flex-1 flex-col items-center justify-center gap-2 p-8", children: [
6491
+ ) : pages && pages.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "relative flex min-h-0 flex-1 flex-col", children: [
6492
+ /* @__PURE__ */ jsx("div", { className: "scrollbar-thin bg-bg-2 min-h-0 flex-1 overflow-auto p-4 sm:p-6", children: /* @__PURE__ */ jsx(
6493
+ "div",
6494
+ {
6495
+ className: cn("mx-auto flex flex-col gap-4", !zoomable && "max-w-[820px]"),
6496
+ style: zoomable ? {
6497
+ width: Math.round(BASE_PAGE_WIDTH * zoom),
6498
+ maxWidth: zoom <= 1 ? "100%" : void 0
6499
+ } : void 0,
6500
+ children: pages.map((page, i) => /* @__PURE__ */ jsx(
6501
+ "img",
6502
+ {
6503
+ src: page,
6504
+ alt: `Page ${i + 1}`,
6505
+ className: "rounded-input border-rule shadow-card bg-surface w-full border"
6506
+ },
6507
+ i
6508
+ ))
6509
+ }
6510
+ ) }),
6511
+ zoomable && /* @__PURE__ */ jsxs(
6512
+ "div",
6513
+ {
6514
+ role: "group",
6515
+ "aria-label": "Zoom controls",
6516
+ className: "border-rule bg-surface shadow-pop rounded-pill absolute bottom-4 left-1/2 flex -translate-x-1/2 items-center gap-0.5 border p-1",
6517
+ children: [
6518
+ /* @__PURE__ */ jsx(
6519
+ "button",
6520
+ {
6521
+ type: "button",
6522
+ onClick: () => setZoom((z) => clampZoom(z - ZOOM_STEP)),
6523
+ disabled: zoom <= MIN_ZOOM,
6524
+ "aria-label": "Zoom out",
6525
+ className: zoomAction,
6526
+ children: /* @__PURE__ */ jsx(ZoomOutIcon, { className: "size-4", "aria-hidden": "true" })
6527
+ }
6528
+ ),
6529
+ /* @__PURE__ */ jsxs(
6530
+ "button",
6531
+ {
6532
+ type: "button",
6533
+ onClick: () => setZoom(1),
6534
+ "aria-label": `Zoom ${zoomPercent}%, reset to 100%`,
6535
+ className: zoomLabel,
6536
+ children: [
6537
+ zoomPercent,
6538
+ "%"
6539
+ ]
6540
+ }
6541
+ ),
6542
+ /* @__PURE__ */ jsx(
6543
+ "button",
6544
+ {
6545
+ type: "button",
6546
+ onClick: () => setZoom((z) => clampZoom(z + ZOOM_STEP)),
6547
+ disabled: zoom >= MAX_ZOOM,
6548
+ "aria-label": "Zoom in",
6549
+ className: zoomAction,
6550
+ children: /* @__PURE__ */ jsx(ZoomInIcon, { className: "size-4", "aria-hidden": "true" })
6551
+ }
6552
+ )
6553
+ ]
6554
+ }
6555
+ )
6556
+ ] }) : /* @__PURE__ */ jsxs("div", { className: "bg-bg-2 text-fg-4 flex min-h-0 flex-1 flex-col items-center justify-center gap-2 p-8", children: [
6416
6557
  /* @__PURE__ */ jsx(FileTextIcon, { className: "size-8", "aria-hidden": "true" }),
6417
6558
  /* @__PURE__ */ jsx("p", { className: "text-sm", children: "No preview available" })
6418
6559
  ] })
@@ -8271,6 +8412,10 @@ var SpreadsheetPreview = forwardRef(
8271
8412
  minColumns = 0,
8272
8413
  fileName,
8273
8414
  onDownload,
8415
+ onApprove,
8416
+ approved,
8417
+ onReject,
8418
+ rejected,
8274
8419
  onClose,
8275
8420
  variant,
8276
8421
  className,
@@ -8291,6 +8436,46 @@ var SpreadsheetPreview = forwardRef(
8291
8436
  }
8292
8437
  ),
8293
8438
  /* @__PURE__ */ jsx("span", { className: "text-fg line-clamp-1 flex-1 text-sm font-medium", children: fileName }),
8439
+ onApprove && (approved ? /* @__PURE__ */ jsxs("span", { className: "bg-success-bg text-success-fg rounded-icon inline-flex h-7 shrink-0 items-center gap-1.5 px-2.5 text-xs font-semibold", children: [
8440
+ /* @__PURE__ */ jsx(CheckIcon, { className: "size-4", "aria-hidden": "true" }),
8441
+ "Approved"
8442
+ ] }) : /* @__PURE__ */ jsxs(
8443
+ "button",
8444
+ {
8445
+ type: "button",
8446
+ onClick: onApprove,
8447
+ className: cn(
8448
+ "rounded-icon inline-flex h-7 shrink-0 items-center gap-1.5 px-2.5 text-xs font-semibold",
8449
+ "bg-success-fg text-fg-on-success hover:bg-success-fg-hover active:bg-success-fg-active",
8450
+ "transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out-quart)] motion-reduce:transition-none",
8451
+ "focus-visible:[box-shadow:var(--shadow-focus-ring)] focus-visible:outline-none"
8452
+ ),
8453
+ children: [
8454
+ /* @__PURE__ */ jsx(CheckIcon, { className: "size-4", "aria-hidden": "true" }),
8455
+ "Approve"
8456
+ ]
8457
+ }
8458
+ )),
8459
+ onReject && (rejected ? /* @__PURE__ */ jsxs("span", { className: "bg-danger-bg text-danger-fg rounded-icon inline-flex h-7 shrink-0 items-center gap-1.5 px-2.5 text-xs font-semibold", children: [
8460
+ /* @__PURE__ */ jsx(AlertTriangleIcon, { className: "size-4", "aria-hidden": "true" }),
8461
+ "Rejected"
8462
+ ] }) : /* @__PURE__ */ jsxs(
8463
+ "button",
8464
+ {
8465
+ type: "button",
8466
+ onClick: onReject,
8467
+ className: cn(
8468
+ "rounded-icon inline-flex h-7 shrink-0 items-center gap-1.5 px-2.5 text-xs font-semibold",
8469
+ "bg-danger-fg text-fg-on-danger hover:bg-danger-fg-hover active:bg-danger-fg-active",
8470
+ "transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out-quart)] motion-reduce:transition-none",
8471
+ "focus-visible:[box-shadow:var(--shadow-focus-ring)] focus-visible:outline-none"
8472
+ ),
8473
+ children: [
8474
+ /* @__PURE__ */ jsx(AlertTriangleIcon, { className: "size-4", "aria-hidden": "true" }),
8475
+ "Reject"
8476
+ ]
8477
+ }
8478
+ )),
8294
8479
  onDownload && /* @__PURE__ */ jsx(
8295
8480
  "button",
8296
8481
  {
@@ -8332,7 +8517,7 @@ var SpreadsheetPreview = forwardRef(
8332
8517
  /* @__PURE__ */ jsx(
8333
8518
  "th",
8334
8519
  {
8335
- className: cn(headerCell, "left-0 top-0 z-20 w-11 min-w-11"),
8520
+ className: cn(headerCell, "top-0 left-0 z-20 w-11 min-w-11"),
8336
8521
  "aria-hidden": "true"
8337
8522
  }
8338
8523
  ),
@@ -8362,8 +8547,8 @@ var SpreadsheetPreview = forwardRef(
8362
8547
  "td",
8363
8548
  {
8364
8549
  className: cn(
8365
- "border-rule-soft text-fg border-b border-r",
8366
- "h-8 min-w-[88px] max-w-[260px] truncate px-3 text-sm",
8550
+ "border-rule-soft text-fg border-r border-b",
8551
+ "h-8 max-w-[260px] min-w-[88px] truncate px-3 text-sm",
8367
8552
  typeof data?.[r]?.[c] === "number" && "text-right tabular-nums"
8368
8553
  ),
8369
8554
  children: data?.[r]?.[c] ?? ""
@@ -13923,36 +14108,36 @@ var DocumentDetailPanel = forwardRef(
13923
14108
  DocumentDetailPanel.displayName = "DocumentDetailPanel";
13924
14109
  var DocumentDetailHeader = forwardRef(
13925
14110
  function DocumentDetailHeader2({ tags, status, onClose, className, children, ...props }, ref) {
13926
- const showBar = tags || status || onClose;
14111
+ const showControls = Boolean(status || onClose);
14112
+ const tagsClearance = !showControls ? void 0 : status ? "pr-32" : "pr-12";
14113
+ const titleClearance = !showControls || tags ? void 0 : status ? "[&>:first-child]:pr-32" : "[&>:first-child]:pr-12";
13927
14114
  return /* @__PURE__ */ jsxs(
13928
14115
  "div",
13929
14116
  {
13930
14117
  ref,
13931
- className: cn("border-rule shrink-0 space-y-3 border-b px-5 py-4", className),
14118
+ className: cn("border-rule relative shrink-0 space-y-3 border-b px-5 py-4", className),
13932
14119
  ...props,
13933
14120
  children: [
13934
- showBar && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
13935
- /* @__PURE__ */ jsx("div", { className: "flex min-w-0 flex-wrap items-center gap-1.5", children: tags }),
13936
- /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [
13937
- status,
13938
- onClose && /* @__PURE__ */ jsx(
13939
- "button",
13940
- {
13941
- type: "button",
13942
- onClick: onClose,
13943
- "aria-label": "Close",
13944
- className: cn(
13945
- "inline-flex size-7 shrink-0 items-center justify-center",
13946
- "rounded-icon text-fg-4 transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out-quart)] motion-reduce:transition-none",
13947
- "hover:bg-overlay-hover hover:text-fg",
13948
- "focus-visible:[box-shadow:var(--shadow-focus-ring)] focus-visible:outline-none"
13949
- ),
13950
- children: /* @__PURE__ */ jsx(XIcon, { className: "size-4", "aria-hidden": "true" })
13951
- }
13952
- )
13953
- ] })
14121
+ showControls && /* @__PURE__ */ jsxs("div", { className: "absolute top-4 right-5 z-10 flex shrink-0 items-center gap-2", children: [
14122
+ status,
14123
+ onClose && /* @__PURE__ */ jsx(
14124
+ "button",
14125
+ {
14126
+ type: "button",
14127
+ onClick: onClose,
14128
+ "aria-label": "Close",
14129
+ className: cn(
14130
+ "inline-flex size-7 shrink-0 items-center justify-center",
14131
+ "rounded-icon text-fg-4 transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out-quart)] motion-reduce:transition-none",
14132
+ "hover:bg-overlay-hover hover:text-fg",
14133
+ "focus-visible:[box-shadow:var(--shadow-focus-ring)] focus-visible:outline-none"
14134
+ ),
14135
+ children: /* @__PURE__ */ jsx(XIcon, { className: "size-4", "aria-hidden": "true" })
14136
+ }
14137
+ )
13954
14138
  ] }),
13955
- children
14139
+ tags && /* @__PURE__ */ jsx("div", { className: cn("flex min-w-0 flex-wrap items-center gap-1.5", tagsClearance), children: tags }),
14140
+ /* @__PURE__ */ jsx("div", { className: cn("space-y-3", titleClearance), children })
13956
14141
  ]
13957
14142
  }
13958
14143
  );
@@ -14052,7 +14237,7 @@ var DocumentListSection = forwardRef(
14052
14237
  }
14053
14238
  );
14054
14239
  DocumentListSection.displayName = "DocumentListSection";
14055
- var DocumentRow = forwardRef(function DocumentRow2({ fileName, meta, icon, actions, className, ...props }, ref) {
14240
+ var DocumentRow = forwardRef(function DocumentRow2({ fileName, meta, icon, approved, rejected, actions, className, ...props }, ref) {
14056
14241
  return /* @__PURE__ */ jsxs(
14057
14242
  "div",
14058
14243
  {
@@ -14069,12 +14254,24 @@ var DocumentRow = forwardRef(function DocumentRow2({ fileName, meta, icon, actio
14069
14254
  "span",
14070
14255
  {
14071
14256
  "aria-hidden": "true",
14072
- className: "rounded-icon bg-bg-2 text-fg-3 inline-flex size-9 shrink-0 items-center justify-center",
14257
+ className: cn(
14258
+ "rounded-icon inline-flex size-9 shrink-0 items-center justify-center",
14259
+ approved ? "bg-success-bg text-success-fg" : rejected ? "bg-danger-bg text-danger-fg" : "bg-bg-2 text-fg-3"
14260
+ ),
14073
14261
  children: icon ?? /* @__PURE__ */ jsx(FileTextIcon, { className: "size-4.5" })
14074
14262
  }
14075
14263
  ),
14076
14264
  /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
14077
- /* @__PURE__ */ jsx("div", { className: "text-fg line-clamp-1 text-sm font-medium", children: fileName }),
14265
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-1.5", children: [
14266
+ /* @__PURE__ */ jsx("span", { className: "text-fg line-clamp-1 min-w-0 text-sm font-medium", children: fileName }),
14267
+ approved ? /* @__PURE__ */ jsxs("span", { className: "bg-success-bg text-success-fg inline-flex shrink-0 items-center gap-1 rounded-md px-1.5 py-0.5 text-[10.5px] font-semibold", children: [
14268
+ /* @__PURE__ */ jsx(CheckIcon, { className: "size-3", "aria-hidden": "true" }),
14269
+ "Approved"
14270
+ ] }) : rejected ? /* @__PURE__ */ jsxs("span", { className: "bg-danger-bg text-danger-fg inline-flex shrink-0 items-center gap-1 rounded-md px-1.5 py-0.5 text-[10.5px] font-semibold", children: [
14271
+ /* @__PURE__ */ jsx(AlertTriangleIcon, { className: "size-3", "aria-hidden": "true" }),
14272
+ "Rejected"
14273
+ ] }) : null
14274
+ ] }),
14078
14275
  meta && /* @__PURE__ */ jsx("div", { className: "text-fg-4 line-clamp-1 text-xs", children: meta })
14079
14276
  ] }),
14080
14277
  actions && /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center gap-0.5", children: actions })
@@ -14095,11 +14292,30 @@ var TONE_PILL = {
14095
14292
  danger: "bg-danger-bg text-danger-fg",
14096
14293
  muted: "bg-surface-2 text-fg-3"
14097
14294
  };
14295
+ var TONE_DOT2 = {
14296
+ warning: "bg-warning-fg",
14297
+ success: "bg-success-fg",
14298
+ danger: "bg-danger-fg",
14299
+ muted: "bg-fg-4"
14300
+ };
14098
14301
  function initials(name) {
14099
14302
  return name.split(/\s+/).slice(0, 2).map((p) => p[0]?.toUpperCase() ?? "").join("");
14100
14303
  }
14101
14304
  var DocumentRequestCard = forwardRef(
14102
- function DocumentRequestCard2({ title, category, highPriority, due, comment, fulfilledCount, totalCount, items, assignees = [], onOpen, className, ...props }, ref) {
14305
+ function DocumentRequestCard2({
14306
+ title,
14307
+ category,
14308
+ highPriority,
14309
+ due,
14310
+ comment,
14311
+ fulfilledCount,
14312
+ totalCount,
14313
+ items,
14314
+ assignees = [],
14315
+ onOpen,
14316
+ className,
14317
+ ...props
14318
+ }, ref) {
14103
14319
  const docWord = totalCount === 1 ? "document" : "documents";
14104
14320
  return /* @__PURE__ */ jsxs(
14105
14321
  "div",
@@ -14117,7 +14333,7 @@ var DocumentRequestCard = forwardRef(
14117
14333
  className: cn(
14118
14334
  "rounded-card border-rule bg-surface cursor-pointer overflow-hidden border shadow-sm",
14119
14335
  "transition-shadow duration-[var(--duration-fast)] ease-[var(--ease-out-quart)] motion-reduce:transition-none",
14120
- "hover:shadow-md focus-visible:outline-none focus-visible:[box-shadow:var(--shadow-focus-ring)]",
14336
+ "hover:shadow-md focus-visible:[box-shadow:var(--shadow-focus-ring)] focus-visible:outline-none",
14121
14337
  className
14122
14338
  ),
14123
14339
  ...props,
@@ -14131,7 +14347,14 @@ var DocumentRequestCard = forwardRef(
14131
14347
  /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
14132
14348
  /* @__PURE__ */ jsx("span", { className: "text-fg min-w-0 truncate text-sm font-semibold", children: title }),
14133
14349
  category && /* @__PURE__ */ jsx("span", { className: "bg-surface-2 text-fg-3 inline-flex shrink-0 items-center rounded-md px-2 py-0.5 text-xs font-medium", children: category }),
14134
- highPriority && /* @__PURE__ */ jsx(AlertTriangleIcon, { size: 14, className: "text-warning-fg shrink-0", "aria-label": "Urgent request" }),
14350
+ highPriority && /* @__PURE__ */ jsx(
14351
+ AlertTriangleIcon,
14352
+ {
14353
+ size: 14,
14354
+ className: "text-warning-fg shrink-0",
14355
+ "aria-label": "Urgent request"
14356
+ }
14357
+ ),
14135
14358
  due && /* @__PURE__ */ jsx(
14136
14359
  "span",
14137
14360
  {
@@ -14160,12 +14383,25 @@ var DocumentRequestCard = forwardRef(
14160
14383
  comment,
14161
14384
  "\u201D"
14162
14385
  ] }),
14163
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2 px-5 pb-4 pt-3", children: items.map((item) => /* @__PURE__ */ jsxs("div", { className: "bg-surface-2 flex items-center gap-3 rounded-xl px-4 py-3.5", children: [
14164
- /* @__PURE__ */ jsx(FileTextIcon, { size: 16, className: "text-fg-3 shrink-0" }),
14165
- /* @__PURE__ */ jsx("span", { className: "text-fg min-w-0 flex-1 truncate text-sm font-semibold", children: item.label }),
14166
- item.docType && /* @__PURE__ */ jsx("span", { className: "border-rule bg-surface text-fg-3 inline-flex shrink-0 items-center rounded-md border px-2 py-0.5 text-[10.5px] font-semibold uppercase tracking-wide", children: item.docType }),
14167
- /* @__PURE__ */ jsx("span", { className: cn("shrink-0 text-[13px] font-semibold", TONE_TEXT[item.statusTone]), children: item.statusLabel })
14168
- ] }, item.id)) }),
14386
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2 px-5 pt-3 pb-4", children: items.map((item) => /* @__PURE__ */ jsxs(
14387
+ "div",
14388
+ {
14389
+ className: "bg-surface-2 flex items-center gap-3 rounded-xl px-4 py-3.5",
14390
+ children: [
14391
+ /* @__PURE__ */ jsx(FileTextIcon, { size: 16, className: "text-fg-3 shrink-0" }),
14392
+ /* @__PURE__ */ jsx("span", { className: "text-fg min-w-0 flex-1 truncate text-sm font-semibold", children: item.label }),
14393
+ item.docType && /* @__PURE__ */ jsx("span", { className: "border-rule bg-surface text-fg-3 inline-flex shrink-0 items-center rounded-md border px-2 py-0.5 text-[10.5px] font-semibold tracking-wide uppercase", children: item.docType }),
14394
+ /* @__PURE__ */ jsx(
14395
+ "span",
14396
+ {
14397
+ className: cn("shrink-0 text-[13px] font-semibold", TONE_TEXT[item.statusTone]),
14398
+ children: item.statusLabel
14399
+ }
14400
+ )
14401
+ ]
14402
+ },
14403
+ item.id
14404
+ )) }),
14169
14405
  /* @__PURE__ */ jsxs("div", { className: "border-rule flex items-center gap-2 border-t px-5 py-2.5", children: [
14170
14406
  /* @__PURE__ */ jsx(FolderClosedIcon, { size: 14, className: "text-fg-4 shrink-0" }),
14171
14407
  /* @__PURE__ */ jsxs("span", { className: "text-fg-3 text-[12.5px] tabular-nums", children: [
@@ -14234,8 +14470,10 @@ var DocumentRequestDetail = forwardRef(
14234
14470
  tab,
14235
14471
  defaultTab = "documents",
14236
14472
  onTabChange,
14237
- clientUploads,
14473
+ clientUploads = [],
14238
14474
  firmDocuments,
14475
+ requestedItems,
14476
+ otherUploads = [],
14239
14477
  onUploadFirmDocument,
14240
14478
  comments,
14241
14479
  commentDraft,
@@ -14246,20 +14484,22 @@ var DocumentRequestDetail = forwardRef(
14246
14484
  activity,
14247
14485
  className
14248
14486
  } = props;
14249
- const docCount = clientUploads.length + firmDocuments.length;
14487
+ const clientDocCount = requestedItems ? requestedItems.reduce((n, it) => n + it.documents.length, 0) + otherUploads.length : clientUploads.length;
14488
+ const docCount = clientDocCount + firmDocuments.length;
14489
+ const providedCount = requestedItems?.filter((it) => it.statusTone === "success").length ?? 0;
14250
14490
  const selectedAssignees = assignees.filter((a) => a.selected);
14251
14491
  return /* @__PURE__ */ jsxs(DocumentDetailPanel, { ref, className, children: [
14252
14492
  /* @__PURE__ */ jsxs(
14253
14493
  DocumentDetailHeader,
14254
14494
  {
14255
14495
  onClose,
14256
- tags: /* @__PURE__ */ jsxs(Fragment, { children: [
14496
+ tags: category || highPriority ? /* @__PURE__ */ jsxs(Fragment, { children: [
14257
14497
  category && /* @__PURE__ */ jsxs(Badge, { variant: "outline", className: "gap-1", children: [
14258
14498
  /* @__PURE__ */ jsx(FolderClosedIcon, { className: "size-3" }),
14259
14499
  category
14260
14500
  ] }),
14261
14501
  highPriority && /* @__PURE__ */ jsx(Badge, { variant: "warning", children: "High priority" })
14262
- ] }),
14502
+ ] }) : void 0,
14263
14503
  status: statusLabel ? /* @__PURE__ */ jsx(Badge, { variant: statusVariant, children: statusLabel }) : void 0,
14264
14504
  children: [
14265
14505
  /* @__PURE__ */ jsx(DocumentDetailTitle, { children: title }),
@@ -14317,7 +14557,12 @@ var DocumentRequestDetail = forwardRef(
14317
14557
  },
14318
14558
  className: "flex items-center gap-2.5 py-2",
14319
14559
  children: [
14320
- /* @__PURE__ */ jsx("span", { className: cn("size-2.5 shrink-0 rounded-full", opt.color ?? "bg-fg-4") }),
14560
+ /* @__PURE__ */ jsx(
14561
+ "span",
14562
+ {
14563
+ className: cn("size-2.5 shrink-0 rounded-full", opt.color ?? "bg-fg-4")
14564
+ }
14565
+ ),
14321
14566
  /* @__PURE__ */ jsx("span", { className: "flex-1 text-sm", children: opt.label }),
14322
14567
  /* @__PURE__ */ jsx(
14323
14568
  "span",
@@ -14372,12 +14617,85 @@ var DocumentRequestDetail = forwardRef(
14372
14617
  /* @__PURE__ */ jsx(LockIcon, { size: 15, className: "shrink-0" }),
14373
14618
  "This request is locked \u2014 the client can no longer upload documents."
14374
14619
  ] }),
14375
- /* @__PURE__ */ jsxs(DocumentList, { children: [
14620
+ /* @__PURE__ */ jsx(DocumentList, { children: requestedItems ? /* @__PURE__ */ jsxs(Fragment, { children: [
14621
+ /* @__PURE__ */ jsxs("div", { className: "text-fg-3 px-2.5 text-[13px] font-medium tabular-nums", children: [
14622
+ providedCount,
14623
+ " of ",
14624
+ requestedItems.length,
14625
+ " provided"
14626
+ ] }),
14627
+ requestedItems.map((item) => /* @__PURE__ */ jsxs("section", { className: "space-y-1", children: [
14628
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-2.5 py-1", children: [
14629
+ /* @__PURE__ */ jsx(FileTextIcon, { size: 15, className: "text-fg-3 shrink-0" }),
14630
+ /* @__PURE__ */ jsx("span", { className: "text-fg min-w-0 flex-1 truncate text-sm font-semibold", children: item.label }),
14631
+ item.docType && /* @__PURE__ */ jsx("span", { className: "border-rule bg-surface text-fg-3 inline-flex shrink-0 items-center rounded-md border px-1.5 py-0.5 text-[10px] font-semibold tracking-wide uppercase", children: item.docType }),
14632
+ /* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-1.5", children: [
14633
+ /* @__PURE__ */ jsx(
14634
+ "span",
14635
+ {
14636
+ "aria-hidden": true,
14637
+ className: cn("size-2 rounded-full", TONE_DOT2[item.statusTone])
14638
+ }
14639
+ ),
14640
+ /* @__PURE__ */ jsx("span", { className: cn("text-xs font-semibold", TONE_TEXT[item.statusTone]), children: item.statusLabel })
14641
+ ] })
14642
+ ] }),
14643
+ /* @__PURE__ */ jsx("div", { className: "space-y-0.5 pl-[1.625rem]", children: item.documents.length > 0 ? item.documents.map((d) => /* @__PURE__ */ jsx(
14644
+ DocumentRow,
14645
+ {
14646
+ fileName: d.fileName,
14647
+ meta: d.meta,
14648
+ approved: d.approved,
14649
+ rejected: d.rejected,
14650
+ className: d.active ? "bg-overlay-hover" : void 0,
14651
+ actions: /* @__PURE__ */ jsx(FileRowActions, { doc: d })
14652
+ },
14653
+ d.id
14654
+ )) : /* @__PURE__ */ jsx("p", { className: "text-fg-4 px-2.5 py-1.5 text-[13px]", children: "Awaiting client upload" }) })
14655
+ ] }, item.id)),
14656
+ otherUploads.length > 0 && /* @__PURE__ */ jsx(DocumentListSection, { label: "Other uploads", count: otherUploads.length, children: otherUploads.map((d) => /* @__PURE__ */ jsx(
14657
+ DocumentRow,
14658
+ {
14659
+ fileName: d.fileName,
14660
+ meta: d.meta,
14661
+ approved: d.approved,
14662
+ rejected: d.rejected,
14663
+ className: d.active ? "bg-overlay-hover" : void 0,
14664
+ actions: /* @__PURE__ */ jsx(FileRowActions, { doc: d })
14665
+ },
14666
+ d.id
14667
+ )) }),
14668
+ /* @__PURE__ */ jsx(
14669
+ DocumentListSection,
14670
+ {
14671
+ label: "Firm reference",
14672
+ count: firmDocuments.length,
14673
+ action: onUploadFirmDocument ? /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "sm", onClick: onUploadFirmDocument, children: [
14674
+ /* @__PURE__ */ jsx(UploadIcon, {}),
14675
+ "Upload"
14676
+ ] }) : void 0,
14677
+ children: firmDocuments.length > 0 ? firmDocuments.map((d) => /* @__PURE__ */ jsx(
14678
+ DocumentRow,
14679
+ {
14680
+ fileName: d.fileName,
14681
+ meta: d.meta,
14682
+ approved: d.approved,
14683
+ rejected: d.rejected,
14684
+ className: d.active ? "bg-overlay-hover" : void 0,
14685
+ actions: /* @__PURE__ */ jsx(FileRowActions, { doc: d })
14686
+ },
14687
+ d.id
14688
+ )) : /* @__PURE__ */ jsx("p", { className: "text-fg-4 px-2.5 py-2 text-sm", children: "No firm documents attached." })
14689
+ }
14690
+ )
14691
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
14376
14692
  /* @__PURE__ */ jsx(DocumentListSection, { label: "Client uploads", count: clientUploads.length, children: clientUploads.length > 0 ? clientUploads.map((d) => /* @__PURE__ */ jsx(
14377
14693
  DocumentRow,
14378
14694
  {
14379
14695
  fileName: d.fileName,
14380
14696
  meta: d.meta,
14697
+ approved: d.approved,
14698
+ rejected: d.rejected,
14381
14699
  className: d.active ? "bg-overlay-hover" : void 0,
14382
14700
  actions: /* @__PURE__ */ jsx(FileRowActions, { doc: d })
14383
14701
  },
@@ -14397,6 +14715,8 @@ var DocumentRequestDetail = forwardRef(
14397
14715
  {
14398
14716
  fileName: d.fileName,
14399
14717
  meta: d.meta,
14718
+ approved: d.approved,
14719
+ rejected: d.rejected,
14400
14720
  className: d.active ? "bg-overlay-hover" : void 0,
14401
14721
  actions: /* @__PURE__ */ jsx(FileRowActions, { doc: d })
14402
14722
  },
@@ -14404,7 +14724,7 @@ var DocumentRequestDetail = forwardRef(
14404
14724
  )) : /* @__PURE__ */ jsx("p", { className: "text-fg-4 px-2.5 py-2 text-sm", children: "No firm documents attached." })
14405
14725
  }
14406
14726
  )
14407
- ] })
14727
+ ] }) })
14408
14728
  ] }),
14409
14729
  /* @__PURE__ */ jsxs(TabsContent, { value: "comments", className: "flex min-h-0 flex-1 flex-col", children: [
14410
14730
  /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-y-auto px-5 py-4", children: comments.length > 0 ? /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4", children: comments.map((c) => /* @__PURE__ */ jsx(CommentRow, { comment: c }, c.id)) }) : /* @__PURE__ */ jsx("p", { className: "text-fg-4 text-sm", children: "No comments yet. Start the conversation below." }) }),
@@ -14467,7 +14787,7 @@ function AssigneePicker({
14467
14787
  const selected = assignees.filter((a) => a.selected);
14468
14788
  const stack = /* @__PURE__ */ jsx("span", { className: "flex -space-x-2", children: selected.map((a) => /* @__PURE__ */ jsx(Avatar, { size: "sm", name: a.name, variant: "branded" }, a.id)) });
14469
14789
  if (!onToggle) {
14470
- return /* @__PURE__ */ jsxs("span", { className: "rounded-pill border-rule inline-flex items-center gap-2 border py-1 pl-1.5 pr-2.5", children: [
14790
+ return /* @__PURE__ */ jsxs("span", { className: "rounded-pill border-rule inline-flex items-center gap-2 border py-1 pr-2.5 pl-1.5", children: [
14471
14791
  stack,
14472
14792
  /* @__PURE__ */ jsx("span", { className: "text-fg-2 text-sm font-semibold tabular-nums", children: selected.length })
14473
14793
  ] });
@@ -14478,7 +14798,7 @@ function AssigneePicker({
14478
14798
  {
14479
14799
  type: "button",
14480
14800
  "aria-label": "Edit assignees",
14481
- className: "rounded-pill border-rule hover:bg-overlay-hover inline-flex items-center gap-2 border py-1 pl-1.5 pr-2.5 transition-colors focus-visible:outline-none focus-visible:[box-shadow:var(--shadow-focus-ring)]",
14801
+ className: "rounded-pill border-rule hover:bg-overlay-hover inline-flex items-center gap-2 border py-1 pr-2.5 pl-1.5 transition-colors focus-visible:[box-shadow:var(--shadow-focus-ring)] focus-visible:outline-none",
14482
14802
  children: [
14483
14803
  stack,
14484
14804
  /* @__PURE__ */ jsx("span", { className: "text-fg-2 text-sm font-semibold tabular-nums", children: selected.length }),
@@ -14506,23 +14826,49 @@ function AssigneePicker({
14506
14826
  ] });
14507
14827
  }
14508
14828
  function CommentRow({ comment }) {
14509
- return /* @__PURE__ */ jsxs("div", { className: "flex gap-2.5", children: [
14510
- /* @__PURE__ */ jsx(Avatar, { size: "sm", name: comment.author, variant: "branded" }),
14511
- /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
14512
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
14513
- /* @__PURE__ */ jsxs("span", { className: "text-fg truncate text-[13px] font-semibold", children: [
14514
- comment.author,
14515
- comment.you && " (You)"
14516
- ] }),
14517
- /* @__PURE__ */ jsx(Badge, { variant: comment.isFirm ? "secondary" : "info", size: "sm", children: comment.isFirm ? "Firm" : "Client" }),
14518
- /* @__PURE__ */ jsx("span", { className: "text-fg-4 ml-auto shrink-0 text-[11.5px]", children: comment.time })
14519
- ] }),
14520
- /* @__PURE__ */ jsx("p", { className: "text-fg-2 mt-0.5 text-[13px] leading-snug", children: comment.body })
14521
- ] })
14829
+ const { isFirm } = comment;
14830
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex gap-2.5", isFirm ? "flex-row-reverse" : "flex-row"), children: [
14831
+ /* @__PURE__ */ jsx(Avatar, { size: "sm", name: comment.author, variant: "branded", className: "mt-0.5 shrink-0" }),
14832
+ /* @__PURE__ */ jsxs(
14833
+ "div",
14834
+ {
14835
+ className: cn("flex max-w-[78%] min-w-0 flex-col", isFirm ? "items-end" : "items-start"),
14836
+ children: [
14837
+ /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", isFirm && "flex-row-reverse"), children: [
14838
+ /* @__PURE__ */ jsxs("span", { className: "text-fg truncate text-[13px] font-semibold", children: [
14839
+ comment.author,
14840
+ comment.you && " (You)"
14841
+ ] }),
14842
+ /* @__PURE__ */ jsx("span", { className: "text-fg-4 shrink-0 text-[11.5px]", children: comment.time })
14843
+ ] }),
14844
+ /* @__PURE__ */ jsx(
14845
+ "div",
14846
+ {
14847
+ className: cn(
14848
+ "mt-1 rounded-2xl px-3 py-2 text-[13px] leading-snug",
14849
+ isFirm ? "bg-pro-bg text-pro-fg rounded-tr-sm" : "bg-surface-2 text-fg-2 rounded-tl-sm"
14850
+ ),
14851
+ children: /* @__PURE__ */ jsx("p", { className: "break-words whitespace-pre-wrap", children: comment.body })
14852
+ }
14853
+ )
14854
+ ]
14855
+ }
14856
+ )
14522
14857
  ] });
14523
14858
  }
14524
14859
  function FileRowActions({ doc }) {
14525
14860
  return /* @__PURE__ */ jsxs(Fragment, { children: [
14861
+ doc.onApprove && !doc.approved && /* @__PURE__ */ jsx(
14862
+ Button,
14863
+ {
14864
+ variant: "ghost",
14865
+ size: "icon-sm",
14866
+ "aria-label": "Approve",
14867
+ className: "hover:text-success-fg",
14868
+ onClick: doc.onApprove,
14869
+ children: /* @__PURE__ */ jsx(CheckIcon, {})
14870
+ }
14871
+ ),
14526
14872
  doc.onPreview && /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "Preview", onClick: doc.onPreview, children: /* @__PURE__ */ jsx(EyeIcon, {}) }),
14527
14873
  doc.onDownload && /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "Download", onClick: doc.onDownload, children: /* @__PURE__ */ jsx(DownloadIcon, {}) }),
14528
14874
  doc.onDelete && /* @__PURE__ */ jsx(