@mindbill/react 0.33.0 → 0.34.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.d.ts CHANGED
@@ -618,7 +618,7 @@ declare function BillSubmissionForm({ initialBill, attachments, onSubmit, onSubm
618
618
  declare function extractSendRouteEmail(raw: string | null | undefined): string | null;
619
619
  /** "(213) 555-0199" for 10/11-digit US numbers; anything else trimmed as-is. */
620
620
  declare function formatSendRouteFax(raw: string | null | undefined): string;
621
- type SendRouteSubmission = Pick<SubmitBillInput, "route" | "destination" | "attention" | "subject">;
621
+ type SendRouteSubmission = Pick<SubmitBillInput, "route" | "destination" | "attention" | "subject" | "note" | "cc">;
622
622
  type SendRouteDialogProps = {
623
623
  /** Dialog heading, e.g. "Send bill". */
624
624
  title?: ReactNode;
package/dist/index.js CHANGED
@@ -1315,6 +1315,17 @@ function formatSendRouteFax(raw) {
1315
1315
  if (ten.length === 10) return `(${ten.slice(0, 3)}) ${ten.slice(3, 6)}-${ten.slice(6)}`;
1316
1316
  return raw.trim();
1317
1317
  }
1318
+ function formatSendRouteFaxInput(raw) {
1319
+ const trimmed = raw.trimStart();
1320
+ if (trimmed.startsWith("+")) return raw;
1321
+ const all = trimmed.replace(/\D/g, "");
1322
+ const digits = all.length === 11 && all.startsWith("1") ? all.slice(1) : all;
1323
+ if (digits.length > 10 || all.length === 11 && !all.startsWith("1") || all.length > 11) return raw;
1324
+ if (digits.length === 0) return "";
1325
+ if (digits.length <= 3) return `(${digits}`;
1326
+ if (digits.length <= 6) return `(${digits.slice(0, 3)}) ${digits.slice(3)}`;
1327
+ return `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6)}`;
1328
+ }
1318
1329
  var css = `
1319
1330
  .mbrd-overlay{position:fixed;inset:0;z-index:1000;display:grid;place-items:center;padding:20px;background:rgba(15,30,40,.45)}
1320
1331
  .mbrd{display:grid;gap:16px;width:min(560px,100%);max-height:min(86vh,860px);overflow:auto;overscroll-behavior:contain;padding:24px;border:1px solid var(--mb-border);border-radius:var(--mb-radius);background:var(--mb-surface);color:var(--mb-text);font-family:var(--mb-font);font-size:15px;box-shadow:0 24px 60px rgba(17,38,49,.28)}
@@ -1451,6 +1462,8 @@ function SendRouteDialog({
1451
1462
  const [faxMode, setFaxMode] = useState3(onFileFax ? "onfile" : "alt");
1452
1463
  const [emailTo, setEmailTo] = useState3("");
1453
1464
  const [subject, setSubject] = useState3("");
1465
+ const [message, setMessage] = useState3("");
1466
+ const [ccInput, setCcInput] = useState3("");
1454
1467
  const [faxTo, setFaxTo] = useState3("");
1455
1468
  const [attention, setAttention] = useState3("");
1456
1469
  const [mailTo, setMailTo] = useState3(onFileMail);
@@ -1471,15 +1484,19 @@ function SendRouteDialog({
1471
1484
  const effectiveFax = faxMode === "onfile" && onFileFax ? onFileFax : faxTo;
1472
1485
  const faxDigits = effectiveFax.replace(/\D/g, "");
1473
1486
  const emailValid = EMAIL_RE.test(effectiveEmail);
1487
+ const ccList = ccInput.split(/[,;]/).map((entry) => entry.trim()).filter(Boolean);
1488
+ const ccValid = ccList.every((entry) => EMAIL_RE.test(entry));
1474
1489
  const faxValid = faxDigits.length >= 10;
1475
1490
  const mailValid = mailTo.trim().length > 2;
1476
- const confirmDisabled = submitting || disabled || route === "email" && !emailValid || route === "fax" && !faxValid || route === "mail" && !mailValid;
1491
+ const confirmDisabled = submitting || disabled || route === "email" && (!emailValid || !ccValid) || route === "fax" && !faxValid || route === "mail" && !mailValid;
1477
1492
  const submission = useMemo2(() => {
1478
1493
  if (route === "email") {
1479
1494
  return {
1480
1495
  route,
1481
1496
  destination: { email: effectiveEmail },
1482
- ...subject.trim() ? { subject: subject.trim() } : {}
1497
+ ...subject.trim() ? { subject: subject.trim() } : {},
1498
+ ...message.trim() ? { note: message.trim() } : {},
1499
+ ...ccList.length ? { cc: ccList } : {}
1483
1500
  };
1484
1501
  }
1485
1502
  if (route === "fax") {
@@ -1493,7 +1510,7 @@ function SendRouteDialog({
1493
1510
  return { route, destination: { mailingAddress: mailTo.trim() } };
1494
1511
  }
1495
1512
  return { route };
1496
- }, [route, effectiveEmail, subject, effectiveFax, attention, mailTo]);
1513
+ }, [route, effectiveEmail, subject, message, ccInput, effectiveFax, attention, mailTo]);
1497
1514
  return /* @__PURE__ */ jsxs3("div", { className: "mbrd-overlay", role: "presentation", onMouseDown: (event) => {
1498
1515
  if (event.target === event.currentTarget && !submitting) onCancel();
1499
1516
  }, children: [
@@ -1506,8 +1523,8 @@ function SendRouteDialog({
1506
1523
  ] }),
1507
1524
  /* @__PURE__ */ jsx3("button", { className: "mbrd-close", type: "button", "aria-label": "Close", disabled: submitting, onClick: onCancel, children: "\xD7" })
1508
1525
  ] }),
1509
- /* @__PURE__ */ jsxs3("div", { className: "mbrd-cards", role: "radiogroup", "aria-label": "Delivery method", children: [
1510
- ebillOption ? /* @__PURE__ */ jsx3(
1526
+ /* @__PURE__ */ jsx3("div", { className: "mbrd-cards", role: "radiogroup", "aria-label": "Delivery method", children: (() => {
1527
+ const ebillCard = ebillOption ? /* @__PURE__ */ jsx3(
1511
1528
  RouteCard,
1512
1529
  {
1513
1530
  selected: route === "ebill",
@@ -1521,9 +1538,10 @@ function SendRouteDialog({
1521
1538
  recommendedRoute === "ebill" ? /* @__PURE__ */ jsx3("span", { className: "mbrd-badge", "data-tone": "auto", children: "Auto" }) : null
1522
1539
  ] }),
1523
1540
  onSelect: () => setRoute("ebill")
1524
- }
1525
- ) : null,
1526
- /* @__PURE__ */ jsxs3(
1541
+ },
1542
+ "ebill"
1543
+ ) : null;
1544
+ const emailCard = /* @__PURE__ */ jsxs3(
1527
1545
  RouteCard,
1528
1546
  {
1529
1547
  selected: route === "email",
@@ -1560,14 +1578,24 @@ function SendRouteDialog({
1560
1578
  }
1561
1579
  )
1562
1580
  ] }),
1581
+ /* @__PURE__ */ jsxs3("label", { className: "mbrd-field", children: [
1582
+ /* @__PURE__ */ jsx3("span", { className: "mbrd-label", children: "Cc \u2014 optional" }),
1583
+ /* @__PURE__ */ jsx3("input", { className: "mbrd-input", value: ccInput, placeholder: "adjuster@payer.com, supervisor@payer.com", onChange: (event) => setCcInput(event.target.value) }),
1584
+ !ccValid ? /* @__PURE__ */ jsx3("span", { className: "mbrd-error", children: "Each Cc entry must be a valid email address (separate with commas)." }) : null
1585
+ ] }),
1563
1586
  /* @__PURE__ */ jsxs3("label", { className: "mbrd-field", children: [
1564
1587
  /* @__PURE__ */ jsx3("span", { className: "mbrd-label", children: "Email subject \u2014 optional" }),
1565
1588
  /* @__PURE__ */ jsx3("input", { className: "mbrd-input", value: subject, maxLength: 255, onChange: (event) => setSubject(event.target.value) })
1589
+ ] }),
1590
+ /* @__PURE__ */ jsxs3("label", { className: "mbrd-field", children: [
1591
+ /* @__PURE__ */ jsx3("span", { className: "mbrd-label", children: "Message \u2014 optional" }),
1592
+ /* @__PURE__ */ jsx3("textarea", { className: "mbrd-textarea", value: message, maxLength: 5e3, placeholder: "Added at the top of the email body, above the bill summary.", onChange: (event) => setMessage(event.target.value) })
1566
1593
  ] })
1567
1594
  ]
1568
- }
1569
- ),
1570
- /* @__PURE__ */ jsxs3(
1595
+ },
1596
+ "email"
1597
+ );
1598
+ const faxCard = /* @__PURE__ */ jsxs3(
1571
1599
  RouteCard,
1572
1600
  {
1573
1601
  selected: route === "fax",
@@ -1598,7 +1626,7 @@ function SendRouteDialog({
1598
1626
  "Alternative fax number ",
1599
1627
  /* @__PURE__ */ jsx3("span", { className: "mbrd-star", children: "*" })
1600
1628
  ] }),
1601
- /* @__PURE__ */ jsx3("input", { className: "mbrd-input", inputMode: "tel", value: faxTo, placeholder: "(000) 000-0000", onChange: (event) => setFaxTo(event.target.value) }),
1629
+ /* @__PURE__ */ jsx3("input", { className: "mbrd-input", inputMode: "tel", value: faxTo, placeholder: "(000) 000-0000", onChange: (event) => setFaxTo(formatSendRouteFaxInput(event.target.value)) }),
1602
1630
  faxTo.trim() && faxTo.replace(/\D/g, "").length < 10 ? /* @__PURE__ */ jsx3("span", { className: "mbrd-error", children: "Enter a valid fax number (10 digits)." }) : null
1603
1631
  ] })
1604
1632
  }
@@ -1610,9 +1638,10 @@ function SendRouteDialog({
1610
1638
  /* @__PURE__ */ jsx3("span", { className: "mbrd-help", children: "Printed as ATTENTION on the fax cover sheet." })
1611
1639
  ] })
1612
1640
  ]
1613
- }
1614
- ),
1615
- /* @__PURE__ */ jsx3(
1641
+ },
1642
+ "fax"
1643
+ );
1644
+ const mailCard = /* @__PURE__ */ jsx3(
1616
1645
  RouteCard,
1617
1646
  {
1618
1647
  selected: route === "mail",
@@ -1629,9 +1658,18 @@ function SendRouteDialog({
1629
1658
  !mailValid ? /* @__PURE__ */ jsx3("span", { className: "mbrd-error", children: "Enter a mailing address." }) : null,
1630
1659
  /* @__PURE__ */ jsx3("span", { className: "mbrd-help", children: mailOption?.printAndMail ? mailOption.detail : "Sent as physical mail \u2014 printed and mailed to this address." })
1631
1660
  ] })
1632
- }
1633
- )
1634
- ] }),
1661
+ },
1662
+ "mail"
1663
+ );
1664
+ const cards = [];
1665
+ if (ebillCard) cards.push(ebillCard);
1666
+ if (onFileFax) cards.push(faxCard);
1667
+ if (onFileEmail) cards.push(emailCard);
1668
+ cards.push(mailCard);
1669
+ if (!onFileFax) cards.push(faxCard);
1670
+ if (!onFileEmail) cards.push(emailCard);
1671
+ return cards;
1672
+ })() }),
1635
1673
  error ? /* @__PURE__ */ jsx3("div", { className: "mbrd-alert", role: "alert", children: error }) : null,
1636
1674
  /* @__PURE__ */ jsxs3("div", { className: "mbrd-actions", children: [
1637
1675
  /* @__PURE__ */ jsx3("button", { className: "mbrd-cancel", type: "button", disabled: submitting, onClick: onCancel, children: "Cancel" }),