@mindbill/react 0.21.1 → 0.21.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.
package/dist/index.js CHANGED
@@ -40,20 +40,20 @@ var mindBillThemePresets = {
40
40
  fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif"
41
41
  },
42
42
  "orange-bright": {
43
- accentColor: "#ff4f0a",
43
+ accentColor: "#f4510b",
44
44
  accentTextColor: "#ffffff",
45
45
  backgroundColor: "#fffaf6",
46
- surfaceColor: "#ffffff",
46
+ surfaceColor: "#fffefd",
47
47
  inputBackgroundColor: "#ffffff",
48
- textColor: "#111827",
48
+ textColor: "#090f1f",
49
49
  mutedColor: "#626a73",
50
- borderColor: "#e5e1dc",
51
- borderRadius: "8px",
52
- controlRadius: "6px",
53
- shadow: "0 4px 18px rgba(17,24,39,.06)",
54
- dangerColor: "#b42318",
55
- successColor: "#16794f",
56
- warningColor: "#9a5b13",
50
+ borderColor: "#e7e1da",
51
+ borderRadius: "16px",
52
+ controlRadius: "10px",
53
+ shadow: "0 12px 36px rgba(244,81,11,.08), 0 1px 2px rgba(9,15,31,.05)",
54
+ dangerColor: "#c4322b",
55
+ successColor: "#16835b",
56
+ warningColor: "#a65f00",
57
57
  fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif"
58
58
  },
59
59
  "clinical-blue": {
@@ -1320,6 +1320,7 @@ var documentLabels = {
1320
1320
  var MAX_PDF_BYTES = 25 * 1024 * 1024;
1321
1321
  var MAX_UPLOAD_BYTES = 100 * 1024 * 1024;
1322
1322
  var MAX_DOCUMENTS = 25;
1323
+ var DIAGNOSIS_PAGE_SIZE = 100;
1323
1324
  var EMPTY_ATTACHMENTS = [];
1324
1325
  function previewUploadedPdf(file) {
1325
1326
  const url = URL.createObjectURL(file);
@@ -1389,19 +1390,19 @@ function cloneBill(bill) {
1389
1390
  }
1390
1391
  function validateBillSubmission(bill) {
1391
1392
  const errors = {};
1392
- const required = (path, value) => {
1393
- if (typeof value !== "string" || !value.trim()) errors[path] = "Required";
1393
+ const required = (path, value, message) => {
1394
+ if (typeof value !== "string" || !value.trim()) errors[path] = message;
1394
1395
  };
1395
- required("patient.firstName", bill.patient.firstName);
1396
- required("patient.lastName", bill.patient.lastName);
1397
- required("patient.dateOfBirth", bill.patient.dateOfBirth);
1398
- required("patient.address.line1", bill.patient.address.line1);
1399
- required("patient.address.city", bill.patient.address.city);
1400
- required("patient.address.state", bill.patient.address.state);
1401
- required("patient.address.postalCode", bill.patient.address.postalCode);
1402
- required("claim.claimNumber", bill.claim.claimNumber);
1403
- required("claim.claimsAdministrator", bill.claim.claimsAdministrator?.name);
1404
- required("service.date", bill.service.date);
1396
+ required("patient.firstName", bill.patient.firstName, "Enter the patient's first name.");
1397
+ required("patient.lastName", bill.patient.lastName, "Enter the patient's last name.");
1398
+ required("patient.dateOfBirth", bill.patient.dateOfBirth, "Enter the patient's date of birth.");
1399
+ required("patient.address.line1", bill.patient.address.line1, "Enter the patient's street address.");
1400
+ required("patient.address.city", bill.patient.address.city, "Enter the patient's city.");
1401
+ required("patient.address.state", bill.patient.address.state, "Enter the patient's 2-letter state code.");
1402
+ required("patient.address.postalCode", bill.patient.address.postalCode, "Enter the patient's ZIP code.");
1403
+ required("claim.claimNumber", bill.claim.claimNumber, "Enter the claim number.");
1404
+ required("claim.claimsAdministrator", bill.claim.claimsAdministrator?.name, "Select a claims administrator so MindBill can route this bill.");
1405
+ required("service.date", bill.service.date, "Enter the date of service.");
1405
1406
  if (bill.claim.claimsAdministrator?.name && !bill.claim.claimsAdministrator.id) {
1406
1407
  errors["claim.claimsAdministrator"] = "Select a claims administrator from the payer directory.";
1407
1408
  }
@@ -1410,7 +1411,7 @@ function validateBillSubmission(bill) {
1410
1411
  const lines = submittedLines(bill.serviceLines);
1411
1412
  if (!lines.length) errors.serviceLines = "Add at least one service line";
1412
1413
  lines.forEach((line, index) => {
1413
- required(`serviceLines.${index}.code`, line.code);
1414
+ required(`serviceLines.${index}.code`, line.code, "Select a procedure code.");
1414
1415
  if (!Number.isInteger(line.units) || (line.units ?? 0) < 1) errors[`serviceLines.${index}.units`] = "Enter at least 1 unit";
1415
1416
  if (bill.billingMode === "professional" && (!Number.isFinite(line.charge) || (line.charge ?? 0) < 0)) errors[`serviceLines.${index}.charge`] = "Enter the billed charge";
1416
1417
  });
@@ -1419,25 +1420,25 @@ function validateBillSubmission(bill) {
1419
1420
  var css = `
1420
1421
  .mbsf{display:grid;gap:20px;color:var(--mb-text);font-family:var(--mb-font);font-size:15px}.mbsf *{box-sizing:border-box}
1421
1422
  .mbsf-head,.mbsf-section-head,.mbsf-attach-row,.mbsf-actions{display:flex;align-items:center;justify-content:space-between;gap:16px}.mbsf-title{margin:0;font-size:24px}.mbsf-copy,.mbsf-help{color:var(--mb-muted);margin:5px 0 0}.mbsf-required{font-size:13px;color:var(--mb-muted);white-space:nowrap}.mbsf-star,.mbsf-error{color:var(--mb-danger)}
1422
- .mbsf-card{min-width:0;margin:0;padding:24px;border:1px solid var(--mb-border);border-radius:var(--mb-radius);background:var(--mb-surface);box-shadow:var(--mb-shadow)}.mbsf-legend{padding:0 10px;font-size:18px;font-weight:760}.mbsf-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px 24px}.mbsf-span{grid-column:1/-1}.mbsf-field{display:grid;align-content:start;gap:7px;min-width:0}.mbsf-label{font-weight:680}.mbsf-input,.mbsf-select{width:100%;min-height:46px;padding:10px 12px;border:1px solid var(--mb-border);border-radius:var(--mb-control-radius);background:var(--mb-input);color:var(--mb-text);font:inherit}.mbsf-input:focus,.mbsf-select:focus{outline:3px solid color-mix(in srgb,var(--mb-accent) 22%,transparent);border-color:var(--mb-accent)}
1423
- .mbsf-combo{position:relative}.mbsf-menu{position:absolute;z-index:20;top:calc(100% + 5px);left:0;right:0;max-height:min(300px,42vh);overflow:auto;overscroll-behavior:contain;padding:7px;border:1px solid var(--mb-border);border-radius:12px;background:var(--mb-surface);box-shadow:0 14px 35px rgba(17,38,49,.16)}.mbsf-option{display:grid;width:100%;gap:2px;padding:10px;border:0;border-radius:8px;background:transparent;color:var(--mb-text);font:inherit;text-align:left;cursor:pointer}.mbsf-option:hover,.mbsf-option:focus{background:color-mix(in srgb,var(--mb-accent) 9%,var(--mb-surface))}.mbsf-option small{color:var(--mb-muted)}
1423
+ .mbsf-card{min-width:0;margin:0;padding:24px;border:1px solid var(--mb-border);border-radius:var(--mb-radius);background:var(--mb-surface);box-shadow:var(--mb-shadow)}.mbsf-legend{padding:0 10px;font-size:18px;font-weight:760}.mbsf-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px 24px}.mbsf-span{grid-column:1/-1}.mbsf-field{display:grid;align-content:start;gap:7px;min-width:0}.mbsf-label{font-weight:680}.mbsf-input,.mbsf-select{width:100%;min-height:46px;padding:10px 12px;border:1px solid var(--mb-border);border-radius:var(--mb-control-radius);background:var(--mb-input);color:var(--mb-text);font:inherit}.mbsf-input:focus,.mbsf-select:focus{outline:3px solid color-mix(in srgb,var(--mb-accent) 22%,transparent);border-color:var(--mb-accent)}.mbsf-field[data-invalid=true] .mbsf-input,.mbsf-field[data-invalid=true] .mbsf-select,.mbsf-invalid-control .mbsf-input{border-color:var(--mb-danger);background:color-mix(in srgb,var(--mb-danger) 4%,var(--mb-input))}.mbsf-field[data-invalid=true] .mbsf-input:focus,.mbsf-field[data-invalid=true] .mbsf-select:focus{outline-color:color-mix(in srgb,var(--mb-danger) 24%,transparent)}
1424
+ .mbsf-combo{position:relative}.mbsf-menu{position:absolute;z-index:20;top:calc(100% + 5px);left:0;right:0;max-height:min(360px,46vh);overflow:auto;overscroll-behavior:contain;padding:7px;border:1px solid var(--mb-border);border-radius:12px;background:var(--mb-surface);box-shadow:0 14px 35px rgba(17,38,49,.16)}.mbsf-option{display:grid;width:100%;gap:2px;padding:10px;border:0;border-radius:8px;background:transparent;color:var(--mb-text);font:inherit;text-align:left;cursor:pointer}.mbsf-option:hover,.mbsf-option:focus{background:color-mix(in srgb,var(--mb-accent) 9%,var(--mb-surface))}.mbsf-option small{color:var(--mb-muted)}.mbsf-menu-status{padding:12px;text-align:center;color:var(--mb-muted);font-size:13px}
1424
1425
  .mbsf-chips,.mbsf-quick-picks{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:8px}.mbsf-chip,.mbsf-quick-pick{display:inline-flex;align-items:center;gap:7px;padding:5px 9px;border:1px solid var(--mb-border);border-radius:999px;background:var(--mb-input)}.mbsf-chip button{border:0;background:transparent;color:var(--mb-muted);cursor:pointer;font:inherit}.mbsf-quick-pick{color:var(--mb-text);font:inherit;cursor:pointer}.mbsf-quick-pick[data-selected=true]{border-color:var(--mb-accent);color:var(--mb-accent)}
1425
1426
  .mbsf-segments{display:grid;grid-template-columns:repeat(3,1fr);border:1px solid var(--mb-border);border-radius:var(--mb-control-radius);overflow:hidden}.mbsf-segment{min-height:44px;border:0;border-right:1px solid var(--mb-border);background:var(--mb-input);color:var(--mb-text);font:inherit;font-weight:700;cursor:pointer}.mbsf-segment:last-child{border-right:0}.mbsf-segment[aria-pressed=true]{background:var(--mb-accent);color:var(--mb-accent-contrast)}
1426
- .mbsf-lines{margin-top:18px;border:1px solid var(--mb-border);border-radius:var(--mb-control-radius);overflow:visible}.mbsf-line-head,.mbsf-line{display:grid;grid-template-columns:minmax(190px,1.05fr) minmax(220px,1.5fr) 100px 120px 42px;gap:12px;align-items:start;padding:12px}.mbsf-line-head{color:var(--mb-muted);font-size:13px;font-weight:700;border-bottom:1px solid var(--mb-border)}.mbsf-line{border-bottom:1px solid var(--mb-border)}.mbsf-line:last-child{border-bottom:0}.mbsf-money{padding-top:12px;text-align:right;font-variant-numeric:tabular-nums}.mbsf-total{display:flex;justify-content:flex-end;gap:45px;padding:16px 56px 16px 16px;font-size:17px;font-weight:760}
1427
+ .mbsf-lines{margin-top:18px;border:1px solid var(--mb-border);border-radius:var(--mb-control-radius);overflow:visible}.mbsf-lines[data-invalid=true]{border-color:var(--mb-danger)}.mbsf-line-head,.mbsf-line{display:grid;grid-template-columns:minmax(190px,1.05fr) minmax(220px,1.5fr) 100px 120px 42px;gap:12px;align-items:start;padding:12px}.mbsf-line-head{color:var(--mb-muted);font-size:13px;font-weight:700;border-bottom:1px solid var(--mb-border)}.mbsf-line{border-bottom:1px solid var(--mb-border)}.mbsf-line:last-child{border-bottom:0}.mbsf-line [data-invalid=true] .mbsf-input{border-color:var(--mb-danger);background:color-mix(in srgb,var(--mb-danger) 4%,var(--mb-input))}.mbsf-money{padding-top:12px;text-align:right;font-variant-numeric:tabular-nums}.mbsf-total{display:flex;justify-content:flex-end;gap:45px;padding:16px 56px 16px 16px;font-size:17px;font-weight:760}
1427
1428
  .mbsf-icon-btn{width:40px;height:42px;border:0;background:transparent;color:var(--mb-text);font-size:22px;cursor:pointer}.mbsf-secondary{min-height:40px;padding:8px 14px;border:1px solid var(--mb-border);border-radius:var(--mb-control-radius);background:var(--mb-surface);color:var(--mb-text);font:inherit;font-weight:680;cursor:pointer}.mbsf-attach-list{display:grid;gap:10px;margin-bottom:18px}.mbsf-attach-row{padding:14px;border:1px solid var(--mb-border);border-radius:var(--mb-control-radius)}.mbsf-attach-row[data-auto=true]{border-color:color-mix(in srgb,#159447 45%,var(--mb-border));background:color-mix(in srgb,#159447 5%,var(--mb-surface))}.mbsf-attach-main{display:flex;align-items:center;gap:12px;min-width:0;flex:1}.mbsf-attach-actions{display:flex;align-items:center;gap:6px;flex:0 0 auto}.mbsf-file{min-width:0}.mbsf-file strong{overflow-wrap:anywhere}.mbsf-badge{display:inline-block;margin-left:8px;padding:2px 7px;border:1px solid var(--mb-border);border-radius:7px;color:var(--mb-muted);font-size:12px;font-weight:600}.mbsf-drop{display:grid;width:100%;place-items:center;min-height:210px;padding:30px;border:2px dashed color-mix(in srgb,var(--mb-muted) 55%,transparent);border-radius:var(--mb-control-radius);background:color-mix(in srgb,var(--mb-accent) 3%,var(--mb-surface));color:var(--mb-text);font:inherit;text-align:center;cursor:pointer}.mbsf-drop[data-active=true]{border-color:var(--mb-accent);background:color-mix(in srgb,var(--mb-accent) 10%,var(--mb-surface))}.mbsf-alert{padding:12px 14px;border-radius:var(--mb-control-radius);background:color-mix(in srgb,var(--mb-danger) 10%,transparent);color:var(--mb-danger)}.mbsf-actions{justify-content:flex-end}.mbsf-submit{min-width:180px;min-height:48px;padding:11px 24px;border:0;border-radius:var(--mb-control-radius);background:var(--mb-accent);color:var(--mb-accent-contrast);font:inherit;font-weight:780;cursor:pointer}
1428
1429
  @media(max-width:820px){.mbsf{gap:16px}.mbsf-grid{grid-template-columns:1fr}.mbsf-span{grid-column:auto}.mbsf-card{padding:18px 16px}.mbsf-line-head{display:none}.mbsf-line{position:relative;display:grid;grid-template-columns:minmax(0,1fr) 86px;gap:14px;padding:18px 16px}.mbsf-line>div:before{display:block;margin-bottom:6px;color:var(--mb-muted);font-size:12px;font-weight:700;content:attr(data-label)}.mbsf-line>div:nth-child(1),.mbsf-line>div:nth-child(2){grid-column:1/-1}.mbsf-money{align-self:end;padding:0 0 12px;text-align:right}.mbsf-line .mbsf-icon-btn{position:absolute;right:8px;bottom:3px}.mbsf-total{padding:16px 18px;gap:24px}.mbsf-head{align-items:flex-start}.mbsf-segments{grid-template-columns:repeat(3,minmax(0,1fr))}.mbsf-segment{min-width:0;padding:8px 4px;border-right:1px solid var(--mb-border);border-bottom:0;font-size:13px}.mbsf-segment:last-child{border-right:0}.mbsf-attach-row{align-items:flex-start;flex-wrap:wrap}.mbsf-attach-main{align-items:flex-start}.mbsf-attach-actions{margin-left:auto}.mbsf-drop{min-height:190px;padding:24px 18px}.mbsf-actions{position:sticky;bottom:86px;z-index:10}.mbsf-submit{width:100%}}
1429
1430
  `;
1430
1431
  function RequiredMark() {
1431
1432
  return /* @__PURE__ */ jsx3("span", { className: "mbsf-star", children: " *" });
1432
1433
  }
1433
- function Field2({ label, required, error, span, children }) {
1434
- return /* @__PURE__ */ jsxs3("label", { className: `mbsf-field${span ? " mbsf-span" : ""}`, children: [
1434
+ function Field2({ label, required, error, path, span, children }) {
1435
+ return /* @__PURE__ */ jsxs3("label", { className: `mbsf-field${span ? " mbsf-span" : ""}`, "data-field-path": path, "data-invalid": Boolean(error), children: [
1435
1436
  /* @__PURE__ */ jsxs3("span", { className: "mbsf-label", children: [
1436
1437
  label,
1437
1438
  required ? /* @__PURE__ */ jsx3(RequiredMark, {}) : null
1438
1439
  ] }),
1439
1440
  children,
1440
- error ? /* @__PURE__ */ jsx3("small", { className: "mbsf-error", children: error }) : null
1441
+ error ? /* @__PURE__ */ jsx3("small", { className: "mbsf-error", role: "alert", children: error }) : null
1441
1442
  ] });
1442
1443
  }
1443
1444
  function TextDateInput({ value, onChange, disabled, required, ariaLabel }) {
@@ -1459,7 +1460,7 @@ function TextDateInput({ value, onChange, disabled, required, ariaLabel }) {
1459
1460
  invalid ? /* @__PURE__ */ jsx3("small", { className: "mbsf-error", children: "Use MM/DD/YYYY" }) : null
1460
1461
  ] });
1461
1462
  }
1462
- function ComboBox({ value, placeholder, options, disabled, loading, onQuery, onSelect, createOption, ariaLabel }) {
1463
+ function ComboBox({ value, placeholder, options, disabled, loading, loadingMore, invalid, onOpen, onQuery, onEndReached, onSelect, createOption, ariaLabel }) {
1463
1464
  const [open, setOpen] = useState2(false);
1464
1465
  const [query, setQuery] = useState2("");
1465
1466
  const visible = useMemo2(() => {
@@ -1470,24 +1471,50 @@ function ComboBox({ value, placeholder, options, disabled, loading, onQuery, onS
1470
1471
  }, [createOption, options, query]);
1471
1472
  const showMenu = open && (loading || visible.length > 0 || query.trim().length >= 2);
1472
1473
  return /* @__PURE__ */ jsxs3("div", { className: "mbsf-combo", children: [
1473
- /* @__PURE__ */ jsx3("input", { className: "mbsf-input", role: "combobox", "aria-label": ariaLabel, "aria-expanded": showMenu, autoComplete: "off", disabled, placeholder, value: open ? query : value, onFocus: () => {
1474
+ /* @__PURE__ */ jsx3("input", { className: "mbsf-input", role: "combobox", "aria-label": ariaLabel, "aria-invalid": invalid, "aria-expanded": showMenu, autoComplete: "off", disabled, placeholder, value: open ? query : value, onFocus: () => {
1474
1475
  setOpen(true);
1475
1476
  setQuery("");
1477
+ onOpen?.();
1476
1478
  }, onChange: (event) => {
1477
1479
  setOpen(true);
1478
1480
  setQuery(event.target.value);
1479
1481
  onQuery?.(event.target.value);
1480
1482
  }, onBlur: () => setTimeout(() => setOpen(false), 120) }),
1481
- showMenu ? /* @__PURE__ */ jsx3("div", { className: "mbsf-menu", role: "listbox", children: loading ? /* @__PURE__ */ jsx3("div", { className: "mbsf-option", children: "Searching\u2026" }) : visible.length ? visible.map((option) => /* @__PURE__ */ jsxs3("button", { className: "mbsf-option", type: "button", role: "option", onMouseDown: (event) => event.preventDefault(), onClick: () => {
1482
- onSelect(option);
1483
- setOpen(false);
1484
- setQuery("");
1483
+ showMenu ? /* @__PURE__ */ jsxs3("div", { className: "mbsf-menu", role: "listbox", onScroll: (event) => {
1484
+ const menu = event.currentTarget;
1485
+ if (menu.scrollHeight - menu.scrollTop - menu.clientHeight < 120) onEndReached?.();
1485
1486
  }, children: [
1486
- /* @__PURE__ */ jsx3("strong", { children: option.label }),
1487
- option.detail ? /* @__PURE__ */ jsx3("small", { children: option.detail }) : null
1488
- ] }, option.id)) : /* @__PURE__ */ jsx3("div", { className: "mbsf-option", children: "No matches" }) }) : null
1487
+ loading && !visible.length ? /* @__PURE__ */ jsx3("div", { className: "mbsf-menu-status", children: "Loading codes\u2026" }) : visible.length ? visible.map((option) => /* @__PURE__ */ jsxs3("button", { className: "mbsf-option", type: "button", role: "option", onMouseDown: (event) => event.preventDefault(), onClick: () => {
1488
+ onSelect(option);
1489
+ setOpen(false);
1490
+ setQuery("");
1491
+ }, children: [
1492
+ /* @__PURE__ */ jsx3("strong", { children: option.label }),
1493
+ option.detail ? /* @__PURE__ */ jsx3("small", { children: option.detail }) : null
1494
+ ] }, option.id)) : /* @__PURE__ */ jsx3("div", { className: "mbsf-option", children: "No matches" }),
1495
+ loadingMore ? /* @__PURE__ */ jsx3("div", { className: "mbsf-menu-status", children: "Loading more\u2026" }) : null
1496
+ ] }) : null
1489
1497
  ] });
1490
1498
  }
1499
+ function focusFirstInvalid(form) {
1500
+ const field = form.querySelector('[data-invalid="true"]');
1501
+ if (!field) return;
1502
+ const control = field.querySelector('input,select,textarea,button,[tabindex]:not([tabindex="-1"])');
1503
+ control?.focus({ preventScroll: true });
1504
+ const fieldRect = field.getBoundingClientRect();
1505
+ let scrollParent = field.parentElement;
1506
+ while (scrollParent) {
1507
+ const style = window.getComputedStyle(scrollParent);
1508
+ if (/(auto|scroll)/.test(style.overflowY) && scrollParent.scrollHeight > scrollParent.clientHeight) break;
1509
+ scrollParent = scrollParent.parentElement;
1510
+ }
1511
+ if (scrollParent) {
1512
+ const parentRect = scrollParent.getBoundingClientRect();
1513
+ scrollParent.scrollTo({ top: Math.max(0, scrollParent.scrollTop + fieldRect.top - parentRect.top - 24), behavior: "smooth" });
1514
+ } else {
1515
+ window.scrollTo({ top: Math.max(0, window.scrollY + fieldRect.top - 24), behavior: "smooth" });
1516
+ }
1517
+ }
1491
1518
  function customProcedureOption(query) {
1492
1519
  const code = query.trim().toUpperCase().replace(/\s+/g, "");
1493
1520
  if (!/^(?:\d{5}|[A-Z]\d{4}|ML(?:20[0-5]|PRR))$/.test(code)) return null;
@@ -1498,6 +1525,9 @@ function mergeOptions(defaults, supplied) {
1498
1525
  supplied?.forEach((item) => map.set(item.code.toUpperCase(), item));
1499
1526
  return [...map.values()];
1500
1527
  }
1528
+ function mergeDiagnosisOptions(options) {
1529
+ return [...new Map(options.map((item) => [item.code.toUpperCase(), item])).values()].sort((left, right) => left.code.localeCompare(right.code, void 0, { numeric: true }));
1530
+ }
1501
1531
  function BillSubmissionForm({
1502
1532
  initialBill,
1503
1533
  attachments = EMPTY_ATTACHMENTS,
@@ -1525,15 +1555,22 @@ function BillSubmissionForm({
1525
1555
  const [removedSourceIds, setRemovedSourceIds] = useState2([]);
1526
1556
  const [uploads, setUploads] = useState2([]);
1527
1557
  const [errors, setErrors] = useState2({});
1558
+ const [validationActive, setValidationActive] = useState2(false);
1528
1559
  const [formError, setFormError] = useState2(null);
1529
1560
  const [submitting, setSubmitting] = useState2(false);
1530
1561
  const [payerResults, setPayerResults] = useState2([]);
1531
1562
  const [payerLoading, setPayerLoading] = useState2(false);
1532
- const [diagnosisResults, setDiagnosisResults] = useState2(diagnosisOptions);
1563
+ const [diagnosisResults, setDiagnosisResults] = useState2([]);
1533
1564
  const [diagnosisLoading, setDiagnosisLoading] = useState2(false);
1565
+ const [diagnosisLoadingMore, setDiagnosisLoadingMore] = useState2(false);
1566
+ const [diagnosisQuery, setDiagnosisQuery] = useState2(null);
1567
+ const [diagnosisHasMore, setDiagnosisHasMore] = useState2(true);
1534
1568
  const [postalStatus, setPostalStatus] = useState2(null);
1535
1569
  const [dragActive, setDragActive] = useState2(false);
1570
+ const formRef = useRef2(null);
1536
1571
  const fileInput = useRef2(null);
1572
+ const diagnosisRequest = useRef2(0);
1573
+ const diagnosisAppendPending = useRef2(false);
1537
1574
  const procedures = useMemo2(() => mergeOptions(DEFAULT_BILL_SUBMISSION_PROCEDURES, procedureOptions), [procedureOptions]);
1538
1575
  const modifiers = useMemo2(() => mergeOptions(DEFAULT_BILL_SUBMISSION_MODIFIERS, modifierOptions), [modifierOptions]);
1539
1576
  const [evaluationType, setEvaluationType] = useState2(() => initialBill.renderingProvider?.isAme ? "ame" : initialBill.renderingProvider?.specialty?.toLowerCase().includes("psych") ? "psych_qme" : "qme");
@@ -1545,8 +1582,17 @@ function BillSubmissionForm({
1545
1582
  setRemovedSourceIds([]);
1546
1583
  setUploads([]);
1547
1584
  setErrors({});
1585
+ setValidationActive(false);
1548
1586
  setFormError(null);
1587
+ setDiagnosisResults([]);
1588
+ setDiagnosisQuery(null);
1589
+ setDiagnosisHasMore(true);
1590
+ diagnosisRequest.current += 1;
1591
+ diagnosisAppendPending.current = false;
1549
1592
  }, [initialBill, attachments]);
1593
+ useEffect2(() => {
1594
+ if (validationActive) setErrors(validateBillSubmission(bill).fieldErrors);
1595
+ }, [bill, validationActive]);
1550
1596
  const addFiles = useCallback((fileList) => {
1551
1597
  const files = Array.from(fileList);
1552
1598
  if (!files.length) return;
@@ -1610,17 +1656,43 @@ function BillSubmissionForm({
1610
1656
  }
1611
1657
  void search(query, bill.claim.claimNumber).then(setPayerResults).catch((caught) => setFormError(caught instanceof Error ? caught.message : "Claims administrator search is unavailable.")).finally(() => setPayerLoading(false));
1612
1658
  };
1613
- const searchDiagnoses = (query) => {
1659
+ const loadDiagnoses = (query, append = false) => {
1614
1660
  const trimmed = query.trim();
1615
- if (!trimmed) {
1616
- setDiagnosisResults(diagnosisOptions);
1661
+ const search = onSearchDiagnoses ?? referenceClient?.searchDiagnosisCodes;
1662
+ if (!search) {
1663
+ setDiagnosisResults(mergeDiagnosisOptions(diagnosisOptions));
1664
+ setDiagnosisHasMore(false);
1665
+ setDiagnosisQuery(trimmed);
1617
1666
  return;
1618
1667
  }
1619
- const search = onSearchDiagnoses ?? referenceClient?.searchDiagnosisCodes;
1620
- if (!search) return;
1621
- setDiagnosisLoading(true);
1622
- void search(trimmed).then(setDiagnosisResults).catch(() => setDiagnosisResults([])).finally(() => setDiagnosisLoading(false));
1668
+ const continuing = append && diagnosisQuery === trimmed;
1669
+ if (continuing && (!diagnosisHasMore || diagnosisAppendPending.current)) return;
1670
+ const offset = continuing ? diagnosisResults.length : 0;
1671
+ const request = ++diagnosisRequest.current;
1672
+ if (continuing) {
1673
+ diagnosisAppendPending.current = true;
1674
+ setDiagnosisLoadingMore(true);
1675
+ } else {
1676
+ setDiagnosisLoading(true);
1677
+ setDiagnosisLoadingMore(false);
1678
+ setDiagnosisQuery(trimmed);
1679
+ setDiagnosisHasMore(true);
1680
+ }
1681
+ void search(trimmed, DIAGNOSIS_PAGE_SIZE, offset).then((page) => {
1682
+ if (request !== diagnosisRequest.current) return;
1683
+ setDiagnosisResults((current) => mergeDiagnosisOptions(continuing ? [...current, ...page] : page));
1684
+ setDiagnosisHasMore(page.length >= DIAGNOSIS_PAGE_SIZE);
1685
+ }).catch(() => {
1686
+ if (request === diagnosisRequest.current && !continuing) setDiagnosisResults([]);
1687
+ }).finally(() => {
1688
+ if (request !== diagnosisRequest.current) return;
1689
+ diagnosisAppendPending.current = false;
1690
+ setDiagnosisLoading(false);
1691
+ setDiagnosisLoadingMore(false);
1692
+ });
1623
1693
  };
1694
+ const searchDiagnoses = (query) => loadDiagnoses(query);
1695
+ const diagnosisChoices = useMemo2(() => mergeDiagnosisOptions([...diagnosisOptions, ...diagnosisResults]), [diagnosisOptions, diagnosisResults]);
1624
1696
  const updatePostalCode = (postalCode) => {
1625
1697
  setAddress({ postalCode });
1626
1698
  setPostalStatus(null);
@@ -1645,9 +1717,18 @@ function BillSubmissionForm({
1645
1717
  return charge == null ? line : { ...line, charge };
1646
1718
  }) };
1647
1719
  const validation = validateBillSubmission(clean);
1720
+ setValidationActive(true);
1648
1721
  setErrors(validation.fieldErrors);
1649
1722
  setFormError(null);
1650
- if (!validation.valid) return setFormError("Complete the required fields before submitting.");
1723
+ if (!validation.valid) {
1724
+ const count = Object.keys(validation.fieldErrors).length;
1725
+ const first = Object.values(validation.fieldErrors)[0];
1726
+ setFormError(`Fix ${count} highlighted field${count === 1 ? "" : "s"} before submitting. ${first}`);
1727
+ window.requestAnimationFrame(() => {
1728
+ if (formRef.current) focusFirstInvalid(formRef.current);
1729
+ });
1730
+ return;
1731
+ }
1651
1732
  if (selectedIds.length + uploads.length > MAX_DOCUMENTS) return setFormError(`A bill can include at most ${MAX_DOCUMENTS} attachments.`);
1652
1733
  setSubmitting(true);
1653
1734
  try {
@@ -1658,7 +1739,8 @@ function BillSubmissionForm({
1658
1739
  setSubmitting(false);
1659
1740
  }
1660
1741
  }
1661
- return /* @__PURE__ */ jsxs3("form", { className: `${className} mbsf`, style: { ...mindBillAppearanceStyle(appearance), ...style }, onSubmit: (event) => {
1742
+ const claimsAdministratorError = errors["claim.claimsAdministrator"] ?? (!bill.claim.claimsAdministrator?.id ? "Required for routing \u2014 search and select a claims administrator." : void 0);
1743
+ return /* @__PURE__ */ jsxs3("form", { ref: formRef, className: `${className} mbsf`, style: { ...mindBillAppearanceStyle(appearance), ...style }, onSubmit: (event) => {
1662
1744
  event.preventDefault();
1663
1745
  void submit();
1664
1746
  }, noValidate: true, children: [
@@ -1676,29 +1758,29 @@ function BillSubmissionForm({
1676
1758
  /* @__PURE__ */ jsxs3("fieldset", { className: "mbsf-card", disabled: locked, children: [
1677
1759
  /* @__PURE__ */ jsx3("legend", { className: "mbsf-legend", children: "Patient" }),
1678
1760
  /* @__PURE__ */ jsxs3("div", { className: "mbsf-grid", children: [
1679
- /* @__PURE__ */ jsx3(Field2, { label: "First name", required: true, error: errors["patient.firstName"], children: text(bill.patient.firstName, (firstName) => setBill((c) => ({ ...c, patient: { ...c.patient, firstName } }))) }),
1680
- /* @__PURE__ */ jsx3(Field2, { label: "Last name", required: true, error: errors["patient.lastName"], children: text(bill.patient.lastName, (lastName) => setBill((c) => ({ ...c, patient: { ...c.patient, lastName } }))) }),
1761
+ /* @__PURE__ */ jsx3(Field2, { path: "patient.firstName", label: "First name", required: true, error: errors["patient.firstName"], children: text(bill.patient.firstName, (firstName) => setBill((c) => ({ ...c, patient: { ...c.patient, firstName } }))) }),
1762
+ /* @__PURE__ */ jsx3(Field2, { path: "patient.lastName", label: "Last name", required: true, error: errors["patient.lastName"], children: text(bill.patient.lastName, (lastName) => setBill((c) => ({ ...c, patient: { ...c.patient, lastName } }))) }),
1681
1763
  /* @__PURE__ */ jsx3(Field2, { label: "Middle name", children: text(bill.patient.middleName, (middleName) => setBill((c) => ({ ...c, patient: { ...c.patient, middleName } }))) }),
1682
1764
  /* @__PURE__ */ jsx3(Field2, { label: "Phone (optional)", children: text(bill.patient.phone, (phone) => setBill((c) => ({ ...c, patient: { ...c.patient, phone } })), { type: "tel" }) }),
1683
- /* @__PURE__ */ jsx3(Field2, { label: "Date of birth", required: true, error: errors["patient.dateOfBirth"], children: /* @__PURE__ */ jsx3(TextDateInput, { ariaLabel: "Date of birth", value: bill.patient.dateOfBirth, disabled: locked, required: true, onChange: (dateOfBirth) => setBill((c) => ({ ...c, patient: { ...c.patient, dateOfBirth } })) }) }),
1684
- /* @__PURE__ */ jsx3(Field2, { label: "Address", required: true, span: true, error: errors["patient.address.line1"], children: text(bill.patient.address.line1, (line1) => setAddress({ line1 }), { placeholder: "Street address" }) }),
1685
- /* @__PURE__ */ jsxs3(Field2, { label: "ZIP", required: true, error: errors["patient.address.postalCode"], children: [
1765
+ /* @__PURE__ */ jsx3(Field2, { path: "patient.dateOfBirth", label: "Date of birth", required: true, error: errors["patient.dateOfBirth"], children: /* @__PURE__ */ jsx3(TextDateInput, { ariaLabel: "Date of birth", value: bill.patient.dateOfBirth, disabled: locked, required: true, onChange: (dateOfBirth) => setBill((c) => ({ ...c, patient: { ...c.patient, dateOfBirth } })) }) }),
1766
+ /* @__PURE__ */ jsx3(Field2, { path: "patient.address.line1", label: "Address", required: true, span: true, error: errors["patient.address.line1"], children: text(bill.patient.address.line1, (line1) => setAddress({ line1 }), { placeholder: "Street address" }) }),
1767
+ /* @__PURE__ */ jsxs3(Field2, { path: "patient.address.postalCode", label: "ZIP", required: true, error: errors["patient.address.postalCode"], children: [
1686
1768
  text(bill.patient.address.postalCode, updatePostalCode, { maxLength: 10 }),
1687
1769
  postalStatus ? /* @__PURE__ */ jsx3("small", { className: "mbsf-help", children: postalStatus }) : null
1688
1770
  ] }),
1689
- /* @__PURE__ */ jsx3(Field2, { label: "City", required: true, error: errors["patient.address.city"], children: text(bill.patient.address.city, (city) => setAddress({ city })) }),
1690
- /* @__PURE__ */ jsx3(Field2, { label: "State", required: true, error: errors["patient.address.state"], children: text(bill.patient.address.state, (state) => setAddress({ state: state.toUpperCase() }), { maxLength: 2 }) })
1771
+ /* @__PURE__ */ jsx3(Field2, { path: "patient.address.city", label: "City", required: true, error: errors["patient.address.city"], children: text(bill.patient.address.city, (city) => setAddress({ city })) }),
1772
+ /* @__PURE__ */ jsx3(Field2, { path: "patient.address.state", label: "State", required: true, error: errors["patient.address.state"], children: text(bill.patient.address.state, (state) => setAddress({ state: state.toUpperCase() }), { maxLength: 2 }) })
1691
1773
  ] })
1692
1774
  ] }),
1693
1775
  /* @__PURE__ */ jsxs3("fieldset", { className: "mbsf-card", disabled: locked, children: [
1694
1776
  /* @__PURE__ */ jsx3("legend", { className: "mbsf-legend", children: "Injury & claim" }),
1695
1777
  /* @__PURE__ */ jsxs3("div", { className: "mbsf-grid", children: [
1696
- /* @__PURE__ */ jsx3(Field2, { label: "Date of service", required: true, error: errors["service.date"], children: /* @__PURE__ */ jsx3(TextDateInput, { ariaLabel: "Date of service", value: bill.service.date, disabled: locked, required: true, onChange: (date2) => setBill((c) => ({ ...c, service: { ...c.service, date: date2 } })) }) }),
1778
+ /* @__PURE__ */ jsx3(Field2, { path: "service.date", label: "Date of service", required: true, error: errors["service.date"], children: /* @__PURE__ */ jsx3(TextDateInput, { ariaLabel: "Date of service", value: bill.service.date, disabled: locked, required: true, onChange: (date2) => setBill((c) => ({ ...c, service: { ...c.service, date: date2 } })) }) }),
1697
1779
  /* @__PURE__ */ jsx3(Field2, { label: "Date of injury", children: /* @__PURE__ */ jsx3(TextDateInput, { ariaLabel: "Date of injury", value: bill.claim.dateOfInjury, disabled: locked, onChange: (dateOfInjury) => setBill((c) => ({ ...c, claim: { ...c.claim, dateOfInjury } })) }) }),
1698
1780
  /* @__PURE__ */ jsx3(Field2, { label: "Employer (optional)", children: text(bill.claim.employer, (employer) => setBill((c) => ({ ...c, claim: { ...c.claim, employer } }))) }),
1699
- /* @__PURE__ */ jsx3(Field2, { label: "Claim number", required: true, error: errors["claim.claimNumber"], children: text(bill.claim.claimNumber, (claimNumber) => setBill((c) => ({ ...c, claim: { ...c.claim, claimNumber } }))) }),
1781
+ /* @__PURE__ */ jsx3(Field2, { path: "claim.claimNumber", label: "Claim number", required: true, error: errors["claim.claimNumber"], children: text(bill.claim.claimNumber, (claimNumber) => setBill((c) => ({ ...c, claim: { ...c.claim, claimNumber } }))) }),
1700
1782
  /* @__PURE__ */ jsx3(Field2, { label: "WCAB / ADJ number (optional)", children: text(bill.claim.adjNumber, (adjNumber) => setBill((c) => ({ ...c, claim: { ...c.claim, adjNumber } }))) }),
1701
- /* @__PURE__ */ jsx3(Field2, { label: "Claims administrator", required: true, span: true, error: errors["claim.claimsAdministrator"], children: /* @__PURE__ */ jsx3(ComboBox, { ariaLabel: "Claims administrator", disabled: locked, loading: payerLoading, value: bill.claim.claimsAdministrator?.name ?? "", placeholder: "Search the payer directory\u2026", options: payerResults.map((payer) => ({ id: payer.id, label: payer.name, detail: [payer.hasElectronic ? "Electronic" : "Work comp", ...payer.states ?? []].join(" \xB7 ") })), onQuery: searchPayers, onSelect: (option) => setBill((c) => ({ ...c, claim: { ...c.claim, claimsAdministrator: { id: option.id, name: option.label } } })) }) }),
1783
+ /* @__PURE__ */ jsx3(Field2, { path: "claim.claimsAdministrator", label: "Claims administrator", required: true, span: true, error: claimsAdministratorError, children: /* @__PURE__ */ jsx3(ComboBox, { ariaLabel: "Claims administrator", invalid: Boolean(claimsAdministratorError), disabled: locked, loading: payerLoading, value: bill.claim.claimsAdministrator?.name ?? "", placeholder: "Search the payer directory\u2026", options: payerResults.map((payer) => ({ id: payer.id, label: payer.name, detail: [payer.hasElectronic ? "Electronic" : "Work comp", ...payer.states ?? []].join(" \xB7 ") })), onQuery: searchPayers, onSelect: (option) => setBill((c) => ({ ...c, claim: { ...c.claim, claimsAdministrator: { id: option.id, name: option.label } } })) }) }),
1702
1784
  /* @__PURE__ */ jsx3(Field2, { label: "Injury description (optional)", span: true, children: text(bill.claim.description, (description2) => setBill((c) => ({ ...c, claim: { ...c.claim, description: description2 } }))) }),
1703
1785
  /* @__PURE__ */ jsxs3(Field2, { label: "Diagnosis codes (ICD-10)", span: true, children: [
1704
1786
  /* @__PURE__ */ jsx3("div", { className: "mbsf-quick-picks", "aria-label": "Common diagnosis codes", children: BILL_SUBMISSION_DIAGNOSIS_QUICK_PICKS.map((option) => {
@@ -1710,14 +1792,16 @@ function BillSubmissionForm({
1710
1792
  ] }, option.code);
1711
1793
  }) }),
1712
1794
  /* @__PURE__ */ jsx3("div", { className: "mbsf-chips", children: (bill.diagnoses ?? []).map((code) => {
1713
- const option = [...BILL_SUBMISSION_DIAGNOSIS_QUICK_PICKS, ...diagnosisOptions, ...diagnosisResults].find((item) => item.code === code);
1795
+ const option = [...BILL_SUBMISSION_DIAGNOSIS_QUICK_PICKS, ...diagnosisChoices].find((item) => item.code === code);
1714
1796
  return /* @__PURE__ */ jsxs3("span", { className: "mbsf-chip", children: [
1715
1797
  /* @__PURE__ */ jsx3("strong", { children: code }),
1716
1798
  option?.description ? ` ${option.description}` : "",
1717
1799
  /* @__PURE__ */ jsx3("button", { type: "button", "aria-label": `Remove ${code}`, onClick: () => setBill((c) => ({ ...c, diagnoses: (c.diagnoses ?? []).filter((item) => item !== code) })), children: "\xD7" })
1718
1800
  ] }, code);
1719
1801
  }) }),
1720
- /* @__PURE__ */ jsx3(ComboBox, { ariaLabel: "Add diagnosis code", disabled: locked, loading: diagnosisLoading, value: "", placeholder: bill.diagnoses?.length ?? 0 ? `${bill.diagnoses.length} selected \u2014 add more\u2026` : "Search ICD-10 codes\u2026", options: [...new Map([...BILL_SUBMISSION_DIAGNOSIS_QUICK_PICKS, ...diagnosisOptions, ...diagnosisResults].map((item) => [item.code, item])).values()].filter((item) => !(bill.diagnoses ?? []).includes(item.code)).map((item) => ({ id: item.code, label: item.code, detail: item.description })), onQuery: searchDiagnoses, onSelect: (option) => setBill((c) => ({ ...c, diagnoses: [.../* @__PURE__ */ new Set([...c.diagnoses ?? [], option.id])] })) })
1802
+ /* @__PURE__ */ jsx3(ComboBox, { ariaLabel: "Add diagnosis code", disabled: locked, loading: diagnosisLoading, loadingMore: diagnosisLoadingMore, value: "", placeholder: bill.diagnoses?.length ?? 0 ? `${bill.diagnoses.length} selected \u2014 add more\u2026` : "Search ICD-10 codes\u2026", options: diagnosisChoices.filter((item) => !(bill.diagnoses ?? []).includes(item.code)).map((item) => ({ id: item.code, label: item.code, detail: item.description })), onOpen: () => {
1803
+ if (diagnosisQuery !== "") loadDiagnoses("");
1804
+ }, onQuery: searchDiagnoses, onEndReached: () => loadDiagnoses(diagnosisQuery ?? "", true), onSelect: (option) => setBill((c) => ({ ...c, diagnoses: [.../* @__PURE__ */ new Set([...c.diagnoses ?? [], option.id])] })) })
1721
1805
  ] })
1722
1806
  ] })
1723
1807
  ] }),
@@ -1742,7 +1826,7 @@ function BillSubmissionForm({
1742
1826
  /* @__PURE__ */ jsx3("p", { className: "mbsf-help", children: "Sets the evaluator/specialty modifier on medical-legal evaluation lines." }),
1743
1827
  /* @__PURE__ */ jsx3("div", { className: "mbsf-segments", role: "group", "aria-label": "Evaluation type", children: [["qme", "QME (default)"], ["ame", "AME"], ["psych_qme", "Psych QME"]].map(([type, label]) => /* @__PURE__ */ jsx3("button", { className: "mbsf-segment", type: "button", "aria-pressed": evaluationType === type, onClick: () => changeEvaluation(type), children: label }, type)) }),
1744
1828
  /* @__PURE__ */ jsx3("p", { className: "mbsf-help", children: evaluationType === "ame" ? "Agreed Medical Evaluator \u2014 eligible ML evaluation codes default to modifier -94." : evaluationType === "psych_qme" ? "Psychiatric QME \u2014 eligible ML evaluation codes default to modifier -96 (-95 for ML200)." : "Qualified Medical Evaluator \u2014 eligible ML evaluation codes default to modifier -95." }),
1745
- /* @__PURE__ */ jsxs3("div", { className: "mbsf-lines", children: [
1829
+ /* @__PURE__ */ jsxs3("div", { className: "mbsf-lines", "data-field-path": "serviceLines", "data-invalid": Boolean(errors.serviceLines), children: [
1746
1830
  /* @__PURE__ */ jsxs3("div", { className: "mbsf-line-head", children: [
1747
1831
  /* @__PURE__ */ jsx3("span", { children: "Procedure code" }),
1748
1832
  /* @__PURE__ */ jsx3("span", { children: "Modifiers" }),
@@ -1752,13 +1836,13 @@ function BillSubmissionForm({
1752
1836
  " "
1753
1837
  ] }),
1754
1838
  bill.serviceLines.map((line, index) => /* @__PURE__ */ jsxs3("div", { className: "mbsf-line", children: [
1755
- /* @__PURE__ */ jsxs3("div", { "data-label": "Procedure code", children: [
1756
- /* @__PURE__ */ jsx3(ComboBox, { ariaLabel: `Procedure code ${index + 1}`, disabled: locked, value: line.code, placeholder: "Search or enter code\u2026", options: procedures.map((item) => ({ id: item.code, label: item.code, detail: item.description })), createOption: customProcedureOption, onSelect: (option) => {
1839
+ /* @__PURE__ */ jsxs3("div", { "data-label": "Procedure code", "data-field-path": `serviceLines.${index}.code`, "data-invalid": Boolean(errors[`serviceLines.${index}.code`]), children: [
1840
+ /* @__PURE__ */ jsx3(ComboBox, { ariaLabel: `Procedure code ${index + 1}`, invalid: Boolean(errors[`serviceLines.${index}.code`]), disabled: locked, value: line.code, placeholder: "Search or enter code\u2026", options: procedures.map((item) => ({ id: item.code, label: item.code, detail: item.description })), createOption: customProcedureOption, onSelect: (option) => {
1757
1841
  const auto = evaluationModifier(evaluationType, option.id);
1758
1842
  setLine(index, { code: option.id, ...auto ? { modifiers: [auto, ...(line.modifiers ?? []).filter((item) => !["94", "95", "96"].includes(item.replace(/^-/, "")))] } : line.modifiers ? { modifiers: line.modifiers } : {} });
1759
1843
  } }),
1760
1844
  line.code ? /* @__PURE__ */ jsx3("small", { className: "mbsf-help", children: procedures.find((item) => item.code === line.code)?.description ?? "Custom CPT, HCPCS, or medical-legal code" }) : null,
1761
- errors[`serviceLines.${index}.code`] ? /* @__PURE__ */ jsx3("small", { className: "mbsf-error", children: errors[`serviceLines.${index}.code`] }) : null
1845
+ errors[`serviceLines.${index}.code`] ? /* @__PURE__ */ jsx3("small", { className: "mbsf-error", role: "alert", children: errors[`serviceLines.${index}.code`] }) : null
1762
1846
  ] }),
1763
1847
  /* @__PURE__ */ jsxs3("div", { "data-label": "Modifiers", children: [
1764
1848
  /* @__PURE__ */ jsx3("div", { className: "mbsf-chips", children: (line.modifiers ?? []).map((modifier) => /* @__PURE__ */ jsxs3("span", { className: "mbsf-chip", children: [
@@ -1768,9 +1852,9 @@ function BillSubmissionForm({
1768
1852
  ] }, modifier)) }),
1769
1853
  /* @__PURE__ */ jsx3(ComboBox, { ariaLabel: `Modifiers ${index + 1}`, disabled: locked, value: "", placeholder: line.modifiers?.length ?? 0 ? `${line.modifiers.length} modifier${line.modifiers.length === 1 ? "" : "s"}` : "Add modifiers\u2026", options: modifiers.filter((item) => !(line.modifiers ?? []).includes(item.code)).map((item) => ({ id: item.code, label: `\u2212${item.code}`, detail: item.description })), onSelect: (option) => setLine(index, { modifiers: [.../* @__PURE__ */ new Set([...line.modifiers ?? [], option.id])] }) })
1770
1854
  ] }),
1771
- /* @__PURE__ */ jsxs3("div", { "data-label": "Units", children: [
1772
- /* @__PURE__ */ jsx3("input", { className: "mbsf-input", "aria-label": `Units ${index + 1}`, type: "number", min: 1, value: line.units ?? 1, onChange: (event) => setLine(index, { units: Number(event.target.value) }) }),
1773
- errors[`serviceLines.${index}.units`] ? /* @__PURE__ */ jsx3("small", { className: "mbsf-error", children: errors[`serviceLines.${index}.units`] }) : null
1855
+ /* @__PURE__ */ jsxs3("div", { "data-label": "Units", "data-field-path": `serviceLines.${index}.units`, "data-invalid": Boolean(errors[`serviceLines.${index}.units`]), children: [
1856
+ /* @__PURE__ */ jsx3("input", { className: "mbsf-input", "aria-label": `Units ${index + 1}`, "aria-invalid": Boolean(errors[`serviceLines.${index}.units`]), type: "number", min: 1, value: line.units ?? 1, onChange: (event) => setLine(index, { units: Number(event.target.value) }) }),
1857
+ errors[`serviceLines.${index}.units`] ? /* @__PURE__ */ jsx3("small", { className: "mbsf-error", role: "alert", children: errors[`serviceLines.${index}.units`] }) : null
1774
1858
  ] }),
1775
1859
  /* @__PURE__ */ jsx3("div", { className: "mbsf-money", "data-label": "Allowed", children: lineCharge(line) == null ? "\u2014" : lineCharge(line).toLocaleString(void 0, { style: "currency", currency: "USD" }) }),
1776
1860
  /* @__PURE__ */ jsx3("button", { className: "mbsf-icon-btn", type: "button", "aria-label": `Remove service line ${index + 1}`, disabled: locked || !lineHasContent(line) && index === bill.serviceLines.length - 1, onClick: () => setBill((c) => ({ ...c, serviceLines: ensureTrailingBillSubmissionLine(c.serviceLines.filter((_, itemIndex) => itemIndex !== index)) })), children: "\xD7" })
@@ -1780,7 +1864,7 @@ function BillSubmissionForm({
1780
1864
  /* @__PURE__ */ jsx3("span", { children: total.toLocaleString(void 0, { style: "currency", currency: "USD" }) })
1781
1865
  ] })
1782
1866
  ] }),
1783
- errors.serviceLines ? /* @__PURE__ */ jsx3("p", { className: "mbsf-error", children: errors.serviceLines }) : null
1867
+ errors.serviceLines ? /* @__PURE__ */ jsx3("p", { className: "mbsf-error", role: "alert", children: errors.serviceLines }) : null
1784
1868
  ] }),
1785
1869
  /* @__PURE__ */ jsxs3("fieldset", { className: "mbsf-card", disabled: locked, children: [
1786
1870
  /* @__PURE__ */ jsx3("legend", { className: "mbsf-legend", children: "Attachments" }),
@@ -2168,7 +2252,7 @@ function BillActivityTimeline({ events, emptyLabel = "No bill activity yet.", ap
2168
2252
  ] });
2169
2253
  }
2170
2254
  var lifecycleStages = [
2171
- { id: "submitted", label: "Submitted" },
2255
+ { id: "submitted", label: "Sent" },
2172
2256
  { id: "accepted", label: "Accepted" },
2173
2257
  { id: "processed", label: "Processed" },
2174
2258
  { id: "closed", label: "Closed" }
@@ -2176,17 +2260,28 @@ var lifecycleStages = [
2176
2260
  function billLifecycleStage(state) {
2177
2261
  const value = state.toLowerCase();
2178
2262
  if (value.includes("closed") || value.includes("written_off")) return "closed";
2179
- if (value.includes("processed") || value.includes("paid") || value.includes("denied") || value.includes("reject") || value.includes("partial") || value.includes("response") || value.includes("second_review") || value.includes("ibr") || value.includes("lien") || value.includes("appeal")) return "processed";
2263
+ if (value.includes("second_review") || value.includes("appeal") || value.includes("reject")) return "submitted";
2264
+ if (value.includes("processed") || value.includes("paid") || value.includes("denied") || value.includes("partial") || value.includes("response") || value.includes("ibr") || value.includes("lien")) return "processed";
2180
2265
  if (value.includes("accepted")) return "accepted";
2181
2266
  return "submitted";
2182
2267
  }
2268
+ function billLifecycleDisplayLabel(state, nativeStatus) {
2269
+ const value = state.toLowerCase();
2270
+ if (value === "submitted") return "Sent";
2271
+ if (value === "second_review") return "Second Review sent";
2272
+ if (value === "rejected") return "Rejected";
2273
+ if (value === "denied") return "Denied";
2274
+ if (value === "partially_paid") return "Partially paid";
2275
+ if (value === "written_off") return "Written off";
2276
+ return humanize(state || nativeStatus || "submitted");
2277
+ }
2183
2278
  function BillLifecycleProgress({ state, nativeStatus, submittedAt, agingDays, appearance, className, style }) {
2184
2279
  const current = billLifecycleStage(state);
2185
2280
  const currentIndex = lifecycleStages.findIndex((stage) => stage.id === current);
2186
2281
  return /* @__PURE__ */ jsxs5("section", { className: classes("mb-surface mb-progress", className), style: mindBillAppearanceStyle(appearance, style), "aria-label": "Bill lifecycle", children: [
2187
2282
  /* @__PURE__ */ jsx5("style", { children: lifecycleSurfaceStyles }),
2188
2283
  /* @__PURE__ */ jsx5("header", { className: "mb-surface-heading", children: /* @__PURE__ */ jsxs5("div", { children: [
2189
- /* @__PURE__ */ jsx5("strong", { children: humanize(nativeStatus || state) }),
2284
+ /* @__PURE__ */ jsx5("strong", { children: billLifecycleDisplayLabel(state, nativeStatus) }),
2190
2285
  /* @__PURE__ */ jsxs5("span", { children: [
2191
2286
  submittedAt ? `Submitted ${defaultFormatDate(submittedAt)}` : "Submitted",
2192
2287
  typeof agingDays === "number" ? ` \xB7 ${agingDays} days old` : ""
@@ -2452,7 +2547,9 @@ function useBillLifecycle({
2452
2547
  closeBill: (input) => mutate(() => client.closeBill(input)),
2453
2548
  reopenBill: (input) => mutate(() => client.reopenBill(input)),
2454
2549
  postPayment: (input) => mutate(() => client.postPayment(input)),
2455
- submitSecondReview: (input) => mutate(() => client.submitSecondReview(input))
2550
+ submitSecondReview: (input) => mutate(() => client.submitSecondReview(input)),
2551
+ resubmitBill: (input) => mutate(() => client.resubmitBill(input)),
2552
+ simulateSandbox: (input) => mutate(() => client.simulateSandbox(input))
2456
2553
  };
2457
2554
  }
2458
2555
  function LifecycleDialog({ children, title, onClose }) {
@@ -2476,16 +2573,25 @@ function today() {
2476
2573
  const now = /* @__PURE__ */ new Date();
2477
2574
  return new Date(now.getTime() - now.getTimezoneOffset() * 6e4).toISOString().slice(0, 10);
2478
2575
  }
2479
- function stateLabel(state) {
2480
- return state.replace(/[._-]+/g, " ").replace(/\b\w/g, (letter) => letter.toUpperCase());
2481
- }
2482
2576
  function actionPanel(action) {
2577
+ if (action.id === "resubmit") return "resubmit";
2483
2578
  if (action.id === "second_review") return "second_review";
2484
2579
  if (action.id === "post_payment") return "payment";
2485
2580
  if (action.id === "close") return "close";
2486
2581
  if (action.id === "reopen") return "reopen";
2487
2582
  return "";
2488
2583
  }
2584
+ function sandboxScenarios(state) {
2585
+ if (state === "submitted") return [
2586
+ { id: "accepted", label: "Accept submission", detail: "Add clearinghouse and payer acknowledgements." },
2587
+ { id: "rejected", label: "Reject submission", detail: "Return a correctable routing rejection." }
2588
+ ];
2589
+ if (state === "accepted" || state === "second_review") return [
2590
+ { id: "processed", label: "Process with EOR", detail: "Attach a synthetic payer EOR and enable payment posting." },
2591
+ { id: "denied", label: "Deny payment", detail: "Attach a realistic denial EOR and enable Second Review." }
2592
+ ];
2593
+ return [];
2594
+ }
2489
2595
  function ConnectedBillLifecycle({ appearance, className, style, loadingFallback, errorFallback, onChanged, ...options }) {
2490
2596
  const lifecycle = useBillLifecycle(options);
2491
2597
  const { data } = lifecycle;
@@ -2527,8 +2633,9 @@ function ConnectedBillLifecycle({ appearance, className, style, loadingFallback,
2527
2633
  }
2528
2634
  };
2529
2635
  const viewEor = data.lifecycle.actions.find((action) => action.id === "view_eor" && action.enabled);
2530
- const supportedActions = /* @__PURE__ */ new Set(["second_review", "post_payment", "close", "reopen"]);
2636
+ const supportedActions = /* @__PURE__ */ new Set(["resubmit", "second_review", "post_payment", "close", "reopen"]);
2531
2637
  const actions = data.lifecycle.actions.filter((action) => action.enabled && supportedActions.has(action.id));
2638
+ const simulations = data.environment === "sandbox" ? sandboxScenarios(data.lifecycle.state) : [];
2532
2639
  return /* @__PURE__ */ jsxs6("section", { className: ["mb-connected-lifecycle", className].filter(Boolean).join(" "), style: mindBillAppearanceStyle(appearance, style), children: [
2533
2640
  /* @__PURE__ */ jsx6("style", { children: CONNECTED_LIFECYCLE_STYLES }),
2534
2641
  /* @__PURE__ */ jsx6(BillLifecycleProgress, { state: data.lifecycle.state, nativeStatus: data.lifecycle.nativeStatus, submittedAt: data.lifecycle.submittedAt ?? null, agingDays: data.lifecycle.agingDays ?? null, ...appearance ? { appearance } : {} }),
@@ -2539,7 +2646,7 @@ function ConnectedBillLifecycle({ appearance, className, style, loadingFallback,
2539
2646
  "Bill #",
2540
2647
  data.bill.billNumber
2541
2648
  ] }),
2542
- /* @__PURE__ */ jsx6("span", { children: stateLabel(data.lifecycle.nativeStatus || data.lifecycle.state) })
2649
+ /* @__PURE__ */ jsx6("span", { children: billLifecycleDisplayLabel(data.lifecycle.state, data.lifecycle.nativeStatus) })
2543
2650
  ] }),
2544
2651
  /* @__PURE__ */ jsxs6("p", { children: [
2545
2652
  "Claim ",
@@ -2556,6 +2663,17 @@ function ConnectedBillLifecycle({ appearance, className, style, loadingFallback,
2556
2663
  /* @__PURE__ */ jsx6("span", { children: data.activity.length })
2557
2664
  ] })
2558
2665
  ] }),
2666
+ data.environment === "sandbox" ? /* @__PURE__ */ jsxs6("section", { className: "mb-lifecycle-simulator", "aria-label": "Sandbox lifecycle simulator", children: [
2667
+ /* @__PURE__ */ jsxs6("div", { children: [
2668
+ /* @__PURE__ */ jsx6("span", { children: "Sandbox demo controls" }),
2669
+ /* @__PURE__ */ jsx6("h3", { children: "Simulate the next payer response" }),
2670
+ /* @__PURE__ */ jsx6("p", { children: "This changes sandbox data only. QME Companion receives the result through the same lifecycle API and components partners use." })
2671
+ ] }),
2672
+ simulations.length ? /* @__PURE__ */ jsx6("div", { className: "mb-lifecycle-simulator-actions", children: simulations.map((scenario) => /* @__PURE__ */ jsxs6("button", { type: "button", disabled: lifecycle.isMutating, onClick: () => void complete(`${scenario.label} simulated.`, () => lifecycle.simulateSandbox({ scenario: scenario.id })), children: [
2673
+ /* @__PURE__ */ jsx6("strong", { children: scenario.label }),
2674
+ /* @__PURE__ */ jsx6("span", { children: scenario.detail })
2675
+ ] }, scenario.id)) }) : /* @__PURE__ */ jsx6("p", { className: "mb-lifecycle-simulator-idle", children: "No simulated payer transition is needed at this stage. Use the bill action below to continue." })
2676
+ ] }) : null,
2559
2677
  tab === "details" ? /* @__PURE__ */ jsxs6("div", { className: "mb-lifecycle-tabpanel", role: "tabpanel", children: [
2560
2678
  /* @__PURE__ */ jsx6(BillReadOnlyForm, { data, onOpenAttachment: lifecycle.openAttachment, ...appearance ? { appearance } : {} }),
2561
2679
  data.eors.length ? /* @__PURE__ */ jsxs6("section", { className: "mb-lifecycle-card", id: `mb-eors-${data.bill.id}`, children: [
@@ -2588,6 +2706,20 @@ function ConnectedBillLifecycle({ appearance, className, style, loadingFallback,
2588
2706
  ] })
2589
2707
  ] }) : null
2590
2708
  ] }) : /* @__PURE__ */ jsx6("div", { className: "mb-lifecycle-tabpanel", role: "tabpanel", children: /* @__PURE__ */ jsx6(BillActivityTimeline, { events: data.activity, ...appearance ? { appearance } : {} }) }),
2709
+ panel === "resubmit" ? /* @__PURE__ */ jsx6(LifecycleDialog, { title: "Correct and resubmit", onClose: () => setPanel(""), children: /* @__PURE__ */ jsxs6("section", { className: "mb-lifecycle-panel", children: [
2710
+ /* @__PURE__ */ jsxs6("div", { children: [
2711
+ /* @__PURE__ */ jsx6("h3", { children: "Correct and resubmit" }),
2712
+ /* @__PURE__ */ jsx6("p", { children: "The original submission remains immutable. This records a new submission attempt after the routing issue is corrected." })
2713
+ ] }),
2714
+ /* @__PURE__ */ jsxs6("label", { children: [
2715
+ /* @__PURE__ */ jsx6("span", { children: "Correction note (optional)" }),
2716
+ /* @__PURE__ */ jsx6("textarea", { value: reason, placeholder: "What changed before resubmission?", onChange: (event) => setReason(event.target.value) })
2717
+ ] }),
2718
+ /* @__PURE__ */ jsxs6("div", { className: "mb-lifecycle-panel-actions", children: [
2719
+ /* @__PURE__ */ jsx6("button", { type: "button", className: "mb-lifecycle-button secondary", onClick: () => setPanel(""), children: "Cancel" }),
2720
+ /* @__PURE__ */ jsx6("button", { type: "button", className: "mb-lifecycle-button primary", disabled: lifecycle.isMutating, onClick: () => void complete("Bill resubmitted.", () => lifecycle.resubmitBill({ reason })), children: lifecycle.isMutating ? "Resubmitting\u2026" : "Resubmit bill" })
2721
+ ] })
2722
+ ] }) }) : null,
2591
2723
  panel === "second_review" ? /* @__PURE__ */ jsx6(LifecycleDialog, { title: "Submit Second Review", onClose: () => setPanel(""), children: /* @__PURE__ */ jsxs6("section", { className: "mb-lifecycle-panel", children: [
2592
2724
  /* @__PURE__ */ jsxs6("div", { children: [
2593
2725
  /* @__PURE__ */ jsx6("h3", { children: "Submit Second Review" }),
@@ -2686,6 +2818,7 @@ function ConnectedBillLifecycle({ appearance, className, style, loadingFallback,
2686
2818
  ] });
2687
2819
  }
2688
2820
  var CONNECTED_LIFECYCLE_STYLES = `
2821
+ .mb-lifecycle-simulator{display:grid;gap:14px;padding:18px;border:1px solid #b8dadd;border-radius:var(--mb-radius,14px);background:#f2fbfb}.mb-lifecycle-simulator>div:first-child>span{color:var(--mb-accent);font-size:.72rem;font-weight:850;letter-spacing:.09em;text-transform:uppercase}.mb-lifecycle-simulator h3{margin:3px 0 0;font-size:1.05rem}.mb-lifecycle-simulator p{margin:4px 0 0;color:var(--mb-muted)}.mb-lifecycle-simulator-actions{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:10px}.mb-lifecycle-simulator-actions button{min-height:76px;border:1px solid #a9cccf;border-radius:10px;background:var(--mb-surface);color:var(--mb-text);cursor:pointer;padding:12px 14px;text-align:left;font:inherit}.mb-lifecycle-simulator-actions button:hover{border-color:var(--mb-accent);box-shadow:0 3px 14px rgba(23,108,112,.1)}.mb-lifecycle-simulator-actions button:disabled{cursor:not-allowed;opacity:.55}.mb-lifecycle-simulator-actions button strong,.mb-lifecycle-simulator-actions button span{display:block}.mb-lifecycle-simulator-actions button span{margin-top:3px;color:var(--mb-muted);font-size:.83rem}.mb-lifecycle-simulator-idle{padding:10px 12px;border-radius:8px;background:rgba(255,255,255,.72)}
2689
2822
  .mb-connected-lifecycle{--mb-accent:#176c70;--mb-text:#17282d;--mb-muted:#607176;--mb-border:#d7e0df;--mb-soft:#f4f7f6;--mb-surface:#fff;display:grid;gap:18px;color:var(--mb-text);font:14px/1.45 var(--mb-font,Inter,ui-sans-serif,system-ui,sans-serif)}.mb-connected-lifecycle *{box-sizing:border-box}.mb-lifecycle-head{display:flex;align-items:center;justify-content:space-between;gap:20px}.mb-lifecycle-title{display:flex;align-items:center;flex-wrap:wrap;gap:10px}.mb-lifecycle-title h2{margin:0;font-size:1.7rem}.mb-lifecycle-title span{border-radius:999px;background:var(--mb-soft);padding:5px 10px;font-weight:750}.mb-lifecycle-head p{margin:3px 0 0;color:var(--mb-muted)}.mb-lifecycle-tabs{display:grid;grid-template-columns:1fr 1fr;border:1px solid var(--mb-border);border-radius:12px;background:var(--mb-surface);padding:6px}.mb-lifecycle-tabs button{min-height:46px;border:0;border-radius:8px;background:transparent;color:var(--mb-muted);font:inherit;font-size:1rem;font-weight:750;cursor:pointer}.mb-lifecycle-tabs button[aria-selected=true]{background:var(--mb-accent);color:white}.mb-lifecycle-tabs span{display:inline-grid;place-items:center;min-width:24px;height:24px;margin-left:6px;border-radius:999px;background:rgba(127,127,127,.14);font-size:.8rem}.mb-lifecycle-tabpanel{display:grid;gap:18px}.mb-lifecycle-button{min-height:40px;border:1px solid var(--mb-border);border-radius:var(--mb-control-radius,8px);background:var(--mb-input,#fff);color:var(--mb-text);cursor:pointer;font:inherit;font-weight:750;padding:9px 14px}.mb-lifecycle-button.primary{border-color:var(--mb-accent);background:var(--mb-accent);color:var(--mb-accent-contrast,#fff)}.mb-lifecycle-button:disabled{cursor:not-allowed;opacity:.5}.mb-lifecycle-card,.mb-lifecycle-actions-sheet,.mb-lifecycle-panel{padding:20px;border:1px solid var(--mb-border);border-radius:var(--mb-radius,14px);background:var(--mb-surface)}.mb-lifecycle-card header,.mb-lifecycle-actions-sheet{display:flex;align-items:center;justify-content:space-between;gap:20px}.mb-lifecycle-card h3,.mb-lifecycle-actions-sheet h3,.mb-lifecycle-panel h3{margin:0;font-size:1.08rem}.mb-lifecycle-card p,.mb-lifecycle-actions-sheet p,.mb-lifecycle-panel p{margin:3px 0 0;color:var(--mb-muted)}.mb-lifecycle-card header>span{display:grid;place-items:center;min-width:28px;height:28px;border-radius:999px;background:var(--mb-soft);font-weight:750}.mb-lifecycle-actions-sheet>div:last-child{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px}.mb-lifecycle-documents{list-style:none;margin:14px 0 0;padding:0}.mb-lifecycle-documents li{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:12px 0;border-top:1px solid var(--mb-border)}.mb-lifecycle-documents li>div{display:grid;gap:3px;min-width:0}.mb-lifecycle-documents li span{color:var(--mb-muted);font-size:.85rem}.mb-lifecycle-dialog-backdrop{position:fixed;z-index:2147483000;inset:0;display:grid;place-items:center;padding:20px;background:rgba(18,35,43,.56);backdrop-filter:blur(3px)}.mb-lifecycle-dialog{position:relative;width:min(760px,100%);max-height:calc(100vh - 40px);overflow:auto;outline:0}.mb-lifecycle-dialog-close{position:absolute;z-index:1;top:12px;right:12px;width:34px;height:34px;border:1px solid var(--mb-border);border-radius:8px;background:var(--mb-surface);color:var(--mb-text);cursor:pointer;font:22px/1 inherit}.mb-lifecycle-panel{display:grid;gap:17px;padding-top:24px;box-shadow:0 24px 70px rgba(18,35,43,.22)}.mb-lifecycle-panel label{display:grid;gap:6px;font-size:.85rem;font-weight:750}.mb-lifecycle-panel label small{color:var(--mb-muted);font-weight:500}.mb-lifecycle-panel input,.mb-lifecycle-panel select,.mb-lifecycle-panel textarea{width:100%;min-height:44px;border:1px solid var(--mb-border);border-radius:var(--mb-control-radius,8px);background:var(--mb-input,#fff);color:var(--mb-text);font:inherit;padding:10px 12px}.mb-lifecycle-panel textarea{min-height:100px;resize:vertical}.mb-lifecycle-fields{display:grid;gap:13px}.mb-lifecycle-fields.two{grid-template-columns:repeat(2,minmax(0,1fr))}.mb-lifecycle-fields .full{grid-column:1/-1}.mb-lifecycle-panel-actions{display:flex;justify-content:flex-end;gap:8px}.mb-lifecycle-packet{display:grid;gap:0;margin:0;padding:0;border:0}.mb-lifecycle-packet legend{margin-bottom:7px;font-size:.85rem;font-weight:800}.mb-lifecycle-packet>label{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:10px;padding:10px 2px;border-top:1px solid var(--mb-border)}.mb-lifecycle-packet>label>input{width:16px;min-height:16px}.mb-lifecycle-packet>label>span{display:grid}.mb-lifecycle-packet button{border:0;background:transparent;color:var(--mb-accent);cursor:pointer;font:inherit}.mb-lifecycle-message,.mb-lifecycle-error,.mb-lifecycle-loading{padding:12px 14px;border-radius:9px}.mb-lifecycle-message.success{background:#edf9f2;color:#217449}.mb-lifecycle-message.error,.mb-lifecycle-error{background:#fff0ef;color:#9d3029}.mb-lifecycle-error{display:flex;align-items:center;gap:12px}.mb-lifecycle-error span{flex:1}.mb-lifecycle-error button{border:1px solid currentColor;border-radius:7px;background:transparent;color:inherit;padding:7px 10px}
2690
2823
  @media(max-width:700px){.mb-lifecycle-head,.mb-lifecycle-actions-sheet,.mb-lifecycle-card header{align-items:stretch;flex-direction:column}.mb-lifecycle-head>.mb-lifecycle-button{width:100%}.mb-lifecycle-actions-sheet>div:last-child{justify-content:stretch}.mb-lifecycle-actions-sheet .mb-lifecycle-button{width:100%}.mb-lifecycle-fields.two{grid-template-columns:1fr}.mb-lifecycle-fields .full{grid-column:auto}.mb-lifecycle-dialog-backdrop{align-items:end;padding:0}.mb-lifecycle-dialog{max-height:92vh}.mb-lifecycle-dialog .mb-lifecycle-panel{border-radius:18px 18px 0 0}.mb-lifecycle-tabs button{font-size:.9rem}.mb-lifecycle-title h2{font-size:1.4rem}}
2691
2824
  `;
@@ -2753,6 +2886,7 @@ export {
2753
2886
  MindBillBillTimeline,
2754
2887
  applyBillSubmissionEvaluationModifiers,
2755
2888
  billActivityEventLabel,
2889
+ billLifecycleDisplayLabel,
2756
2890
  billLifecycleStage,
2757
2891
  buildBillReviewSaveInput,
2758
2892
  calculateBillSubmissionAllowedAmount,