@cwellt_software/cwellt-reactjs-lib 1.6.3 → 1.7.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.
Files changed (102) hide show
  1. package/dist/index.cjs.js +2479 -146
  2. package/dist/index.css +1 -1
  3. package/dist/index.d.ts +679 -2
  4. package/dist/index.es.js +2465 -147
  5. package/dist/src/components/custom/report-viewer/CwReportGauge.d.ts +19 -0
  6. package/dist/src/components/custom/report-viewer/CwReportGauge.d.ts.map +1 -0
  7. package/dist/src/components/custom/report-viewer/CwReportLineChart.d.ts +21 -0
  8. package/dist/src/components/custom/report-viewer/CwReportLineChart.d.ts.map +1 -0
  9. package/dist/src/components/custom/report-viewer/CwReportPage.d.ts +36 -0
  10. package/dist/src/components/custom/report-viewer/CwReportPage.d.ts.map +1 -0
  11. package/dist/src/components/custom/report-viewer/CwReportParameterForm.d.ts +26 -0
  12. package/dist/src/components/custom/report-viewer/CwReportParameterForm.d.ts.map +1 -0
  13. package/dist/src/components/custom/report-viewer/CwReportPieChart.d.ts +13 -0
  14. package/dist/src/components/custom/report-viewer/CwReportPieChart.d.ts.map +1 -0
  15. package/dist/src/components/custom/report-viewer/CwReportToolbar.d.ts +40 -0
  16. package/dist/src/components/custom/report-viewer/CwReportToolbar.d.ts.map +1 -0
  17. package/dist/src/components/custom/report-viewer/CwReportViewer.d.ts +50 -0
  18. package/dist/src/components/custom/report-viewer/CwReportViewer.d.ts.map +1 -0
  19. package/dist/src/components/custom/report-viewer/ReportItem.d.ts +21 -0
  20. package/dist/src/components/custom/report-viewer/ReportItem.d.ts.map +1 -0
  21. package/dist/src/components/custom/report-viewer/ReportTextbox.d.ts +10 -0
  22. package/dist/src/components/custom/report-viewer/ReportTextbox.d.ts.map +1 -0
  23. package/dist/src/components/custom/report-viewer/logic/rdlChartMarkers.d.ts +26 -0
  24. package/dist/src/components/custom/report-viewer/logic/rdlChartMarkers.d.ts.map +1 -0
  25. package/dist/src/components/custom/report-viewer/logic/rdlChartScale.d.ts +75 -0
  26. package/dist/src/components/custom/report-viewer/logic/rdlChartScale.d.ts.map +1 -0
  27. package/dist/src/components/custom/report-viewer/logic/rdlFind.d.ts +38 -0
  28. package/dist/src/components/custom/report-viewer/logic/rdlFind.d.ts.map +1 -0
  29. package/dist/src/components/custom/report-viewer/logic/rdlGauge.d.ts +40 -0
  30. package/dist/src/components/custom/report-viewer/logic/rdlGauge.d.ts.map +1 -0
  31. package/dist/src/components/custom/report-viewer/logic/rdlListMarkers.d.ts +12 -0
  32. package/dist/src/components/custom/report-viewer/logic/rdlListMarkers.d.ts.map +1 -0
  33. package/dist/src/components/custom/report-viewer/logic/rdlNumberFormat.d.ts +8 -0
  34. package/dist/src/components/custom/report-viewer/logic/rdlNumberFormat.d.ts.map +1 -0
  35. package/dist/src/components/custom/report-viewer/logic/rdlPageGeometry.d.ts +38 -0
  36. package/dist/src/components/custom/report-viewer/logic/rdlPageGeometry.d.ts.map +1 -0
  37. package/dist/src/components/custom/report-viewer/logic/rdlParameterValues.d.ts +42 -0
  38. package/dist/src/components/custom/report-viewer/logic/rdlParameterValues.d.ts.map +1 -0
  39. package/dist/src/components/custom/report-viewer/logic/rdlStyle.d.ts +62 -0
  40. package/dist/src/components/custom/report-viewer/logic/rdlStyle.d.ts.map +1 -0
  41. package/dist/src/components/custom/report-viewer/logic/rdlTableLayout.d.ts +33 -0
  42. package/dist/src/components/custom/report-viewer/logic/rdlTableLayout.d.ts.map +1 -0
  43. package/dist/src/components/custom/report-viewer/logic/rdlToggles.d.ts +20 -0
  44. package/dist/src/components/custom/report-viewer/logic/rdlToggles.d.ts.map +1 -0
  45. package/dist/src/components/custom/report-viewer/logic/rdlUnits.d.ts +9 -0
  46. package/dist/src/components/custom/report-viewer/logic/rdlUnits.d.ts.map +1 -0
  47. package/dist/src/components/custom/report-viewer/logic/reportOutputGuard.d.ts +20 -0
  48. package/dist/src/components/custom/report-viewer/logic/reportOutputGuard.d.ts.map +1 -0
  49. package/dist/src/components/custom/report-viewer/logic/reportViewerLayout.d.ts +17 -0
  50. package/dist/src/components/custom/report-viewer/logic/reportViewerLayout.d.ts.map +1 -0
  51. package/dist/src/components/custom/report-viewer/rdlTypes.d.ts +333 -0
  52. package/dist/src/components/custom/report-viewer/rdlTypes.d.ts.map +1 -0
  53. package/dist/src/components/custom/report-viewer/reportChartShared.d.ts +53 -0
  54. package/dist/src/components/custom/report-viewer/reportChartShared.d.ts.map +1 -0
  55. package/dist/src/components/custom/report-viewer/reportRenderContext.d.ts +25 -0
  56. package/dist/src/components/custom/report-viewer/reportRenderContext.d.ts.map +1 -0
  57. package/dist/src/components/custom/report-viewer/useReportParameterForm.d.ts +30 -0
  58. package/dist/src/components/custom/report-viewer/useReportParameterForm.d.ts.map +1 -0
  59. package/dist/src/components/custom/report-viewer/useReportViewerState.d.ts +74 -0
  60. package/dist/src/components/custom/report-viewer/useReportViewerState.d.ts.map +1 -0
  61. package/dist/src/components/custom/report-viewer/useSidebarResize.d.ts +22 -0
  62. package/dist/src/components/custom/report-viewer/useSidebarResize.d.ts.map +1 -0
  63. package/dist/src/components/display/data/tooltip_manager/CwTooltipManager.d.ts +1 -1
  64. package/dist/src/components/display/data/tooltip_manager/CwTooltipManager.d.ts.map +1 -1
  65. package/dist/src/index.d.ts +15 -0
  66. package/dist/src/index.d.ts.map +1 -1
  67. package/dist/src/playground/PlaygroundApp.d.ts.map +1 -1
  68. package/dist/src/playground/pages/ReportViewerPage.d.ts +8 -0
  69. package/dist/src/playground/pages/ReportViewerPage.d.ts.map +1 -0
  70. package/dist/src/playground/pages/reportViewerFakeData.d.ts +13 -0
  71. package/dist/src/playground/pages/reportViewerFakeData.d.ts.map +1 -0
  72. package/dist/test/components/custom/report-viewer/rdlChartMarkers.test.d.ts +2 -0
  73. package/dist/test/components/custom/report-viewer/rdlChartMarkers.test.d.ts.map +1 -0
  74. package/dist/test/components/custom/report-viewer/rdlChartScale.test.d.ts +2 -0
  75. package/dist/test/components/custom/report-viewer/rdlChartScale.test.d.ts.map +1 -0
  76. package/dist/test/components/custom/report-viewer/rdlFind.test.d.ts +2 -0
  77. package/dist/test/components/custom/report-viewer/rdlFind.test.d.ts.map +1 -0
  78. package/dist/test/components/custom/report-viewer/rdlGauge.test.d.ts +2 -0
  79. package/dist/test/components/custom/report-viewer/rdlGauge.test.d.ts.map +1 -0
  80. package/dist/test/components/custom/report-viewer/rdlNumberFormat.test.d.ts +2 -0
  81. package/dist/test/components/custom/report-viewer/rdlNumberFormat.test.d.ts.map +1 -0
  82. package/dist/test/components/custom/report-viewer/rdlParameterValues.test.d.ts +2 -0
  83. package/dist/test/components/custom/report-viewer/rdlParameterValues.test.d.ts.map +1 -0
  84. package/dist/test/components/custom/report-viewer/rdlTableLayout.test.d.ts +2 -0
  85. package/dist/test/components/custom/report-viewer/rdlTableLayout.test.d.ts.map +1 -0
  86. package/dist/test/components/custom/report-viewer/rdlText.test.d.ts +2 -0
  87. package/dist/test/components/custom/report-viewer/rdlText.test.d.ts.map +1 -0
  88. package/dist/test/components/custom/report-viewer/rdlToggles.test.d.ts +2 -0
  89. package/dist/test/components/custom/report-viewer/rdlToggles.test.d.ts.map +1 -0
  90. package/dist/test/components/custom/report-viewer/rdlUnits.test.d.ts +2 -0
  91. package/dist/test/components/custom/report-viewer/rdlUnits.test.d.ts.map +1 -0
  92. package/dist/test/components/custom/report-viewer/reportOutputGuard.test.d.ts +2 -0
  93. package/dist/test/components/custom/report-viewer/reportOutputGuard.test.d.ts.map +1 -0
  94. package/dist/test/components/custom/report-viewer/reportViewerLayout.test.d.ts +2 -0
  95. package/dist/test/components/custom/report-viewer/reportViewerLayout.test.d.ts.map +1 -0
  96. package/dist/test/components/custom/report-viewer/useReportParameterForm.test.d.ts +2 -0
  97. package/dist/test/components/custom/report-viewer/useReportParameterForm.test.d.ts.map +1 -0
  98. package/dist/test/components/custom/report-viewer/useReportViewerState.test.d.ts +2 -0
  99. package/dist/test/components/custom/report-viewer/useReportViewerState.test.d.ts.map +1 -0
  100. package/dist/test/helpers/renderHookHeadless.d.ts +8 -0
  101. package/dist/test/helpers/renderHookHeadless.d.ts.map +1 -0
  102. package/package.json +89 -89
package/dist/index.es.js CHANGED
@@ -174,7 +174,7 @@ function getContrastColor(color) {
174
174
  return `hsl(${hsl.h}, ${contrastS}%, ${targetL}%)`;
175
175
  }
176
176
 
177
- var styles$A = {"cw-tooltip-content":"cw-tooltip-module__cw-tooltip-content__RZczd","cw-tooltip":"cw-tooltip-module__cw-tooltip__1KYig"};
177
+ var styles$D = {"cw-tooltip-content":"cw-tooltip-module__cw-tooltip-content__RZczd","cw-tooltip":"cw-tooltip-module__cw-tooltip__1KYig"};
178
178
 
179
179
  // Constants
180
180
  const margin$1 = 16;
@@ -464,7 +464,7 @@ const CwTooltipManager = () => {
464
464
  if (!state.isVisible || !state.content) {
465
465
  return null;
466
466
  }
467
- return createPortal(jsx("div", { ref: tooltipRef, className: styles$A["cw-tooltip-content"], "data-position": actualPosition, "data-visible": state.isVisible, "data-inline": state.displayInline, style: {
467
+ return createPortal(jsx("div", { ref: tooltipRef, className: styles$D["cw-tooltip-content"], "data-position": actualPosition, "data-visible": state.isVisible, "data-inline": state.displayInline, style: {
468
468
  top: `${tooltipPosition.top}px`,
469
469
  left: `${tooltipPosition.left}px`,
470
470
  opacity: (isPositioned && !isMeasuring) ? 1 : 0,
@@ -545,7 +545,7 @@ const CwTooltipNew = ({ children, content = null, position = "right", dissapears
545
545
  useEffect(() => {
546
546
  ensureTooltipManager();
547
547
  }, []);
548
- return (jsx("div", { ref: containerRef, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, className: styles$A["cw-tooltip"], children: children }));
548
+ return (jsx("div", { ref: containerRef, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, className: styles$D["cw-tooltip"], children: children }));
549
549
  };
550
550
 
551
551
  const SVG_ICONS = {
@@ -665,7 +665,7 @@ function resolveBadgeAria(label, loading, hasText) {
665
665
  return hasText ? {} : { 'aria-hidden': 'true' };
666
666
  }
667
667
 
668
- var styles$z = {"badge":"cw-badge-module__badge__PKlak"};
668
+ var styles$C = {"badge":"cw-badge-module__badge__PKlak"};
669
669
 
670
670
  /**
671
671
  * CwBadge - the small coloured circle with a number, used for alert and notification counts.
@@ -701,7 +701,7 @@ const CwBadge = ({ count, content, color = 'info', variant = 'solid', size = 'sm
701
701
  ? formatBadgeCount(count, max)
702
702
  : undefined;
703
703
  const isDot = !loading && !hasContent && count === undefined;
704
- const badgeClassNames = ['cw-badge', styles$z.badge, className].filter(Boolean).join(' ');
704
+ const badgeClassNames = ['cw-badge', styles$C.badge, className].filter(Boolean).join(' ');
705
705
  return (jsx("span", { ...dataAttributes, className: badgeClassNames, "data-color": color, "data-variant": variant, "data-size": size, "data-loading": loading ? 'true' : undefined, "data-dot": isDot ? 'true' : undefined, ...resolveBadgeAria(label, loading, !loading && (hasContent || countText !== undefined)), style: style, children: loading ? jsx(CwIcon, { iconId: "spinner", size: "small" }) : hasContent ? content : countText }));
706
706
  };
707
707
 
@@ -1089,7 +1089,7 @@ function CwLoading({ isLoading = false, text = '', size = 'regular', iconPositio
1089
1089
  return (jsxs("div", { "aria-busy": isLoading, className: "cw-loading-container", "data-children": !!children, children: [overlay, jsx("div", { className: "cw-loading-disabled-content", children: children })] }));
1090
1090
  }
1091
1091
 
1092
- var styles$y = {"skeleton":"cw-skeleton-module__skeleton__Jvx2x","group":"cw-skeleton-module__group__Cm8AU"};
1092
+ var styles$B = {"skeleton":"cw-skeleton-module__skeleton__Jvx2x","group":"cw-skeleton-module__group__Cm8AU"};
1093
1093
 
1094
1094
  /*
1095
1095
  * Internal helper for skeleton allocations (CwSkeleton, tables, cards).
@@ -1131,8 +1131,8 @@ function CwSkeleton({ variant = 'text', width, height, count = 1, radius, gap })
1131
1131
  };
1132
1132
  // The un-hashed cw-skeleton / cw-skeleton-group classes carry no styles in the
1133
1133
  // library - they are stable public hooks for exceptional external overrides.
1134
- const skeletonClassName = ['cw-skeleton', styles$y.skeleton].filter(Boolean).join(' ');
1135
- const groupClassName = ['cw-skeleton-group', styles$y.group].filter(Boolean).join(' ');
1134
+ const skeletonClassName = ['cw-skeleton', styles$B.skeleton].filter(Boolean).join(' ');
1135
+ const groupClassName = ['cw-skeleton-group', styles$B.group].filter(Boolean).join(' ');
1136
1136
  const lineCount = normalizeSkeletonCount(count, 1);
1137
1137
  if (lineCount <= 1) {
1138
1138
  return (jsx("span", { className: skeletonClassName, "data-variant": variant, "aria-hidden": "true", style: style }));
@@ -1144,7 +1144,7 @@ function CwSkeleton({ variant = 'text', width, height, count = 1, radius, gap })
1144
1144
  return (jsx("span", { className: groupClassName, "aria-hidden": "true", style: groupStyle, children: skeletonElements }));
1145
1145
  }
1146
1146
 
1147
- var styles$x = {"progress":"cw-progress-module__progress__d-g2-","value":"cw-progress-module__value__Q-DrH","label":"cw-progress-module__label__jwOWp","track":"cw-progress-module__track__572-3","footer":"cw-progress-module__footer__0Wo4G","header":"cw-progress-module__header__mv5ct","fill":"cw-progress-module__fill__fX1UA"};
1147
+ var styles$A = {"progress":"cw-progress-module__progress__d-g2-","value":"cw-progress-module__value__Q-DrH","label":"cw-progress-module__label__jwOWp","track":"cw-progress-module__track__572-3","footer":"cw-progress-module__footer__0Wo4G","header":"cw-progress-module__header__mv5ct","fill":"cw-progress-module__fill__fX1UA"};
1148
1148
 
1149
1149
  /**
1150
1150
  * CwProgress - a determinate or indeterminate progress bar.
@@ -1168,17 +1168,17 @@ function CwProgress({ value, indeterminate = false, label, rightLabel, footer, s
1168
1168
  const valueContent = rightLabel ?? (percent !== undefined ? `${percent}%` : '');
1169
1169
  // The un-hashed cw-progress class carries no styles in the library - a stable
1170
1170
  // public hook for exceptional external overrides only.
1171
- const rootClassName = ['cw-progress', styles$x.progress, className].filter(Boolean).join(' ');
1172
- const labelSpan = label ? jsx("span", { className: styles$x.label, id: labelId, children: label }) : null;
1173
- const valueLabel = showValue ? (jsx("span", { className: styles$x.value, "data-mono": monoValue || undefined, children: valueContent })) : null;
1174
- return (jsxs("div", { ...dataAttributes, className: rootClassName, style: style, "data-layout": layout, "data-size": size, "data-color": color, "data-prominent": prominent || undefined, "data-indeterminate": indeterminate || undefined, children: [layout === 'column' && (labelSpan || valueLabel) && (jsxs("header", { className: styles$x.header, children: [labelSpan, valueLabel] })), layout === 'row' && labelSpan, jsx("div", { className: styles$x.track, role: "progressbar", ...(label && { 'aria-labelledby': labelId }), ...(!indeterminate && percent !== undefined && {
1171
+ const rootClassName = ['cw-progress', styles$A.progress, className].filter(Boolean).join(' ');
1172
+ const labelSpan = label ? jsx("span", { className: styles$A.label, id: labelId, children: label }) : null;
1173
+ const valueLabel = showValue ? (jsx("span", { className: styles$A.value, "data-mono": monoValue || undefined, children: valueContent })) : null;
1174
+ return (jsxs("div", { ...dataAttributes, className: rootClassName, style: style, "data-layout": layout, "data-size": size, "data-color": color, "data-prominent": prominent || undefined, "data-indeterminate": indeterminate || undefined, children: [layout === 'column' && (labelSpan || valueLabel) && (jsxs("header", { className: styles$A.header, children: [labelSpan, valueLabel] })), layout === 'row' && labelSpan, jsx("div", { className: styles$A.track, role: "progressbar", ...(label && { 'aria-labelledby': labelId }), ...(!indeterminate && percent !== undefined && {
1175
1175
  'aria-valuenow': percent,
1176
1176
  'aria-valuemin': 0,
1177
1177
  'aria-valuemax': 100
1178
- }), children: jsx("div", { className: styles$x.fill, style: !indeterminate && clamped !== undefined ? { width: `${clamped}%` } : undefined }) }), layout === 'row' && valueLabel, footer != null && jsx("footer", { className: styles$x.footer, children: footer })] }));
1178
+ }), children: jsx("div", { className: styles$A.fill, style: !indeterminate && clamped !== undefined ? { width: `${clamped}%` } : undefined }) }), layout === 'row' && valueLabel, footer != null && jsx("footer", { className: styles$A.footer, children: footer })] }));
1179
1179
  }
1180
1180
 
1181
- var styles$w = {"cw-generic-tooltip-content":"cw-generic-tooltip-module__cw-generic-tooltip-content__la-Si","cw-generic-tooltip":"cw-generic-tooltip-module__cw-generic-tooltip__Ij76M"};
1181
+ var styles$z = {"cw-generic-tooltip-content":"cw-generic-tooltip-module__cw-generic-tooltip-content__la-Si","cw-generic-tooltip":"cw-generic-tooltip-module__cw-generic-tooltip__Ij76M"};
1182
1182
 
1183
1183
  // Constants moved outside to prevent recreation
1184
1184
  const margin = 16;
@@ -1305,12 +1305,12 @@ const CwGenericTooltip = ({ children, content = null, position = defaultPosition
1305
1305
  const { setTooltipTimeout, clearTooltipTimeout } = useTooltipDelay(() => {
1306
1306
  setIsVisible(true);
1307
1307
  }, showDelay);
1308
- const { position: tooltipPosition, actualPosition } = useTooltipPosition(isVisible, containerRef, position, styles$w["cw-generic-tooltip-content"]);
1308
+ const { position: tooltipPosition, actualPosition } = useTooltipPosition(isVisible, containerRef, position, styles$z["cw-generic-tooltip-content"]);
1309
1309
  // Memoize tooltip content creation
1310
1310
  const tooltipContent = useMemo(() => {
1311
1311
  if (hide || !isVisible || !content)
1312
1312
  return null;
1313
- return createPortal(jsx("div", { className: styles$w["cw-generic-tooltip-content"], "data-position": actualPosition, "data-visible": isVisible, "data-inline": displayInline, style: {
1313
+ return createPortal(jsx("div", { className: styles$z["cw-generic-tooltip-content"], "data-position": actualPosition, "data-visible": isVisible, "data-inline": displayInline, style: {
1314
1314
  position: 'fixed',
1315
1315
  top: `${tooltipPosition.top}px`,
1316
1316
  left: `${tooltipPosition.left}px`,
@@ -1325,7 +1325,7 @@ const CwGenericTooltip = ({ children, content = null, position = defaultPosition
1325
1325
  clearTooltipTimeout();
1326
1326
  setIsVisible(false);
1327
1327
  }, [clearTooltipTimeout]);
1328
- return (jsxs("div", { ref: containerRef, className: styles$w["cw-generic-tooltip"], onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, children: [tooltipContent, children] }));
1328
+ return (jsxs("div", { ref: containerRef, className: styles$z["cw-generic-tooltip"], onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, children: [tooltipContent, children] }));
1329
1329
  };
1330
1330
 
1331
1331
  const CwButton = React__default.forwardRef(function CwButton({ text, variant = 'solid', color = 'primary', size = 'medium', iconPosition = 'left', pressed, className = '', icon = "", title, tooltipPosition = "bottom", badge, children, ...buttonProps }, ref) {
@@ -1393,7 +1393,7 @@ function CwModal(custModalProps) {
1393
1393
  return (jsx("div", { children: custModalProps.modalState && (jsxs("div", { className: custModalProps.classNameModalOverlay + " cwelltModalOverlay", children: [jsx("div", { className: "cwelltModalOverlayBg", onClick: custModalProps.onCloseModal }), jsx(Draggable, { disabled: isModalDisabled, axis: "both", nodeRef: draggableRef, children: jsxs("div", { className: custModalProps.classNameModal + " cwelltContainerModal", ref: draggableRef, style: widthModalDef !== "40em" ? modalStyle.widthCustomStyle : modalStyle.widthDefStyle, children: [jsxs("div", { className: "cwelltModalHeader", onMouseOver: cwelltOnMouseOverModal, onMouseOut: cwelltOnMouseOutModal, children: [jsx("div", { className: "cwelltModalTitle", children: custModalProps.titleModal }), jsx("button", { className: "cwelltBtnCloseModal", onClick: custModalProps.onCloseModal, children: jsx("span", { className: "cwelltCloseIcon" }) })] }), jsx("div", { className: "cwelltModalBody", children: jsx("div", { className: "cwelltContainerModalBody", style: { position: "relative" }, children: custModalProps.children }) }), isHide === false ? (jsx("footer", { className: "legacy-modal-footer", onMouseOver: cwelltOnMouseOverModal, onMouseOut: cwelltOnMouseOutModal, children: jsx(CwButton, { variant: "icon", icon: "save", title: "Save", onClick: custModalProps.onSaveModal, form: custModalProps.formSaveModal, hidden: custModalProps.HideBtnModal, type: custModalProps.HtmlSubmitModal }) })) : (jsx("div", { style: { display: "none" } }))] }) })] })) }));
1394
1394
  }
1395
1395
 
1396
- var styles$v = {"overlayPositioned":"CwConfirmationPopup-module__overlayPositioned__11qYB","popup":"CwConfirmationPopup-module__popup__ahPjM","message":"CwConfirmationPopup-module__message__MnNL4","buttons":"CwConfirmationPopup-module__buttons__fGYYE","button":"CwConfirmationPopup-module__button__ugYQE","confirmButton":"CwConfirmationPopup-module__confirmButton__rTP4S","cancelButton":"CwConfirmationPopup-module__cancelButton__Ry694"};
1396
+ var styles$y = {"overlayPositioned":"CwConfirmationPopup-module__overlayPositioned__11qYB","popup":"CwConfirmationPopup-module__popup__ahPjM","message":"CwConfirmationPopup-module__message__MnNL4","buttons":"CwConfirmationPopup-module__buttons__fGYYE","button":"CwConfirmationPopup-module__button__ugYQE","confirmButton":"CwConfirmationPopup-module__confirmButton__rTP4S","cancelButton":"CwConfirmationPopup-module__cancelButton__Ry694"};
1397
1397
 
1398
1398
  /**
1399
1399
  * Small anchored confirmation for a destructive action.
@@ -1462,15 +1462,15 @@ function CwConfirmationPopup(props) {
1462
1462
  onCancel();
1463
1463
  }
1464
1464
  };
1465
- return (jsxs(Fragment, { children: [renderChildren(), isOpen && (jsx("div", { className: styles$v.overlayPositioned, onClick: handleOverlayClick, children: jsxs("div", { ref: popupRef, className: styles$v.popup, style: {
1465
+ return (jsxs(Fragment, { children: [renderChildren(), isOpen && (jsx("div", { className: styles$y.overlayPositioned, onClick: handleOverlayClick, children: jsxs("div", { ref: popupRef, className: styles$y.popup, style: {
1466
1466
  position: 'absolute',
1467
1467
  top: `${position.top}px`,
1468
1468
  left: `${position.left}px`,
1469
1469
  transform: 'none'
1470
- }, children: [jsx("p", { className: styles$v.message, children: message }), jsxs("div", { className: styles$v.buttons, children: [jsx("button", { className: `${styles$v.button} ${styles$v.confirmButton}`, onClick: onConfirm, children: confirmText }), jsx("button", { className: `${styles$v.button} ${styles$v.cancelButton}`, onClick: onCancel, children: cancelText })] })] }) }))] }));
1470
+ }, children: [jsx("p", { className: styles$y.message, children: message }), jsxs("div", { className: styles$y.buttons, children: [jsx("button", { className: `${styles$y.button} ${styles$y.confirmButton}`, onClick: onConfirm, children: confirmText }), jsx("button", { className: `${styles$y.button} ${styles$y.cancelButton}`, onClick: onCancel, children: cancelText })] })] }) }))] }));
1471
1471
  }
1472
1472
 
1473
- var styles$u = {"cw-dialog-main":"cw-dialog-module__cw-dialog-main__cHxHt","cw-dialog-button-close":"cw-dialog-module__cw-dialog-button-close__9GRd8"};
1473
+ var styles$x = {"cw-dialog-main":"cw-dialog-module__cw-dialog-main__cHxHt","cw-dialog-button-close":"cw-dialog-module__cw-dialog-button-close__9GRd8"};
1474
1474
 
1475
1475
  // Helper function to parse size values
1476
1476
  const parseSize = (size) => {
@@ -1743,7 +1743,7 @@ const CwDialog = props => {
1743
1743
  }
1744
1744
  }
1745
1745
  }, [open]);
1746
- const header = useMemo(() => (jsxs("header", { onMouseDown: handleMouseDown, children: [jsx("span", { children: headline }), customHeader || (jsx("button", { className: styles$u["cw-dialog-button-close"], onClick: onClose }))] })), [handleMouseDown, headline, customHeader, onClose]);
1746
+ const header = useMemo(() => (jsxs("header", { onMouseDown: handleMouseDown, children: [jsx("span", { children: headline }), customHeader || (jsx("button", { className: styles$x["cw-dialog-button-close"], onClick: onClose }))] })), [handleMouseDown, headline, customHeader, onClose]);
1747
1747
  const content = useMemo(() => (jsx("section", { children: children })), [children]);
1748
1748
  const footer = useMemo(() => (jsx("footer", { children: customFooter || (jsx(CwButton, { variant: "icon", icon: "save", title: "Save", onClick: onSave, tooltipPosition: "top", disabled: disableSave, "data-testid": "cw-dialog-save" })) })), [customFooter, onSave, disableSave]);
1749
1749
  const resizeHandles = useMemo(() => size.autoHeight
@@ -1770,7 +1770,7 @@ const CwDialog = props => {
1770
1770
  : `${convertFromPx(size.height, size.heightUnit)}${size.heightUnit}`;
1771
1771
  return { displayWidth, displayHeight };
1772
1772
  }, [size.width, size.height, size.widthUnit, size.heightUnit, size.autoHeight]);
1773
- const dialogContent = (jsx("div", { "data-has-scrim": hasScrim, className: styles$u["cw-dialog-main"], onMouseDown: handleScrimMouseDown, onMouseUp: handleScrimMouseUpOrLeave, onMouseLeave: handleScrimMouseUpOrLeave, "data-pressing": isPressingScrim, children: jsxs("dialog", { ...domProps, ref: dialogRef, style: {
1773
+ const dialogContent = (jsx("div", { "data-has-scrim": hasScrim, className: styles$x["cw-dialog-main"], onMouseDown: handleScrimMouseDown, onMouseUp: handleScrimMouseUpOrLeave, onMouseLeave: handleScrimMouseUpOrLeave, "data-pressing": isPressingScrim, children: jsxs("dialog", { ...domProps, ref: dialogRef, style: {
1774
1774
  left: `${position.x}px`,
1775
1775
  top: `${position.y}px`,
1776
1776
  width: displayDimensions.displayWidth,
@@ -1932,7 +1932,7 @@ function CwAlign(props) {
1932
1932
  }, children: props.children }));
1933
1933
  }
1934
1934
 
1935
- var styles$t = {"card":"cw-card-module__card__HJUT0","content":"cw-card-module__content__ma9qy","clickable":"cw-card-module__clickable__Y-V3X","disabled":"cw-card-module__disabled__0wHh1","headerContent":"cw-card-module__headerContent__x4Jfl","footerTags":"cw-card-module__footerTags__80sSW"};
1935
+ var styles$w = {"card":"cw-card-module__card__HJUT0","content":"cw-card-module__content__ma9qy","clickable":"cw-card-module__clickable__Y-V3X","disabled":"cw-card-module__disabled__0wHh1","headerContent":"cw-card-module__headerContent__x4Jfl","footerTags":"cw-card-module__footerTags__80sSW"};
1936
1936
 
1937
1937
  /**
1938
1938
  * CwCard - A simple card component for displaying content in a contained format
@@ -1958,10 +1958,10 @@ const CwCard = ({ id, title, subtitle, alignment = 'center', children, footer, o
1958
1958
  // Construct class names using CSS modules
1959
1959
  const cardClassNames = [
1960
1960
  'cw-card',
1961
- styles$t.card,
1961
+ styles$w.card,
1962
1962
  className,
1963
- clickable ? styles$t.clickable : '',
1964
- disabled ? styles$t.disabled : '',
1963
+ clickable ? styles$w.clickable : '',
1964
+ disabled ? styles$w.disabled : '',
1965
1965
  ].filter(Boolean).join(' ');
1966
1966
  // Handle click event when card is clickable
1967
1967
  const handleClick = () => {
@@ -1979,15 +1979,15 @@ const CwCard = ({ id, title, subtitle, alignment = 'center', children, footer, o
1979
1979
  const hasFooter = hasChips || footer || (hasActions && resolvedDirection === "row");
1980
1980
  // Actions component to reuse. While loading, each provided action renders a circular
1981
1981
  // ghost sized to the CwButton icon footprint (2rem) - no interactive buttons.
1982
- const ActionsComponent = hasActions && !disabled ? (jsx("div", { className: styles$t.actions, children: isLoading ? (jsxs(Fragment, { children: [extraActions && jsx(CwSkeleton, { variant: "circle", height: "2rem" }), onEdit && jsx(CwSkeleton, { variant: "circle", height: "2rem" }), onDelete && jsx(CwSkeleton, { variant: "circle", height: "2rem" })] })) : (jsxs(Fragment, { children: [extraActions ?? null, onEdit && jsx(CwButton, { variant: "icon", icon: "edit", onClick: onEdit }), onDelete && jsx(CwButton, { variant: "icon", icon: "delete", color: "danger", onClick: onDelete })] })) })) : null;
1982
+ const ActionsComponent = hasActions && !disabled ? (jsx("div", { className: styles$w.actions, children: isLoading ? (jsxs(Fragment, { children: [extraActions && jsx(CwSkeleton, { variant: "circle", height: "2rem" }), onEdit && jsx(CwSkeleton, { variant: "circle", height: "2rem" }), onDelete && jsx(CwSkeleton, { variant: "circle", height: "2rem" })] })) : (jsxs(Fragment, { children: [extraActions ?? null, onEdit && jsx(CwButton, { variant: "icon", icon: "edit", onClick: onEdit }), onDelete && jsx(CwButton, { variant: "icon", icon: "delete", color: "danger", onClick: onDelete })] })) })) : null;
1983
1983
  return (jsxs("div", { ...(id && { id }), className: cardClassNames, ...(style && { style }), ...(clickable && !isLoading && {
1984
1984
  role: 'button',
1985
1985
  tabIndex: 0,
1986
1986
  onClick: handleClick,
1987
- }), "data-variant": variant, "data-direction": resolvedDirection, "aria-busy": isLoading || undefined, children: [isLoading ? (jsxs("header", { children: [jsx("div", { className: styles$t.headerContent, "data-align": resolvedAlign, children: jsx(CwSkeleton, { width: "8rem", height: "1.5em" }) }), resolvedDirection === "column" && ActionsComponent] })) : (hasHeader && (jsxs("header", { children: [(title || subtitle) && (jsxs("div", { className: styles$t.headerContent, "data-align": resolvedAlign, children: [title && jsx("h5", { children: title }), subtitle && jsx("strong", { children: subtitle })] })), resolvedDirection === "column" && ActionsComponent] }))), jsx("div", { className: styles$t.content, children: isLoading ? jsx(CwSkeleton, { count: normalizeSkeletonCount(skeletonLines, 3) }) : children }), hasFooter && (isLoading ? (jsx("footer", { children: jsx("div", { className: styles$t.footerTags, children: jsx(CwSkeleton, { variant: "rect", width: "4rem", height: "1.5em", radius: "1rem" }) }) })) : (jsxs("footer", { children: [hasChips && (jsx("div", { className: styles$t.footerTags, children: chips.map((chip, index) => (jsx(CwChip, { label: chip.label, color: chip.color, colorScheme: chip.colorScheme, className: styles$t.chip, ...(chip.customColor && { customColor: chip.customColor }), ...(chip.variant && { variant: chip.variant }), ...(chip.icon && { icon: chip.icon }) }, index))) })), footer && (jsx("div", { className: styles$t.footerContent, children: footer }))] }))), resolvedDirection === "row" && ActionsComponent] }));
1987
+ }), "data-variant": variant, "data-direction": resolvedDirection, "aria-busy": isLoading || undefined, children: [isLoading ? (jsxs("header", { children: [jsx("div", { className: styles$w.headerContent, "data-align": resolvedAlign, children: jsx(CwSkeleton, { width: "8rem", height: "1.5em" }) }), resolvedDirection === "column" && ActionsComponent] })) : (hasHeader && (jsxs("header", { children: [(title || subtitle) && (jsxs("div", { className: styles$w.headerContent, "data-align": resolvedAlign, children: [title && jsx("h5", { children: title }), subtitle && jsx("strong", { children: subtitle })] })), resolvedDirection === "column" && ActionsComponent] }))), jsx("div", { className: styles$w.content, children: isLoading ? jsx(CwSkeleton, { count: normalizeSkeletonCount(skeletonLines, 3) }) : children }), hasFooter && (isLoading ? (jsx("footer", { children: jsx("div", { className: styles$w.footerTags, children: jsx(CwSkeleton, { variant: "rect", width: "4rem", height: "1.5em", radius: "1rem" }) }) })) : (jsxs("footer", { children: [hasChips && (jsx("div", { className: styles$w.footerTags, children: chips.map((chip, index) => (jsx(CwChip, { label: chip.label, color: chip.color, colorScheme: chip.colorScheme, className: styles$w.chip, ...(chip.customColor && { customColor: chip.customColor }), ...(chip.variant && { variant: chip.variant }), ...(chip.icon && { icon: chip.icon }) }, index))) })), footer && (jsx("div", { className: styles$w.footerContent, children: footer }))] }))), resolvedDirection === "row" && ActionsComponent] }));
1988
1988
  };
1989
1989
 
1990
- var styles$s = {"cardContainer":"cw-card-list-module__cardContainer__l3YEh","pagination":"cw-card-list-module__pagination__5Ay78","pageInfo":"cw-card-list-module__pageInfo__uiMel","emptyState":"cw-card-list-module__emptyState__RlqiS"};
1990
+ var styles$v = {"cardContainer":"cw-card-list-module__cardContainer__l3YEh","pagination":"cw-card-list-module__pagination__5Ay78","pageInfo":"cw-card-list-module__pageInfo__uiMel","emptyState":"cw-card-list-module__emptyState__RlqiS"};
1991
1991
 
1992
1992
  /**
1993
1993
  * Option to display in the CwSelect
@@ -2082,10 +2082,10 @@ function CwCardList({ items, renderCard, pageSize = 10, layout = 'grid', default
2082
2082
  icon: sortDirection === 'asc' ? 'arrow-up' : 'arrow-down',
2083
2083
  onClick: () => setSortDirection(prev => prev === 'asc' ? 'desc' : 'asc'),
2084
2084
  title: `Sort ${sortDirection === 'asc' ? 'descending' : 'ascending'}`,
2085
- }, value: sortKey, onChange: (e) => handleSortChange(e.target.value), children: sortOptions.map(option => (jsx(CwOption, { value: option.key, children: option.label }, option.key))) }) })), isLoading ? (jsx("div", { className: `${styles$s.cardContainer}`, "data-layout": layout, style: gridStyle, "aria-busy": true, children: Array.from({ length: normalizeSkeletonCount(skeletonCards, 6) }, (_, index) => (jsx(CwCard, { isLoading: true, children: null }, `skeleton_${index}`))) })) : sortedItems.length === 0 ? (jsx("div", { className: styles$s.emptyState, children: emptyState || jsx("p", { children: "No items to display" }) })) : (jsxs(Fragment, { children: [jsx("div", { className: `${styles$s.cardContainer}`, "data-layout": layout, style: gridStyle, children: visibleItems.map((item, index) => (jsx(React__default.Fragment, { children: renderCard(item, index) }, keyExtractor ? keyExtractor(item, index) : index))) }), totalPages > 1 && (jsxs("div", { className: styles$s.pagination, children: [jsx(CwButton, { variant: "icon", icon: "chevron-left", disabled: currentPage === 1, onClick: () => setCurrentPage(p => Math.max(1, p - 1)) }), jsxs("span", { className: styles$s.pageInfo, children: [currentPage, " / ", totalPages] }), jsx(CwButton, { variant: "icon", icon: "chevron-right", disabled: currentPage === totalPages, onClick: () => setCurrentPage(p => Math.min(totalPages, p + 1)) })] }))] }))] }));
2085
+ }, value: sortKey, onChange: (e) => handleSortChange(e.target.value), children: sortOptions.map(option => (jsx(CwOption, { value: option.key, children: option.label }, option.key))) }) })), isLoading ? (jsx("div", { className: `${styles$v.cardContainer}`, "data-layout": layout, style: gridStyle, "aria-busy": true, children: Array.from({ length: normalizeSkeletonCount(skeletonCards, 6) }, (_, index) => (jsx(CwCard, { isLoading: true, children: null }, `skeleton_${index}`))) })) : sortedItems.length === 0 ? (jsx("div", { className: styles$v.emptyState, children: emptyState || jsx("p", { children: "No items to display" }) })) : (jsxs(Fragment, { children: [jsx("div", { className: `${styles$v.cardContainer}`, "data-layout": layout, style: gridStyle, children: visibleItems.map((item, index) => (jsx(React__default.Fragment, { children: renderCard(item, index) }, keyExtractor ? keyExtractor(item, index) : index))) }), totalPages > 1 && (jsxs("div", { className: styles$v.pagination, children: [jsx(CwButton, { variant: "icon", icon: "chevron-left", disabled: currentPage === 1, onClick: () => setCurrentPage(p => Math.max(1, p - 1)) }), jsxs("span", { className: styles$v.pageInfo, children: [currentPage, " / ", totalPages] }), jsx(CwButton, { variant: "icon", icon: "chevron-right", disabled: currentPage === totalPages, onClick: () => setCurrentPage(p => Math.min(totalPages, p + 1)) })] }))] }))] }));
2086
2086
  }
2087
2087
 
2088
- var styles$r = {"cw-accordion":"cw-accordion-module__cw-accordion__ErvlW","cw-accordion-body":"cw-accordion-module__cw-accordion-body__xlI8b"};
2088
+ var styles$u = {"cw-accordion":"cw-accordion-module__cw-accordion__ErvlW","cw-accordion-body":"cw-accordion-module__cw-accordion-body__xlI8b"};
2089
2089
 
2090
2090
  /**
2091
2091
  * Legacy collapsible section with its own header markup.
@@ -2100,7 +2100,7 @@ function CwAccordionContainer(CwelltAccordionContainerProps) {
2100
2100
  setVisible_accordionBody(!isVisible_accordionBody);
2101
2101
  };
2102
2102
  // #endregion
2103
- return (jsxs("div", { className: styles$r["cw-accordion"], style: CwelltAccordionContainerProps.style, "data-open": isVisible_accordionBody, children: [jsxs("header", { onClick: () => showAccordionBody(), children: [jsx("div", { children: CwelltAccordionContainerProps.desc_text }), jsx("button", { className: "cw-button-icon" })] }), jsx("div", { className: styles$r["cw-accordion-body"], children: CwelltAccordionContainerProps.children })] }));
2103
+ return (jsxs("div", { className: styles$u["cw-accordion"], style: CwelltAccordionContainerProps.style, "data-open": isVisible_accordionBody, children: [jsxs("header", { onClick: () => showAccordionBody(), children: [jsx("div", { children: CwelltAccordionContainerProps.desc_text }), jsx("button", { className: "cw-button-icon" })] }), jsx("div", { className: styles$u["cw-accordion-body"], children: CwelltAccordionContainerProps.children })] }));
2104
2104
  }
2105
2105
 
2106
2106
  /*
@@ -2379,7 +2379,7 @@ function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10,
2379
2379
  }, min: 1, max: totalPages }), jsx("span", { children: "/" }), jsx("span", { children: totalPages }), jsx(CwButton, { onClick: () => handlePageChange(page + 1), disabled: page === totalPages || totalPages <= 1, variant: "icon", icon: "chevron-right" }), jsx(CwButton, { onClick: () => handlePageChange(totalPages), disabled: page === totalPages || totalPages <= 1, variant: "icon", icon: "chevron-right-double" })] })] }))] }));
2380
2380
  }
2381
2381
 
2382
- var styles$q = {"dropIndicator":"cw-sortable-table-module__dropIndicator__ov-Jz","dragging":"cw-sortable-table-module__dragging__MrLrz","saveBar":"cw-sortable-table-module__saveBar__3OdoZ cw-flex-row cw-align-center-center cw-gap-small"};
2382
+ var styles$t = {"dropIndicator":"cw-sortable-table-module__dropIndicator__ov-Jz","dragging":"cw-sortable-table-module__dragging__MrLrz","saveBar":"cw-sortable-table-module__saveBar__3OdoZ cw-flex-row cw-align-center-center cw-gap-small"};
2383
2383
 
2384
2384
  /**
2385
2385
  * Hook that provides state management for CwSortableTable.
@@ -2442,7 +2442,7 @@ function useSortableTable(initialItems) {
2442
2442
  }
2443
2443
 
2444
2444
  // ─── Drop indicator row ───────────────────────────────────────────────────────
2445
- const DropIndicatorRow = ({ colSpan }) => (jsx("tr", { className: styles$q.dropIndicator, "aria-hidden": true, children: jsx("td", { colSpan: colSpan, children: jsx("div", {}) }) }));
2445
+ const DropIndicatorRow = ({ colSpan }) => (jsx("tr", { className: styles$t.dropIndicator, "aria-hidden": true, children: jsx("td", { colSpan: colSpan, children: jsx("div", {}) }) }));
2446
2446
  // ─── Loading skeleton ─────────────────────────────────────────────────────────
2447
2447
  // Plain td cells (no local class): the ghost cells get the same global cw-table
2448
2448
  // padding as real body cells, so row heights match the loaded rows exactly.
@@ -2545,11 +2545,11 @@ function CwSortableTable({ columns, data, rowKey = "key", onReorder, loading = f
2545
2545
  return items.map((item, index) => {
2546
2546
  const key = item[rowKey];
2547
2547
  const isDragging = draggedItem?.[rowKey] === key;
2548
- return (jsxs(React__default.Fragment, { children: [dropIndicatorIndex === index && (jsx(DropIndicatorRow, { colSpan: totalCols })), jsxs("tr", { draggable: true, onDragStart: (e) => handleDragStart(e, item), onDragOver: (e) => handleDragOver(e, index), onDragEnd: handleDragEnd, className: isDragging ? styles$q.dragging : "", children: [showHandle && (jsx("td", { className: "cw-table-col-action", children: jsx(CwIcon, { iconId: "grip-dots", color: "neutral", style: { opacity: 0.75 } }) })), columns.map(col => (jsx("td", { className: col.className ?? "", style: col.width ? { width: col.width } : undefined, children: renderCell(item, col) }, `${String(key)}_${col.key}`)))] }), index === items.length - 1 && dropIndicatorIndex === items.length && (jsx(DropIndicatorRow, { colSpan: totalCols }))] }, String(key)));
2548
+ return (jsxs(React__default.Fragment, { children: [dropIndicatorIndex === index && (jsx(DropIndicatorRow, { colSpan: totalCols })), jsxs("tr", { draggable: true, onDragStart: (e) => handleDragStart(e, item), onDragOver: (e) => handleDragOver(e, index), onDragEnd: handleDragEnd, className: isDragging ? styles$t.dragging : "", children: [showHandle && (jsx("td", { className: "cw-table-col-action", children: jsx(CwIcon, { iconId: "grip-dots", color: "neutral", style: { opacity: 0.75 } }) })), columns.map(col => (jsx("td", { className: col.className ?? "", style: col.width ? { width: col.width } : undefined, children: renderCell(item, col) }, `${String(key)}_${col.key}`)))] }), index === items.length - 1 && dropIndicatorIndex === items.length && (jsx(DropIndicatorRow, { colSpan: totalCols }))] }, String(key)));
2549
2549
  });
2550
2550
  };
2551
2551
  // ── Render ──────────────────────────────────────────────────────────────
2552
- return (jsxs("div", { className: `cw-table-container ${className ?? ""}`, style: containerStyle, "aria-busy": loading || undefined, children: [jsxs("table", { className: `cw-table cw-sortable-table ${tableClassName ?? ""}`, style: { width: "100%" }, children: [jsx("thead", { children: jsxs("tr", { children: [showHandle && jsx("th", { className: "cw-table-col-action" }), columns.map(col => (jsx("th", { className: col.className ?? "", style: col.width ? { width: col.width, minWidth: 50 } : undefined, children: col.title }, col.key)))] }) }), jsx("tbody", { children: renderBody() })] }), !loading && hasChanges && (jsxs("footer", { className: styles$q.saveBar, children: [jsx(CwButton, { variant: "outline", color: "neutral", icon: "undo", text: discardLabel, onClick: handleDiscard }), jsx(CwButton, { variant: "solid", color: "primary", icon: "save", text: saveLabel, onClick: () => handleSave(onReorder) })] }))] }));
2552
+ return (jsxs("div", { className: `cw-table-container ${className ?? ""}`, style: containerStyle, "aria-busy": loading || undefined, children: [jsxs("table", { className: `cw-table cw-sortable-table ${tableClassName ?? ""}`, style: { width: "100%" }, children: [jsx("thead", { children: jsxs("tr", { children: [showHandle && jsx("th", { className: "cw-table-col-action" }), columns.map(col => (jsx("th", { className: col.className ?? "", style: col.width ? { width: col.width, minWidth: 50 } : undefined, children: col.title }, col.key)))] }) }), jsx("tbody", { children: renderBody() })] }), !loading && hasChanges && (jsxs("footer", { className: styles$t.saveBar, children: [jsx(CwButton, { variant: "outline", color: "neutral", icon: "undo", text: discardLabel, onClick: handleDiscard }), jsx(CwButton, { variant: "solid", color: "primary", icon: "save", text: saveLabel, onClick: () => handleSave(onReorder) })] }))] }));
2553
2553
  }
2554
2554
 
2555
2555
  /**
@@ -2750,7 +2750,7 @@ function CwTableServerSide({ columns, data, totalItems, pagination = false, page
2750
2750
  }, min: 1, max: totalPages }), jsx("span", { children: "/" }), jsx("span", { children: totalPages }), jsx(CwButton, { onClick: () => handlePageChange(state.page + 1), disabled: state.page === totalPages || totalPages <= 1, variant: "icon", icon: "chevron-right" }), jsx(CwButton, { onClick: () => handlePageChange(totalPages), disabled: state.page === totalPages || totalPages <= 1, variant: "icon", icon: "chevron-right-double" })] })] }))] }));
2751
2751
  }
2752
2752
 
2753
- var styles$p = {"cw-tabs":"cw-tabs-module__cw-tabs__1pmji","cw-tabs-content":"cw-tabs-module__cw-tabs-content__HTp8d"};
2753
+ var styles$s = {"cw-tabs":"cw-tabs-module__cw-tabs__1pmji","cw-tabs-content":"cw-tabs-module__cw-tabs-content__HTp8d"};
2754
2754
 
2755
2755
  const BADGE_COLOR_SCHEMES = ['primary', 'danger', 'warning', 'success', 'info', 'neutral'];
2756
2756
  function isBadgeColorScheme(value) {
@@ -2804,11 +2804,11 @@ function CwTabs(CwTabsProps) {
2804
2804
  const tabsListStyle = position === 'left' && CwTabsProps.tabsListWidth
2805
2805
  ? { minWidth: CwTabsProps.tabsListWidth }
2806
2806
  : undefined;
2807
- return (jsxs("div", { id: CwTabsProps.id, "data-testid": CwTabsProps.testId, className: styles$p['cw-tabs'] + (CwTabsProps.className ? ` ${CwTabsProps.className}` : "") + "", style: CwTabsProps.style, "data-tabs-position": position, children: [jsx("ul", { style: tabsListStyle, children: CwTabsProps.tabs.map(tab => {
2807
+ return (jsxs("div", { id: CwTabsProps.id, "data-testid": CwTabsProps.testId, className: styles$s['cw-tabs'] + (CwTabsProps.className ? ` ${CwTabsProps.className}` : "") + "", style: CwTabsProps.style, "data-tabs-position": position, children: [jsx("ul", { style: tabsListStyle, children: CwTabsProps.tabs.map(tab => {
2808
2808
  const badgeScheme = tab.badgeColor && isBadgeColorScheme(tab.badgeColor) ? tab.badgeColor : undefined;
2809
2809
  const rawBadgeColor = tab.badgeColor && !badgeScheme ? tab.badgeColor : undefined;
2810
2810
  return (jsxs("li", { className: `${tab.key === activeTab ? "cw-tab-active" : ""}`, onClick: () => handleTabClick(tab), "data-active": tab.key === activeTab, "data-tab-key": tab.key, "data-badge-themed": tab.badgeColor ? "true" : undefined, children: [jsx(TabIcon, { icon: tab.icon }), tab.title, (tab.badge !== undefined || tab.badgeColor) && (jsx(CwBadge, { count: typeof tab.badge === 'number' ? tab.badge : undefined, content: typeof tab.badge === 'string' ? tab.badge : undefined, size: "medium", color: badgeScheme ?? 'primary', variant: badgeScheme ? 'solid' : 'soft', style: rawBadgeColor ? { backgroundColor: rawBadgeColor, color: getContrastColor(rawBadgeColor) } : undefined }))] }, tab.key));
2811
- }) }), jsx("div", { className: styles$p['cw-tabs-content'], "data-active-tab-key": activeTab ?? undefined, style: CwTabsProps.contentHeight ? { '--tabs-height': CwTabsProps.contentHeight } : undefined, children: activeTab !== null && CwTabsProps.tabs.find(tab => tab.key === activeTab)?.content })] }));
2811
+ }) }), jsx("div", { className: styles$s['cw-tabs-content'], "data-active-tab-key": activeTab ?? undefined, style: CwTabsProps.contentHeight ? { '--tabs-height': CwTabsProps.contentHeight } : undefined, children: activeTab !== null && CwTabsProps.tabs.find(tab => tab.key === activeTab)?.content })] }));
2812
2812
  }
2813
2813
 
2814
2814
  /**
@@ -2836,7 +2836,7 @@ const CwExpandable = ({ briefing, onToggle, onOpen, onClose, children, ...detail
2836
2836
  return (jsxs("details", { ref: myRef, ...detailsProps, className: "cw-expandable", children: [jsx("summary", { children: briefing }), children && jsx("section", { children: children })] }));
2837
2837
  };
2838
2838
 
2839
- var styles$o = {"cw-master-detail":"cw-master-detail-module__cw-master-detail__O8-FA","resizer":"cw-master-detail-module__resizer__hvGhL","detail":"cw-master-detail-module__detail__BG4Dm","skeletonRow":"cw-master-detail-module__skeletonRow__6BUgt","detailSkeleton":"cw-master-detail-module__detailSkeleton__GcDS4","detail-empty":"cw-master-detail-module__detail-empty__KFScK"};
2839
+ var styles$r = {"cw-master-detail":"cw-master-detail-module__cw-master-detail__O8-FA","resizer":"cw-master-detail-module__resizer__hvGhL","detail":"cw-master-detail-module__detail__BG4Dm","skeletonRow":"cw-master-detail-module__skeletonRow__6BUgt","detailSkeleton":"cw-master-detail-module__detailSkeleton__GcDS4","detail-empty":"cw-master-detail-module__detail-empty__KFScK"};
2840
2840
 
2841
2841
  /*
2842
2842
  * Fixed rem widths for the ghosts: the master rows and detail panel size their
@@ -2880,12 +2880,12 @@ const CwMasterDetail = ({ id, className, style, items, selectedKey, onSelect, de
2880
2880
  document.body.style.userSelect = '';
2881
2881
  };
2882
2882
  }, [isResizing, minMasterWidth, maxMasterWidth]);
2883
- const rootClassName = [styles$o['cw-master-detail'], className].filter(Boolean).join(' ');
2883
+ const rootClassName = [styles$r['cw-master-detail'], className].filter(Boolean).join(' ');
2884
2884
  return (jsxs("div", { id: id, ref: containerRef, className: rootClassName, style: style, "aria-busy": loading || undefined, children: [jsxs("aside", { style: { width: masterWidth, minWidth: masterWidth }, children: [showSearch && (jsx("search", { children: jsx("input", { type: "text", placeholder: searchPlaceholder, onChange: (e) => onSearch?.(e.target.value) }) })), masterHeader && (jsx("header", { children: masterHeader })), jsx("ul", { children: loading
2885
- ? Array.from({ length: skeletonRows }, (_unused, rowIndex) => (jsxs("li", { "aria-hidden": "true", children: [jsx(CwSkeleton, { variant: "circle", height: "2rem" }), jsxs("div", { className: styles$o.skeletonRow, children: [jsx(CwSkeleton, { variant: "text", width: MASTER_TITLE_WIDTHS[rowIndex % MASTER_TITLE_WIDTHS.length] }), jsx(CwSkeleton, { variant: "text", width: MASTER_SUBTITLE_WIDTH })] })] }, `skeleton_${rowIndex}`)))
2886
- : items.map((item) => (jsx("li", { "data-master-key": item.key, "data-selected": item.key === selectedKey, "data-disabled": item.disabled, onClick: () => onSelect?.(item.key), children: item.content }, item.key))) }), masterFooter && (jsx("footer", { children: masterFooter }))] }), resizable && (jsx("div", { className: styles$o.resizer, "data-resizing": isResizing, onMouseDown: handleMouseDown })), jsx("section", { className: styles$o.detail, children: loading ? (jsxs("div", { className: styles$o.detailSkeleton, "aria-hidden": "true", children: [jsx(CwSkeleton, { variant: "text", width: "14rem", height: "1.5em" }), jsx(CwSkeleton, { variant: "text", width: "22rem" }), jsx(CwSkeleton, { variant: "text", width: "18rem" }), jsx(CwSkeleton, { variant: "text", width: "20rem" })] })) : selectedKey && detailContent
2885
+ ? Array.from({ length: skeletonRows }, (_unused, rowIndex) => (jsxs("li", { "aria-hidden": "true", children: [jsx(CwSkeleton, { variant: "circle", height: "2rem" }), jsxs("div", { className: styles$r.skeletonRow, children: [jsx(CwSkeleton, { variant: "text", width: MASTER_TITLE_WIDTHS[rowIndex % MASTER_TITLE_WIDTHS.length] }), jsx(CwSkeleton, { variant: "text", width: MASTER_SUBTITLE_WIDTH })] })] }, `skeleton_${rowIndex}`)))
2886
+ : items.map((item) => (jsx("li", { "data-master-key": item.key, "data-selected": item.key === selectedKey, "data-disabled": item.disabled, onClick: () => onSelect?.(item.key), children: item.content }, item.key))) }), masterFooter && (jsx("footer", { children: masterFooter }))] }), resizable && (jsx("div", { className: styles$r.resizer, "data-resizing": isResizing, onMouseDown: handleMouseDown })), jsx("section", { className: styles$r.detail, children: loading ? (jsxs("div", { className: styles$r.detailSkeleton, "aria-hidden": "true", children: [jsx(CwSkeleton, { variant: "text", width: "14rem", height: "1.5em" }), jsx(CwSkeleton, { variant: "text", width: "22rem" }), jsx(CwSkeleton, { variant: "text", width: "18rem" }), jsx(CwSkeleton, { variant: "text", width: "20rem" })] })) : selectedKey && detailContent
2887
2887
  ? detailContent
2888
- : (jsx("div", { className: styles$o['detail-empty'], children: emptyDetail ?? 'Select an item to view details' })) })] }));
2888
+ : (jsx("div", { className: styles$r['detail-empty'], children: emptyDetail ?? 'Select an item to view details' })) })] }));
2889
2889
  };
2890
2890
 
2891
2891
  /*
@@ -2925,7 +2925,7 @@ const CwKeyValueList = ({ items, className = "", emptyValue = "-", direction = "
2925
2925
  return (jsx("dl", { className: `cw-keyvalue-list ${className}`, "data-direction": groupLayout?.direction, "data-align": groupLayout?.align, "data-justify": groupLayout?.justify, "data-gap": groupLayout?.gap, "aria-busy": loading || undefined, ...htmlProps, children: renderItems() }));
2926
2926
  };
2927
2927
 
2928
- var styles$n = {"sortableList":"cw-sortable-list-module__sortableList__PyLO-","sortableItem":"cw-sortable-list-module__sortableItem__FAnn2","readOnly":"cw-sortable-list-module__readOnly__r7GcH","dragging":"cw-sortable-list-module__dragging__MD715","moved":"cw-sortable-list-module__moved__sE6-N","expandedContent":"cw-sortable-list-module__expandedContent__Kocna","sortableHandle":"cw-sortable-list-module__sortableHandle__HvYBK","sortableContent":"cw-sortable-list-module__sortableContent__C6JhR","sortableTitle":"cw-sortable-list-module__sortableTitle__EgWXr","sortableExtraContent":"cw-sortable-list-module__sortableExtraContent__s4LSv","sortableActions":"cw-sortable-list-module__sortableActions__gwQOU","dropIndicator":"cw-sortable-list-module__dropIndicator__MNSF-","emptyMessage":"cw-sortable-list-module__emptyMessage__gMpaL"};
2928
+ var styles$q = {"sortableList":"cw-sortable-list-module__sortableList__PyLO-","sortableItem":"cw-sortable-list-module__sortableItem__FAnn2","readOnly":"cw-sortable-list-module__readOnly__r7GcH","dragging":"cw-sortable-list-module__dragging__MD715","moved":"cw-sortable-list-module__moved__sE6-N","expandedContent":"cw-sortable-list-module__expandedContent__Kocna","sortableHandle":"cw-sortable-list-module__sortableHandle__HvYBK","sortableContent":"cw-sortable-list-module__sortableContent__C6JhR","sortableTitle":"cw-sortable-list-module__sortableTitle__EgWXr","sortableExtraContent":"cw-sortable-list-module__sortableExtraContent__s4LSv","sortableActions":"cw-sortable-list-module__sortableActions__gwQOU","dropIndicator":"cw-sortable-list-module__dropIndicator__MNSF-","emptyMessage":"cw-sortable-list-module__emptyMessage__gMpaL"};
2929
2929
 
2930
2930
  function CwSortableList({ items, onReorder, renderItem, className = '', movedItems = new Set(), emptyMessage = "No elements to show", readOnly = false, maxHeight = "300px", }) {
2931
2931
  const [draggedItem, setDraggedItem] = useState(null);
@@ -2988,15 +2988,15 @@ function CwSortableList({ items, onReorder, renderItem, className = '', movedIte
2988
2988
  }
2989
2989
  };
2990
2990
  if (items.length === 0) {
2991
- return (jsx("div", { className: `${styles$n.sortableList} ${styles$n.emptyState} ${className}`, children: jsx("div", { className: styles$n.emptyMessage, children: emptyMessage }) }));
2991
+ return (jsx("div", { className: `${styles$q.sortableList} ${styles$q.emptyState} ${className}`, children: jsx("div", { className: styles$q.emptyMessage, children: emptyMessage }) }));
2992
2992
  }
2993
- return (jsx("div", { className: `${styles$n.sortableList} ${className}`, style: { maxHeight }, children: items.map((item, index) => {
2993
+ return (jsx("div", { className: `${styles$q.sortableList} ${className}`, style: { maxHeight }, children: items.map((item, index) => {
2994
2994
  const { title, extraContent, actions, showHandle = true, expandedContent } = renderItem(item);
2995
2995
  const isDragging = draggedItem?.id === item.id;
2996
2996
  const isMoved = movedItems.has(item.id);
2997
2997
  const canExpand = Boolean(expandedContent);
2998
2998
  const isExpanded = expandedItems.has(item.id);
2999
- return (jsxs(React__default.Fragment, { children: [dropIndicatorIndex === index && jsx("div", { className: styles$n.dropIndicator }), jsxs("div", { className: `${styles$n.sortableItem} ${isDragging ? styles$n.dragging : ''} ${isMoved ? styles$n.moved : ''} ${readOnly ? styles$n.readOnly : ''}`, draggable: !readOnly, onDragStart: (e) => handleDragStart(e, item), onDragOver: (e) => handleDragOver(e, index), onDragEnd: handleDragEnd, children: [jsxs("header", { children: [canExpand ? (jsx(CwButton, { variant: "icon", onClick: () => toggleExpanded(item.id), type: "button", title: isExpanded ? "Collapse" : "Expand", icon: isExpanded ? "chevron-up" : "chevron-down" })) : showHandle ? (jsx("div", { className: styles$n.sortableHandle, children: jsx(CwIcon, { iconId: "grip-dots" }) })) : null, jsxs("div", { className: styles$n.sortableContent, children: [jsx("div", { className: styles$n.sortableTitle, children: title }), extraContent && jsx("div", { className: styles$n.sortableExtraContent, children: extraContent })] }), jsx("div", { className: styles$n.sortableActions, children: actions })] }), isExpanded && expandedContent && (jsx("div", { className: styles$n.expandedContent, children: expandedContent }))] }), !readOnly && dropIndicatorIndex === items.length && index === items.length - 1 && (jsx("div", { className: styles$n.dropIndicator }))] }, item.id));
2999
+ return (jsxs(React__default.Fragment, { children: [dropIndicatorIndex === index && jsx("div", { className: styles$q.dropIndicator }), jsxs("div", { className: `${styles$q.sortableItem} ${isDragging ? styles$q.dragging : ''} ${isMoved ? styles$q.moved : ''} ${readOnly ? styles$q.readOnly : ''}`, draggable: !readOnly, onDragStart: (e) => handleDragStart(e, item), onDragOver: (e) => handleDragOver(e, index), onDragEnd: handleDragEnd, children: [jsxs("header", { children: [canExpand ? (jsx(CwButton, { variant: "icon", onClick: () => toggleExpanded(item.id), type: "button", title: isExpanded ? "Collapse" : "Expand", icon: isExpanded ? "chevron-up" : "chevron-down" })) : showHandle ? (jsx("div", { className: styles$q.sortableHandle, children: jsx(CwIcon, { iconId: "grip-dots" }) })) : null, jsxs("div", { className: styles$q.sortableContent, children: [jsx("div", { className: styles$q.sortableTitle, children: title }), extraContent && jsx("div", { className: styles$q.sortableExtraContent, children: extraContent })] }), jsx("div", { className: styles$q.sortableActions, children: actions })] }), isExpanded && expandedContent && (jsx("div", { className: styles$q.expandedContent, children: expandedContent }))] }), !readOnly && dropIndicatorIndex === items.length && index === items.length - 1 && (jsx("div", { className: styles$q.dropIndicator }))] }, item.id));
3000
3000
  }) }));
3001
3001
  }
3002
3002
 
@@ -3123,7 +3123,7 @@ const CwTableGrouped = props => {
3123
3123
  group.rows.map((child, j) => (jsx("tr", { "data-row": true, "data-row-last-of-group": j == group.rows.length - 1, children: child.cells.map((cell, k) => (jsx("td", { children: cell.content }, k))) }, j)))] }, i))) }), jsx("tfoot", {})] }) }));
3124
3124
  };
3125
3125
 
3126
- var styles$m = {"fileUploadContainer":"cw-file-upload-multiple-module__fileUploadContainer__liEc1","hiddenInput":"cw-file-upload-multiple-module__hiddenInput__TZBBI","uploadArea":"cw-file-upload-multiple-module__uploadArea__DdOhs","uploadAreaDisabled":"cw-file-upload-multiple-module__uploadAreaDisabled__VWeFX","uploadTitle":"cw-file-upload-multiple-module__uploadTitle__gjRk8","uploadSubtitle":"cw-file-upload-multiple-module__uploadSubtitle__Z0S5t","filesContainer":"cw-file-upload-multiple-module__filesContainer__g44PY","fileItem":"cw-file-upload-multiple-module__fileItem__w27Dg","fileIcon":"cw-file-upload-multiple-module__fileIcon__iJJUX","fileExtension":"cw-file-upload-multiple-module__fileExtension__vOuHv","fileInfo":"cw-file-upload-multiple-module__fileInfo__R5ZTv","fileName":"cw-file-upload-multiple-module__fileName__DjepK","fileSize":"cw-file-upload-multiple-module__fileSize__b8GSm","smallButton":"cw-file-upload-multiple-module__smallButton__siUAh"};
3126
+ var styles$p = {"fileUploadContainer":"cw-file-upload-multiple-module__fileUploadContainer__liEc1","hiddenInput":"cw-file-upload-multiple-module__hiddenInput__TZBBI","uploadArea":"cw-file-upload-multiple-module__uploadArea__DdOhs","uploadAreaDisabled":"cw-file-upload-multiple-module__uploadAreaDisabled__VWeFX","uploadTitle":"cw-file-upload-multiple-module__uploadTitle__gjRk8","uploadSubtitle":"cw-file-upload-multiple-module__uploadSubtitle__Z0S5t","filesContainer":"cw-file-upload-multiple-module__filesContainer__g44PY","fileItem":"cw-file-upload-multiple-module__fileItem__w27Dg","fileIcon":"cw-file-upload-multiple-module__fileIcon__iJJUX","fileExtension":"cw-file-upload-multiple-module__fileExtension__vOuHv","fileInfo":"cw-file-upload-multiple-module__fileInfo__R5ZTv","fileName":"cw-file-upload-multiple-module__fileName__DjepK","fileSize":"cw-file-upload-multiple-module__fileSize__b8GSm","smallButton":"cw-file-upload-multiple-module__smallButton__siUAh"};
3127
3127
 
3128
3128
  const DEFAULT_LABELS$1 = {
3129
3129
  uploadDisabled: 'Upload disabled',
@@ -3309,12 +3309,12 @@ function CwFileUploadMultiple(fileUploadProps) {
3309
3309
  }
3310
3310
  }
3311
3311
  };
3312
- return (jsxs("div", { className: `${styles$m.fileUploadContainer} ${fileUploadProps.className}`, children: [jsx("input", { ref: fileInputRef, type: "file", name: fileUploadProps.name, accept: fileUploadProps.accept, multiple: fileUploadProps.multiple, onChange: handleFileSelectInternal, disabled: fileUploadProps.disabled, "aria-label": "files", className: styles$m.hiddenInput }), selectedFiles.length === 0 && !existingFile ? (jsxs("div", { className: `${styles$m.uploadArea} ${fileUploadProps.disabled ? styles$m.uploadAreaDisabled : ''}`, onDragOver: handleDragOver, onDrop: handleDrop, onClick: !fileUploadProps.disabled ? handleButtonClick : undefined, children: [jsx(CwIcon, { iconId: "upload" }), jsx("p", { className: `${styles$m.uploadTitle}`, children: fileUploadProps.disabled ? labels.uploadDisabled : labels.clickToUpload }), jsxs("p", { className: `${styles$m.uploadSubtitle}`, children: [fileUploadProps.accept ? labels.acceptedFiles(fileUploadProps.accept) : labels.allTypesAccepted, !fileUploadProps.multiple && ` ${labels.singleFileOnly}`] })] })) : selectedFiles.length === 0 && existingFile ? (jsxs("div", { className: styles$m.filesContainer, children: [jsxs("div", { className: styles$m.fileItem, children: [jsxs("div", { className: styles$m.fileIcon, children: [jsx(CwIcon, { iconId: "page" }), jsx("span", { className: styles$m.fileExtension, children: getFileExtension(existingFile) })] }), jsx("div", { className: styles$m.fileInfo, children: jsx("p", { className: styles$m.fileName, children: existingFile }) }), jsx(CwButton, { variant: "icon", icon: "close", color: "neutral", onClick: () => {
3312
+ return (jsxs("div", { className: `${styles$p.fileUploadContainer} ${fileUploadProps.className}`, children: [jsx("input", { ref: fileInputRef, type: "file", name: fileUploadProps.name, accept: fileUploadProps.accept, multiple: fileUploadProps.multiple, onChange: handleFileSelectInternal, disabled: fileUploadProps.disabled, "aria-label": "files", className: styles$p.hiddenInput }), selectedFiles.length === 0 && !existingFile ? (jsxs("div", { className: `${styles$p.uploadArea} ${fileUploadProps.disabled ? styles$p.uploadAreaDisabled : ''}`, onDragOver: handleDragOver, onDrop: handleDrop, onClick: !fileUploadProps.disabled ? handleButtonClick : undefined, children: [jsx(CwIcon, { iconId: "upload" }), jsx("p", { className: `${styles$p.uploadTitle}`, children: fileUploadProps.disabled ? labels.uploadDisabled : labels.clickToUpload }), jsxs("p", { className: `${styles$p.uploadSubtitle}`, children: [fileUploadProps.accept ? labels.acceptedFiles(fileUploadProps.accept) : labels.allTypesAccepted, !fileUploadProps.multiple && ` ${labels.singleFileOnly}`] })] })) : selectedFiles.length === 0 && existingFile ? (jsxs("div", { className: styles$p.filesContainer, children: [jsxs("div", { className: styles$p.fileItem, children: [jsxs("div", { className: styles$p.fileIcon, children: [jsx(CwIcon, { iconId: "page" }), jsx("span", { className: styles$p.fileExtension, children: getFileExtension(existingFile) })] }), jsx("div", { className: styles$p.fileInfo, children: jsx("p", { className: styles$p.fileName, children: existingFile }) }), jsx(CwButton, { variant: "icon", icon: "close", color: "neutral", onClick: () => {
3313
3313
  setExistingFile(undefined);
3314
3314
  if (fileUploadProps.onSelect) {
3315
3315
  fileUploadProps.onSelect(null);
3316
3316
  }
3317
- }, disabled: fileUploadProps.disabled, className: styles$m.smallButton })] }), jsx(CwButton, { text: labels.changeFile, icon: "refresh", onClick: handleButtonClick, disabled: fileUploadProps.disabled })] })) : (jsxs("div", { className: styles$m.filesContainer, children: [jsxs("header", { className: "cw-flex-row cw-align-between-center cw-flex-wrap", children: [jsx("small", { className: styles$m.filesCount, children: fileUploadProps.statusText ?? labels.filesSelected(selectedFiles.length) }), jsxs("div", { className: "cw-flex-row", children: [fileUploadProps.onConfirm && selectedFiles.length > 0 && (jsx(CwButton, { onClick: () => {
3317
+ }, disabled: fileUploadProps.disabled, className: styles$p.smallButton })] }), jsx(CwButton, { text: labels.changeFile, icon: "refresh", onClick: handleButtonClick, disabled: fileUploadProps.disabled })] })) : (jsxs("div", { className: styles$p.filesContainer, children: [jsxs("header", { className: "cw-flex-row cw-align-between-center cw-flex-wrap", children: [jsx("small", { className: styles$p.filesCount, children: fileUploadProps.statusText ?? labels.filesSelected(selectedFiles.length) }), jsxs("div", { className: "cw-flex-row", children: [fileUploadProps.onConfirm && selectedFiles.length > 0 && (jsx(CwButton, { onClick: () => {
3318
3318
  let files = fileInputRef.current?.files ?? null;
3319
3319
  if (!files) {
3320
3320
  const dataTransfer = new DataTransfer();
@@ -3322,7 +3322,7 @@ function CwFileUploadMultiple(fileUploadProps) {
3322
3322
  files = dataTransfer.files;
3323
3323
  }
3324
3324
  fileUploadProps.onConfirm?.(files);
3325
- }, disabled: fileUploadProps.disabled || fileUploadProps.confirmDisabled, icon: "upload", text: fileUploadProps.confirmLabel ?? labels.upload })), !fileUploadProps.hideClearAll && (jsx(CwButton, { onClick: removeAllFiles, disabled: fileUploadProps.disabled, color: "danger", variant: "outline", icon: "delete", text: labels.clearAll }))] })] }), selectedFiles.map((file, index) => (jsxs("div", { className: styles$m.fileItem, children: [jsxs("div", { className: styles$m.fileIcon, children: [jsx(CwIcon, { iconId: "page" }), jsx("span", { className: styles$m.fileExtension, children: getFileExtension(file.name) })] }), jsxs("div", { className: styles$m.fileInfo, children: [jsx("p", { className: styles$m.fileName, children: file.name }), jsxs("p", { className: styles$m.fileSize, children: [(file.size / 1024).toFixed(1), " KB"] })] }), jsx(CwButton, { variant: "icon", icon: "close", color: "neutral", onClick: () => removeFile(index), className: styles$m.smallButton })] }, `${file.name}-${file.size}`))), fileUploadProps.multiple && (jsx(CwButton, { text: labels.addMoreFiles, icon: "plus", variant: "outline", onClick: handleButtonClick, disabled: fileUploadProps.disabled })), !fileUploadProps.multiple && (jsx(CwButton, { text: labels.changeFile, icon: "refresh", onClick: handleButtonClick, disabled: fileUploadProps.disabled }))] }))] }));
3325
+ }, disabled: fileUploadProps.disabled || fileUploadProps.confirmDisabled, icon: "upload", text: fileUploadProps.confirmLabel ?? labels.upload })), !fileUploadProps.hideClearAll && (jsx(CwButton, { onClick: removeAllFiles, disabled: fileUploadProps.disabled, color: "danger", variant: "outline", icon: "delete", text: labels.clearAll }))] })] }), selectedFiles.map((file, index) => (jsxs("div", { className: styles$p.fileItem, children: [jsxs("div", { className: styles$p.fileIcon, children: [jsx(CwIcon, { iconId: "page" }), jsx("span", { className: styles$p.fileExtension, children: getFileExtension(file.name) })] }), jsxs("div", { className: styles$p.fileInfo, children: [jsx("p", { className: styles$p.fileName, children: file.name }), jsxs("p", { className: styles$p.fileSize, children: [(file.size / 1024).toFixed(1), " KB"] })] }), jsx(CwButton, { variant: "icon", icon: "close", color: "neutral", onClick: () => removeFile(index), className: styles$p.smallButton })] }, `${file.name}-${file.size}`))), fileUploadProps.multiple && (jsx(CwButton, { text: labels.addMoreFiles, icon: "plus", variant: "outline", onClick: handleButtonClick, disabled: fileUploadProps.disabled })), !fileUploadProps.multiple && (jsx(CwButton, { text: labels.changeFile, icon: "refresh", onClick: handleButtonClick, disabled: fileUploadProps.disabled }))] }))] }));
3326
3326
  }
3327
3327
 
3328
3328
  /**
@@ -3375,7 +3375,7 @@ function CwDigit(props) {
3375
3375
  return (jsxs("div", { className: "cw-input-text", "data-direction": labelProps ? flexDirection : "column", "data-feedback-position": feedbackPosition, children: [jsxs(CwAlign, { ...alignProps, itemProp: inputProps.required === true ? "required" : "", children: [labelProps && (jsxs(CwLabel, { ...labelProps, children: [iconProps && jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxs("div", { className: "cw-input-button", children: [jsx("input", { type: "number", ...inputProps, "aria-describedby": describedBy }), buttonProps && jsx(CwButton, { ...buttonProps })] })] }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { id: feedbackIds[index], className: "cw-input-info", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] }));
3376
3376
  }
3377
3377
 
3378
- var styles$l = {"colorPreview":"cw-color-picker-module__colorPreview__ylJcD","hueBar":"cw-color-picker-module__hueBar__bFhyC","hueBarSlider":"cw-color-picker-module__hueBarSlider__D53IV","colorPickerInteractiveArea":"cw-color-picker-module__colorPickerInteractiveArea__KZFR1","colorArea":"cw-color-picker-module__colorArea__xgpSE","colorAreaOverlay":"cw-color-picker-module__colorAreaOverlay__pmgOc","hueBackground":"cw-color-picker-module__hueBackground__Mks78","whiteGradient":"cw-color-picker-module__whiteGradient__Bt-fU","blackGradient":"cw-color-picker-module__blackGradient__VnEKJ","colorAreaCursor":"cw-color-picker-module__colorAreaCursor__lotg3"};
3378
+ var styles$o = {"colorPreview":"cw-color-picker-module__colorPreview__ylJcD","hueBar":"cw-color-picker-module__hueBar__bFhyC","hueBarSlider":"cw-color-picker-module__hueBarSlider__D53IV","colorPickerInteractiveArea":"cw-color-picker-module__colorPickerInteractiveArea__KZFR1","colorArea":"cw-color-picker-module__colorArea__xgpSE","colorAreaOverlay":"cw-color-picker-module__colorAreaOverlay__pmgOc","hueBackground":"cw-color-picker-module__hueBackground__Mks78","whiteGradient":"cw-color-picker-module__whiteGradient__Bt-fU","blackGradient":"cw-color-picker-module__blackGradient__VnEKJ","colorAreaCursor":"cw-color-picker-module__colorAreaCursor__lotg3"};
3379
3379
 
3380
3380
  const CwColorPicker = ({ initialColor, onChange, previewText = "Color preview" }) => {
3381
3381
  const [rgb, setRgb] = useState({ r: 255, g: 255, b: 255 });
@@ -3578,13 +3578,13 @@ const CwColorPicker = ({ initialColor, onChange, previewText = "Color preview" }
3578
3578
  // Calculate background color for the main area based on current hue
3579
3579
  const hueColor = hsvToRgb(hsv.h, 100, 100);
3580
3580
  const hueHex = rgbToHex(hueColor.r, hueColor.g, hueColor.b);
3581
- return (jsxs("div", { className: "cw-flex-column cw-gap-small", children: [jsxs("div", { className: "cw-flex-row cw-align-between-center cw-gap-small", children: [jsx("div", { className: styles$l.colorPreview, style: { backgroundColor: hexColor, color: getContrastColor(hexColor) }, children: previewText }), jsx("button", { type: "button", className: "cw-button", onClick: toggleInputMode, style: { minWidth: "3ch" }, children: inputMode === 'hex' ? 'RGB' : 'HEX' })] }), jsx("div", { className: "color-inputs-row", children: inputMode === 'hex' ? (jsx("input", { type: "text", value: hexColor, onChange: handleHexChange })) : (jsxs("div", { className: "cw-grid-base-3 cw-gap-small", children: [jsxs("div", { children: [jsx("label", { children: "R:" }), jsx("input", { type: "number", name: "r", min: "0", max: "255", value: rgb.r, onChange: handleRgbChange })] }), jsxs("div", { children: [jsx("label", { children: "G:" }), jsx("input", { type: "number", name: "g", min: "0", max: "255", value: rgb.g, onChange: handleRgbChange })] }), jsxs("div", { children: [jsx("label", { children: "B:" }), jsx("input", { type: "number", name: "b", min: "0", max: "255", value: rgb.b, onChange: handleRgbChange })] })] })) }), jsxs("div", { className: styles$l.colorPickerInteractiveArea, children: [jsx("div", { className: styles$l.hueBar, ref: hueBarRef, onClick: handleHueBarClick, children: jsx("div", { className: styles$l.hueBarSlider, style: { top: `${(360 - hsv.h) / 360 * 100}%` } }) }), jsxs("div", { className: styles$l.colorArea, ref: colorAreaRef, onClick: handleColorAreaClick, children: [jsxs("div", { className: styles$l.colorAreaOverlay, children: [jsx("div", { className: styles$l.hueBackground, style: { backgroundColor: hueHex } }), jsx("div", { className: styles$l.whiteGradient }), jsx("div", { className: styles$l.blackGradient })] }), jsx("div", { className: styles$l.colorAreaCursor, style: {
3581
+ return (jsxs("div", { className: "cw-flex-column cw-gap-small", children: [jsxs("div", { className: "cw-flex-row cw-align-between-center cw-gap-small", children: [jsx("div", { className: styles$o.colorPreview, style: { backgroundColor: hexColor, color: getContrastColor(hexColor) }, children: previewText }), jsx("button", { type: "button", className: "cw-button", onClick: toggleInputMode, style: { minWidth: "3ch" }, children: inputMode === 'hex' ? 'RGB' : 'HEX' })] }), jsx("div", { className: "color-inputs-row", children: inputMode === 'hex' ? (jsx("input", { type: "text", value: hexColor, onChange: handleHexChange })) : (jsxs("div", { className: "cw-grid-base-3 cw-gap-small", children: [jsxs("div", { children: [jsx("label", { children: "R:" }), jsx("input", { type: "number", name: "r", min: "0", max: "255", value: rgb.r, onChange: handleRgbChange })] }), jsxs("div", { children: [jsx("label", { children: "G:" }), jsx("input", { type: "number", name: "g", min: "0", max: "255", value: rgb.g, onChange: handleRgbChange })] }), jsxs("div", { children: [jsx("label", { children: "B:" }), jsx("input", { type: "number", name: "b", min: "0", max: "255", value: rgb.b, onChange: handleRgbChange })] })] })) }), jsxs("div", { className: styles$o.colorPickerInteractiveArea, children: [jsx("div", { className: styles$o.hueBar, ref: hueBarRef, onClick: handleHueBarClick, children: jsx("div", { className: styles$o.hueBarSlider, style: { top: `${(360 - hsv.h) / 360 * 100}%` } }) }), jsxs("div", { className: styles$o.colorArea, ref: colorAreaRef, onClick: handleColorAreaClick, children: [jsxs("div", { className: styles$o.colorAreaOverlay, children: [jsx("div", { className: styles$o.hueBackground, style: { backgroundColor: hueHex } }), jsx("div", { className: styles$o.whiteGradient }), jsx("div", { className: styles$o.blackGradient })] }), jsx("div", { className: styles$o.colorAreaCursor, style: {
3582
3582
  left: `${hsv.s}%`,
3583
3583
  top: `${100 - hsv.v}%`
3584
3584
  } })] })] })] }));
3585
3585
  };
3586
3586
 
3587
- var styles$k = {"container":"cw-input-color-module__container__x7gpk","selectColor":"cw-input-color-module__selectColor__DTo3V","disabled":"cw-input-color-module__disabled__O1fK5","readOnly":"cw-input-color-module__readOnly__HL-Bz","colorDropdown":"cw-input-color-module__colorDropdown__pX2bc"};
3587
+ var styles$n = {"container":"cw-input-color-module__container__x7gpk","selectColor":"cw-input-color-module__selectColor__DTo3V","disabled":"cw-input-color-module__disabled__O1fK5","readOnly":"cw-input-color-module__readOnly__HL-Bz","colorDropdown":"cw-input-color-module__colorDropdown__pX2bc"};
3588
3588
 
3589
3589
  const CwInputColor = ({ value, onChange, previewText = "Color preview", disabled = false, readOnly = false, width = '4rem', height = '2rem', labelProps, layoutProps, className, style, }) => {
3590
3590
  const [isOpen, setIsOpen] = useState(false);
@@ -3717,11 +3717,11 @@ const CwInputColor = ({ value, onChange, previewText = "Color preview", disabled
3717
3717
  break;
3718
3718
  }
3719
3719
  };
3720
- return (jsxs("div", { className: `cw-input-color ${styles$k.container}${className ? ` ${className}` : ''}`, style: style, "data-direction": layoutProps?.direction ?? "row", "data-align": layoutProps?.align, children: [labelProps && (jsx(CwLabel, { ...labelProps })), jsx("div", { ref: containerRef, onClick: handleToggle, className: `${styles$k.selectColor} ${disabled ? styles$k.disabled : ''} ${readOnly ? styles$k.readOnly : ''}`, style: {
3720
+ return (jsxs("div", { className: `cw-input-color ${styles$n.container}${className ? ` ${className}` : ''}`, style: style, "data-direction": layoutProps?.direction ?? "row", "data-align": layoutProps?.align, children: [labelProps && (jsx(CwLabel, { ...labelProps })), jsx("div", { ref: containerRef, onClick: handleToggle, className: `${styles$n.selectColor} ${disabled ? styles$n.disabled : ''} ${readOnly ? styles$n.readOnly : ''}`, style: {
3721
3721
  width,
3722
3722
  height,
3723
3723
  backgroundColor: value,
3724
- }, "aria-label": "Open color picker", "aria-expanded": isOpen, "aria-haspopup": "dialog", "aria-readonly": readOnly, role: "button", tabIndex: disabled ? -1 : 0, onKeyDown: handleKeyDown }), isOpen && createPortal(jsx("div", { ref: dropdownRef, className: styles$k.colorDropdown, style: dropdownStyle, role: "dialog", "aria-modal": "true", "aria-label": "Color picker", children: jsx(CwColorPicker, { initialColor: value, onChange: handleColorChange, previewText: previewText }) }), document.body)] }));
3724
+ }, "aria-label": "Open color picker", "aria-expanded": isOpen, "aria-haspopup": "dialog", "aria-readonly": readOnly, role: "button", tabIndex: disabled ? -1 : 0, onKeyDown: handleKeyDown }), isOpen && createPortal(jsx("div", { ref: dropdownRef, className: styles$n.colorDropdown, style: dropdownStyle, role: "dialog", "aria-modal": "true", "aria-label": "Color picker", children: jsx(CwColorPicker, { initialColor: value, onChange: handleColorChange, previewText: previewText }) }), document.body)] }));
3725
3725
  };
3726
3726
 
3727
3727
  /**
@@ -3976,7 +3976,7 @@ function CwInputDateText(props) {
3976
3976
  return (jsx("div", { className: "cw-input-date-text", children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxs(CwLabel, { ...labelProps, children: [iconProps && jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxs("div", { children: [jsx("input", { type: "text", disabled: disabled, maxLength: 10, onChange: onChangeInputText, pattern: "^$ --|[.0-9\\/\\-]{10}", placeholder: format.toLowerCase(), readOnly: readOnly, ref: textInputRef, required: required, size: width, tabIndex: tabIndex, value: displayedDate }), jsxs("span", { children: [jsx(CwIcon, { iconId: "calendar" }), jsx("input", { type: "date", disabled: disabled, onChange: onChangeInputDate, readOnly: readOnly, ref: dateInputRef, tabIndex: -1, value: date, ...inputProps })] })] }), buttonProps && jsx(CwButton, { ...buttonProps })] }) }));
3977
3977
  }
3978
3978
 
3979
- var styles$j = {"hiddenInput":"cw-input-image-module__hiddenInput__pS7hb","dropZone":"cw-input-image-module__dropZone__ygrGu","title":"cw-input-image-module__title__Rji5M","subtitle":"cw-input-image-module__subtitle__djYYu","container":"cw-input-image-module__container__qh7Tm"};
3979
+ var styles$m = {"hiddenInput":"cw-input-image-module__hiddenInput__pS7hb","dropZone":"cw-input-image-module__dropZone__ygrGu","title":"cw-input-image-module__title__Rji5M","subtitle":"cw-input-image-module__subtitle__djYYu","container":"cw-input-image-module__container__qh7Tm"};
3980
3980
 
3981
3981
  const DEFAULT_LABELS = {
3982
3982
  dropImageHere: "Drop image here",
@@ -4055,7 +4055,7 @@ function CwInputImage(props) {
4055
4055
  const file = e.currentTarget.files?.[0];
4056
4056
  void handleFile(file ?? null);
4057
4057
  };
4058
- return (jsxs("div", { className: `cw-input-image ${styles$j.container}`, "data-size": size, children: [jsxs("div", { onDragOver: (e) => e.preventDefault(), onDrop: handleDrop, className: styles$j.dropZone, children: [jsx(CwIcon, { iconId: "upload" }), jsxs("div", { className: "cw-flex-column cw-gap-tiny", children: [jsx("p", { className: styles$j.title, children: labels.dropImageHere }), jsx("p", { className: styles$j.subtitle, children: labels.acceptedFormats(allowedFormats.join(", ").replace(/image\//g, "")) })] })] }), jsxs("div", { className: "cw-flex-row cw-align-center-center cw-gap-small", children: [jsx(CwButton, { onClick: onPasteButtonClick, icon: "paste", text: labels.paste, size: size }), jsx(CwButton, { onClick: () => inputRef.current?.click(), icon: "folder-open", text: labels.browse, size: size })] }), jsx("input", { ref: inputRef, type: "file", accept: allowedFormats.join(","), onChange: handleFileChange, className: styles$j.hiddenInput, ...inputProps })] }));
4058
+ return (jsxs("div", { className: `cw-input-image ${styles$m.container}`, "data-size": size, children: [jsxs("div", { onDragOver: (e) => e.preventDefault(), onDrop: handleDrop, className: styles$m.dropZone, children: [jsx(CwIcon, { iconId: "upload" }), jsxs("div", { className: "cw-flex-column cw-gap-tiny", children: [jsx("p", { className: styles$m.title, children: labels.dropImageHere }), jsx("p", { className: styles$m.subtitle, children: labels.acceptedFormats(allowedFormats.join(", ").replace(/image\//g, "")) })] })] }), jsxs("div", { className: "cw-flex-row cw-align-center-center cw-gap-small", children: [jsx(CwButton, { onClick: onPasteButtonClick, icon: "paste", text: labels.paste, size: size }), jsx(CwButton, { onClick: () => inputRef.current?.click(), icon: "folder-open", text: labels.browse, size: size })] }), jsx("input", { ref: inputRef, type: "file", accept: allowedFormats.join(","), onChange: handleFileChange, className: styles$m.hiddenInput, ...inputProps })] }));
4059
4059
  }
4060
4060
 
4061
4061
  /**
@@ -4187,7 +4187,7 @@ const CwImageArea = forwardRef((props, ref) => {
4187
4187
  });
4188
4188
  CwImageArea.displayName = "CwImageArea";
4189
4189
 
4190
- var styles$i = {"container":"cw-weekday-selector-module__container__pwcvx","days":"cw-weekday-selector-module__days__Dd3RH"};
4190
+ var styles$l = {"container":"cw-weekday-selector-module__container__pwcvx","days":"cw-weekday-selector-module__days__Dd3RH"};
4191
4191
 
4192
4192
  /* 2024-01-01 was a Monday. Formatted in UTC so a negative browser offset cannot shift a day. */
4193
4193
  const MONDAY_UTC = Date.UTC(2024, 0, 1);
@@ -4385,16 +4385,16 @@ const CwWeekdaySelector = ({ value = "mtwrfsu", onChange, disabled = false, labe
4385
4385
  // Points at the label element rather than copying its text, which also covers a labelProps that
4386
4386
  // carries children instead of `text`.
4387
4387
  const labelId = labelProps?.id ?? `${feedbackId}-label`;
4388
- return (jsxs("div", { ...dataAttributes, className: `cw-weekday-selector ${styles$i.container}${className ? ` ${className}` : ""}`, "data-direction": labelProps ? layout?.direction ?? "row" : "column", "data-align": layout?.align, "data-gap": layout?.gap, children: [labelProps && jsx(CwLabel, { id: labelId, ...labelProps }), jsx("div", { role: "group", className: styles$i.days, "aria-labelledby": labelProps ? labelId : undefined, "aria-describedby": describedBy, children: Weekdays.getFullWeek().map(day => (jsx("input", { type: "checkbox", "data-day": day, "data-letter": dayNames[day].letter, "aria-label": dayNames[day].full, title: dayNames[day].full, checked: selectedDays.includes(day), onChange: (e) => handleChange(day, e.target.checked), disabled: disabled }, day))) }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] }));
4388
+ return (jsxs("div", { ...dataAttributes, className: `cw-weekday-selector ${styles$l.container}${className ? ` ${className}` : ""}`, "data-direction": labelProps ? layout?.direction ?? "row" : "column", "data-align": layout?.align, "data-gap": layout?.gap, children: [labelProps && jsx(CwLabel, { id: labelId, ...labelProps }), jsx("div", { role: "group", className: styles$l.days, "aria-labelledby": labelProps ? labelId : undefined, "aria-describedby": describedBy, children: Weekdays.getFullWeek().map(day => (jsx("input", { type: "checkbox", "data-day": day, "data-letter": dayNames[day].letter, "aria-label": dayNames[day].full, title: dayNames[day].full, checked: selectedDays.includes(day), onChange: (e) => handleChange(day, e.target.checked), disabled: disabled }, day))) }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] }));
4389
4389
  };
4390
4390
 
4391
- var styles$h = {"check-container":"cw-check-module__check-container__4nscZ","group":"cw-check-module__group__6JCQo","options":"cw-check-module__options__-g9LF"};
4391
+ var styles$k = {"check-container":"cw-check-module__check-container__4nscZ","group":"cw-check-module__group__6JCQo","options":"cw-check-module__options__-g9LF"};
4392
4392
 
4393
4393
  function CwCheck(props) {
4394
4394
  const { labelProps, labelText, direction, alignment, className, ...inputProps } = props;
4395
4395
  const resolvedDirection = direction ?? alignment ?? "row";
4396
4396
  const displayText = labelProps?.text ?? labelText;
4397
- return (jsx("div", { className: `cw-check ${styles$h["check-container"]}${className ? ` ${className}` : ''}`, children: jsxs("label", { "data-direction": resolvedDirection, children: [jsx("input", { type: "checkbox", ...inputProps }), displayText && (jsx("span", { className: "cw-icon-text", children: displayText }))] }) }));
4397
+ return (jsx("div", { className: `cw-check ${styles$k["check-container"]}${className ? ` ${className}` : ''}`, children: jsxs("label", { "data-direction": resolvedDirection, children: [jsx("input", { type: "checkbox", ...inputProps }), displayText && (jsx("span", { className: "cw-icon-text", children: displayText }))] }) }));
4398
4398
  }
4399
4399
 
4400
4400
  function CwCheckbox(CwCheckboxProps) {
@@ -4448,14 +4448,14 @@ function CwCheckboxGroup({ options, value = [], onChange, labelProps, groupLayou
4448
4448
  ?? (optionsAlignment === "column" ? "row" : "column");
4449
4449
  // Each checkbox's box-to-text layout is the opposite of the options flow, mirroring CwRadioGroup.
4450
4450
  const checkDirection = itemDirection === "row" ? "column" : "row";
4451
- return (jsxs("div", { className: `cw-checkbox-group ${styles$h.group}${className ? ` ${className}` : ""}`, "data-testid": dataTestId, "data-direction": labelProps ? groupDirection : "column", "data-align": groupLayout?.align, "data-gap": groupLayout?.gap, children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsx("div", { className: styles$h.options, role: "group", "aria-label": labelProps?.text, "aria-describedby": describedBy, "aria-required": required || undefined, "data-direction": itemDirection, "data-gap": itemLayout?.gap, children: options.map((option) => (jsx(CwCheck, { labelProps: { text: option.label }, checked: value.includes(option.value), disabled: disabled || option.disabled, direction: checkDirection, onChange: (e) => handleChange(option.value, e.currentTarget.checked) }, option.value))) }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] }));
4451
+ return (jsxs("div", { className: `cw-checkbox-group ${styles$k.group}${className ? ` ${className}` : ""}`, "data-testid": dataTestId, "data-direction": labelProps ? groupDirection : "column", "data-align": groupLayout?.align, "data-gap": groupLayout?.gap, children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsx("div", { className: styles$k.options, role: "group", "aria-label": labelProps?.text, "aria-describedby": describedBy, "aria-required": required || undefined, "data-direction": itemDirection, "data-gap": itemLayout?.gap, children: options.map((option) => (jsx(CwCheck, { labelProps: { text: option.label }, checked: value.includes(option.value), disabled: disabled || option.disabled, direction: checkDirection, onChange: (e) => handleChange(option.value, e.currentTarget.checked) }, option.value))) }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] }));
4452
4452
  }
4453
4453
 
4454
- var styles$g = {"radio":"cw-radio-module__radio__5sh7a","group":"cw-radio-module__group__br-HM","options":"cw-radio-module__options__LSw7M"};
4454
+ var styles$j = {"radio":"cw-radio-module__radio__5sh7a","group":"cw-radio-module__group__br-HM","options":"cw-radio-module__options__LSw7M"};
4455
4455
 
4456
4456
  /** Single native radio input. Building block for CwRadioGroup. */
4457
4457
  function CwRadio({ label, direction = "row", className, ...inputProps }) {
4458
- return (jsxs("label", { className: `cw-radio ${styles$g.radio}${className ? ` ${className}` : ""}`, "data-direction": direction, children: [jsx("input", { type: "radio", ...inputProps }), label && jsx("span", { children: label })] }));
4458
+ return (jsxs("label", { className: `cw-radio ${styles$j.radio}${className ? ` ${className}` : ""}`, "data-direction": direction, children: [jsx("input", { type: "radio", ...inputProps }), label && jsx("span", { children: label })] }));
4459
4459
  }
4460
4460
 
4461
4461
  /**
@@ -4482,7 +4482,7 @@ function CwRadioGroup({ options, value, onChange, labelProps, groupLayout, itemL
4482
4482
  // (itemLayout column) reads best with the circle beside the text; a side-by-side row reads
4483
4483
  // best with the circle above the text.
4484
4484
  const radioDirection = itemLayout?.direction === "row" ? "column" : "row";
4485
- return (jsxs("div", { className: `cw-radio-group ${styles$g.group}${className ? ` ${className}` : ""}`, "data-testid": dataTestId, "data-direction": labelProps ? (groupLayout?.direction ?? "column") : "column", "data-align": groupLayout?.align, "data-gap": groupLayout?.gap, children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsx("div", { className: styles$g.options, role: "radiogroup", "aria-describedby": describedBy, "aria-labelledby": ariaLabelledby, "aria-label": ariaLabelledby ? undefined : (ariaLabel ?? labelProps?.text), "aria-required": required || undefined, "data-direction": itemLayout?.direction ?? "column", "data-gap": itemLayout?.gap, children: options.map((option) => (jsx(CwRadio, { name: groupName, label: option.label, direction: radioDirection, checked: value === option.value, required: required, disabled: disabled || option.disabled, onChange: () => onChange(option.value) }, option.value))) }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] }));
4485
+ return (jsxs("div", { className: `cw-radio-group ${styles$j.group}${className ? ` ${className}` : ""}`, "data-testid": dataTestId, "data-direction": labelProps ? (groupLayout?.direction ?? "column") : "column", "data-align": groupLayout?.align, "data-gap": groupLayout?.gap, children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsx("div", { className: styles$j.options, role: "radiogroup", "aria-describedby": describedBy, "aria-labelledby": ariaLabelledby, "aria-label": ariaLabelledby ? undefined : (ariaLabel ?? labelProps?.text), "aria-required": required || undefined, "data-direction": itemLayout?.direction ?? "column", "data-gap": itemLayout?.gap, children: options.map((option) => (jsx(CwRadio, { name: groupName, label: option.label, direction: radioDirection, checked: value === option.value, required: required, disabled: disabled || option.disabled, onChange: () => onChange(option.value) }, option.value))) }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] }));
4486
4486
  }
4487
4487
 
4488
4488
  function CwToggle(props) {
@@ -4623,7 +4623,7 @@ function useDropdownPortal({ anchorRef, isOpen, onClose, positionStrategy = defa
4623
4623
  return { panelRef, panelStyle: style, renderPanel };
4624
4624
  }
4625
4625
 
4626
- var styles$f = {"dropdown":"cw-dropdown-module__dropdown__EFZ9M cw-choice-dropdown-module__dropdown__P0b4j","option":"cw-dropdown-module__option__TuMdI cw-choice-dropdown-module__option__uR-ro","optionFocused":"cw-dropdown-module__optionFocused__7LGaC cw-choice-dropdown-module__optionFocused__BYMxj","optionSelected":"cw-dropdown-module__optionSelected__OiXIc cw-choice-dropdown-module__optionSelected__Lt8Xg","optionDisabled":"cw-dropdown-module__optionDisabled__lYM6w cw-choice-dropdown-module__optionDisabled__n3scM","emptyState":"cw-dropdown-module__emptyState__gp8KT cw-choice-dropdown-module__emptyState__HO0Y7","searchBox":"cw-dropdown-module__searchBox__Bx0JE cw-choice-dropdown-module__searchBox__0gox7","searchInput":"cw-dropdown-module__searchInput__JrxCK cw-choice-dropdown-module__searchInput__G5oRs","value":"cw-dropdown-module__value__i-7IN","colorCircle":"cw-dropdown-module__colorCircle__5kgiT cw-choice-dropdown-module__colorCircle__x7mI9"};
4626
+ var styles$i = {"dropdown":"cw-dropdown-module__dropdown__EFZ9M cw-choice-dropdown-module__dropdown__P0b4j","option":"cw-dropdown-module__option__TuMdI cw-choice-dropdown-module__option__uR-ro","optionFocused":"cw-dropdown-module__optionFocused__7LGaC cw-choice-dropdown-module__optionFocused__BYMxj","optionSelected":"cw-dropdown-module__optionSelected__OiXIc cw-choice-dropdown-module__optionSelected__Lt8Xg","optionDisabled":"cw-dropdown-module__optionDisabled__lYM6w cw-choice-dropdown-module__optionDisabled__n3scM","emptyState":"cw-dropdown-module__emptyState__gp8KT cw-choice-dropdown-module__emptyState__HO0Y7","searchBox":"cw-dropdown-module__searchBox__Bx0JE cw-choice-dropdown-module__searchBox__0gox7","searchInput":"cw-dropdown-module__searchInput__JrxCK cw-choice-dropdown-module__searchInput__G5oRs","value":"cw-dropdown-module__value__i-7IN","colorCircle":"cw-dropdown-module__colorCircle__5kgiT cw-choice-dropdown-module__colorCircle__x7mI9"};
4627
4627
 
4628
4628
  /**
4629
4629
  * Custom dropdown component with colour-coded options, optional search filter, and full
@@ -4737,12 +4737,12 @@ function CwDropdown({ options, value, onChange, labelProps, alignProps, placehol
4737
4737
  }
4738
4738
  }, [isOpen, highlightedIndex, filteredOptions, handleOptionSelect]);
4739
4739
  const flexDirection = alignProps?.flexDirection ?? "row";
4740
- return (jsx("div", { ref: containerRef, className: `cw-dropdown${className ? ` ${className}` : ""}`, "data-direction": flexDirection, style: style, ...otherProps, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && jsx(CwLabel, { id: labelId, ...labelProps }), jsxs("div", { className: styles$f.value, children: [jsxs("div", { className: "cw-dropdown-wrapper", ref: wrapperRef, children: [jsxs("button", { type: "button", className: "cw-dropdown-trigger", onClick: handleTriggerClick, onKeyDown: handleKeyDown, disabled: disabled, "aria-haspopup": "listbox", "aria-expanded": isOpen, "aria-labelledby": labelProps ? `${labelId} ${valueId}` : undefined, "aria-label": labelProps ? undefined : (selectedOption?.label || placeholder), "aria-describedby": describedBy, children: [jsx("div", { className: "cw-dropdown-trigger-content", id: valueId, children: selectedOption ? (jsxs(Fragment, { children: [selectedOption.color && (jsx("span", { className: styles$f.colorCircle, style: { backgroundColor: selectedOption.color } })), jsx("span", { children: selectedOption.label })] })) : (jsx("span", { className: "cw-dropdown-placeholder", children: placeholder })) }), jsx(CwIcon, { iconId: "chevron-down", size: "small" })] }), renderPanel(jsxs("div", { ref: panelRef, className: styles$f.dropdown, style: panelStyle, role: "listbox", onKeyDown: handleKeyDown, children: [allowSearch && (jsx("div", { className: styles$f.searchBox, children: jsx("input", { ref: inputRef, type: "text", placeholder: "Search...", value: searchText, onChange: handleSearchChange, onKeyDown: handleKeyDown, className: styles$f.searchInput, autoComplete: "off" }) })), jsx("ul", { children: filteredOptions.length > 0 ? (filteredOptions.map((option, index) => (jsxs("li", { ref: highlightedIndex === index ? highlightedItemRef : null, className: [
4741
- styles$f.option,
4742
- value === option.value ? styles$f.optionSelected : "",
4743
- highlightedIndex === index ? styles$f.optionFocused : "",
4744
- option.disabled ? styles$f.optionDisabled : "",
4745
- ].filter(Boolean).join(" "), onClick: () => !option.disabled && handleOptionSelect(option.value), onMouseEnter: () => setHighlightedIndex(index), role: "option", "aria-selected": value === option.value, "aria-disabled": option.disabled, children: [option.color && (jsx("span", { className: styles$f.colorCircle, style: { backgroundColor: option.color } })), jsx("span", { children: option.label })] }, option.value)))) : (jsx("li", { className: styles$f.emptyState, children: "No options available" })) })] }))] }), feedbackMessages.map((item, index) => (jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": item.type, "aria-live": "polite", children: item.message }, index)))] })] }) }));
4740
+ return (jsx("div", { ref: containerRef, className: `cw-dropdown${className ? ` ${className}` : ""}`, "data-direction": flexDirection, style: style, ...otherProps, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && jsx(CwLabel, { id: labelId, ...labelProps }), jsxs("div", { className: styles$i.value, children: [jsxs("div", { className: "cw-dropdown-wrapper", ref: wrapperRef, children: [jsxs("button", { type: "button", className: "cw-dropdown-trigger", onClick: handleTriggerClick, onKeyDown: handleKeyDown, disabled: disabled, "aria-haspopup": "listbox", "aria-expanded": isOpen, "aria-labelledby": labelProps ? `${labelId} ${valueId}` : undefined, "aria-label": labelProps ? undefined : (selectedOption?.label || placeholder), "aria-describedby": describedBy, children: [jsx("div", { className: "cw-dropdown-trigger-content", id: valueId, children: selectedOption ? (jsxs(Fragment, { children: [selectedOption.color && (jsx("span", { className: styles$i.colorCircle, style: { backgroundColor: selectedOption.color } })), jsx("span", { children: selectedOption.label })] })) : (jsx("span", { className: "cw-dropdown-placeholder", children: placeholder })) }), jsx(CwIcon, { iconId: "chevron-down", size: "small" })] }), renderPanel(jsxs("div", { ref: panelRef, className: styles$i.dropdown, style: panelStyle, role: "listbox", onKeyDown: handleKeyDown, children: [allowSearch && (jsx("div", { className: styles$i.searchBox, children: jsx("input", { ref: inputRef, type: "text", placeholder: "Search...", value: searchText, onChange: handleSearchChange, onKeyDown: handleKeyDown, className: styles$i.searchInput, autoComplete: "off" }) })), jsx("ul", { children: filteredOptions.length > 0 ? (filteredOptions.map((option, index) => (jsxs("li", { ref: highlightedIndex === index ? highlightedItemRef : null, className: [
4741
+ styles$i.option,
4742
+ value === option.value ? styles$i.optionSelected : "",
4743
+ highlightedIndex === index ? styles$i.optionFocused : "",
4744
+ option.disabled ? styles$i.optionDisabled : "",
4745
+ ].filter(Boolean).join(" "), onClick: () => !option.disabled && handleOptionSelect(option.value), onMouseEnter: () => setHighlightedIndex(index), role: "option", "aria-selected": value === option.value, "aria-disabled": option.disabled, children: [option.color && (jsx("span", { className: styles$i.colorCircle, style: { backgroundColor: option.color } })), jsx("span", { children: option.label })] }, option.value)))) : (jsx("li", { className: styles$i.emptyState, children: "No options available" })) })] }))] }), feedbackMessages.map((item, index) => (jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": item.type, "aria-live": "polite", children: item.message }, index)))] })] }) }));
4746
4746
  }
4747
4747
 
4748
4748
  /**
@@ -4759,7 +4759,7 @@ function CwDropdownFilter(props) {
4759
4759
  return (jsxs("div", { id: props.IdContent, className: containerClassName, children: [props.children, isVisible && (jsx("nav", { className: "cw-dropdown-menu", style: inlineStyles, onMouseLeave: props.onMouseLeave, id: props.idDropDownFilter, role: "menu", children: jsx("ul", { role: "none", children: props.DataSourceDropDownItem?.map((item) => (jsx("li", { id: item.IdDropDown_filter, role: "menuitem", children: item.dropDownFilter_desc }, item.IdDropDown_filter))) }) }))] }));
4760
4760
  }
4761
4761
 
4762
- var styles$e = {"container":"cw-popover-button-module__container__YSWQU","panel":"cw-popover-button-module__panel__C-BTn"};
4762
+ var styles$h = {"container":"cw-popover-button-module__container__YSWQU","panel":"cw-popover-button-module__panel__C-BTn"};
4763
4763
 
4764
4764
  /**
4765
4765
  * Button that toggles a floating panel with arbitrary children.
@@ -4838,7 +4838,7 @@ function CwPopoverButton({ children, panelWidth = "auto", placement = "bottom-st
4838
4838
  }
4839
4839
  panel.showPopover();
4840
4840
  }, [placement]);
4841
- return (jsxs("div", { ref: containerRef, className: styles$e.container, children: [jsx(CwButton, { ...buttonProps, onClick: handleClick }), jsx("div", { ref: panelCallbackRef, className: `${styles$e.panel}${panelClassName ? ` ${panelClassName}` : ""}`, style: { width: panelWidth }, children: children })] }));
4841
+ return (jsxs("div", { ref: containerRef, className: styles$h.container, children: [jsx(CwButton, { ...buttonProps, onClick: handleClick }), jsx("div", { ref: panelCallbackRef, className: `${styles$h.panel}${panelClassName ? ` ${panelClassName}` : ""}`, style: { width: panelWidth }, children: children })] }));
4842
4842
  }
4843
4843
 
4844
4844
  function itemsToMultiFilterTags(items, nameKey, valueKey, category, primaryColor, onPrimaryColor) {
@@ -4856,13 +4856,13 @@ function itemsToMultiFilterTags(items, nameKey, valueKey, category, primaryColor
4856
4856
  return result;
4857
4857
  }
4858
4858
 
4859
- var styles$d = {"cw-multifilter-tag":"cw-multi-filter-tag-module__cw-multifilter-tag__Epda-"};
4859
+ var styles$g = {"cw-multifilter-tag":"cw-multi-filter-tag-module__cw-multifilter-tag__Epda-"};
4860
4860
 
4861
4861
  const CwMultiFilterTag = props => {
4862
4862
  const { ID, Name, Value, Category, Removable, PrimaryColor, Selectable, Selected } = props;
4863
4863
  const backgroundColor = `rgb(${PrimaryColor.r},${PrimaryColor.g},${PrimaryColor.b})`;
4864
4864
  const isOutlineMode = Selected && !Removable;
4865
- return (jsx("li", { className: styles$d["cw-multifilter-tag"], id: ID, "data-value": Value, "data-category": Category, "data-selected": !!Selected, title: props.tooltip ?? Name, onClick: () => {
4865
+ return (jsx("li", { className: styles$g["cw-multifilter-tag"], id: ID, "data-value": Value, "data-category": Category, "data-selected": !!Selected, title: props.tooltip ?? Name, onClick: () => {
4866
4866
  if (Selectable)
4867
4867
  props.OnSelect?.(props);
4868
4868
  }, children: jsx(CwChip, { label: Name, colorScheme: "custom", customColor: backgroundColor, variant: isOutlineMode ? "outline" : "soft", closable: Removable, onClose: () => props.OnRemove?.(props),
@@ -4872,7 +4872,7 @@ const CwMultiFilterTag = props => {
4872
4872
  } : undefined }) }));
4873
4873
  };
4874
4874
 
4875
- var styles$c = {"cw-multi-filter-catalog-container":"cw-multi-filter-module__cw-multi-filter-catalog-container__S3nsq","cw-multi-filter":"cw-multi-filter-module__cw-multi-filter__zipBK","category-selected":"cw-multi-filter-module__category-selected__eYbes","cw-multi-filter-search":"cw-multi-filter-module__cw-multi-filter-search__eyHr0 cw-choice-input-box-module__inputBox__gHY9d"};
4875
+ var styles$f = {"cw-multi-filter-catalog-container":"cw-multi-filter-module__cw-multi-filter-catalog-container__S3nsq","cw-multi-filter":"cw-multi-filter-module__cw-multi-filter__zipBK","category-selected":"cw-multi-filter-module__category-selected__eYbes","cw-multi-filter-search":"cw-multi-filter-module__cw-multi-filter-search__eyHr0 cw-choice-input-box-module__inputBox__gHY9d"};
4876
4876
 
4877
4877
  /**
4878
4878
  * A multiple filter selector, a MULTI-SELECT even. Allows users to select and filter items based on tags.
@@ -5113,9 +5113,9 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
5113
5113
  inputRef.current?.focus();
5114
5114
  }
5115
5115
  };
5116
- return (jsxs("form", { ref: componentRef, id: id, "data-testid": testId, className: `${styles$c["cw-multi-filter"]}${className ? ` ${className}` : ""}`, style: style, onSubmit: (e) => {
5116
+ return (jsxs("form", { ref: componentRef, id: id, "data-testid": testId, className: `${styles$f["cw-multi-filter"]}${className ? ` ${className}` : ""}`, style: style, onSubmit: (e) => {
5117
5117
  e.preventDefault();
5118
- }, children: [jsxs("div", { onClick: handleDivClick, ref: wrapperRef, className: styles$c["cw-multi-filter-search"], style: isPanelOpen ? { outline: "1px solid var(--cw-outline-variant)" } : {}, children: [jsxs("ul", { id: id + "_selected_filters", children: [Array.from(selectedTags).map(tag => (createElement(CwMultiFilterTag, { ...tag, key: tag.ID, Selectable: false, Removable: true, OnRemove: () => removeTag(tag.ID) }))), jsx("input", { type: "text", id: id + "_input", ref: inputRef, value: inputTextValue, spellCheck: false, onFocus: () => setIsPanelOpen(true), onChange: e => handleInputText(e.currentTarget.value), autoComplete: "off", placeholder: selectedTags.size === 0 ? placeholder : "", onKeyDown: e => {
5118
+ }, children: [jsxs("div", { onClick: handleDivClick, ref: wrapperRef, className: styles$f["cw-multi-filter-search"], style: isPanelOpen ? { outline: "1px solid var(--cw-outline-variant)" } : {}, children: [jsxs("ul", { id: id + "_selected_filters", children: [Array.from(selectedTags).map(tag => (createElement(CwMultiFilterTag, { ...tag, key: tag.ID, Selectable: false, Removable: true, OnRemove: () => removeTag(tag.ID) }))), jsx("input", { type: "text", id: id + "_input", ref: inputRef, value: inputTextValue, spellCheck: false, onFocus: () => setIsPanelOpen(true), onChange: e => handleInputText(e.currentTarget.value), autoComplete: "off", placeholder: selectedTags.size === 0 ? placeholder : "", onKeyDown: e => {
5119
5119
  switch (e.key) {
5120
5120
  case "Enter":
5121
5121
  case "Tab": {
@@ -5142,7 +5142,7 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
5142
5142
  break;
5143
5143
  }
5144
5144
  }
5145
- } })] }), selectedTags.size > 0 && (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onMouseDown: e => e.preventDefault(), onClick: (e) => { e.stopPropagation(); onChangeSelectedTags(new Set()); setIsPanelOpen(false); }, tabIndex: -1, "aria-label": "Clear all" }))] }), renderPanel(jsxs("section", { ref: panelRef, className: styles$c["cw-multi-filter-catalog-container"], style: panelStyle, children: [jsxs("nav", { children: [jsx("button", { className: selectedCategory === "All" ? styles$c["category-selected"] : undefined, onClick: () => handleClickCategory("All"), children: allCategoriesLabel }), Array.from(categoriesMappedToTags().keys()).map(category => (jsx("button", { className: selectedCategory === category ? styles$c["category-selected"] : undefined, style: {
5145
+ } })] }), selectedTags.size > 0 && (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onMouseDown: e => e.preventDefault(), onClick: (e) => { e.stopPropagation(); onChangeSelectedTags(new Set()); setIsPanelOpen(false); }, tabIndex: -1, "aria-label": "Clear all" }))] }), renderPanel(jsxs("section", { ref: panelRef, className: styles$f["cw-multi-filter-catalog-container"], style: panelStyle, children: [jsxs("nav", { children: [jsx("button", { className: selectedCategory === "All" ? styles$f["category-selected"] : undefined, onClick: () => handleClickCategory("All"), children: allCategoriesLabel }), Array.from(categoriesMappedToTags().keys()).map(category => (jsx("button", { className: selectedCategory === category ? styles$f["category-selected"] : undefined, style: {
5146
5146
  backgroundColor: getColor(category).primary,
5147
5147
  color: getColor(category).onPrimary,
5148
5148
  }, onClick: () => handleClickCategory(category), children: category }, category)))] }), jsx("ul", { children: displayTags
@@ -5168,7 +5168,7 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
5168
5168
  } }, props.ID))) })] }))] }));
5169
5169
  };
5170
5170
 
5171
- var styles$b = {"container":"cw-tag-selector-module__container__-do8i","value":"cw-tag-selector-module__value__TDAy3","inputBox":"cw-tag-selector-module__inputBox__3NGz9 cw-choice-input-box-module__inputBox__gHY9d","disabled":"cw-tag-selector-module__disabled__vbud9 cw-choice-input-box-module__disabled__TFAnC","dropdown":"cw-tag-selector-module__dropdown__X6Dob cw-choice-dropdown-module__dropdown__P0b4j","option":"cw-tag-selector-module__option__2UQ7g cw-choice-dropdown-module__option__uR-ro","optionFocused":"cw-tag-selector-module__optionFocused__8-lv8 cw-choice-dropdown-module__optionFocused__BYMxj","optionDot":"cw-tag-selector-module__optionDot__CdFlG cw-choice-dropdown-module__colorCircle__x7mI9","selectAll":"cw-tag-selector-module__selectAll__HyvMA"};
5171
+ var styles$e = {"container":"cw-tag-selector-module__container__-do8i","value":"cw-tag-selector-module__value__TDAy3","inputBox":"cw-tag-selector-module__inputBox__3NGz9 cw-choice-input-box-module__inputBox__gHY9d","disabled":"cw-tag-selector-module__disabled__vbud9 cw-choice-input-box-module__disabled__TFAnC","dropdown":"cw-tag-selector-module__dropdown__X6Dob cw-choice-dropdown-module__dropdown__P0b4j","option":"cw-tag-selector-module__option__2UQ7g cw-choice-dropdown-module__option__uR-ro","optionFocused":"cw-tag-selector-module__optionFocused__8-lv8 cw-choice-dropdown-module__optionFocused__BYMxj","optionDot":"cw-tag-selector-module__optionDot__CdFlG cw-choice-dropdown-module__colorCircle__x7mI9","selectAll":"cw-tag-selector-module__selectAll__HyvMA"};
5172
5172
 
5173
5173
  /**
5174
5174
  * Multi-select input with chip tags and searchable dropdown.
@@ -5319,11 +5319,11 @@ function CwTagSelector({ id, options, value, onChange, labelProps, iconProps, al
5319
5319
  const feedbackId = useId();
5320
5320
  const feedbackIds = feedbackMessages.map((_, index) => `${feedbackId}-${index}`);
5321
5321
  const describedBy = feedbackIds.join(" ") || undefined;
5322
- return (jsxs("div", { ref: containerRef, className: `${styles$b.container}${className ? ` ${className}` : ""}`, style: style, id: id, "data-direction": direction, children: [jsxs(CwAlign, { ...alignProps, children: [labelProps && (jsxs(CwLabel, { ...labelProps, children: [iconProps && jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxs("div", { className: styles$b.value, children: [jsxs("div", { className: `${styles$b.inputBox}${disabled ? ` ${styles$b.disabled}` : ""}`, ref: inputBoxRef, onClick: () => { if (!disabled)
5323
- inputRef.current?.focus(); }, children: [selectedOptions.map(opt => (jsx(CwChip, { label: opt.label, colorScheme: opt.color ? "custom" : "info", customColor: opt.color, closable: !disabled, onClose: () => handleRemove(opt.value) }, opt.value))), jsx("input", { ref: inputRef, type: "text", value: search, onChange: handleInputChange, onFocus: handleInputFocus, onKeyDown: handleKeyDown, placeholder: selectedOptions.length === 0 ? placeholder : "", disabled: disabled, autoComplete: "off", "aria-describedby": describedBy }), value.length > 0 && !disabled && (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onMouseDown: (e) => e.preventDefault(), onClick: (e) => { e.stopPropagation(); onChange([]); setSearch(""); setOpen(false); }, tabIndex: -1, "aria-label": "Clear all" }))] }), feedbackMessages.map((fb, i) => (jsx("p", { id: feedbackIds[i], className: "cw-input-feedback", "data-color": fb.type, "aria-live": "polite", children: fb.message }, i)))] })] }), renderPanel((showSelectAll || filtered.length > 0) ? (jsxs("div", { ref: panelRef, className: styles$b.dropdown, style: panelStyle, children: [showSelectAll && !search && (jsxs("div", { className: styles$b.selectAll, onMouseDown: (e) => e.preventDefault(), onClick: handleToggleAll, children: [jsx("input", { type: "checkbox", checked: allSelected, readOnly: true, tabIndex: -1 }), allSelected ? "Deselect all" : "Select all"] })), jsx("ul", { ref: listRef, children: filtered.map((opt, idx) => (jsxs("li", { className: `${styles$b.option}${idx === focusedIndex ? ` ${styles$b.optionFocused}` : ""}`, onMouseDown: (e) => e.preventDefault(), onClick: () => handleSelect(opt.value), onMouseEnter: () => setFocusedIndex(idx), title: opt.tooltip, children: [opt.color && jsx("span", { className: styles$b.optionDot, style: { backgroundColor: opt.color } }), opt.label] }, opt.value))) })] })) : null)] }));
5322
+ return (jsxs("div", { ref: containerRef, className: `${styles$e.container}${className ? ` ${className}` : ""}`, style: style, id: id, "data-direction": direction, children: [jsxs(CwAlign, { ...alignProps, children: [labelProps && (jsxs(CwLabel, { ...labelProps, children: [iconProps && jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxs("div", { className: styles$e.value, children: [jsxs("div", { className: `${styles$e.inputBox}${disabled ? ` ${styles$e.disabled}` : ""}`, ref: inputBoxRef, onClick: () => { if (!disabled)
5323
+ inputRef.current?.focus(); }, children: [selectedOptions.map(opt => (jsx(CwChip, { label: opt.label, colorScheme: opt.color ? "custom" : "info", customColor: opt.color, closable: !disabled, onClose: () => handleRemove(opt.value) }, opt.value))), jsx("input", { ref: inputRef, type: "text", value: search, onChange: handleInputChange, onFocus: handleInputFocus, onKeyDown: handleKeyDown, placeholder: selectedOptions.length === 0 ? placeholder : "", disabled: disabled, autoComplete: "off", "aria-describedby": describedBy }), value.length > 0 && !disabled && (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onMouseDown: (e) => e.preventDefault(), onClick: (e) => { e.stopPropagation(); onChange([]); setSearch(""); setOpen(false); }, tabIndex: -1, "aria-label": "Clear all" }))] }), feedbackMessages.map((fb, i) => (jsx("p", { id: feedbackIds[i], className: "cw-input-feedback", "data-color": fb.type, "aria-live": "polite", children: fb.message }, i)))] })] }), renderPanel((showSelectAll || filtered.length > 0) ? (jsxs("div", { ref: panelRef, className: styles$e.dropdown, style: panelStyle, children: [showSelectAll && !search && (jsxs("div", { className: styles$e.selectAll, onMouseDown: (e) => e.preventDefault(), onClick: handleToggleAll, children: [jsx("input", { type: "checkbox", checked: allSelected, readOnly: true, tabIndex: -1 }), allSelected ? "Deselect all" : "Select all"] })), jsx("ul", { ref: listRef, children: filtered.map((opt, idx) => (jsxs("li", { className: `${styles$e.option}${idx === focusedIndex ? ` ${styles$e.optionFocused}` : ""}`, onMouseDown: (e) => e.preventDefault(), onClick: () => handleSelect(opt.value), onMouseEnter: () => setFocusedIndex(idx), title: opt.tooltip, children: [opt.color && jsx("span", { className: styles$e.optionDot, style: { backgroundColor: opt.color } }), opt.label] }, opt.value))) })] })) : null)] }));
5324
5324
  }
5325
5325
 
5326
- var styles$a = {"tree-container":"cw-tree-view-module__tree-container__NN-HJ","tree-wrapper":"cw-tree-view-module__tree-wrapper__keBZI","tree-item":"cw-tree-view-module__tree-item__prE9N","tree-node":"cw-tree-view-module__tree-node__wfro9","selected":"cw-tree-view-module__selected__XJQ0w","non-selectable":"cw-tree-view-module__non-selectable__YuPSx","tree-children":"cw-tree-view-module__tree-children__ji8CZ","empty-state":"cw-tree-view-module__empty-state__yvRjo","tree-label":"cw-tree-view-module__tree-label__ss3Nf","tree-spacer":"cw-tree-view-module__tree-spacer__E9Ud2"};
5326
+ var styles$d = {"tree-container":"cw-tree-view-module__tree-container__NN-HJ","tree-wrapper":"cw-tree-view-module__tree-wrapper__keBZI","tree-item":"cw-tree-view-module__tree-item__prE9N","tree-node":"cw-tree-view-module__tree-node__wfro9","selected":"cw-tree-view-module__selected__XJQ0w","non-selectable":"cw-tree-view-module__non-selectable__YuPSx","tree-children":"cw-tree-view-module__tree-children__ji8CZ","empty-state":"cw-tree-view-module__empty-state__yvRjo","tree-label":"cw-tree-view-module__tree-label__ss3Nf","tree-spacer":"cw-tree-view-module__tree-spacer__E9Ud2"};
5327
5327
 
5328
5328
  function CwTreeView({ data, onSelect, allowParentSelection = false, selectedId: initialSelectedId = null, ...dataAttributes }) {
5329
5329
  const [expanded, setExpanded] = useState(new Set());
@@ -5390,10 +5390,10 @@ function CwTreeView({ data, onSelect, allowParentSelection = false, selectedId:
5390
5390
  const isLeaf = !hasChildren;
5391
5391
  const isSelected = selectedId?.toString().toLowerCase() === node.id.toString().toLowerCase();
5392
5392
  const selectable = allowParentSelection || isLeaf;
5393
- return (jsxs("div", { className: styles$a["tree-item"], children: [jsxs("div", { className: [
5394
- styles$a["tree-node"],
5395
- isSelected && styles$a["selected"],
5396
- !selectable && styles$a["non-selectable"]
5393
+ return (jsxs("div", { className: styles$d["tree-item"], children: [jsxs("div", { className: [
5394
+ styles$d["tree-node"],
5395
+ isSelected && styles$d["selected"],
5396
+ !selectable && styles$d["non-selectable"]
5397
5397
  ].filter(Boolean).join(' '), style: { paddingLeft: `${depth * 24 + 8}px` }, onClick: () => {
5398
5398
  if (selectable) {
5399
5399
  setSelectedId(node.id);
@@ -5405,7 +5405,7 @@ function CwTreeView({ data, onSelect, allowParentSelection = false, selectedId:
5405
5405
  }, children: [hasChildren && (jsx(CwButton, { variant: "icon", color: "neutral", icon: isExpanded ? "chevron-down" : "chevron-right", "aria-expanded": isExpanded, "aria-label": `${isExpanded ? "Collapse" : "Expand"} ${node.label}`, onClick: (event) => {
5406
5406
  event.stopPropagation();
5407
5407
  toggleExpand(node.id);
5408
- } })), jsx("div", { className: `${styles$a["tree-label"]} ${!hasChildren ? styles$a["tree-spacer"] : ''}`, children: node.label })] }), hasChildren && isExpanded && (jsx("div", { className: styles$a["tree-children"], children: node.children.map((child) => renderNode(child, depth + 1)) }))] }, node.id));
5408
+ } })), jsx("div", { className: `${styles$d["tree-label"]} ${!hasChildren ? styles$d["tree-spacer"] : ''}`, children: node.label })] }), hasChildren && isExpanded && (jsx("div", { className: styles$d["tree-children"], children: node.children.map((child) => renderNode(child, depth + 1)) }))] }, node.id));
5409
5409
  };
5410
5410
  // Function to search for nodes that match the search term
5411
5411
  const searchInTree = (nodes, searchTerm) => {
@@ -5429,7 +5429,7 @@ function CwTreeView({ data, onSelect, allowParentSelection = false, selectedId:
5429
5429
  return results;
5430
5430
  };
5431
5431
  const filteredData = searchInTree(data, search);
5432
- return (jsxs("div", { ...dataAttributes, className: `cw-tree-view ${styles$a["tree-container"]}`, children: [jsxs("header", { children: [jsx("input", { type: "text", placeholder: "Search in tree...", value: search, onChange: (e) => setSearch(e.target.value) }), search && (jsx(CwButton, { onClick: () => setSearch(""), type: "button", icon: "close", variant: "icon", color: "neutral" }))] }), jsx("div", { className: styles$a["tree-wrapper"], children: filteredData.length > 0 ? (filteredData.map((node) => renderNode(node))) : (jsxs("div", { className: styles$a["empty-state"], children: [jsx(CwIcon, { iconId: "comment" }), search ? "No results found" : "There are no items"] })) })] }));
5432
+ return (jsxs("div", { ...dataAttributes, className: `cw-tree-view ${styles$d["tree-container"]}`, children: [jsxs("header", { children: [jsx("input", { type: "text", placeholder: "Search in tree...", value: search, onChange: (e) => setSearch(e.target.value) }), search && (jsx(CwButton, { onClick: () => setSearch(""), type: "button", icon: "close", variant: "icon", color: "neutral" }))] }), jsx("div", { className: styles$d["tree-wrapper"], children: filteredData.length > 0 ? (filteredData.map((node) => renderNode(node))) : (jsxs("div", { className: styles$d["empty-state"], children: [jsx(CwIcon, { iconId: "comment" }), search ? "No results found" : "There are no items"] })) })] }));
5433
5433
  }
5434
5434
 
5435
5435
  const EXACT_PHRASE = /"([^"]+)"/g;
@@ -5497,7 +5497,7 @@ function sortNavItems(items, alphabetically) {
5497
5497
  return [...items].sort((first, second) => first.label.localeCompare(second.label));
5498
5498
  }
5499
5499
 
5500
- var styles$9 = {"menu":"cw-nav-menu-module__menu__LmeQg","expandIndicator":"cw-nav-menu-module__expandIndicator__TBSdQ","favorites":"cw-nav-menu-module__favorites__Esaqd","favoritesContent":"cw-nav-menu-module__favoritesContent__l5DGG","favoriteStar":"cw-nav-menu-module__favoriteStar__J-jzg","emptyMessage":"cw-nav-menu-module__emptyMessage__-CQNd","skeleton":"cw-nav-menu-module__skeleton__INQqF"};
5500
+ var styles$c = {"menu":"cw-nav-menu-module__menu__LmeQg","expandIndicator":"cw-nav-menu-module__expandIndicator__TBSdQ","favorites":"cw-nav-menu-module__favorites__Esaqd","favoritesContent":"cw-nav-menu-module__favoritesContent__l5DGG","favoriteStar":"cw-nav-menu-module__favoriteStar__J-jzg","emptyMessage":"cw-nav-menu-module__emptyMessage__-CQNd","skeleton":"cw-nav-menu-module__skeleton__INQqF"};
5501
5501
 
5502
5502
  const SKELETON_ROW_COUNT = 5;
5503
5503
  const defaultRenderLink = (item, children) => (jsx("a", { href: item.href, children: children }));
@@ -5509,13 +5509,13 @@ function CwNavMenu({ items, loading = false, isActive, renderLink = defaultRende
5509
5509
  const renderItem = (item, level) => {
5510
5510
  const children = item.children;
5511
5511
  if (children && children.length > 0) {
5512
- return (jsx("li", { children: jsxs("details", { "data-level": level, open: hasActiveDescendant(item) || undefined, children: [jsxs("summary", { children: [item.icon && jsx(CwIcon, { iconId: item.icon, size: level >= 2 ? "small" : "medium" }), item.label, (showExpandIndicator || level >= 2) && (jsx(CwIcon, { iconId: "chevron-down", size: "small", className: styles$9.expandIndicator }))] }), jsx("ul", { children: children.map(child => renderItem(child, level + 1)) })] }) }, item.id));
5512
+ return (jsx("li", { children: jsxs("details", { "data-level": level, open: hasActiveDescendant(item) || undefined, children: [jsxs("summary", { children: [item.icon && jsx(CwIcon, { iconId: item.icon, size: level >= 2 ? "small" : "medium" }), item.label, (showExpandIndicator || level >= 2) && (jsx(CwIcon, { iconId: "chevron-down", size: "small", className: styles$c.expandIndicator }))] }), jsx("ul", { children: children.map(child => renderItem(child, level + 1)) })] }) }, item.id));
5513
5513
  }
5514
- return (jsx("li", { "data-active": isActive?.(item) ? "true" : undefined, children: renderLink(item, jsxs(Fragment, { children: [item.icon && jsx(CwIcon, { iconId: item.icon, size: "medium" }), item.label, isFavorite?.(item) && jsx(CwIcon, { iconId: "star", size: "small", className: styles$9.favoriteStar })] })) }, item.id));
5514
+ return (jsx("li", { "data-active": isActive?.(item) ? "true" : undefined, children: renderLink(item, jsxs(Fragment, { children: [item.icon && jsx(CwIcon, { iconId: item.icon, size: "medium" }), item.label, isFavorite?.(item) && jsx(CwIcon, { iconId: "star", size: "small", className: styles$c.favoriteStar })] })) }, item.id));
5515
5515
  };
5516
- return (jsxs("nav", { ...navProps, className: [styles$9.menu, className].filter(Boolean).join(" "), "aria-busy": loading || undefined, children: [favoritesSlot && (jsxs("details", { open: true, ...favoritesProps, className: [styles$9.favorites, favoritesProps?.className].filter(Boolean).join(" "), children: [jsxs("summary", { children: [jsx(CwIcon, { iconId: "star", size: "medium" }), favoritesLabel] }), jsx("div", { className: styles$9.favoritesContent, children: favoritesSlot })] })), beforeTreeSlot, jsx("ul", { children: loading
5517
- ? Array.from({ length: SKELETON_ROW_COUNT }, (_unused, index) => (jsx("li", { className: styles$9.skeleton, children: jsx(CwSkeleton, { height: "var(--cw-size-small)", radius: "var(--cw-border-radius-small)" }) }, index)))
5518
- : visibleItems.map(item => renderItem(item, 1)) }), showEmptyMessage && jsx("p", { className: styles$9.emptyMessage, children: emptyMessage })] }));
5516
+ return (jsxs("nav", { ...navProps, className: [styles$c.menu, className].filter(Boolean).join(" "), "aria-busy": loading || undefined, children: [favoritesSlot && (jsxs("details", { open: true, ...favoritesProps, className: [styles$c.favorites, favoritesProps?.className].filter(Boolean).join(" "), children: [jsxs("summary", { children: [jsx(CwIcon, { iconId: "star", size: "medium" }), favoritesLabel] }), jsx("div", { className: styles$c.favoritesContent, children: favoritesSlot })] })), beforeTreeSlot, jsx("ul", { children: loading
5517
+ ? Array.from({ length: SKELETON_ROW_COUNT }, (_unused, index) => (jsx("li", { className: styles$c.skeleton, children: jsx(CwSkeleton, { height: "var(--cw-size-small)", radius: "var(--cw-border-radius-small)" }) }, index)))
5518
+ : visibleItems.map(item => renderItem(item, 1)) }), showEmptyMessage && jsx("p", { className: styles$c.emptyMessage, children: emptyMessage })] }));
5519
5519
  }
5520
5520
 
5521
5521
  var dropdownStyles = {"dropdown":"cw-choice-dropdown-module__dropdown__P0b4j","option":"cw-choice-dropdown-module__option__uR-ro","optionFocused":"cw-choice-dropdown-module__optionFocused__BYMxj"};
@@ -5681,7 +5681,7 @@ function CwSearchInput(optionsProps) {
5681
5681
  return (jsxs("div", { className: `cw-search-input ${className || ""}`, style: style, ...otherProps, "data-direction": direction, children: [jsxs(CwAlign, { ...alignProps, children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: "cw-search-input-wrapper", ref: wrapperRef, children: [jsx("input", { ref: inputRef, id: id, type: "text", value: searchText, onChange: handleInputChange, onKeyDown: handleKeyDown, onFocus: handleInputFocus, onBlur: handleInputBlur, placeholder: placeholder, className: "cw-input-search", disabled: disabled, autoFocus: autoFocus, autoComplete: "off", role: "combobox", "aria-haspopup": "listbox", "aria-expanded": showDropdown && filteredOptions.length > 0, "aria-controls": listboxId, "aria-activedescendant": highlightedIndex >= 0 ? optionId(highlightedIndex) : undefined }), isLoading && (jsx("div", { className: "cw-search-input-loading", children: jsx(CwIcon, { iconId: "spinner" }) })), jsx("div", { className: "cw-search-input-icons", children: searchText && !disabled && !isLoading ? (jsx(CwButton, { type: "button", onClick: handleClearClick, "aria-label": "Clear search", variant: "icon", icon: "close", color: "neutral" })) : (iconProps ? jsx(CwIcon, { ...iconProps }) : jsx(CwIcon, { iconId: "search" })) })] })] }), renderPanel(jsx("div", { ref: panelRef, id: listboxId, className: dropdownStyles.dropdown, style: panelStyle, role: "listbox", children: jsx("ul", { children: filteredOptions.map((option, index) => (jsx("li", { id: optionId(index), className: `${dropdownStyles.option}${index === highlightedIndex ? ` ${dropdownStyles.optionFocused}` : ""}`, onClick: () => handleOptionSelect(option), onMouseDown: (e) => e.preventDefault(), onMouseEnter: () => setHighlightedIndex(index), role: "option", "aria-selected": index === highlightedIndex, children: renderOption ? renderOption(option) : option.description }, option.id))) }) }))] }));
5682
5682
  }
5683
5683
 
5684
- var styles$8 = {"value":"cw-search-async-module__value__z53xT"};
5684
+ var styles$b = {"value":"cw-search-async-module__value__z53xT"};
5685
5685
 
5686
5686
  /**
5687
5687
  * Generic API-backed search input. Fetches matching options from a caller-supplied `onSearch`
@@ -5945,10 +5945,10 @@ const CwSearchAsync = ({ onSearch, onChange, value, onResolveInitial, onResolveS
5945
5945
  return (jsxs("div", { ...dataAttributes, className: `cw-search-input ${className}`, style: {
5946
5946
  ...(width ? { width } : {}),
5947
5947
  ...(labelProps?.labelWidth ? { "--label-width": labelProps.labelWidth } : {}),
5948
- }, "data-direction": direction, children: [jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: styles$8.value, children: [jsxs("div", { className: "cw-search-input-wrapper", ref: wrapperRef, children: [jsx("input", { ref: inputRef, type: "text", value: inputValue, onChange: handleInputChange, onKeyDown: handleKeyDown, onFocus: handleInputFocus, placeholder: isInitialLoading ? "Loading…" : placeholder, disabled: disabled, required: required, autoComplete: "off", role: "combobox", "aria-haspopup": "listbox", "aria-expanded": showDropdown, "aria-controls": listboxId, "aria-activedescendant": highlightedIndex >= 0 ? optionId(highlightedIndex) : undefined, "aria-describedby": describedBy, title: tooltipText }), (isLoading || isInitialLoading) && (jsx("div", { className: "cw-search-input-loading", children: jsx(CwIcon, { iconId: "spinner" }) })), jsx("div", { className: "cw-search-input-icons", children: inputValue && !disabled && !isInitialLoading ? (jsx(CwButton, { type: "button", onClick: handleClear, "aria-label": "Clear selection", variant: "icon", icon: "close", color: "neutral" })) : (icon ? jsx(CwIcon, { ...icon }) : jsx(CwIcon, { iconId: "search" })) })] }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] })] }), renderPanel(jsx("div", { ref: panelRef, id: listboxId, className: dropdownStyles.dropdown, style: panelStyle, role: "listbox", children: jsx("ul", { children: options.map((option, index) => (jsx("li", { id: optionId(index), className: `${dropdownStyles.option}${index === highlightedIndex ? ` ${dropdownStyles.optionFocused}` : ""}`, onClick: () => handleOptionSelect(option.id), onMouseDown: (e) => e.preventDefault(), onMouseEnter: () => setHighlightedIndex(index), role: "option", "aria-selected": index === highlightedIndex, children: option.subLabel ? (jsxs("span", { className: "cw-search-async-option-lines", children: [jsx("span", { children: option.label }), jsx("span", { className: "cw-search-async-option-sub", children: option.subLabel })] })) : (option.label) }, option.id))) }) }))] }));
5948
+ }, "data-direction": direction, children: [jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: styles$b.value, children: [jsxs("div", { className: "cw-search-input-wrapper", ref: wrapperRef, children: [jsx("input", { ref: inputRef, type: "text", value: inputValue, onChange: handleInputChange, onKeyDown: handleKeyDown, onFocus: handleInputFocus, placeholder: isInitialLoading ? "Loading…" : placeholder, disabled: disabled, required: required, autoComplete: "off", role: "combobox", "aria-haspopup": "listbox", "aria-expanded": showDropdown, "aria-controls": listboxId, "aria-activedescendant": highlightedIndex >= 0 ? optionId(highlightedIndex) : undefined, "aria-describedby": describedBy, title: tooltipText }), (isLoading || isInitialLoading) && (jsx("div", { className: "cw-search-input-loading", children: jsx(CwIcon, { iconId: "spinner" }) })), jsx("div", { className: "cw-search-input-icons", children: inputValue && !disabled && !isInitialLoading ? (jsx(CwButton, { type: "button", onClick: handleClear, "aria-label": "Clear selection", variant: "icon", icon: "close", color: "neutral" })) : (icon ? jsx(CwIcon, { ...icon }) : jsx(CwIcon, { iconId: "search" })) })] }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] })] }), renderPanel(jsx("div", { ref: panelRef, id: listboxId, className: dropdownStyles.dropdown, style: panelStyle, role: "listbox", children: jsx("ul", { children: options.map((option, index) => (jsx("li", { id: optionId(index), className: `${dropdownStyles.option}${index === highlightedIndex ? ` ${dropdownStyles.optionFocused}` : ""}`, onClick: () => handleOptionSelect(option.id), onMouseDown: (e) => e.preventDefault(), onMouseEnter: () => setHighlightedIndex(index), role: "option", "aria-selected": index === highlightedIndex, children: option.subLabel ? (jsxs("span", { className: "cw-search-async-option-lines", children: [jsx("span", { children: option.label }), jsx("span", { className: "cw-search-async-option-sub", children: option.subLabel })] })) : (option.label) }, option.id))) }) }))] }));
5949
5949
  };
5950
5950
 
5951
- var styles$7 = {"menu":"cw-context-menu-module__menu__tXmun","item":"cw-context-menu-module__item__-ko8L","arrow":"cw-context-menu-module__arrow__LHZmQ"};
5951
+ var styles$a = {"menu":"cw-context-menu-module__menu__tXmun","item":"cw-context-menu-module__item__-ko8L","arrow":"cw-context-menu-module__arrow__LHZmQ"};
5952
5952
 
5953
5953
  const ARROW_SIZE = 8;
5954
5954
  const SAFETY_MARGIN = 8;
@@ -6089,14 +6089,14 @@ const CwAnchoredMenu = ({ children, options, onSelect, placement = 'bottom', ope
6089
6089
  document.removeEventListener("keydown", handleEscape);
6090
6090
  };
6091
6091
  }, [isOpen]);
6092
- return (jsxs(Fragment, { children: [jsx("div", { ref: triggerRef, onContextMenu: handleContextMenu, style: { display: "contents" }, children: children }), isOpen && normalizedOptions.length > 0 && createPortal(jsxs("div", { ref: menuRef, className: styles$7["menu"], style: {
6092
+ return (jsxs(Fragment, { children: [jsx("div", { ref: triggerRef, onContextMenu: handleContextMenu, style: { display: "contents" }, children: children }), isOpen && normalizedOptions.length > 0 && createPortal(jsxs("div", { ref: menuRef, className: styles$a["menu"], style: {
6093
6093
  top: `${position.y}px`,
6094
6094
  left: `${position.x}px`,
6095
- }, "data-has-arrow": "true", children: [jsx("div", { ref: arrowRef, className: styles$7["arrow"], "data-placement": placement }), normalizedOptions.map(option => (jsxs("div", { onClick: (e) => {
6095
+ }, "data-has-arrow": "true", children: [jsx("div", { ref: arrowRef, className: styles$a["arrow"], "data-placement": placement }), normalizedOptions.map(option => (jsxs("div", { onClick: (e) => {
6096
6096
  e.stopPropagation();
6097
6097
  e.preventDefault();
6098
6098
  handleOptionClick(option);
6099
- }, className: `${styles$7["item"]} ${option.disabled ? styles$7["disabled"] : ""}`, "data-disabled": option.disabled, children: [option.icon && jsx("span", { className: styles$7["icon"], children: option.icon }), option.label] }, option.key)))] }), document.body)] }));
6099
+ }, className: `${styles$a["item"]} ${option.disabled ? styles$a["disabled"] : ""}`, "data-disabled": option.disabled, children: [option.icon && jsx("span", { className: styles$a["icon"], children: option.icon }), option.label] }, option.key)))] }), document.body)] }));
6100
6100
  };
6101
6101
 
6102
6102
  /**
@@ -6169,13 +6169,13 @@ const CwContextMenu = ({ children, options, offset = DEFAULT_OFFSET, onSelect })
6169
6169
  document.removeEventListener("keydown", handleEscape);
6170
6170
  };
6171
6171
  }, [isOpen]);
6172
- return (jsxs(Fragment, { children: [jsx("div", { onContextMenu: handleContextMenu, children: children }), isOpen && createPortal(jsx("div", { ref: menuRef, className: styles$7["menu"], style: {
6172
+ return (jsxs(Fragment, { children: [jsx("div", { onContextMenu: handleContextMenu, children: children }), isOpen && createPortal(jsx("div", { ref: menuRef, className: styles$a["menu"], style: {
6173
6173
  top: `${position.y}px`,
6174
6174
  left: `${position.x}px`,
6175
- }, children: options.map(option => (jsx("div", { onClick: () => handleOptionClick(option), className: styles$7["item"], children: option }, option))) }), document.body)] }));
6175
+ }, children: options.map(option => (jsx("div", { onClick: () => handleOptionClick(option), className: styles$a["item"], children: option }, option))) }), document.body)] }));
6176
6176
  };
6177
6177
 
6178
- var styles$6 = {"split":"cw-button-split-module__split__B2KbU","menu":"cw-button-split-module__menu__mKDlt","item":"cw-button-split-module__item__Aqw6f"};
6178
+ var styles$9 = {"split":"cw-button-split-module__split__B2KbU","menu":"cw-button-split-module__menu__mKDlt","item":"cw-button-split-module__item__Aqw6f"};
6179
6179
 
6180
6180
  /**
6181
6181
  * CwButtonSplit - A primary action joined to a dropdown of alternative actions.
@@ -6201,7 +6201,7 @@ function CwButtonSplit({ text, icon, onClick, actions, onSelect, variant = "soli
6201
6201
  onSelect(action.key);
6202
6202
  event.currentTarget.closest("[popover]")?.hidePopover();
6203
6203
  };
6204
- return (jsxs("div", { className: styles$6.split, "data-variant": variant, "data-testid": dataTestId, children: [jsx(CwButton, { text: text, icon: icon, variant: variant, color: color, size: size, onClick: onClick, disabled: disabled }), jsx(CwPopoverButton, { icon: "chevron-down", title: "More actions", variant: variant, color: color, size: size, disabled: disabled, placement: placement, children: jsx("div", { className: styles$6.menu, children: actions.map((action) => (jsx(CwButton, { variant: "ghost", color: "neutral", text: action.label, icon: action.icon, disabled: action.disabled, className: styles$6.item, onClick: handleSelect(action) }, action.key))) }) })] }));
6204
+ return (jsxs("div", { className: styles$9.split, "data-variant": variant, "data-testid": dataTestId, children: [jsx(CwButton, { text: text, icon: icon, variant: variant, color: color, size: size, onClick: onClick, disabled: disabled }), jsx(CwPopoverButton, { icon: "chevron-down", title: "More actions", variant: variant, color: color, size: size, disabled: disabled, placement: placement, children: jsx("div", { className: styles$9.menu, children: actions.map((action) => (jsx(CwButton, { variant: "ghost", color: "neutral", text: action.label, icon: action.icon, disabled: action.disabled, className: styles$9.item, onClick: handleSelect(action) }, action.key))) }) })] }));
6205
6205
  }
6206
6206
 
6207
6207
  /**
@@ -6269,7 +6269,7 @@ function useRovingSingleSelect(options, value, onChange) {
6269
6269
  return { activeIndex, getSegmentProps };
6270
6270
  }
6271
6271
 
6272
- var styles$5 = {"switch":"cw-button-switch-module__switch__vdWV-","segment":"cw-button-switch-module__segment__JmVla","iconOnly":"cw-button-switch-module__iconOnly__-kCwj"};
6272
+ var styles$8 = {"switch":"cw-button-switch-module__switch__vdWV-","segment":"cw-button-switch-module__segment__JmVla","iconOnly":"cw-button-switch-module__iconOnly__-kCwj"};
6273
6273
 
6274
6274
  /**
6275
6275
  * CwButtonSwitch - Segmented single-select control: a strip of joined CwButtons.
@@ -6299,10 +6299,10 @@ var styles$5 = {"switch":"cw-button-switch-module__switch__vdWV-","segment":"cw-
6299
6299
  */
6300
6300
  function CwButtonSwitch({ options, value, onChange, size = "medium", color = "primary", iconOnly = false, direction = "row", disabled = false, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, ...dataAttributes }) {
6301
6301
  const { getSegmentProps } = useRovingSingleSelect(options, value, onChange);
6302
- return (jsx("div", { ...dataAttributes, className: `cw-button-switch ${styles$5.switch}`, role: "radiogroup", "aria-labelledby": ariaLabelledby, "aria-label": ariaLabelledby ? undefined : ariaLabel, "data-direction": direction, children: options.map((option, index) => {
6302
+ return (jsx("div", { ...dataAttributes, className: `cw-button-switch ${styles$8.switch}`, role: "radiogroup", "aria-labelledby": ariaLabelledby, "aria-label": ariaLabelledby ? undefined : ariaLabel, "data-direction": direction, children: options.map((option, index) => {
6303
6303
  const selected = option.value === value;
6304
6304
  const segmentProps = getSegmentProps(index);
6305
- return (jsx(CwButton, { text: iconOnly ? undefined : option.label, title: iconOnly ? option.label : undefined, icon: option.icon, size: size, color: color, variant: selected ? "solid" : "outline", role: "radio", "aria-checked": selected, disabled: disabled || option.disabled, onClick: () => onChange(option.value), className: `${styles$5.segment}${iconOnly ? ` ${styles$5.iconOnly}` : ""}`, tabIndex: segmentProps.tabIndex, ref: segmentProps.ref, onKeyDown: segmentProps.onKeyDown }, option.value));
6305
+ return (jsx(CwButton, { text: iconOnly ? undefined : option.label, title: iconOnly ? option.label : undefined, icon: option.icon, size: size, color: color, variant: selected ? "solid" : "outline", role: "radio", "aria-checked": selected, disabled: disabled || option.disabled, onClick: () => onChange(option.value), className: `${styles$8.segment}${iconOnly ? ` ${styles$8.iconOnly}` : ""}`, tabIndex: segmentProps.tabIndex, ref: segmentProps.ref, onKeyDown: segmentProps.onKeyDown }, option.value));
6306
6306
  }) }));
6307
6307
  }
6308
6308
 
@@ -6344,7 +6344,7 @@ function CwBtnCancel({ cw_btnOnclick, cw_btn_disabled, onClick, disabled, ...res
6344
6344
  return (jsx(CwButton, { ...rest, variant: "icon", icon: "cancel", color: "danger", onClick: onClick ?? cw_btnOnclick, disabled: disabled ?? cw_btn_disabled, title: "Cancel" }));
6345
6345
  }
6346
6346
 
6347
- var styles$4 = {"value":"cw-pickers-base-module__value__BR67P","pickerWrapper":"cw-pickers-base-module__pickerWrapper__Fb9Zo","pickerIcons":"cw-pickers-base-module__pickerIcons__dyd2-","pickerPopup":"cw-pickers-base-module__pickerPopup__dkxJo"};
6347
+ var styles$7 = {"value":"cw-pickers-base-module__value__BR67P","pickerWrapper":"cw-pickers-base-module__pickerWrapper__Fb9Zo","pickerIcons":"cw-pickers-base-module__pickerIcons__dyd2-","pickerPopup":"cw-pickers-base-module__pickerPopup__dkxJo"};
6348
6348
 
6349
6349
  /**
6350
6350
  * Renders a picker popup in a portal so it escapes overflow containers.
@@ -6584,7 +6584,7 @@ function CwDatePicker({ value, onChange, minDate, maxDate, disabledDates, disabl
6584
6584
  ...(maxDate ? [{ after: maxDate }] : []),
6585
6585
  ...(disabledMatcher ? [disabledMatcher] : []),
6586
6586
  ], [disabledDates, minDate, maxDate, disabledMatcher]);
6587
- return (jsx("div", { ...dataAttributes, ref: containerRef, className: `cw-datepicker ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: styles$4.value, children: [jsxs("div", { ref: wrapperRef, className: styles$4.pickerWrapper, children: [jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length }), jsx("div", { className: styles$4.pickerIcons, children: showClear && value && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClear, tabIndex: -1, "aria-label": "Clear date" })) : (jsx(CwIcon, { iconId: "calendar" })) }), renderPopup(jsxs("div", { ref: popupRef, className: styles$4.pickerPopup, style: popupStyle, children: [jsx(DayPicker, { mode: "single", selected: value || undefined, defaultMonth: defaultMonth || value || undefined, onSelect: handleDaySelect, disabled: disabledDays, numberOfMonths: numberOfMonths, locale: locale, captionLayout: "dropdown", startMonth: dropdownStartMonth, endMonth: dropdownEndMonth, modifiers: {
6587
+ return (jsx("div", { ...dataAttributes, ref: containerRef, className: `cw-datepicker ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: styles$7.value, children: [jsxs("div", { ref: wrapperRef, className: styles$7.pickerWrapper, children: [jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length }), jsx("div", { className: styles$7.pickerIcons, children: showClear && value && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClear, tabIndex: -1, "aria-label": "Clear date" })) : (jsx(CwIcon, { iconId: "calendar" })) }), renderPopup(jsxs("div", { ref: popupRef, className: styles$7.pickerPopup, style: popupStyle, children: [jsx(DayPicker, { mode: "single", selected: value || undefined, defaultMonth: defaultMonth || value || undefined, onSelect: handleDaySelect, disabled: disabledDays, numberOfMonths: numberOfMonths, locale: locale, captionLayout: "dropdown", startMonth: dropdownStartMonth, endMonth: dropdownEndMonth, modifiers: {
6588
6588
  today: new Date(),
6589
6589
  }, modifiersClassNames: {
6590
6590
  today: "rdp-day-today",
@@ -7233,7 +7233,7 @@ function CwDateRangePicker({ value, onChange, minDate, maxDate, disabledDates, d
7233
7233
  }
7234
7234
  return undefined;
7235
7235
  }, [value]);
7236
- return (jsx("div", { ...dataAttributes, ref: containerRef, className: `cw-rangepicker ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: styles$4.value, children: [jsxs("div", { ref: wrapperRef, className: rangeStyles.rangeWrapper, children: [jsxs("div", { className: styles$4.pickerWrapper, children: [jsx("input", { ref: inputFromRef, type: "text", value: inputFromValue, placeholder: placeholderFrom, onChange: handleInputFromChange, onBlur: () => handleInputBlur('from'), onClick: handleInputFromClick, onKeyDown: (e) => handleInputKeyDown(e, 'from'), disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length, "data-focused": focusedInput === 'from' }), jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.from && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearFrom, tabIndex: -1, "aria-label": "Clear from date" })) : (jsx(CwIcon, { iconId: "calendar" })) })] }), jsx(CwIcon, { iconId: "arrow-right", size: "medium" }), jsxs("div", { className: styles$4.pickerWrapper, children: [jsx("input", { ref: inputToRef, type: "text", value: inputToValue, placeholder: placeholderTo, onChange: handleInputToChange, onBlur: () => handleInputBlur('to'), onClick: handleInputToClick, onKeyDown: (e) => handleInputKeyDown(e, 'to'), disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length, "data-focused": focusedInput === 'to' }), jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.to && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearTo, tabIndex: -1, "aria-label": "Clear to date" })) : (jsx(CwIcon, { iconId: "calendar" })) })] }), renderPopup(jsxs("div", { ref: popupRef, className: `${styles$4.pickerPopup} ${rangeStyles.rangePopup}`, style: popupStyle, children: [jsxs("div", { className: rangeStyles.rangeCalendarRow, children: [showPresets && presetsToRender.length > 0 && (jsx("div", { className: rangeStyles.presetList, children: presetsToRender.map((preset) => (jsx("button", { type: "button", onClick: (e) => handlePresetClick(preset, e), children: preset.label }, preset.key))) })), jsx(DayPicker, { mode: "range", selected: selectedRange, onSelect: handleRangeSelect, disabled: disabledDays, numberOfMonths: numberOfMonths, defaultMonth: defaultMonth || value?.from || undefined, modifiers: {
7236
+ return (jsx("div", { ...dataAttributes, ref: containerRef, className: `cw-rangepicker ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: styles$7.value, children: [jsxs("div", { ref: wrapperRef, className: rangeStyles.rangeWrapper, children: [jsxs("div", { className: styles$7.pickerWrapper, children: [jsx("input", { ref: inputFromRef, type: "text", value: inputFromValue, placeholder: placeholderFrom, onChange: handleInputFromChange, onBlur: () => handleInputBlur('from'), onClick: handleInputFromClick, onKeyDown: (e) => handleInputKeyDown(e, 'from'), disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length, "data-focused": focusedInput === 'from' }), jsx("div", { className: styles$7.pickerIcons, children: showClear && value?.from && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearFrom, tabIndex: -1, "aria-label": "Clear from date" })) : (jsx(CwIcon, { iconId: "calendar" })) })] }), jsx(CwIcon, { iconId: "arrow-right", size: "medium" }), jsxs("div", { className: styles$7.pickerWrapper, children: [jsx("input", { ref: inputToRef, type: "text", value: inputToValue, placeholder: placeholderTo, onChange: handleInputToChange, onBlur: () => handleInputBlur('to'), onClick: handleInputToClick, onKeyDown: (e) => handleInputKeyDown(e, 'to'), disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length, "data-focused": focusedInput === 'to' }), jsx("div", { className: styles$7.pickerIcons, children: showClear && value?.to && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearTo, tabIndex: -1, "aria-label": "Clear to date" })) : (jsx(CwIcon, { iconId: "calendar" })) })] }), renderPopup(jsxs("div", { ref: popupRef, className: `${styles$7.pickerPopup} ${rangeStyles.rangePopup}`, style: popupStyle, children: [jsxs("div", { className: rangeStyles.rangeCalendarRow, children: [showPresets && presetsToRender.length > 0 && (jsx("div", { className: rangeStyles.presetList, children: presetsToRender.map((preset) => (jsx("button", { type: "button", onClick: (e) => handlePresetClick(preset, e), children: preset.label }, preset.key))) })), jsx(DayPicker, { mode: "range", selected: selectedRange, onSelect: handleRangeSelect, disabled: disabledDays, numberOfMonths: numberOfMonths, defaultMonth: defaultMonth || value?.from || undefined, modifiers: {
7237
7237
  today: new Date(),
7238
7238
  }, modifiersClassNames: {
7239
7239
  today: "rdp-day-today",
@@ -7406,10 +7406,10 @@ function CwTimePicker({ value, onChange, interval = 15, minTime, maxTime, labelP
7406
7406
  const displayValue = inputValue;
7407
7407
  // If using native time input
7408
7408
  if (useNative) {
7409
- return (jsx("div", { ...dataAttributes, className: `cw-timepicker cw-timepicker-native ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: styles$4.value, children: [jsx("div", { className: styles$4.pickerWrapper, children: jsx("input", { type: "time", value: displayValue, onChange: handleNativeChange, min: minTime, max: maxTime, step: interval * 60, disabled: disabled, required: required, placeholder: placeholder, "aria-describedby": describedBy, className: "cw-timepicker-native" }) }), feedbackElements] })] }) }));
7409
+ return (jsx("div", { ...dataAttributes, className: `cw-timepicker cw-timepicker-native ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: styles$7.value, children: [jsx("div", { className: styles$7.pickerWrapper, children: jsx("input", { type: "time", value: displayValue, onChange: handleNativeChange, min: minTime, max: maxTime, step: interval * 60, disabled: disabled, required: required, placeholder: placeholder, "aria-describedby": describedBy, className: "cw-timepicker-native" }) }), feedbackElements] })] }) }));
7410
7410
  }
7411
7411
  // Custom time picker
7412
- return (jsx("div", { ...dataAttributes, ref: containerRef, className: `cw-timepicker ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: styles$4.value, children: [jsxs("div", { ref: wrapperRef, className: `${styles$4.pickerWrapper} ${timeStyles.field}${showClear ? "" : ` ${timeStyles.narrow}`}`, children: [jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, "aria-describedby": describedBy, required: required, maxLength: 5 }), showClear && (jsx("div", { className: styles$4.pickerIcons, children: value && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", icon: "close", color: "neutral", onClick: handleClear, tabIndex: -1, "aria-label": "Clear time" })) : (jsx(CwIcon, { iconId: "clock" })) })), renderPopup(jsx("div", { ref: popupRef, className: `${styles$4.pickerPopup} ${timeStyles.timePickerPopup}`, style: popupStyle, children: jsx("div", { className: timeStyles.timePickerList, children: timeOptions.map((time) => {
7412
+ return (jsx("div", { ...dataAttributes, ref: containerRef, className: `cw-timepicker ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: styles$7.value, children: [jsxs("div", { ref: wrapperRef, className: `${styles$7.pickerWrapper} ${timeStyles.field}${showClear ? "" : ` ${timeStyles.narrow}`}`, children: [jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, "aria-describedby": describedBy, required: required, maxLength: 5 }), showClear && (jsx("div", { className: styles$7.pickerIcons, children: value && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", icon: "close", color: "neutral", onClick: handleClear, tabIndex: -1, "aria-label": "Clear time" })) : (jsx(CwIcon, { iconId: "clock" })) })), renderPopup(jsx("div", { ref: popupRef, className: `${styles$7.pickerPopup} ${timeStyles.timePickerPopup}`, style: popupStyle, children: jsx("div", { className: timeStyles.timePickerList, children: timeOptions.map((time) => {
7413
7413
  const isSelected = time === value;
7414
7414
  return (jsx("button", { ref: isSelected ? selectedItemRef : null, type: "button", className: isSelected ? timeStyles.selected : "", onClick: () => handleTimeSelect(time), children: time }, time));
7415
7415
  }) }) }))] }), feedbackElements] })] }) }));
@@ -7717,7 +7717,7 @@ function CwDateTimePicker({ value, onChange, minDateTime, maxDateTime, disabledD
7717
7717
  const displayMaxDate = useMemo(() => normalizedMaxDateTime && timezoneOffset !== undefined
7718
7718
  ? getDateInOffset(normalizedMaxDateTime, timezoneOffset)
7719
7719
  : normalizedMaxDateTime, [normalizedMaxDateTime, timezoneOffset]);
7720
- return jsx("div", { ...dataAttributes, className: `cw-datetimepicker cw-datetimepicker-separate ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: styles$4.value, children: [jsxs("div", { className: "cw-flex-row cw-align-left-center cw-gap-small", children: [jsx(CwDatePicker, { value: selectedDate, onChange: handleDateChange, minDate: displayMinDate, maxDate: displayMaxDate, disabledDates: disabledDates, disabledMatcher: disabledMatcher, placeholder: datePlaceholder, disabled: disabled, required: required, showClear: showClear, numberOfMonths: numberOfMonths, popupPosition: popupPosition, locale: locale }), jsx(CwTimePicker, { value: selectedTime, onChange: handleTimeChange, interval: timeInterval, minTime: timeRestrictions.minTime, maxTime: timeRestrictions.maxTime, placeholder: timePlaceholder, disabled: disabled, required: required, showClear: showClear, popupPosition: popupPosition }), showNowButton && (jsx(CwButton, { type: "button", variant: "outline", onClick: handleNowClick, disabled: disabled, text: nowLabel }))] }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] })] }) });
7720
+ return jsx("div", { ...dataAttributes, className: `cw-datetimepicker cw-datetimepicker-separate ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: styles$7.value, children: [jsxs("div", { className: "cw-flex-row cw-align-left-center cw-gap-small", children: [jsx(CwDatePicker, { value: selectedDate, onChange: handleDateChange, minDate: displayMinDate, maxDate: displayMaxDate, disabledDates: disabledDates, disabledMatcher: disabledMatcher, placeholder: datePlaceholder, disabled: disabled, required: required, showClear: showClear, numberOfMonths: numberOfMonths, popupPosition: popupPosition, locale: locale }), jsx(CwTimePicker, { value: selectedTime, onChange: handleTimeChange, interval: timeInterval, minTime: timeRestrictions.minTime, maxTime: timeRestrictions.maxTime, placeholder: timePlaceholder, disabled: disabled, required: required, showClear: showClear, popupPosition: popupPosition }), showNowButton && (jsx(CwButton, { type: "button", variant: "outline", onClick: handleNowClick, disabled: disabled, text: nowLabel }))] }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] })] }) });
7721
7721
  }
7722
7722
 
7723
7723
  var compactStyles = {"compactPopup":"cw-datetime-compact-module__compactPopup__GiuNY","calendarWrapper":"cw-datetime-compact-module__calendarWrapper__P4Nlq","timeWrapper":"cw-datetime-compact-module__timeWrapper__uMe-A","compactTimeList":"cw-datetime-compact-module__compactTimeList__MzSQT"};
@@ -7973,7 +7973,7 @@ function CwDateTimePickerCompact({ value, onChange, minDateTime, maxDateTime, di
7973
7973
  ...(maxDateTime ? [{ after: maxDateTime }] : []),
7974
7974
  ...(disabledMatcher ? [disabledMatcher] : []),
7975
7975
  ], [disabledDates, minDateTime, maxDateTime, disabledMatcher]);
7976
- return (jsx("div", { ...dataAttributes, ref: containerRef, className: `cw-datetimepicker ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: styles$4.value, children: [jsxs("div", { ref: wrapperRef, className: styles$4.pickerWrapper, children: [jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, "aria-describedby": describedBy, required: required, maxLength: 16 }), jsx("div", { className: styles$4.pickerIcons, children: showClear && value && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClear, tabIndex: -1, "aria-label": "Clear datetime" })) : (jsx(CwIcon, { iconId: "calendar-time" })) }), renderPopup(jsxs("div", { ref: popupRef, className: `${styles$4.pickerPopup} ${compactStyles.compactPopup}`, style: popupStyle, children: [jsxs("div", { className: compactStyles.calendarWrapper, children: [jsx(DayPicker, { mode: "single", selected: selectedDate, onSelect: handleDaySelect, defaultMonth: selectedDate, disabled: disabledDays, numberOfMonths: numberOfMonths, locale: locale, captionLayout: "dropdown", startMonth: dropdownStartMonth, endMonth: dropdownEndMonth, modifiers: {
7976
+ return (jsx("div", { ...dataAttributes, ref: containerRef, className: `cw-datetimepicker ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: styles$7.value, children: [jsxs("div", { ref: wrapperRef, className: styles$7.pickerWrapper, children: [jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, "aria-describedby": describedBy, required: required, maxLength: 16 }), jsx("div", { className: styles$7.pickerIcons, children: showClear && value && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClear, tabIndex: -1, "aria-label": "Clear datetime" })) : (jsx(CwIcon, { iconId: "calendar-time" })) }), renderPopup(jsxs("div", { ref: popupRef, className: `${styles$7.pickerPopup} ${compactStyles.compactPopup}`, style: popupStyle, children: [jsxs("div", { className: compactStyles.calendarWrapper, children: [jsx(DayPicker, { mode: "single", selected: selectedDate, onSelect: handleDaySelect, defaultMonth: selectedDate, disabled: disabledDays, numberOfMonths: numberOfMonths, locale: locale, captionLayout: "dropdown", startMonth: dropdownStartMonth, endMonth: dropdownEndMonth, modifiers: {
7977
7977
  today: new Date(),
7978
7978
  }, modifiersClassNames: {
7979
7979
  today: "rdp-day-today",
@@ -8208,7 +8208,7 @@ function CwDatePickerTemporal({ value, onChange, minDate, maxDate, disabledDates
8208
8208
  const defaultMonthJsDate = defaultMonth
8209
8209
  ? new Date(defaultMonth.year, defaultMonth.month - 1, 1)
8210
8210
  : selectedJsDate;
8211
- return (jsx("div", { ...dataAttributes, ref: containerRef, className: `cw-datepicker ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: styles$4.value, children: [jsxs("div", { ref: wrapperRef, className: styles$4.pickerWrapper, children: [jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length }), jsx("div", { className: styles$4.pickerIcons, children: showClear && value && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClear, tabIndex: -1, "aria-label": "Clear date" })) : (jsx(CwIcon, { iconId: "calendar" })) }), renderPopup(jsxs("div", { ref: popupRef, className: styles$4.pickerPopup, style: popupStyle, children: [jsx(DayPicker, { mode: "single", selected: selectedJsDate, defaultMonth: defaultMonthJsDate, onSelect: handleDaySelect, disabled: disabledDays, numberOfMonths: numberOfMonths, locale: locale, captionLayout: "dropdown", startMonth: dropdownStartMonth, endMonth: dropdownEndMonth, modifiers: {
8211
+ return (jsx("div", { ...dataAttributes, ref: containerRef, className: `cw-datepicker ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: styles$7.value, children: [jsxs("div", { ref: wrapperRef, className: styles$7.pickerWrapper, children: [jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length }), jsx("div", { className: styles$7.pickerIcons, children: showClear && value && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClear, tabIndex: -1, "aria-label": "Clear date" })) : (jsx(CwIcon, { iconId: "calendar" })) }), renderPopup(jsxs("div", { ref: popupRef, className: styles$7.pickerPopup, style: popupStyle, children: [jsx(DayPicker, { mode: "single", selected: selectedJsDate, defaultMonth: defaultMonthJsDate, onSelect: handleDaySelect, disabled: disabledDays, numberOfMonths: numberOfMonths, locale: locale, captionLayout: "dropdown", startMonth: dropdownStartMonth, endMonth: dropdownEndMonth, modifiers: {
8212
8212
  today: new Date(),
8213
8213
  }, modifiersClassNames: {
8214
8214
  today: "rdp-day-today",
@@ -8509,7 +8509,7 @@ function CwDateTimePickerTemporal({ value, onChange, minDateTime, maxDateTime, d
8509
8509
  minTime,
8510
8510
  maxTime,
8511
8511
  });
8512
- return jsx("div", { ...dataAttributes, className: `cw-datetimepicker cw-datetimepicker-separate ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: styles$4.value, children: [jsxs("div", { className: "cw-flex-row cw-align-left-center cw-gap-small", children: [jsx(CwDatePickerTemporal, { value: picker.date, onChange: picker.selectDate, minDate: picker.minDate, maxDate: picker.maxDate, disabledDates: disabledDates, disabledMatcher: disabledMatcher, placeholder: datePlaceholder, disabled: disabled, required: required, showClear: showClear, numberOfMonths: numberOfMonths, popupPosition: popupPosition, locale: locale }), jsx(CwTimePicker, { value: picker.time, onChange: picker.selectTime, interval: timeInterval, minTime: picker.effectiveMinTime, maxTime: picker.effectiveMaxTime, placeholder: timePlaceholder, disabled: disabled, required: required, showClear: showClear, popupPosition: popupPosition }), showNowButton && (jsx(CwButton, { type: "button", variant: "outline", onClick: picker.selectNow, disabled: disabled, text: nowLabel }))] }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] })] }) });
8512
+ return jsx("div", { ...dataAttributes, className: `cw-datetimepicker cw-datetimepicker-separate ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: styles$7.value, children: [jsxs("div", { className: "cw-flex-row cw-align-left-center cw-gap-small", children: [jsx(CwDatePickerTemporal, { value: picker.date, onChange: picker.selectDate, minDate: picker.minDate, maxDate: picker.maxDate, disabledDates: disabledDates, disabledMatcher: disabledMatcher, placeholder: datePlaceholder, disabled: disabled, required: required, showClear: showClear, numberOfMonths: numberOfMonths, popupPosition: popupPosition, locale: locale }), jsx(CwTimePicker, { value: picker.time, onChange: picker.selectTime, interval: timeInterval, minTime: picker.effectiveMinTime, maxTime: picker.effectiveMaxTime, placeholder: timePlaceholder, disabled: disabled, required: required, showClear: showClear, popupPosition: popupPosition }), showNowButton && (jsx(CwButton, { type: "button", variant: "outline", onClick: picker.selectNow, disabled: disabled, text: nowLabel }))] }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] })] }) });
8513
8513
  }
8514
8514
 
8515
8515
  // dateRangePresetsTemporal.ts
@@ -8961,7 +8961,7 @@ function CwDateRangePickerTemporal({ value, onChange, minDate, maxDate, disabled
8961
8961
  const defaultMonthJsDate = defaultMonth
8962
8962
  ? new Date(defaultMonth.year, defaultMonth.month - 1, 1)
8963
8963
  : (value?.from ? plainDateToJsDate(value.from) : undefined);
8964
- return (jsx("div", { ...dataAttributes, ref: containerRef, className: `cw-rangepicker ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: styles$4.value, children: [jsxs("div", { ref: wrapperRef, className: rangeStyles.rangeWrapper, children: [jsxs("div", { className: styles$4.pickerWrapper, children: [jsx("input", { ref: inputFromRef, type: "text", value: inputFromValue, placeholder: placeholderFrom, onChange: handleInputFromChange, onBlur: () => handleInputBlur('from'), onClick: handleInputFromClick, onKeyDown: (e) => handleInputKeyDown(e, 'from'), disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length, "data-focused": focusedInput === 'from' }), jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.from && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearFrom, tabIndex: -1, "aria-label": "Clear from date" })) : (jsx(CwIcon, { iconId: "calendar" })) })] }), jsx(CwIcon, { iconId: "arrow-right", size: "medium" }), jsxs("div", { className: styles$4.pickerWrapper, children: [jsx("input", { ref: inputToRef, type: "text", value: inputToValue, placeholder: placeholderTo, onChange: handleInputToChange, onBlur: () => handleInputBlur('to'), onClick: handleInputToClick, onKeyDown: (e) => handleInputKeyDown(e, 'to'), disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length, "data-focused": focusedInput === 'to' }), jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.to && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearTo, tabIndex: -1, "aria-label": "Clear to date" })) : (jsx(CwIcon, { iconId: "calendar" })) })] }), renderPopup(jsxs("div", { ref: popupRef, className: `${styles$4.pickerPopup} ${rangeStyles.rangePopup}`, style: popupStyle, children: [jsxs("div", { className: rangeStyles.rangeCalendarRow, children: [showPresets && presetsToRender.length > 0 && (jsx("div", { className: rangeStyles.presetList, children: presetsToRender.map((preset) => (jsx("button", { type: "button", onClick: (e) => handlePresetClick(preset, e), children: preset.label }, preset.key))) })), jsx(DayPicker, { mode: "range", selected: selectedRange, onSelect: handleRangeSelect, disabled: disabledDays, numberOfMonths: numberOfMonths, defaultMonth: defaultMonthJsDate, locale: locale, captionLayout: "dropdown", startMonth: dropdownStartMonth, endMonth: dropdownEndMonth, modifiers: {
8964
+ return (jsx("div", { ...dataAttributes, ref: containerRef, className: `cw-rangepicker ${className || ""}`, children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: styles$7.value, children: [jsxs("div", { ref: wrapperRef, className: rangeStyles.rangeWrapper, children: [jsxs("div", { className: styles$7.pickerWrapper, children: [jsx("input", { ref: inputFromRef, type: "text", value: inputFromValue, placeholder: placeholderFrom, onChange: handleInputFromChange, onBlur: () => handleInputBlur('from'), onClick: handleInputFromClick, onKeyDown: (e) => handleInputKeyDown(e, 'from'), disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length, "data-focused": focusedInput === 'from' }), jsx("div", { className: styles$7.pickerIcons, children: showClear && value?.from && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearFrom, tabIndex: -1, "aria-label": "Clear from date" })) : (jsx(CwIcon, { iconId: "calendar" })) })] }), jsx(CwIcon, { iconId: "arrow-right", size: "medium" }), jsxs("div", { className: styles$7.pickerWrapper, children: [jsx("input", { ref: inputToRef, type: "text", value: inputToValue, placeholder: placeholderTo, onChange: handleInputToChange, onBlur: () => handleInputBlur('to'), onClick: handleInputToClick, onKeyDown: (e) => handleInputKeyDown(e, 'to'), disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length, "data-focused": focusedInput === 'to' }), jsx("div", { className: styles$7.pickerIcons, children: showClear && value?.to && !disabled ? (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearTo, tabIndex: -1, "aria-label": "Clear to date" })) : (jsx(CwIcon, { iconId: "calendar" })) })] }), renderPopup(jsxs("div", { ref: popupRef, className: `${styles$7.pickerPopup} ${rangeStyles.rangePopup}`, style: popupStyle, children: [jsxs("div", { className: rangeStyles.rangeCalendarRow, children: [showPresets && presetsToRender.length > 0 && (jsx("div", { className: rangeStyles.presetList, children: presetsToRender.map((preset) => (jsx("button", { type: "button", onClick: (e) => handlePresetClick(preset, e), children: preset.label }, preset.key))) })), jsx(DayPicker, { mode: "range", selected: selectedRange, onSelect: handleRangeSelect, disabled: disabledDays, numberOfMonths: numberOfMonths, defaultMonth: defaultMonthJsDate, locale: locale, captionLayout: "dropdown", startMonth: dropdownStartMonth, endMonth: dropdownEndMonth, modifiers: {
8965
8965
  today: new Date(),
8966
8966
  }, modifiersClassNames: {
8967
8967
  today: "rdp-day-today",
@@ -9108,7 +9108,7 @@ class OnClickContextMenu {
9108
9108
  }
9109
9109
  }
9110
9110
 
9111
- var styles$3 = {"scheduler-header":"scheduler-header-module__scheduler-header__Y7SNV","scheduler-header-divisions":"scheduler-header-module__scheduler-header-divisions__1JrNe","scheduler-timeline-now":"scheduler-header-module__scheduler-timeline-now__naREv","scheduler-timeline-label":"scheduler-header-module__scheduler-timeline-label__mLVAp","scheduler-header-title":"scheduler-header-module__scheduler-header-title__Jzy94","title-cell":"scheduler-header-module__title-cell__mz7Ki","title":"scheduler-header-module__title__TuJVn","scheduler-dates":"scheduler-header-module__scheduler-dates__O7ePQ","current-day":"scheduler-header-module__current-day__FpHiv","scheduler-hours":"scheduler-header-module__scheduler-hours__ZDCVj"};
9111
+ var styles$6 = {"scheduler-header":"scheduler-header-module__scheduler-header__Y7SNV","scheduler-header-divisions":"scheduler-header-module__scheduler-header-divisions__1JrNe","scheduler-timeline-now":"scheduler-header-module__scheduler-timeline-now__naREv","scheduler-timeline-label":"scheduler-header-module__scheduler-timeline-label__mLVAp","scheduler-header-title":"scheduler-header-module__scheduler-header-title__Jzy94","title-cell":"scheduler-header-module__title-cell__mz7Ki","title":"scheduler-header-module__title__TuJVn","scheduler-dates":"scheduler-header-module__scheduler-dates__O7ePQ","current-day":"scheduler-header-module__current-day__FpHiv","scheduler-hours":"scheduler-header-module__scheduler-hours__ZDCVj"};
9112
9112
 
9113
9113
  const getNow$1 = (isUtc) => {
9114
9114
  let now = new Date();
@@ -9137,9 +9137,9 @@ const TimeLine = ({ left, top = "0px", height, color, width = "2px", zIndexNumbe
9137
9137
  background: color,
9138
9138
  pointerEvents: "none",
9139
9139
  zIndex: zIndexNumber,
9140
- }, className: styles$3["scheduler-timeline-now"], children: isHeader && (jsx("span", { style: {
9140
+ }, className: styles$6["scheduler-timeline-now"], children: isHeader && (jsx("span", { style: {
9141
9141
  color: color,
9142
- }, className: styles$3["scheduler-timeline-label"], children: currentTime.toLocaleTimeString([], {
9142
+ }, className: styles$6["scheduler-timeline-label"], children: currentTime.toLocaleTimeString([], {
9143
9143
  hour: '2-digit',
9144
9144
  minute: '2-digit',
9145
9145
  hour12: false
@@ -9166,17 +9166,17 @@ const SchedulerHeaderDivision = ({ topDivisions, bottomDivisions, classification
9166
9166
  return (jsxs("div", { style: {
9167
9167
  width: topWidth,
9168
9168
  cursor: "pointer"
9169
- }, children: [jsx("div", { className: `${styles$3["scheduler-dates"]} ${isToday(startDate, endDate) ? styles$3["current-day"] : ""}`, children: jsx("span", { children: topDivisions }) }), jsx("div", { style: { display: "flex", justifyContent: "space-between", flex: 1 }, children: bottomDivisions.map((element) => (jsx("div", { className: styles$3["scheduler-hours"], children: jsx("span", { children: element }) }, classification + element + topDivisions))) })] }));
9169
+ }, children: [jsx("div", { className: `${styles$6["scheduler-dates"]} ${isToday(startDate, endDate) ? styles$6["current-day"] : ""}`, children: jsx("span", { children: topDivisions }) }), jsx("div", { style: { display: "flex", justifyContent: "space-between", flex: 1 }, children: bottomDivisions.map((element) => (jsx("div", { className: styles$6["scheduler-hours"], children: jsx("span", { children: element }) }, classification + element + topDivisions))) })] }));
9170
9170
  };
9171
9171
 
9172
9172
  const HeaderTitle = ({ title, dividerText, width }) => {
9173
- return (jsxs("div", { className: styles$3["scheduler-header-title"], style: { width: width }, children: [jsx("div", { className: styles$3["title-cell"], children: jsx("span", { className: styles$3.title, children: title }) }), jsx("div", { children: jsx("span", { children: dividerText }) })] }));
9173
+ return (jsxs("div", { className: styles$6["scheduler-header-title"], style: { width: width }, children: [jsx("div", { className: styles$6["title-cell"], children: jsx("span", { className: styles$6.title, children: title }) }), jsx("div", { children: jsx("span", { children: dividerText }) })] }));
9174
9174
  };
9175
9175
 
9176
9176
  const SchedulerHeader = ({ content, divisions, visibleDays, selectedDate, width, onEvent, timeLinePercentage, isUtc }) => {
9177
9177
  const topWidth = (100 / visibleDays);
9178
9178
  const { title, classification } = content;
9179
- return (jsxs("div", { className: styles$3["scheduler-header"], children: [jsx(HeaderTitle, { title: title, dividerText: classification, width: width }), jsxs("div", { className: styles$3["scheduler-header-divisions"], style: { flex: 1, display: "flex", position: "relative" }, onMouseDown: (e) => {
9179
+ return (jsxs("div", { className: styles$6["scheduler-header"], children: [jsx(HeaderTitle, { title: title, dividerText: classification, width: width }), jsxs("div", { className: styles$6["scheduler-header-divisions"], style: { flex: 1, display: "flex", position: "relative" }, onMouseDown: (e) => {
9180
9180
  e.preventDefault();
9181
9181
  const clickPercentage = getPercentageFromMouseEvent(e);
9182
9182
  const date = dateFromPercentage(selectedDate, visibleDays, clickPercentage);
@@ -9208,7 +9208,7 @@ function getStartEnd(day) {
9208
9208
  };
9209
9209
  }
9210
9210
 
9211
- var styles$2 = {"hide-scrollbar":"new-scheduler-module__hide-scrollbar__33GG9","scheduler-event":"new-scheduler-module__scheduler-event__gphwn","scheduler-event-container":"new-scheduler-module__scheduler-event-container__-h1xm","time-marker":"new-scheduler-module__time-marker__2BejU","underlay":"new-scheduler-module__underlay__RVCnV","label-halo":"new-scheduler-module__label-halo__84c7e","corner-marker":"new-scheduler-module__corner-marker__w7o90","color-bars":"new-scheduler-module__color-bars__MhMF7","scheduler-event-text":"new-scheduler-module__scheduler-event-text__zjvd7"};
9211
+ var styles$5 = {"hide-scrollbar":"new-scheduler-module__hide-scrollbar__33GG9","scheduler-event":"new-scheduler-module__scheduler-event__gphwn","scheduler-event-container":"new-scheduler-module__scheduler-event-container__-h1xm","time-marker":"new-scheduler-module__time-marker__2BejU","underlay":"new-scheduler-module__underlay__RVCnV","label-halo":"new-scheduler-module__label-halo__84c7e","corner-marker":"new-scheduler-module__corner-marker__w7o90","color-bars":"new-scheduler-module__color-bars__MhMF7","scheduler-event-text":"new-scheduler-module__scheduler-event-text__zjvd7"};
9212
9212
 
9213
9213
  const BackgroundEvent = ({ value, heightRem }) => {
9214
9214
  const backColor = getHSLColor(value.color, value.alpha ?? 0.5);
@@ -9235,13 +9235,13 @@ const BackgroundEvent = ({ value, heightRem }) => {
9235
9235
  padding: "0.25rem",
9236
9236
  color: textColor,
9237
9237
  alignItems: value.contentAlign ?? "center"
9238
- }, className: styles$2["scheduler-event-container"], children: [value.icons ? jsx("div", { style: {
9238
+ }, className: styles$5["scheduler-event-container"], children: [value.icons ? jsx("div", { style: {
9239
9239
  display: "flex",
9240
9240
  flexDirection: "row",
9241
9241
  alignItems: "center",
9242
9242
  whiteSpace: "nowrap",
9243
9243
  color: textColor,
9244
- }, children: value.icons }) : null, jsx("span", { className: styles$2["scheduler-event-text"], children: value.name })] }) }) }) }) })) : null;
9244
+ }, children: value.icons }) : null, jsx("span", { className: styles$5["scheduler-event-text"], children: value.name })] }) }) }) }) })) : null;
9245
9245
  };
9246
9246
 
9247
9247
  const eventIsVisible = (startDate, endDate, selectedDate, visibleDays) => {
@@ -9403,7 +9403,7 @@ const WeekEndLine = ({ left, top = "0px", height, widthPercentage }) => {
9403
9403
  } }));
9404
9404
  };
9405
9405
 
9406
- var styles$1 = {"scheduler-row-header":"scheduler-row-module__scheduler-row-header__S-iv4"};
9406
+ var styles$4 = {"scheduler-row-header":"scheduler-row-module__scheduler-row-header__S-iv4"};
9407
9407
 
9408
9408
  const DefaultRowHeader = ({ value, width, onEvent }) => {
9409
9409
  return (jsxs("div", { style: {
@@ -9412,7 +9412,7 @@ const DefaultRowHeader = ({ value, width, onEvent }) => {
9412
9412
  background: value.highlightColor,
9413
9413
  }, onClick: (_) => {
9414
9414
  onEvent(new OnClickRowHeader(value.rowId));
9415
- }, className: styles$1["scheduler-row-header"], children: [jsxs("div", { children: [jsx("strong", { children: value.title }), value.title2 && jsxs("span", { children: ["-", value.title2] }), " ", jsx("strong", { children: value.subtitle })] }), value.subtitle && jsxs("div", { style: { opacity: 0.5 }, children: [value.title3 && jsxs("span", { className: styles$1["scheduler-crewmember-functions"], children: ["(", value.title3, ")"] }), value.subtitle2 && jsxs("span", { children: ["-", value.subtitle2] })] })] }));
9415
+ }, className: styles$4["scheduler-row-header"], children: [jsxs("div", { children: [jsx("strong", { children: value.title }), value.title2 && jsxs("span", { children: ["-", value.title2] }), " ", jsx("strong", { children: value.subtitle })] }), value.subtitle && jsxs("div", { style: { opacity: 0.5 }, children: [value.title3 && jsxs("span", { className: styles$4["scheduler-crewmember-functions"], children: ["(", value.title3, ")"] }), value.subtitle2 && jsxs("span", { children: ["-", value.subtitle2] })] })] }));
9416
9416
  };
9417
9417
 
9418
9418
  const EventSideDrag = ({ left = false, heightRem, onStartEvent }) => {
@@ -9502,7 +9502,7 @@ const SchedulerEvent = ({ value, heightRem, onEvent, maxEventHeightRem }) => {
9502
9502
  height: `calc(${effectiveHeight}rem - 4px)`,
9503
9503
  opacity: eventTransparent ? 0.5 : 1,
9504
9504
  ...value.style,
9505
- }, className: styles$2["scheduler-event"], "data-underlay": value.underlay ? true : undefined, children: [value.underlay && jsx("div", { className: styles$2["underlay"], children: value.underlay }), jsxs("div", { style: {
9505
+ }, className: styles$5["scheduler-event"], "data-underlay": value.underlay ? true : undefined, children: [value.underlay && jsx("div", { className: styles$5["underlay"], children: value.underlay }), jsxs("div", { style: {
9506
9506
  display: "flex",
9507
9507
  flexDirection: "row",
9508
9508
  alignItems: "stretch",
@@ -9513,13 +9513,13 @@ const SchedulerEvent = ({ value, heightRem, onEvent, maxEventHeightRem }) => {
9513
9513
  height: "100%",
9514
9514
  }, children: [value.isResizable && (jsx(EventSideDrag, { left: true, heightRem: effectiveHeight * 0.7, onStartEvent: () => {
9515
9515
  onEvent(new OnLeftDragStart(value.id));
9516
- } })), jsxs("div", { className: styles$2["scheduler-event-container"], children: [jsx("div", { style: {
9516
+ } })), jsxs("div", { className: styles$5["scheduler-event-container"], children: [jsx("div", { style: {
9517
9517
  display: "flex",
9518
9518
  flexDirection: "row",
9519
9519
  alignItems: "center",
9520
9520
  whiteSpace: "nowrap",
9521
9521
  color: textColor,
9522
- }, children: value.icons }), jsx("span", { className: value.underlay ? styles$2["label-halo"] : undefined, style: {
9522
+ }, children: value.icons }), jsx("span", { className: value.underlay ? styles$5["label-halo"] : undefined, style: {
9523
9523
  padding: "0.1rem",
9524
9524
  color: textColor,
9525
9525
  display: "flex",
@@ -9527,13 +9527,13 @@ const SchedulerEvent = ({ value, heightRem, onEvent, maxEventHeightRem }) => {
9527
9527
  alignItems: "center",
9528
9528
  width: "100%",
9529
9529
  ...(value.underlay && { "--label-halo-color": backColor }),
9530
- }, children: value.rectangleColors && value.rectangleColors.length > 0 ? (jsx("div", { className: styles$2["color-bars"], children: value.rectangleColors.map((item, i) => (jsx("div", { style: { backgroundColor: item } }, value.id + "_" + i))) })) : (value.label ?? value.name) })] }), value.isResizable && (jsx(EventSideDrag, { heightRem: effectiveHeight * 0.7, onStartEvent: () => {
9530
+ }, children: value.rectangleColors && value.rectangleColors.length > 0 ? (jsx("div", { className: styles$5["color-bars"], children: value.rectangleColors.map((item, i) => (jsx("div", { style: { backgroundColor: item } }, value.id + "_" + i))) })) : (value.label ?? value.name) })] }), value.isResizable && (jsx(EventSideDrag, { heightRem: effectiveHeight * 0.7, onStartEvent: () => {
9531
9531
  onEvent(new OnRightDragStart(value.id));
9532
- } }))] }), value.primaryTimeMarkerColor && (jsx("div", { className: styles$2["time-marker"], style: {
9532
+ } }))] }), value.primaryTimeMarkerColor && (jsx("div", { className: styles$5["time-marker"], style: {
9533
9533
  backgroundColor: value.primaryTimeMarkerColor,
9534
- } })), value.secondaryTimeMarkerColor && (jsx("div", { className: styles$2["time-marker"], style: {
9534
+ } })), value.secondaryTimeMarkerColor && (jsx("div", { className: styles$5["time-marker"], style: {
9535
9535
  backgroundColor: value.secondaryTimeMarkerColor,
9536
- } }))] }) }) }, value.id) }), value.cornerMarker && (jsx("div", { className: styles$2["corner-marker"], style: {
9536
+ } }))] }) }) }, value.id) }), value.cornerMarker && (jsx("div", { className: styles$5["corner-marker"], style: {
9537
9537
  top: `${topOffsetPx}px`,
9538
9538
  left: `${value.left}%`,
9539
9539
  width: `${value.width}%`,
@@ -10067,13 +10067,13 @@ const Scheduler = (props) => {
10067
10067
  position: "sticky",
10068
10068
  top: 0,
10069
10069
  zIndex: 1,
10070
- }, children: jsx(SchedulerHeader, { ...header }) })), jsx(VariableSizeList, { height: schedulerContentHeight * 16, itemCount: rows.length, itemSize: getItemSize, itemData: itemData, width: "100%", style: { overflowX: "hidden" }, ref: instanceRef, className: styles$2["hide-scrollbar"], children: Row })] }) }));
10070
+ }, children: jsx(SchedulerHeader, { ...header }) })), jsx(VariableSizeList, { height: schedulerContentHeight * 16, itemCount: rows.length, itemSize: getItemSize, itemData: itemData, width: "100%", style: { overflowX: "hidden" }, ref: instanceRef, className: styles$5["hide-scrollbar"], children: Row })] }) }));
10071
10071
  };
10072
10072
 
10073
10073
  class UiEvent {
10074
10074
  }
10075
10075
 
10076
- var styles = {"super-scheduler-row-header":"super-scheduler-module__super-scheduler-row-header__TTs4e","indicators":"super-scheduler-module__indicators__f4lIT","scheduler-crewmember-functions":"super-scheduler-module__scheduler-crewmember-functions__BS2hs"};
10076
+ var styles$3 = {"super-scheduler-row-header":"super-scheduler-module__super-scheduler-row-header__TTs4e","indicators":"super-scheduler-module__indicators__f4lIT","scheduler-crewmember-functions":"super-scheduler-module__scheduler-crewmember-functions__BS2hs"};
10077
10077
 
10078
10078
  class OnPinRow {
10079
10079
  id;
@@ -10101,15 +10101,15 @@ const PinRowHeader = ({ value, width, onEvent }) => {
10101
10101
  flexShrink: 0,
10102
10102
  height: "100%",
10103
10103
  background: highlightColor
10104
- }, className: styles["super-scheduler-row-header"], children: [jsx("button", { className: "cw-button-icon cwi-pin", "data-pinned": value.isPinned, onClick: (_) => {
10104
+ }, className: styles$3["super-scheduler-row-header"], children: [jsx("button", { className: "cw-button-icon cwi-pin", "data-pinned": value.isPinned, onClick: (_) => {
10105
10105
  onEvent(value.isPinned ? new OnUnpinRow(value.rowId) : new OnPinRow(value.rowId));
10106
- } }), jsx("div", { className: styles["indicators"], children: value.indicators ?? undefined }), jsxs("div", { style: {
10106
+ } }), jsx("div", { className: styles$3["indicators"], children: value.indicators ?? undefined }), jsxs("div", { style: {
10107
10107
  display: "flex",
10108
10108
  flexDirection: "column",
10109
10109
  justifyContent: "center",
10110
10110
  alignItems: "flex-start",
10111
10111
  }, children: [jsxs("div", { children: [jsx("strong", { children: value.title }), value.title2 && jsxs("span", { children: ["-", value.title2] }), " ", jsx("strong", { children: value.subtitle })] }), value.subtitle && jsxs("div", { style: { opacity: 0.5 }, children: [value.title3 &&
10112
- jsxs("span", { className: styles["scheduler-crewmember-functions"], children: ["(", value.title3, ")"] }), value.subtitle2 && jsxs("span", { children: ["-", value.subtitle2] })] })] }), isLoading ? jsx("span", { className: "cwi-icons cwi-spinner" }) : undefined] }) }, value.rowId) }, value.rowId);
10112
+ jsxs("span", { className: styles$3["scheduler-crewmember-functions"], children: ["(", value.title3, ")"] }), value.subtitle2 && jsxs("span", { children: ["-", value.subtitle2] })] })] }), isLoading ? jsx("span", { className: "cwi-icons cwi-spinner" }) : undefined] }) }, value.rowId) }, value.rowId);
10113
10113
  };
10114
10114
 
10115
10115
  const SuperScheduler = ({ id, state, header, rows, events, headerColumnComp, pinnedOrderCategory, unPinnedOrderCategory, backgroundEvents, indicatorRows = [], contextMenuItems, onEvent, rowHeightRem = 1.75, rowHeaderWidth, maxEventHeightRem, EventComp = SchedulerEvent, }) => {
@@ -10121,6 +10121,2324 @@ const SuperScheduler = ({ id, state, header, rows, events, headerColumnComp, pin
10121
10121
  }, children: "Clear pinned" }) })] })), jsx(Scheduler, { id: `${id}-notPinned`, state: { ...state, isHeaderVisible: !isFirstVisible }, header: header, rows: notPinnedRows, events: events, backgroundEvents: backgroundEvents, indicatorRows: indicatorRows, contextMenuItems: contextMenuItems, orderCategories: unPinnedOrderCategory, onEvent: onEvent, EventComp: EventComp, RowTitleComp: headerColumnComp, rowHeightRem: rowHeightRem, rowHeaderWidth: rowHeaderWidth, maxEventHeightRem: maxEventHeightRem })] }));
10122
10122
  };
10123
10123
 
10124
+ /** A toggle ref hides its item while `InitiallyHidden` XOR "flipped" is true. */
10125
+ function isToggleRefHidden(ref, flipped) {
10126
+ return ref.InitiallyHidden !== flipped.has(ref.Id);
10127
+ }
10128
+ /** An item, row or cell is visible only when every toggle it depends on is in its visible state. */
10129
+ function isRdlVisible(toggles, flipped) {
10130
+ if (!toggles || toggles.length === 0)
10131
+ return true;
10132
+ return toggles.every(ref => !isToggleRefHidden(ref, flipped));
10133
+ }
10134
+ /** The +/- state of a toggle textbox: the initial state inverted when its id was flipped. */
10135
+ function isToggleExpanded(textbox, flipped) {
10136
+ const initial = textbox.ToggleExpanded ?? false;
10137
+ return textbox.ToggleId ? initial !== flipped.has(textbox.ToggleId) : initial;
10138
+ }
10139
+ /**
10140
+ * The toggle ids an export or print sends so the file shows the drilldown state of the screen: the
10141
+ * ids flipped relative to the render's initial state (a toggle clicked twice is back to its initial
10142
+ * state and not sent), sorted for a stable request.
10143
+ */
10144
+ function flippedToggleIds(flipped) {
10145
+ return [...flipped].sort();
10146
+ }
10147
+ /** The toggle ids to ask the server for after a click on toggle `id`: the flipped ids with `id` flipped once more. */
10148
+ function toggledIds(flipped, id) {
10149
+ return flippedToggleIds(flipToggle(flipped, id));
10150
+ }
10151
+ /** Returns a new set with `id` flipped (added when absent, removed when present). */
10152
+ function flipToggle(flipped, id) {
10153
+ const next = new Set(flipped);
10154
+ if (next.has(id)) {
10155
+ next.delete(id);
10156
+ }
10157
+ else {
10158
+ next.add(id);
10159
+ }
10160
+ return next;
10161
+ }
10162
+
10163
+ /** Number of visible rows among `span` rows starting at `start`, at least 1. */
10164
+ function visibleRowSpan(rowVisible, start, span) {
10165
+ const end = Math.min(rowVisible.length, start + Math.max(1, span));
10166
+ let count = 0;
10167
+ for (let i = start; i < end; i++) {
10168
+ if (rowVisible[i])
10169
+ count++;
10170
+ }
10171
+ return Math.max(1, count);
10172
+ }
10173
+ function sum(values, from, to) {
10174
+ let total = 0;
10175
+ for (let i = Math.max(0, from); i < Math.min(values.length, to); i++)
10176
+ total += values[i];
10177
+ return total;
10178
+ }
10179
+ function visibleHeight(rows, rowVisible, start, span) {
10180
+ const end = Math.min(rows.length, start + Math.max(1, span));
10181
+ let height = 0;
10182
+ for (let i = start; i < end; i++) {
10183
+ if (rowVisible[i])
10184
+ height += rows[i].Height;
10185
+ }
10186
+ return height;
10187
+ }
10188
+ /**
10189
+ * Lays a table out for the current toggle state: hidden rows take no space, cells are placed at
10190
+ * their column with ColSpan/RowSpan and a header cell's RowSpan is recounted over the visible rows.
10191
+ * Cells that start in a hidden row are not drawn.
10192
+ */
10193
+ function layoutRdlTable(table, flipped) {
10194
+ const rows = table.Rows;
10195
+ const widths = table.ColumnWidths;
10196
+ const rowVisible = rows.map(row => isRdlVisible(row.Toggles, flipped));
10197
+ const rowTops = [];
10198
+ let top = 0;
10199
+ rows.forEach((row, index) => {
10200
+ rowTops.push(top);
10201
+ if (rowVisible[index])
10202
+ top += row.Height;
10203
+ });
10204
+ const cells = [];
10205
+ rows.forEach((row, rowIndex) => {
10206
+ if (!rowVisible[rowIndex])
10207
+ return;
10208
+ row.Cells.forEach((cell, cellIndex) => {
10209
+ const colSpan = Math.max(1, cell.ColSpan);
10210
+ cells.push({
10211
+ cell,
10212
+ rowIndex,
10213
+ cellIndex,
10214
+ left: sum(widths, 0, cell.Column),
10215
+ top: rowTops[rowIndex],
10216
+ width: sum(widths, cell.Column, cell.Column + colSpan),
10217
+ height: visibleHeight(rows, rowVisible, rowIndex, cell.RowSpan),
10218
+ rowSpan: visibleRowSpan(rowVisible, rowIndex, cell.RowSpan),
10219
+ hidden: !isRdlVisible(cell.Toggles, flipped)
10220
+ });
10221
+ });
10222
+ });
10223
+ return {
10224
+ width: sum(widths, 0, widths.length),
10225
+ height: top,
10226
+ rowTops,
10227
+ rowVisible,
10228
+ cells
10229
+ };
10230
+ }
10231
+
10232
+ /*
10233
+ * Find over the text of one page. Every run gets a key from its position in the render tree; the
10234
+ * renderer builds the same keys, so a match can be highlighted where the run is drawn.
10235
+ */
10236
+ /** Key prefixes of the three page sections. */
10237
+ const RDL_SECTION_KEYS = { header: "h", body: "b", footer: "f" };
10238
+ function rdlItemKey(parentKey, index) {
10239
+ return `${parentKey}.${index}`;
10240
+ }
10241
+ function rdlCellKey(tableKey, rowIndex, cellIndex) {
10242
+ return `${tableKey}.r${rowIndex}c${cellIndex}`;
10243
+ }
10244
+ function rdlRunKey(textboxKey, paragraphIndex, runIndex) {
10245
+ return `${textboxKey}.p${paragraphIndex}r${runIndex}`;
10246
+ }
10247
+ function collectTextbox(textbox, key, out) {
10248
+ textbox.Paragraphs.forEach((paragraph, p) => {
10249
+ paragraph.Runs.forEach((run, r) => {
10250
+ if (run.Text)
10251
+ out.push({ key: rdlRunKey(key, p, r), text: run.Text });
10252
+ });
10253
+ });
10254
+ }
10255
+ function collectItem(item, key, flipped, out) {
10256
+ if (!isRdlVisible(item.Toggles, flipped))
10257
+ return;
10258
+ switch (item.Kind) {
10259
+ case "textbox":
10260
+ collectTextbox(item, key, out);
10261
+ break;
10262
+ case "rectangle":
10263
+ collectItems(item.Items, key, flipped, out);
10264
+ break;
10265
+ case "table": {
10266
+ const layout = layoutRdlTable(item, flipped);
10267
+ for (const box of layout.cells) {
10268
+ if (box.hidden || !box.cell.Content)
10269
+ continue;
10270
+ collectItem(box.cell.Content, rdlCellKey(key, box.rowIndex, box.cellIndex), flipped, out);
10271
+ }
10272
+ break;
10273
+ }
10274
+ }
10275
+ }
10276
+ function collectItems(items, parentKey, flipped, out) {
10277
+ items.forEach((item, index) => collectItem(item, rdlItemKey(parentKey, index), flipped, out));
10278
+ }
10279
+ /** Every visible text run of a page in document order: header, body, footer. */
10280
+ function collectPageText(page, flipped) {
10281
+ const out = [];
10282
+ if (page.Header)
10283
+ collectItems(page.Header.Items, RDL_SECTION_KEYS.header, flipped, out);
10284
+ collectItems(page.Items, RDL_SECTION_KEYS.body, flipped, out);
10285
+ if (page.Footer)
10286
+ collectItems(page.Footer.Items, RDL_SECTION_KEYS.footer, flipped, out);
10287
+ return out;
10288
+ }
10289
+ /**
10290
+ * The text lower-cased one character at a time, with each code unit of the result pointing back to the
10291
+ * original character it came from: lower-casing can change the length ("İ" becomes two code units outside
10292
+ * Turkish), and the highlights slice the original text.
10293
+ */
10294
+ function lowerWithOffsets(text, locale) {
10295
+ let lower = "";
10296
+ const starts = [];
10297
+ const ends = [];
10298
+ let index = 0;
10299
+ for (const character of text) {
10300
+ const lowered = character.toLocaleLowerCase(locale);
10301
+ for (let unit = 0; unit < lowered.length; unit++) {
10302
+ starts.push(index);
10303
+ ends.push(index + character.length);
10304
+ }
10305
+ lower += lowered;
10306
+ index += character.length;
10307
+ }
10308
+ return { lower, starts, ends };
10309
+ }
10310
+ /**
10311
+ * Case-insensitive, non-overlapping matches of `query` in the runs, in run order, with the casing rules of
10312
+ * `locale` (default: the browser's, so "istanbul" finds "İSTANBUL" in Turkish). A match does not span two runs.
10313
+ */
10314
+ function findInRuns(runs, query, locale) {
10315
+ const needle = query.trim().toLocaleLowerCase(locale);
10316
+ if (needle === "")
10317
+ return [];
10318
+ const matches = [];
10319
+ for (const run of runs) {
10320
+ const { lower, starts, ends } = lowerWithOffsets(run.text, locale);
10321
+ let from = 0;
10322
+ for (;;) {
10323
+ const at = lower.indexOf(needle, from);
10324
+ if (at < 0)
10325
+ break;
10326
+ const start = starts[at];
10327
+ matches.push({ key: run.key, start, length: ends[at + needle.length - 1] - start });
10328
+ from = at + needle.length;
10329
+ }
10330
+ }
10331
+ return matches;
10332
+ }
10333
+ /** Find over the visible text of one page. */
10334
+ function findInPage(page, query, flipped) {
10335
+ return findInRuns(collectPageText(page, flipped), query);
10336
+ }
10337
+ /**
10338
+ * The active match index: -1 without matches; the stored index clamped into the matches when it belongs to the
10339
+ * current page and query (a stored -1 from an empty search becomes 0 once a drilldown reveals matches); else 0.
10340
+ */
10341
+ function activeMatchIndex(storedIndex, storedForCurrentSearch, count) {
10342
+ if (count <= 0)
10343
+ return -1;
10344
+ return storedForCurrentSearch ? Math.min(Math.max(0, storedIndex), count - 1) : 0;
10345
+ }
10346
+ /** The next match index after `current`, cycling; -1 when there are no matches. */
10347
+ function nextMatchIndex(current, count) {
10348
+ if (count <= 0)
10349
+ return -1;
10350
+ return current < 0 ? 0 : (current + 1) % count;
10351
+ }
10352
+
10353
+ /** CSS pixels per point: 96 px per inch, 72 pt per inch. */
10354
+ const PX_PER_PT = 96 / 72;
10355
+ /** Converts points to CSS pixels at a zoom factor (1 = 100%). */
10356
+ function ptToPx(pt, zoom = 1) {
10357
+ return pt * PX_PER_PT * zoom;
10358
+ }
10359
+ const POINTS_PER_UNIT = {
10360
+ pt: 1,
10361
+ px: 72 / 96,
10362
+ in: 72,
10363
+ cm: 72 / 2.54,
10364
+ mm: 72 / 25.4,
10365
+ pc: 12
10366
+ };
10367
+ // Linear: one digit run either side of the point, so a long non-matching value cannot backtrack quadratically.
10368
+ const SIZE_PATTERN = /^\s*(-?(?:\d+(?:\.\d*)?|\.\d+))\s*(pt|px|in|cm|mm|pc)?\s*$/i;
10369
+ /** No real RDL size comes near this; longer report-supplied strings are rejected before matching. */
10370
+ const MAX_SIZE_LENGTH = 32;
10371
+ /** Parses an RDL size ("10pt", "2.5mm", "1in", ...) into points; a bare number is points. Null when unparsable. */
10372
+ function parseRdlSize(value) {
10373
+ if (!value || value.length > MAX_SIZE_LENGTH)
10374
+ return null;
10375
+ const match = SIZE_PATTERN.exec(value);
10376
+ if (!match)
10377
+ return null;
10378
+ const unit = (match[2] ?? "pt").toLowerCase();
10379
+ return parseFloat(match[1]) * POINTS_PER_UNIT[unit];
10380
+ }
10381
+ /** An RDL size as CSS pixels at a zoom factor, or undefined when the size is missing or unparsable. */
10382
+ function rdlSizeToPx(value, zoom) {
10383
+ const pt = parseRdlSize(value);
10384
+ return pt === null ? undefined : ptToPx(pt, zoom);
10385
+ }
10386
+
10387
+ /** The zoom steps of the toolbar, 50% to 200%. */
10388
+ const REPORT_ZOOM_STEPS = [0.5, 0.75, 1, 1.25, 1.5, 2];
10389
+ const MIN_ZOOM = 0.1;
10390
+ const MAX_ZOOM = 4;
10391
+ /** Default margins of a standalone CwReportPage: a quarter inch, so content never touches the paper edge. */
10392
+ const DEFAULT_PAGE_MARGIN_PT = 18;
10393
+ /**
10394
+ * Margins of the sheet in the viewer: none. Like the old ReportViewer, the screen shows the content
10395
+ * (header, body, footer) without the RDL page margins; PDF and print come from the server with them.
10396
+ */
10397
+ const SCREEN_PAGE_MARGINS = { top: 0, right: 0, bottom: 0, left: 0 };
10398
+ /** Width of the page content in points: the page's own `Width` (body plus items reaching past it) when the server sends it, else the body width. */
10399
+ function pageContentWidthPt(page, bodyWidth) {
10400
+ return page.Width && Number.isFinite(page.Width) && page.Width > 0 ? Math.max(page.Width, bodyWidth) : bodyWidth;
10401
+ }
10402
+ /** Size of the drawn sheet in points: margins + header + body + footer, as wide as the content so every item lies on it. */
10403
+ function pageSheetSizePt(page, bodyWidth, margins) {
10404
+ return {
10405
+ width: margins.left + pageContentWidthPt(page, bodyWidth) + margins.right,
10406
+ height: margins.top + (page.Header?.Height ?? 0) + page.Height + (page.Footer?.Height ?? 0) + margins.bottom
10407
+ };
10408
+ }
10409
+ /**
10410
+ * The zoom factor to draw with. "pageWidth" fits the sheet width into the available width,
10411
+ * "wholePage" fits the whole sheet; available sizes are CSS pixels. Clamped to 10%..400%.
10412
+ */
10413
+ function resolveZoomFactor(zoom, sheetPt, available) {
10414
+ if (typeof zoom === "number")
10415
+ return clamp(zoom);
10416
+ const widthPx = ptToPx(sheetPt.width);
10417
+ const heightPx = ptToPx(sheetPt.height);
10418
+ if (widthPx <= 0 || available.width <= 0)
10419
+ return 1;
10420
+ const byWidth = available.width / widthPx;
10421
+ if (zoom === "pageWidth" || heightPx <= 0 || available.height <= 0)
10422
+ return clamp(byWidth);
10423
+ return clamp(Math.min(byWidth, available.height / heightPx));
10424
+ }
10425
+ function clamp(value) {
10426
+ return Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, value));
10427
+ }
10428
+
10429
+ /*
10430
+ * Maps the RDL style vocabulary to CSS. Everything here is report CONTENT: colors, fonts and borders
10431
+ * come from the report definition and are applied as given, not from the design system.
10432
+ */
10433
+ const RDL_DEFAULT_FONT_FAMILY = "Arial";
10434
+ const RDL_DEFAULT_FONT_SIZE = "10pt";
10435
+ const RDL_DEFAULT_COLOR = "black";
10436
+ const FONT_WEIGHTS = {
10437
+ thin: 100,
10438
+ extralight: 200,
10439
+ light: 300,
10440
+ normal: 400,
10441
+ medium: 500,
10442
+ semibold: 600,
10443
+ bold: 700,
10444
+ extrabold: 800,
10445
+ heavy: 900
10446
+ };
10447
+ const BORDER_STYLES = {
10448
+ solid: "solid",
10449
+ dotted: "dotted",
10450
+ dashed: "dashed",
10451
+ double: "double",
10452
+ none: "none"
10453
+ };
10454
+ /** An RDL color as CSS: "Transparent" = transparent, names and #RRGGBB pass through, empty = undefined. */
10455
+ function rdlColor(value) {
10456
+ if (!value)
10457
+ return undefined;
10458
+ const trimmed = value.trim();
10459
+ if (trimmed === "")
10460
+ return undefined;
10461
+ return trimmed.toLowerCase() === "transparent" ? "transparent" : trimmed;
10462
+ }
10463
+ /** Thin..Heavy to 100..900; unknown values fall back to normal. */
10464
+ function rdlFontWeight(value) {
10465
+ if (!value)
10466
+ return 400;
10467
+ return FONT_WEIGHTS[value.toLowerCase()] ?? (/^\d{3}$/.test(value) ? parseInt(value, 10) : 400);
10468
+ }
10469
+ /** A border side as a CSS shorthand; Style None or missing = none. Width defaults to 1pt, color to black. */
10470
+ function rdlBorder(border, zoom) {
10471
+ if (!border)
10472
+ return undefined;
10473
+ const style = BORDER_STYLES[(border.Style ?? "none").toLowerCase()] ?? "solid";
10474
+ if (style === "none")
10475
+ return "none";
10476
+ const widthPt = parseRdlSize(border.Width) ?? 1;
10477
+ const widthPx = Math.max(1, ptToPx(widthPt, zoom));
10478
+ return `${widthPx}px ${style} ${rdlColor(border.Color) ?? RDL_DEFAULT_COLOR}`;
10479
+ }
10480
+ /**
10481
+ * The four borders of an item box as the custom properties its border overlay draws
10482
+ * (`--rdl-border-top` ... in cw-report-page.module.css). Like the report server, borders sit on
10483
+ * the box edge and take no space from the content, so text laid out by the server to just fit
10484
+ * still fits. Always all four sides, "none" when unset: custom properties inherit, and a nested
10485
+ * item must not draw its container's borders.
10486
+ */
10487
+ function rdlBorderVars(style, zoom) {
10488
+ return {
10489
+ "--rdl-border-top": rdlBorder(style?.BorderTop, zoom) ?? "none",
10490
+ "--rdl-border-right": rdlBorder(style?.BorderRight, zoom) ?? "none",
10491
+ "--rdl-border-bottom": rdlBorder(style?.BorderBottom, zoom) ?? "none",
10492
+ "--rdl-border-left": rdlBorder(style?.BorderLeft, zoom) ?? "none"
10493
+ };
10494
+ }
10495
+ /** Background, borders (as overlay custom properties, see `rdlBorderVars`) and padding of an item box. */
10496
+ function rdlBoxStyle(style, zoom) {
10497
+ if (!style)
10498
+ return rdlBorderVars(null, zoom);
10499
+ return {
10500
+ ...rdlBorderVars(style, zoom),
10501
+ backgroundColor: rdlColor(style.BackgroundColor),
10502
+ paddingTop: rdlSizeToPx(style.PaddingTop, zoom),
10503
+ paddingRight: rdlSizeToPx(style.PaddingRight, zoom),
10504
+ paddingBottom: rdlSizeToPx(style.PaddingBottom, zoom),
10505
+ paddingLeft: rdlSizeToPx(style.PaddingLeft, zoom)
10506
+ };
10507
+ }
10508
+ function pick(key, styles) {
10509
+ for (const style of styles) {
10510
+ const value = style?.[key];
10511
+ if (value)
10512
+ return value;
10513
+ }
10514
+ return null;
10515
+ }
10516
+ function resolveRdlTextStyle(run, paragraph, textbox) {
10517
+ const chain = [run, paragraph, textbox];
10518
+ return {
10519
+ color: pick("Color", chain) ?? RDL_DEFAULT_COLOR,
10520
+ fontFamily: pick("FontFamily", chain) ?? RDL_DEFAULT_FONT_FAMILY,
10521
+ fontSize: pick("FontSize", chain) ?? RDL_DEFAULT_FONT_SIZE,
10522
+ fontStyle: pick("FontStyle", chain),
10523
+ fontWeight: pick("FontWeight", chain),
10524
+ textDecoration: pick("TextDecoration", chain),
10525
+ lineHeight: pick("LineHeight", chain)
10526
+ };
10527
+ }
10528
+ /**
10529
+ * The text style of a paragraph element. Its font sets the strut every line box gets, so it takes
10530
+ * the font of its runs (they usually share one; when they differ, the first run's): a paragraph
10531
+ * left at the textbox default (Arial 10pt) around Segoe UI 8pt runs would make every line taller
10532
+ * than the server measured and the text would overflow its box. An RDL LineHeight on the paragraph
10533
+ * or textbox still wins; otherwise the run's LineHeight, if any, applies.
10534
+ */
10535
+ function resolveParagraphTextStyle(runStyles, paragraph, textbox) {
10536
+ const own = resolveRdlTextStyle(null, paragraph, textbox);
10537
+ if (runStyles.length === 0)
10538
+ return own;
10539
+ const run = resolveRdlTextStyle(runStyles[0], paragraph, textbox);
10540
+ return {
10541
+ ...own,
10542
+ fontFamily: run.fontFamily,
10543
+ fontSize: run.fontSize,
10544
+ fontStyle: run.fontStyle,
10545
+ fontWeight: run.fontWeight,
10546
+ lineHeight: own.lineHeight ?? run.lineHeight
10547
+ };
10548
+ }
10549
+ function textDecoration(value) {
10550
+ switch ((value ?? "").toLowerCase()) {
10551
+ case "underline": return "underline";
10552
+ case "linethrough": return "line-through";
10553
+ case "overline": return "overline";
10554
+ default: return undefined;
10555
+ }
10556
+ }
10557
+ /** An RDL LineHeight in pixels, else "normal"; an unparsable value also falls back to normal. */
10558
+ function rdlLineHeight(value, zoom) {
10559
+ const px = rdlSizeToPx(value, zoom);
10560
+ return px === undefined ? "normal" : `${px}px`;
10561
+ }
10562
+ /**
10563
+ * CSS of a resolved text style at a zoom factor. Without an RDL LineHeight the line height is the
10564
+ * font's natural one ("normal"), the spacing the server measures text with; set inline so no app
10565
+ * or base rule on p / span (125%, 1.15) can shrink the line box and clip large glyphs.
10566
+ */
10567
+ function rdlTextCss(text, zoom) {
10568
+ return {
10569
+ // Transparent text is invisible, as in Reporting Services (reports use it to hide values).
10570
+ color: rdlColor(text.color),
10571
+ fontFamily: text.fontFamily,
10572
+ fontSize: rdlSizeToPx(text.fontSize, zoom) ?? ptToPx(10, zoom),
10573
+ fontStyle: (text.fontStyle ?? "").toLowerCase() === "italic" ? "italic" : undefined,
10574
+ fontWeight: text.fontWeight ? rdlFontWeight(text.fontWeight) : undefined,
10575
+ textDecoration: textDecoration(text.textDecoration),
10576
+ lineHeight: rdlLineHeight(text.lineHeight, zoom)
10577
+ };
10578
+ }
10579
+ /** TextAlign Left/Center/Right/General (General = left). */
10580
+ function rdlTextAlign(value) {
10581
+ switch ((value ?? "").toLowerCase()) {
10582
+ case "center": return "center";
10583
+ case "right": return "right";
10584
+ case "justify": return "justify";
10585
+ default: return "left";
10586
+ }
10587
+ }
10588
+ /**
10589
+ * VerticalAlign Top/Middle/Bottom as the justify-content of a column flex box. "safe": when the
10590
+ * text is taller than its box it falls back to the top, so the first line is never cut off.
10591
+ */
10592
+ function rdlVerticalAlign(value) {
10593
+ switch ((value ?? "").toLowerCase()) {
10594
+ case "middle": return "safe center";
10595
+ case "bottom": return "safe flex-end";
10596
+ default: return "flex-start";
10597
+ }
10598
+ }
10599
+ /** The stroke of a line item: BorderTop, else BorderLeft, default 1pt solid black. */
10600
+ function rdlLineStroke(style, zoom) {
10601
+ const border = style?.BorderTop ?? style?.BorderLeft ?? null;
10602
+ const width = Math.max(1, ptToPx(parseRdlSize(border?.Width) ?? 1, zoom));
10603
+ const kind = (border?.Style ?? "solid").toLowerCase();
10604
+ const color = rdlColor(border?.Color) ?? RDL_DEFAULT_COLOR;
10605
+ if (kind === "none")
10606
+ return { color: "transparent", width };
10607
+ if (kind === "dotted")
10608
+ return { color, width, dash: `${width} ${width * 2}` };
10609
+ if (kind === "dashed")
10610
+ return { color, width, dash: `${width * 4} ${width * 2}` };
10611
+ return { color, width };
10612
+ }
10613
+
10614
+ /*
10615
+ * Pure chart math for the report charts. The hex values below are the report's chart palettes:
10616
+ * content colors (like the colors a report carries), not UI chrome, so no design tokens.
10617
+ */
10618
+ /**
10619
+ * The Microsoft chart palettes by name, with the exact colors of the old ReportViewer engine.
10620
+ * The engine's semi-transparent palettes are #AARRGGBB; here they are CSS #RRGGBBAA.
10621
+ */
10622
+ const PALETTES = {
10623
+ Default: [
10624
+ "#008000", "#0000FF", "#800080", "#00FF00", "#FF00FF", "#008080", "#FFFF00", "#808080",
10625
+ "#00FFFF", "#000080", "#800000", "#FF0000", "#808000", "#C0C0C0", "#FF6347", "#FFE4B5"
10626
+ ],
10627
+ Grayscale: [
10628
+ "#C8C8C8", "#BDBDBD", "#B2B2B2", "#A7A7A7", "#9C9C9C", "#919191", "#868686", "#7B7B7B",
10629
+ "#707070", "#656565", "#5A5A5A", "#4F4F4F", "#444444", "#393939", "#2E2E2E", "#232323"
10630
+ ],
10631
+ Excel: [
10632
+ "#9999FF", "#993366", "#FFFFCC", "#CCFFFF", "#660066", "#FF8080", "#0066CC", "#CCCCFF",
10633
+ "#000080", "#FF00FF", "#FFFF00", "#00FFFF", "#800080", "#800000", "#008080", "#0000FF"
10634
+ ],
10635
+ Light: ["#E6E6FA", "#FFF0F5", "#FFDAB9", "#FFFACD", "#FFE4E1", "#F0FFF0", "#F0F8FF", "#F5F5F5", "#FAEBD7", "#E0FFFF"],
10636
+ Pastel: [
10637
+ "#87CEEB", "#32CD32", "#BA55D3", "#F08080", "#4682B4", "#9ACD32", "#40E0D0", "#FF69B4",
10638
+ "#F0E68C", "#D2B48C", "#8FBC8B", "#6495ED", "#DDA0DD", "#5F9EA0", "#FFDAB9", "#FFA07A"
10639
+ ],
10640
+ EarthTones: [
10641
+ "#FF8000", "#B8860B", "#C04000", "#6B8E23", "#CD853F", "#C0C000", "#228B22", "#D2691E",
10642
+ "#808000", "#20B2AA", "#F4A460", "#00C000", "#8FBC8B", "#B22222", "#8B4513", "#C00000"
10643
+ ],
10644
+ SemiTransparent: [
10645
+ "#FF000096", "#00FF0096", "#0000FF96", "#FFFF0096", "#00FFFF96", "#FF00FF96", "#AA781496", "#FF000050",
10646
+ "#00FF0050", "#0000FF50", "#FFFF0050", "#00FFFF50", "#FF00FF50", "#AA781450", "#64783296", "#285A9696"
10647
+ ],
10648
+ Berry: ["#8A2BE2", "#BA55D3", "#4169E1", "#C71585", "#0000FF", "#8A2BE2", "#DA70D6", "#7B68EE", "#C000C0", "#0000CD", "#800080"],
10649
+ Chocolate: ["#A0522D", "#D2691E", "#8B0000", "#CD853F", "#A52A2A", "#F4A460", "#8B4513", "#C04000", "#B22222", "#B65C3A"],
10650
+ Fire: ["#FFD700", "#FF0000", "#FF1493", "#DC143C", "#FF8C00", "#FF00FF", "#FFFF00", "#FF4500", "#C71585", "#DDE221"],
10651
+ SeaGreen: ["#2E8B57", "#66CDAA", "#4682B4", "#008B8B", "#5F9EA0", "#3CB371", "#48D1CC", "#B0C4DE", "#8FBC8B", "#87CEEB"],
10652
+ BrightPastel: [
10653
+ "#418CF0", "#FCB441", "#E0400A", "#056492", "#BFBFBF", "#1A3B69", "#FFE382", "#129CDD",
10654
+ "#CA6B4B", "#005CDB", "#F3D288", "#506381", "#F1B9A8", "#E0830A", "#7893BE"
10655
+ ],
10656
+ Pacific: [
10657
+ "#01B8AA", "#374649", "#FD625E", "#F2C80F", "#5F6B6D", "#8AD4EB", "#FE9666", "#A66999", "#3599B8", "#DFBFBF",
10658
+ "#4AC5BB", "#5F6B6D", "#FB8281", "#F4D25A", "#7F898A", "#A4DDEE", "#FDAB89", "#B687AC", "#28738A", "#A78F8F"
10659
+ ],
10660
+ PacificLight: ["#4AC5BB", "#5F6B6D", "#FB8281", "#F4D25A", "#7F898A", "#A4DDEE", "#FDAB89", "#B687AC", "#28738A", "#A78F8F"],
10661
+ PacificSemiTransparent: [
10662
+ "#01B8AA99", "#37464999", "#FD625E99", "#F2C80F99", "#5F6B6D99", "#8AD4EB99", "#FE966699", "#A6699999", "#3599B899", "#DFBFBF99",
10663
+ "#4AC5BB99", "#5F6B6D99", "#FB828199", "#F4D25A99", "#7F898A99", "#A4DDEE99", "#FDAB8999", "#B687AC99", "#28738A99", "#A78F8F99"
10664
+ ]
10665
+ };
10666
+ const PALETTES_BY_NAME = new Map(Object.entries(PALETTES).map(([name, colors]) => [name.toLowerCase(), colors]));
10667
+ /** The palette for an RDL palette name (any case); a missing or unknown name is "Default", the RDL default. */
10668
+ function chartPalette(name) {
10669
+ return PALETTES_BY_NAME.get((name ?? "").trim().toLowerCase()) ?? PALETTES.Default;
10670
+ }
10671
+ /** The color of series `index`: its own color, else the palette entry. */
10672
+ function seriesColor(series, index, palette) {
10673
+ return series.Color && series.Color.toLowerCase() !== "automatic" ? series.Color : palette[index % palette.length];
10674
+ }
10675
+ /** Steps of a value axis: about five, rounded to 1, 2, 5 or 10 times a power of ten. */
10676
+ const VALUE_AXIS_STEPS = 5;
10677
+ /** Drops the binary noise of step multiples (0.6000000000000001 -> 0.6). */
10678
+ function tidy$1(value) {
10679
+ return Number(value.toPrecision(12));
10680
+ }
10681
+ /**
10682
+ * bound / step, snapped to the nearest integer only when it is within a few ulps of it: 0.07 / 0.01 is
10683
+ * 7.000000000000001 in binary floating point and would otherwise add an axis step. Genuine non-multiples
10684
+ * (0.37 / 0.05) keep their fraction so the bounds still round outwards.
10685
+ */
10686
+ function axisQuotient(bound, step) {
10687
+ const quotient = bound / step;
10688
+ const nearest = Math.round(quotient);
10689
+ const reconstructed = nearest * step;
10690
+ const tolerance = Number.EPSILON * 4 * Math.max(1, Math.abs(bound), Math.abs(reconstructed));
10691
+ return Math.abs(reconstructed - bound) <= tolerance ? nearest : quotient;
10692
+ }
10693
+ /** The nice step for a value range (> 0): range / 5 rounded to 1, 2, 5 or 10 times its magnitude. */
10694
+ function niceAxisStep(range) {
10695
+ const raw = range / VALUE_AXIS_STEPS;
10696
+ const magnitude = Math.pow(10, Math.floor(Math.log10(raw)));
10697
+ const residual = raw / magnitude;
10698
+ const nice = residual < 1.5 ? 1 : residual < 3.5 ? 2 : residual < 7.5 ? 5 : 10;
10699
+ return tidy$1(nice * magnitude);
10700
+ }
10701
+ /**
10702
+ * A value axis over the given values, the same rule as the server's PDF: the range always includes
10703
+ * 0, nulls are ignored, the step is `niceAxisStep(range)` and the bounds are rounded out to whole
10704
+ * steps (data max 113 gives 0..120 in steps of 20). All-null or all-zero data gives 0..1.
10705
+ */
10706
+ function computeValueScale(values) {
10707
+ let min = 0;
10708
+ let max = 0;
10709
+ for (const value of values) {
10710
+ if (value === null || value === undefined || !Number.isFinite(value))
10711
+ continue;
10712
+ if (value < min)
10713
+ min = value;
10714
+ if (value > max)
10715
+ max = value;
10716
+ }
10717
+ if (min === max)
10718
+ max = min + 1;
10719
+ const step = niceAxisStep(max - min);
10720
+ const first = Math.floor(axisQuotient(min, step));
10721
+ const last = Math.ceil(axisQuotient(max, step));
10722
+ const ticks = [];
10723
+ for (let index = first; index <= last; index++)
10724
+ ticks.push(tidy$1(index * step));
10725
+ return { min: tidy$1(first * step), max: tidy$1(last * step), ticks };
10726
+ }
10727
+ /**
10728
+ * The server's category axis labels (`RdlRenderChart.CategoryAxisLabels`) along an axis that starts
10729
+ * at `start` with `band` pixels per category: position 0 is the first category's point (the middle
10730
+ * of its band), fractions fall between two categories. Labels outside the categories are dropped.
10731
+ */
10732
+ function categoryAxisLabels(labels, categoryCount, start, band) {
10733
+ return labels
10734
+ .filter(label => Number.isFinite(label.Position) && label.Position >= -0.5 && label.Position <= categoryCount - 0.5)
10735
+ .map(label => ({ at: start + band * (label.Position + 0.5), text: label.Text }));
10736
+ }
10737
+ /**
10738
+ * Centers a label of `width` on `center`, moved inside [min, max] when it would cross an end: a
10739
+ * category label never runs past the value axis (and its origin label) or the plot's right edge.
10740
+ */
10741
+ function placeAxisLabel(center, width, min, max) {
10742
+ if (center - width / 2 < min)
10743
+ return { x: min, anchor: "start" };
10744
+ if (center + width / 2 > max)
10745
+ return { x: max, anchor: "end" };
10746
+ return { x: center, anchor: "middle" };
10747
+ }
10748
+ /** Maps a value of the scale to a pixel coordinate between `from` (scale min) and `to` (scale max). */
10749
+ function scaleValue(value, scale, from, to) {
10750
+ const span = scale.max - scale.min;
10751
+ if (span === 0)
10752
+ return from;
10753
+ return from + ((value - scale.min) / span) * (to - from);
10754
+ }
10755
+ /** Splits a series into runs of consecutive non-null points: a null value leaves a gap in the line. */
10756
+ function lineSegments(values, x, y) {
10757
+ const segments = [];
10758
+ let current = [];
10759
+ values.forEach((value, index) => {
10760
+ if (value === null || value === undefined || !Number.isFinite(value)) {
10761
+ if (current.length > 0)
10762
+ segments.push(current);
10763
+ current = [];
10764
+ return;
10765
+ }
10766
+ current.push({ index, value, x: x(index), y: y(value) });
10767
+ });
10768
+ if (current.length > 0)
10769
+ segments.push(current);
10770
+ return segments;
10771
+ }
10772
+ /** SVG path of one segment: straight, stepped (horizontal then vertical) or smooth (Catmull-Rom as cubic Beziers). */
10773
+ function segmentPath(points, subtype) {
10774
+ if (points.length === 0)
10775
+ return "";
10776
+ const kind = (subtype ?? "").toLowerCase();
10777
+ let path = `M${points[0].x},${points[0].y}`;
10778
+ for (let i = 1; i < points.length; i++) {
10779
+ const prev = points[i - 1];
10780
+ const point = points[i];
10781
+ if (kind === "stepped") {
10782
+ path += ` H${point.x} V${point.y}`;
10783
+ }
10784
+ else if (kind === "smooth") {
10785
+ const before = points[i - 2] ?? prev;
10786
+ const after = points[i + 1] ?? point;
10787
+ const c1x = prev.x + (point.x - before.x) / 6;
10788
+ const c1y = prev.y + (point.y - before.y) / 6;
10789
+ const c2x = point.x - (after.x - prev.x) / 6;
10790
+ const c2y = point.y - (after.y - prev.y) / 6;
10791
+ path += ` C${c1x},${c1y} ${c2x},${c2y} ${point.x},${point.y}`;
10792
+ }
10793
+ else {
10794
+ path += ` L${point.x},${point.y}`;
10795
+ }
10796
+ }
10797
+ return path;
10798
+ }
10799
+ /** Pie slices of positive values (null, zero and negative values get no slice); angles in radians from 12 o'clock, clockwise. */
10800
+ function pieSlices(values) {
10801
+ const total = values.reduce((acc, value) => acc + (value !== null && value > 0 ? value : 0), 0);
10802
+ if (total <= 0)
10803
+ return [];
10804
+ const slices = [];
10805
+ let angle = 0;
10806
+ values.forEach((value, index) => {
10807
+ if (value === null || value <= 0)
10808
+ return;
10809
+ const fraction = value / total;
10810
+ const end = angle + fraction * Math.PI * 2;
10811
+ slices.push({ index, value, fraction, startAngle: angle, endAngle: end });
10812
+ angle = end;
10813
+ });
10814
+ return slices;
10815
+ }
10816
+ /** A point on a circle; angle in radians from 12 o'clock, clockwise. */
10817
+ function polar(cx, cy, radius, angle) {
10818
+ return { x: cx + radius * Math.sin(angle), y: cy - radius * Math.cos(angle) };
10819
+ }
10820
+ /** SVG path of an arc band (or a pie wedge when innerRadius is 0) between two angles. */
10821
+ function arcPath(cx, cy, outerRadius, innerRadius, start, end) {
10822
+ const sweep = end - start;
10823
+ if (sweep >= Math.PI * 2 - 1e-9) {
10824
+ const mid = start + Math.PI;
10825
+ return arcPath(cx, cy, outerRadius, innerRadius, start, mid) + " " + arcPath(cx, cy, outerRadius, innerRadius, mid, end);
10826
+ }
10827
+ const large = sweep > Math.PI ? 1 : 0;
10828
+ const o1 = polar(cx, cy, outerRadius, start);
10829
+ const o2 = polar(cx, cy, outerRadius, end);
10830
+ if (innerRadius <= 0) {
10831
+ return `M${cx},${cy} L${o1.x},${o1.y} A${outerRadius},${outerRadius} 0 ${large} 1 ${o2.x},${o2.y} Z`;
10832
+ }
10833
+ const i2 = polar(cx, cy, innerRadius, end);
10834
+ const i1 = polar(cx, cy, innerRadius, start);
10835
+ return `M${o1.x},${o1.y} A${outerRadius},${outerRadius} 0 ${large} 1 ${o2.x},${o2.y} L${i2.x},${i2.y} A${innerRadius},${innerRadius} 0 ${large} 0 ${i1.x},${i1.y} Z`;
10836
+ }
10837
+ /** Clamps a gauge value into the scale; null stays at the minimum. */
10838
+ function clampGaugeValue(value, minimum, maximum) {
10839
+ if (value === null || value === undefined || !Number.isFinite(value))
10840
+ return minimum;
10841
+ const low = Math.min(minimum, maximum);
10842
+ const high = Math.max(minimum, maximum);
10843
+ return Math.min(high, Math.max(low, value));
10844
+ }
10845
+ /** Formats an axis or data value compactly: integers without decimals, else up to 2 decimals. */
10846
+ function formatChartValue(value) {
10847
+ if (Number.isInteger(value))
10848
+ return value.toString();
10849
+ return (Math.round(value * 100) / 100).toString();
10850
+ }
10851
+
10852
+ /** More ticks than this on one scale is a broken interval, not a scale anyone can read. */
10853
+ const MAX_GAUGE_TICKS = 200;
10854
+ /**
10855
+ * The ellipse a state indicator fills: its percent box of the panel, stretched to an oval in a box
10856
+ * that is not square, like the old viewer. Null when the active state has no color or the box is empty.
10857
+ */
10858
+ function stateIndicatorEllipse(indicator, panelWidth, panelHeight) {
10859
+ if (!indicator.Color)
10860
+ return null;
10861
+ const width = (Math.max(0, indicator.Width) / 100) * panelWidth;
10862
+ const height = (Math.max(0, indicator.Height) / 100) * panelHeight;
10863
+ if (width <= 0 || height <= 0)
10864
+ return null;
10865
+ const left = (indicator.Left / 100) * panelWidth;
10866
+ const top = (indicator.Top / 100) * panelHeight;
10867
+ return { cx: left + width / 2, cy: top + height / 2, rx: width / 2, ry: height / 2 };
10868
+ }
10869
+ /** The value span a Bar pointer covers: from the scale minimum to the value clamped into the scale. */
10870
+ function gaugeBarSpan(value, minimum, maximum) {
10871
+ return { from: minimum, to: clampGaugeValue(value, minimum, maximum) };
10872
+ }
10873
+ function tidy(value) {
10874
+ return Number(value.toPrecision(12));
10875
+ }
10876
+ /**
10877
+ * The major tick values of a gauge scale: every `interval` from the minimum up to the maximum (the
10878
+ * server computes it); without a usable interval the chart axis' nice step of the range is used.
10879
+ */
10880
+ function gaugeTicks(minimum, maximum, interval) {
10881
+ const low = Math.min(minimum, maximum);
10882
+ const high = Math.max(minimum, maximum);
10883
+ if (!Number.isFinite(low) || !Number.isFinite(high))
10884
+ return [];
10885
+ if (high === low)
10886
+ return [tidy(low)];
10887
+ const step = interval !== null && interval !== undefined && Number.isFinite(interval) && interval > 0
10888
+ ? interval
10889
+ : niceAxisStep(high - low);
10890
+ const count = Math.floor(tidy((high - low) / step));
10891
+ if (count > MAX_GAUGE_TICKS)
10892
+ return [tidy(low), tidy(high)];
10893
+ const ticks = [];
10894
+ for (let index = 0; index <= count; index++)
10895
+ ticks.push(tidy(low + index * step));
10896
+ return ticks;
10897
+ }
10898
+ /**
10899
+ * A thickness given in percent of the gauge's own size (for a horizontal linear gauge its height, as
10900
+ * the chart engine measures range and pointer widths), or the default fraction when it is missing.
10901
+ */
10902
+ function gaugeThickness(percent, gaugeSize, defaultFraction) {
10903
+ const fraction = percent !== null && percent !== undefined && Number.isFinite(percent) && percent > 0 ? percent / 100 : defaultFraction;
10904
+ return gaugeSize * Math.min(1, fraction);
10905
+ }
10906
+ /** Cross (or none) is centred on the scale line, Inside lies above it, Outside below it. */
10907
+ function gaugeBandExtent(placement, thickness) {
10908
+ switch ((placement ?? "").toLowerCase()) {
10909
+ case "inside": return { up: thickness, down: 0 };
10910
+ case "outside": return { up: 0, down: thickness };
10911
+ default: return { up: thickness / 2, down: thickness / 2 };
10912
+ }
10913
+ }
10914
+ /**
10915
+ * The y of the scale line of a horizontal linear gauge `height` tall: the bands (ranges and pointers)
10916
+ * and the tick labels below them (`labelSpace`) are centred as one block.
10917
+ */
10918
+ function linearGaugeScaleY(height, bands, labelSpace) {
10919
+ const up = Math.max(0, ...bands.map(band => band.up));
10920
+ const down = Math.max(0, ...bands.map(band => band.down));
10921
+ return Math.max(up, (height - (up + down + labelSpace)) / 2 + up);
10922
+ }
10923
+
10924
+ /** The order an "Auto" marker takes per series, as the chart engine cycles it. */
10925
+ const AUTO_SHAPES = ["square", "circle", "diamond", "triangle", "cross", "star4", "star5", "star6", "star10"];
10926
+ const SHAPES = {
10927
+ square: "square",
10928
+ circle: "circle",
10929
+ diamond: "diamond",
10930
+ triangle: "triangle",
10931
+ cross: "cross",
10932
+ star4: "star4",
10933
+ star5: "star5",
10934
+ star6: "star6",
10935
+ star10: "star10"
10936
+ };
10937
+ /** The marker size when the series sets none, as the server uses it. */
10938
+ const RDL_DEFAULT_MARKER_SIZE_PT = 5;
10939
+ /**
10940
+ * The marker a series draws, or null for none. The server resolves Auto to a shape, so a missing type
10941
+ * or None means no marker. Should an Auto (or an unknown name) still arrive, a scatter series cycles
10942
+ * the shapes per series, so its points stay visible; a line series then draws none.
10943
+ */
10944
+ function seriesMarker(markerType, scatter, seriesIndex) {
10945
+ if (!markerType)
10946
+ return null;
10947
+ const name = markerType.trim().toLowerCase();
10948
+ if (name === "none" || name === "")
10949
+ return null;
10950
+ const shape = SHAPES[name];
10951
+ if (shape)
10952
+ return shape;
10953
+ return scatter ? AUTO_SHAPES[seriesIndex % AUTO_SHAPES.length] : null;
10954
+ }
10955
+ /** The marker size in pixels at a zoom (RDL size, default 5pt), at least 3 px so it stays visible. */
10956
+ function markerSizePx(markerSize, zoom) {
10957
+ return Math.max(3, ptToPx(parseRdlSize(markerSize) ?? RDL_DEFAULT_MARKER_SIZE_PT, zoom));
10958
+ }
10959
+ function round(value) {
10960
+ return Math.round(value * 100) / 100;
10961
+ }
10962
+ function polygon(points) {
10963
+ return `M${points.map(([x, y]) => `${round(x)},${round(y)}`).join(" L")} Z`;
10964
+ }
10965
+ function star(cx, cy, outer, points) {
10966
+ const inner = outer * (points <= 4 ? 0.35 : 0.45);
10967
+ const corners = [];
10968
+ for (let index = 0; index < points * 2; index++) {
10969
+ const radius = index % 2 === 0 ? outer : inner;
10970
+ const angle = -Math.PI / 2 + (index * Math.PI) / points;
10971
+ corners.push([cx + radius * Math.cos(angle), cy + radius * Math.sin(angle)]);
10972
+ }
10973
+ return polygon(corners);
10974
+ }
10975
+ /** SVG path of a marker of `size` (its width; an X has arms of that length along its diagonals) centered on (cx, cy); every shape is filled. */
10976
+ function markerPath(shape, cx, cy, size) {
10977
+ const r = size / 2;
10978
+ switch (shape) {
10979
+ case "square":
10980
+ return polygon([[cx - r, cy - r], [cx + r, cy - r], [cx + r, cy + r], [cx - r, cy + r]]);
10981
+ case "circle":
10982
+ return `M${round(cx - r)},${round(cy)} A${round(r)},${round(r)} 0 1 0 ${round(cx + r)},${round(cy)} A${round(r)},${round(r)} 0 1 0 ${round(cx - r)},${round(cy)} Z`;
10983
+ case "diamond":
10984
+ return polygon([[cx, cy - r], [cx + r, cy], [cx, cy + r], [cx - r, cy]]);
10985
+ case "triangle":
10986
+ return polygon([[cx, cy - r], [cx + r, cy + r], [cx - r, cy + r]]);
10987
+ case "cross": {
10988
+ // The chart engine's Cross is an X: a filled plus sign, its arms a third of the size thick, turned by 45 degrees.
10989
+ const t = size / 6;
10990
+ const plus = [
10991
+ [-t, -r], [t, -r], [t, -t], [r, -t], [r, t], [t, t],
10992
+ [t, r], [-t, r], [-t, t], [-r, t], [-r, -t], [-t, -t]
10993
+ ];
10994
+ const turn = Math.SQRT1_2;
10995
+ return polygon(plus.map(([dx, dy]) => [cx + (dx - dy) * turn, cy + (dx + dy) * turn]));
10996
+ }
10997
+ case "star4": return star(cx, cy, r, 4);
10998
+ case "star5": return star(cx, cy, r, 5);
10999
+ case "star6": return star(cx, cy, r, 6);
11000
+ case "star10": return star(cx, cy, r, 10);
11001
+ }
11002
+ }
11003
+ const ALIGN = {
11004
+ left: "start",
11005
+ top: "start",
11006
+ center: "center",
11007
+ right: "end",
11008
+ bottom: "end"
11009
+ };
11010
+ /** The RDL default legend position: a column on the right, vertically centered (RightCenter). */
11011
+ const DEFAULT_LEGEND = { edge: "right", align: "center" };
11012
+ /**
11013
+ * The RDL ChartLegend Position as an edge and an alignment: the first word is the edge, the second
11014
+ * the alignment along it (TopLeft = top edge, left aligned; LeftTop = left edge, top aligned).
11015
+ * Missing or unknown = RightCenter, the RDL default.
11016
+ */
11017
+ function legendPlacement(position) {
11018
+ const match = /^(top|bottom|left|right)(left|right|top|bottom|center)$/i.exec((position ?? "").trim());
11019
+ if (!match)
11020
+ return DEFAULT_LEGEND;
11021
+ const edge = match[1].toLowerCase();
11022
+ const along = match[2].toLowerCase();
11023
+ const horizontalEdge = edge === "top" || edge === "bottom";
11024
+ // "TopTop" or "LeftLeft" make no sense: the alignment must run along the edge.
11025
+ const valid = horizontalEdge ? ["left", "center", "right"].includes(along) : ["top", "center", "bottom"].includes(along);
11026
+ return { edge, align: valid ? ALIGN[along] : "center" };
11027
+ }
11028
+
11029
+ var styles$2 = {"chart":"cw-report-chart-module__chart__HEwvf","title":"cw-report-chart-module__title__zvCfx","axis":"cw-report-chart-module__axis__qwHaL","grid":"cw-report-chart-module__grid__xJMG8","tick":"cw-report-chart-module__tick__uQJeQ","muted":"cw-report-chart-module__muted__Nj1-j","hit":"cw-report-chart-module__hit__-u6vf","point":"cw-report-chart-module__point__M-GuI","slice":"cw-report-chart-module__slice__DEbOB","track":"cw-report-chart-module__track__NAVBX","needle":"cw-report-chart-module__needle__m5fJK","cap":"cw-report-chart-module__cap__zL7KT"};
11030
+
11031
+ /** Chart text size in points (scaled with the zoom). */
11032
+ const CHART_FONT_PT = 8;
11033
+ /** Rough width of one character of the chart font, as a share of the font size. */
11034
+ const CHAR_WIDTH = 0.6;
11035
+ function chartFontPx(zoom) {
11036
+ return ptToPx(CHART_FONT_PT, zoom);
11037
+ }
11038
+ function estimateTextWidth(text, fontPx) {
11039
+ return text.length * fontPx * CHAR_WIDTH;
11040
+ }
11041
+ /** Hover handlers that show the shared CwTooltipManager tooltip over an SVG element. */
11042
+ function useChartTooltip() {
11043
+ useEffect(() => {
11044
+ ensureTooltipManager();
11045
+ }, []);
11046
+ const show = useCallback((content) => (event) => {
11047
+ showTooltip(content, event.currentTarget, "top");
11048
+ }, []);
11049
+ const hide = useCallback(() => hideTooltip(), []);
11050
+ return { show, hide };
11051
+ }
11052
+ function tooltipContent(title, label, value) {
11053
+ return (jsxs("span", { children: [jsx("strong", { children: title }), jsx("br", {}), label, ": ", value] }));
11054
+ }
11055
+ /** Lays legend entries out in rows that wrap at `width`, each row aligned within `width` (centered by default). */
11056
+ function layoutLegend(entries, width, fontPx, align = "center") {
11057
+ if (entries.length === 0)
11058
+ return { height: 0, width: 0, items: [] };
11059
+ const swatch = fontPx;
11060
+ const gap = fontPx;
11061
+ const lineHeight = fontPx * 1.6;
11062
+ const rows = [[]];
11063
+ let rowWidth = 0;
11064
+ for (const entry of entries) {
11065
+ const itemWidth = swatch + fontPx * 0.4 + estimateTextWidth(entry.label, fontPx);
11066
+ if (rowWidth > 0 && rowWidth + gap + itemWidth > width) {
11067
+ rows.push([]);
11068
+ rowWidth = 0;
11069
+ }
11070
+ rowWidth += (rowWidth > 0 ? gap : 0) + itemWidth;
11071
+ rows[rows.length - 1].push({ entry, width: itemWidth });
11072
+ }
11073
+ const items = [];
11074
+ let widest = 0;
11075
+ rows.forEach((row, rowIndex) => {
11076
+ const total = row.reduce((acc, item) => acc + item.width, 0) + gap * (row.length - 1);
11077
+ widest = Math.max(widest, total);
11078
+ const free = Math.max(0, width - total);
11079
+ let x = align === "start" ? 0 : align === "end" ? free : free / 2;
11080
+ for (const item of row) {
11081
+ items.push({ entry: item.entry, x, y: rowIndex * lineHeight + lineHeight / 2 });
11082
+ x += item.width + gap;
11083
+ }
11084
+ });
11085
+ return { height: rows.length * lineHeight, width: widest, items };
11086
+ }
11087
+ function ChartLegend({ layout, top, left = 0, fontPx }) {
11088
+ return (jsx("g", { transform: `translate(${left}, ${top})`, children: layout.items.map((item, index) => (jsxs("g", { transform: `translate(${item.x}, ${item.y})`, children: [item.entry.marker
11089
+ ? jsx("path", { d: markerPath(item.entry.marker, fontPx / 2, 0, fontPx), fill: item.entry.color })
11090
+ : jsx("rect", { x: 0, y: -fontPx / 2, width: fontPx, height: fontPx, fill: item.entry.color }), jsx("text", { x: fontPx * 1.4, dominantBaseline: "central", fontSize: fontPx, children: item.entry.label })] }, index))) }));
11091
+ }
11092
+ /** The chart titles, one line each, centered. Returns the height they take. */
11093
+ function ChartTitles({ titles, width, fontPx }) {
11094
+ return (jsx(Fragment, { children: titles.map((title, index) => (jsx("text", { className: styles$2.title, x: width / 2, y: fontPx * 1.5 * (index + 1), textAnchor: "middle", fontSize: fontPx * 1.25, children: title }, index))) }));
11095
+ }
11096
+ function titlesHeight(titles, fontPx) {
11097
+ return titles.length === 0 ? 0 : fontPx * 1.5 * titles.length + fontPx * 0.5;
11098
+ }
11099
+ /** A centered message instead of the plot (dataset error or no rows). */
11100
+ function ChartMessage({ text, width, height, fontPx }) {
11101
+ return (jsx("text", { className: styles$2.muted, x: width / 2, y: height / 2, textAnchor: "middle", dominantBaseline: "central", fontSize: fontPx * 1.2, children: text }));
11102
+ }
11103
+
11104
+ /** 270 degree dial: from 7:30 to 4:30 on a clock face, in radians from 12 o'clock. */
11105
+ const DIAL_START = -Math.PI * 0.75;
11106
+ const DIAL_END = Math.PI * 0.75;
11107
+ /** Report content defaults, as the old viewer drew them: black pointers, the Default palette for ranges. */
11108
+ const POINTER_FALLBACK = "black";
11109
+ const RANGE_PALETTE = chartPalette(null);
11110
+ /** Thickness of a range / pointer without a Width, as a fraction of the gauge height (the chart engine defaults). */
11111
+ const RANGE_DEFAULT_WIDTH = 0.3;
11112
+ const POINTER_DEFAULT_WIDTH = 0.1;
11113
+ const EMPTY_SCALE = { Minimum: 0, Maximum: 100, Pointers: [], Ranges: [] };
11114
+ function isBarPointer(type) {
11115
+ return (type ?? "").toLowerCase() === "bar";
11116
+ }
11117
+ function rangeColor(range, index) {
11118
+ return range.Color || RANGE_PALETTE[index % RANGE_PALETTE.length];
11119
+ }
11120
+ function pointerColor(pointer) {
11121
+ return pointer.Color || POINTER_FALLBACK;
11122
+ }
11123
+ function RadialGauge({ gauge, width, height, fontPx, zoom }) {
11124
+ const scale = gauge.Scales[0] ?? EMPTY_SCALE;
11125
+ const { Minimum: min, Maximum: max } = scale;
11126
+ const radius = Math.max(0, Math.min(width / 2, height / 1.75) - fontPx * 0.5);
11127
+ const cx = width / 2;
11128
+ const cy = fontPx * 0.5 + radius;
11129
+ const band = radius * 0.15;
11130
+ const angle = (value) => scaleValue(clampGaugeValue(value, min, max), { min, max }, DIAL_START, DIAL_END);
11131
+ const minLabel = polar(cx, cy, radius - band * 2.5, DIAL_START);
11132
+ const maxLabel = polar(cx, cy, radius - band * 2.5, DIAL_END);
11133
+ const showLabels = scale.ShowLabels !== false;
11134
+ return (jsxs("g", { children: [jsx("path", { className: styles$2.track, d: arcPath(cx, cy, radius, radius - band, DIAL_START, DIAL_END) }), scale.Ranges.map((range, index) => (jsx("path", { d: arcPath(cx, cy, radius, radius - band, angle(range.Start ?? min), angle(range.End ?? max)), fill: rangeColor(range, index) }, `r${index}`))), scale.Pointers.map((pointer, index) => {
11135
+ if (isBarPointer(pointer.Type)) {
11136
+ const span = gaugeBarSpan(pointer.Value, min, max);
11137
+ return (jsx("path", { d: arcPath(cx, cy, radius - band * 1.2, radius - band * 1.9, angle(span.from), angle(span.to)), fill: pointerColor(pointer) }, `p${index}`));
11138
+ }
11139
+ const tip = polar(cx, cy, radius * 0.8, angle(pointer.Value ?? min));
11140
+ return (jsx("line", { className: styles$2.needle, x1: cx, y1: cy, x2: tip.x, y2: tip.y, style: pointer.Color ? { stroke: pointer.Color } : undefined, strokeWidth: Math.max(1.5, 2.5 * zoom) }, `p${index}`));
11141
+ }), jsx("circle", { className: styles$2.cap, cx: cx, cy: cy, r: Math.max(2, radius * 0.06) }), showLabels && (jsxs(Fragment, { children: [jsx("text", { className: styles$2.tick, x: minLabel.x, y: minLabel.y, textAnchor: "middle", fontSize: fontPx, children: formatChartValue(min) }), jsx("text", { className: styles$2.tick, x: maxLabel.x, y: maxLabel.y, textAnchor: "middle", fontSize: fontPx, children: formatChartValue(max) })] }))] }));
11142
+ }
11143
+ /**
11144
+ * A horizontal linear gauge as the chart engine draws it: range bands and pointers are as thick as
11145
+ * their Width percent of the gauge height (ranges 30%, pointers 10% by default) around the scale line
11146
+ * (Cross centred, Inside above, Outside below), the ranges in their own colour at full opacity, a Bar
11147
+ * pointer on top of them from the minimum to the value, and the major ticks with labels below.
11148
+ */
11149
+ function LinearGauge({ gauge, width, height, fontPx }) {
11150
+ const scale = gauge.Scales[0] ?? EMPTY_SCALE;
11151
+ const { Minimum: min, Maximum: max } = scale;
11152
+ const showLabels = scale.ShowLabels !== false;
11153
+ const left = fontPx;
11154
+ const right = width - fontPx;
11155
+ const labelSpace = showLabels ? fontPx * 2 : 0;
11156
+ const x = (value) => scaleValue(clampGaugeValue(value, min, max), { min, max }, left, right);
11157
+ const ticks = showLabels ? gaugeTicks(min, max, scale.Interval) : [];
11158
+ const ranges = scale.Ranges.map(range => {
11159
+ const thickness = gaugeThickness(range.Width, height, RANGE_DEFAULT_WIDTH);
11160
+ return { range, thickness, extent: gaugeBandExtent(range.Placement, thickness) };
11161
+ });
11162
+ const pointers = scale.Pointers.map(pointer => {
11163
+ const thickness = gaugeThickness(pointer.Width, height, POINTER_DEFAULT_WIDTH);
11164
+ return { pointer, thickness, extent: gaugeBandExtent(pointer.Placement, thickness) };
11165
+ });
11166
+ const extents = [...ranges, ...pointers].map(band => band.extent);
11167
+ const scaleY = linearGaugeScaleY(height, extents, labelSpace);
11168
+ const bandsBottom = scaleY + Math.max(0, ...extents.map(extent => extent.down));
11169
+ return (jsxs("g", { children: [ranges.map(({ range, thickness, extent }, index) => {
11170
+ const from = x(range.Start ?? min);
11171
+ const to = x(range.End ?? max);
11172
+ return (jsx("rect", { x: Math.min(from, to), y: scaleY - extent.up, width: Math.abs(to - from), height: thickness, fill: rangeColor(range, index) }, `r${index}`));
11173
+ }), jsx("line", { className: styles$2.axis, x1: left, x2: right, y1: scaleY, y2: scaleY }), pointers.map(({ pointer, thickness, extent }, index) => {
11174
+ if (isBarPointer(pointer.Type)) {
11175
+ const span = gaugeBarSpan(pointer.Value, min, max);
11176
+ const from = x(span.from);
11177
+ const to = x(span.to);
11178
+ return (jsx("rect", { x: Math.min(from, to), y: scaleY - extent.up, width: Math.abs(to - from), height: thickness, fill: pointerColor(pointer) }, `p${index}`));
11179
+ }
11180
+ // A marker: a triangle pointing at the scale line from below.
11181
+ const at = x(pointer.Value ?? min);
11182
+ const size = Math.max(thickness, fontPx * 0.6);
11183
+ return (jsx("path", { d: `M${at},${scaleY} l${-size / 2},${size} h${size} Z`, fill: pointerColor(pointer) }, `p${index}`));
11184
+ }), ticks.map(tick => (jsxs("g", { children: [jsx("line", { className: styles$2.axis, x1: x(tick), x2: x(tick), y1: bandsBottom, y2: bandsBottom + fontPx * 0.4 }), jsx("text", { className: styles$2.tick, x: x(tick), y: bandsBottom + fontPx * 1.5, textAnchor: "middle", fontSize: fontPx, children: formatChartValue(tick) })] }, tick)))] }));
11185
+ }
11186
+ /**
11187
+ * A gauge panel: its gauges side by side (RadialGauge = 270 degree dial with colored ranges and a
11188
+ * needle or bar per pointer, LinearGauge = horizontal track with range bands, a bar or marker per
11189
+ * pointer and the major ticks), the state indicators at their percent boxes and the panel labels
11190
+ * below. The pointer value is not printed; only the report's own labels are. Only the first scale of
11191
+ * a gauge is drawn.
11192
+ */
11193
+ function CwReportGauge({ panel, width, height, zoom = 1 }) {
11194
+ const fontPx = chartFontPx(zoom);
11195
+ const lineHeight = fontPx * 1.5;
11196
+ const labelsHeight = panel.Labels.length * lineHeight;
11197
+ const gaugeHeight = Math.max(0, height - labelsHeight);
11198
+ const cellWidth = panel.Gauges.length > 0 ? width / panel.Gauges.length : width;
11199
+ return (jsxs("svg", { className: styles$2.chart, width: width, height: height, role: "img", "aria-label": panel.Name, children: [panel.Error ? (jsx(ChartMessage, { text: panel.Error, width: width, height: height, fontPx: fontPx })) : (jsxs(Fragment, { children: [panel.Gauges.map((gauge, index) => {
11200
+ const drawProps = { gauge, width: cellWidth, height: gaugeHeight, fontPx, zoom };
11201
+ return (jsx("g", { transform: `translate(${cellWidth * index}, 0)`, children: gauge.Kind.toLowerCase() === "lineargauge" ? jsx(LinearGauge, { ...drawProps }) : jsx(RadialGauge, { ...drawProps }) }, index));
11202
+ }), (panel.StateIndicators ?? []).map((indicator, index) => {
11203
+ const ellipse = stateIndicatorEllipse(indicator, width, height);
11204
+ return ellipse && jsx("ellipse", { ...ellipse, fill: indicator.Color ?? undefined }, `s${index}`);
11205
+ })] })), panel.Labels.map((label, index) => (jsx("text", { x: width / 2, y: gaugeHeight + lineHeight * (index + 0.7), textAnchor: "middle", fontSize: fontPx, children: label }, index)))] }));
11206
+ }
11207
+
11208
+ /*
11209
+ * The .NET numeric format strings a report puts on a chart's value axis (<Format>), applied with the
11210
+ * report culture so the screen shows the same tick text as the server's PDF. Only the formats reports
11211
+ * actually use are covered; anything else returns null and the caller keeps its own formatting.
11212
+ */
11213
+ /** .NET's default decimals of the N, F and P standard formats without a precision. */
11214
+ const STANDARD_DEFAULT_DECIMALS = 2;
11215
+ const STANDARD_FORMAT = /^([NnFfPp])(\d{1,2})?$/;
11216
+ /** 0, 0.00, 0.0#, #,##0, #,0.00, 0%, 0.0% ... (integer part of 0, # and one optional grouping comma). */
11217
+ const CUSTOM_FORMAT = /^(#*,?#*0+)(?:\.(0*)(#*))?(%?)$/;
11218
+ /**
11219
+ * Formats longer than this are not matched (the custom pattern backtracks quadratically on a long
11220
+ * non-matching string), and more decimals than this are left to the caller: Intl.NumberFormat throws
11221
+ * above 100 fraction digits (above 20 on older browsers), which would break the chart render.
11222
+ */
11223
+ const MAX_FORMAT_LENGTH = 64;
11224
+ const MAX_FRACTION_DIGITS = 20;
11225
+ function parseFormat(format) {
11226
+ if (format.length > MAX_FORMAT_LENGTH)
11227
+ return null;
11228
+ const standard = STANDARD_FORMAT.exec(format);
11229
+ if (standard) {
11230
+ const kind = standard[1].toUpperCase();
11231
+ const digits = standard[2] === undefined ? STANDARD_DEFAULT_DECIMALS : parseInt(standard[2], 10);
11232
+ return {
11233
+ minimumFractionDigits: digits,
11234
+ maximumFractionDigits: digits,
11235
+ grouping: kind !== "F",
11236
+ percent: kind === "P" ? "standard" : null
11237
+ };
11238
+ }
11239
+ const custom = CUSTOM_FORMAT.exec(format);
11240
+ if (custom) {
11241
+ const required = custom[2]?.length ?? 0;
11242
+ const optional = custom[3]?.length ?? 0;
11243
+ return {
11244
+ minimumFractionDigits: required,
11245
+ maximumFractionDigits: required + optional,
11246
+ grouping: custom[1].includes(","),
11247
+ percent: custom[4] === "%" ? "custom" : null
11248
+ };
11249
+ }
11250
+ return null;
11251
+ }
11252
+ function numberFormat(locale, options) {
11253
+ try {
11254
+ return new Intl.NumberFormat(locale || "en-US", options);
11255
+ }
11256
+ catch {
11257
+ return new Intl.NumberFormat("en-US", options);
11258
+ }
11259
+ }
11260
+ /**
11261
+ * A value in a .NET numeric format ("N0", "F1", "P0", "0", "0.0", "#,##0.00", "0%", ...) and a culture
11262
+ * ("de-CH"; missing or unknown = invariant-like en-US). Null for a missing or unsupported format.
11263
+ * The standard "P" uses the culture's percent pattern (e.g. "12 %" in de-DE); a custom "%" appends the
11264
+ * sign directly, as .NET does.
11265
+ */
11266
+ function formatRdlNumber(value, format, culture) {
11267
+ if (!format || !Number.isFinite(value))
11268
+ return null;
11269
+ const spec = parseFormat(format.trim());
11270
+ if (!spec || spec.maximumFractionDigits > MAX_FRACTION_DIGITS)
11271
+ return null;
11272
+ const digits = {
11273
+ minimumFractionDigits: spec.minimumFractionDigits,
11274
+ maximumFractionDigits: spec.maximumFractionDigits,
11275
+ useGrouping: spec.grouping
11276
+ };
11277
+ const locale = culture ?? undefined;
11278
+ if (spec.percent === "standard")
11279
+ return numberFormat(locale, { ...digits, style: "percent" }).format(value);
11280
+ if (spec.percent === "custom") {
11281
+ // The percent style scales by 100 without float noise (0.145 -> 14.5, not 14.499...); its own
11282
+ // sign and spacing are dropped for the plain "%" a custom format appends.
11283
+ const parts = numberFormat(locale, { ...digits, style: "percent" }).formatToParts(value);
11284
+ return `${parts.filter(part => part.type !== "percentSign" && part.type !== "literal").map(part => part.value).join("")}%`;
11285
+ }
11286
+ return numberFormat(locale, digits).format(value);
11287
+ }
11288
+
11289
+ function seriesKind(series) {
11290
+ switch (series.Type.toLowerCase()) {
11291
+ case "column": return "column";
11292
+ case "bar": return "bar";
11293
+ case "area": return "area";
11294
+ case "scatter": return "scatter";
11295
+ default: return "line";
11296
+ }
11297
+ }
11298
+ function truncate(text, maxWidth, fontPx) {
11299
+ if (estimateTextWidth(text, fontPx) <= maxWidth)
11300
+ return text;
11301
+ const chars = Math.max(1, Math.floor(maxWidth / (fontPx * 0.6)) - 1);
11302
+ return text.slice(0, chars) + "…";
11303
+ }
11304
+ /** Categories along the x axis, values up: lines, areas, columns and scatter points. */
11305
+ function VerticalPlot({ chart, colors, scale, fontPx, left, top, right, bottom, strokeWidth, zoom, tickLabel }) {
11306
+ const tooltip = useChartTooltip();
11307
+ const count = Math.max(1, chart.Categories.length);
11308
+ const band = (right - left) / count;
11309
+ const x = (index) => left + band * (index + 0.5);
11310
+ const y = (value) => scaleValue(value, scale, bottom, top);
11311
+ const baseline = y(Math.min(scale.max, Math.max(scale.min, 0)));
11312
+ const columns = chart.Series.map((series, index) => ({ series, index })).filter(({ series }) => {
11313
+ const kind = seriesKind(series);
11314
+ return kind === "column" || kind === "bar";
11315
+ });
11316
+ const groupWidth = band * 0.75;
11317
+ const columnWidth = columns.length > 0 ? groupWidth / columns.length : 0;
11318
+ const labelWidth = Math.max(...chart.Categories.map(label => estimateTextWidth(label, fontPx)), 0) + fontPx;
11319
+ const labelStep = Math.max(1, Math.ceil(Math.min(labelWidth, fontPx * 12) / band));
11320
+ const marks = [];
11321
+ const hits = [];
11322
+ columns.forEach(({ series, index }, columnIndex) => {
11323
+ series.Values.forEach((value, category) => {
11324
+ if (value === null || !Number.isFinite(value))
11325
+ return;
11326
+ const columnX = left + band * category + (band - groupWidth) / 2 + columnWidth * columnIndex;
11327
+ const valueY = y(value);
11328
+ const content = tooltipContent(series.Name, chart.Categories[category] ?? "", formatChartValue(value));
11329
+ marks.push(jsx("rect", { x: columnX, y: Math.min(valueY, baseline), width: Math.max(1, columnWidth - 1), height: Math.max(0, Math.abs(baseline - valueY)), fill: colors[index], onMouseEnter: tooltip.show(content), onMouseLeave: tooltip.hide }, `c${index}-${category}`));
11330
+ if (series.ShowDataLabels) {
11331
+ marks.push(jsx("text", { x: columnX + columnWidth / 2, y: valueY - fontPx * 0.4, textAnchor: "middle", fontSize: fontPx, children: formatChartValue(value) }, `cl${index}-${category}`));
11332
+ }
11333
+ });
11334
+ });
11335
+ chart.Series.forEach((series, index) => {
11336
+ const kind = seriesKind(series);
11337
+ if (kind !== "line" && kind !== "area" && kind !== "scatter")
11338
+ return;
11339
+ const marker = seriesMarker(series.MarkerType, kind === "scatter", index);
11340
+ const markerSize = markerSizePx(series.MarkerSize, zoom);
11341
+ const segments = lineSegments(series.Values, x, y);
11342
+ segments.forEach((segment, segmentIndex) => {
11343
+ if (kind !== "scatter")
11344
+ drawLine(segment, segmentIndex);
11345
+ for (const point of segment) {
11346
+ if (marker) {
11347
+ marks.push(jsx("path", { d: markerPath(marker, point.x, point.y, markerSize), fill: colors[index] }, `m${index}-${point.index}`));
11348
+ }
11349
+ if (series.ShowDataLabels) {
11350
+ marks.push(jsx("text", { x: point.x, y: point.y - Math.max(fontPx * 0.6, markerSize), textAnchor: "middle", fontSize: fontPx, children: formatChartValue(point.value) }, `ll${index}-${point.index}`));
11351
+ }
11352
+ const content = tooltipContent(series.Name, chart.Categories[point.index] ?? "", formatChartValue(point.value));
11353
+ hits.push(jsx("circle", { className: styles$2.hit, cx: point.x, cy: point.y, r: Math.max(4, Math.min(8, band / 3), markerSize / 2), onMouseEnter: tooltip.show(content), onMouseLeave: tooltip.hide }, `h${index}-${point.index}`));
11354
+ }
11355
+ });
11356
+ function drawLine(segment, segmentIndex) {
11357
+ const path = segmentPath(segment, series.Subtype);
11358
+ if (kind === "area") {
11359
+ const first = segment[0];
11360
+ const last = segment[segment.length - 1];
11361
+ marks.push(jsx("path", { d: `${path} L${last.x},${baseline} L${first.x},${baseline} Z`, fill: colors[index], fillOpacity: 0.45, stroke: "none" }, `a${index}-${segmentIndex}`));
11362
+ }
11363
+ marks.push(jsx("path", { d: path, fill: "none", stroke: colors[index], strokeWidth: strokeWidth }, `l${index}-${segmentIndex}`));
11364
+ // A lone point between gaps has no line to show it: a dot, unless the series draws markers.
11365
+ if (segment.length === 1 && !marker) {
11366
+ marks.push(jsx("circle", { className: styles$2.point, cx: segment[0].x, cy: segment[0].y, r: strokeWidth * 1.5, fill: colors[index] }, `p${index}-${segmentIndex}`));
11367
+ }
11368
+ }
11369
+ });
11370
+ const serverLabels = chart.CategoryAxisLabels ? categoryAxisLabels(chart.CategoryAxisLabels, count, left, band) : null;
11371
+ // Category gridlines run through the labelled categories: the server's labels, else every labelStep-th category.
11372
+ const categoryGrid = chart.CategoryAxisGridLines === false
11373
+ ? []
11374
+ : serverLabels?.map(label => label.at) ?? chart.Categories.map((_label, index) => index).filter(index => index % labelStep === 0).map(x);
11375
+ return (jsxs(Fragment, { children: [categoryGrid.map((at, index) => jsx("line", { className: styles$2.grid, x1: at, x2: at, y1: top, y2: bottom }, `cg${index}`)), scale.ticks.map(tick => (jsxs("g", { children: [chart.ValueAxisGridLines !== false && jsx("line", { className: styles$2.grid, x1: left, x2: right, y1: y(tick), y2: y(tick) }), jsx("text", { className: styles$2.tick, x: left - fontPx * 0.4, y: y(tick), textAnchor: "end", dominantBaseline: "central", fontSize: fontPx, children: tickLabel(tick) })] }, tick))), jsx("line", { className: styles$2.axis, x1: left, x2: left, y1: top, y2: bottom }), jsx("line", { className: styles$2.axis, x1: left, x2: right, y1: baseline, y2: baseline }), serverLabels
11376
+ ? serverLabels.map((label, index) => {
11377
+ const placement = placeAxisLabel(label.at, estimateTextWidth(label.text, fontPx), left, right);
11378
+ return (jsxs("g", { children: [jsx("line", { className: styles$2.axis, x1: label.at, x2: label.at, y1: bottom, y2: bottom + fontPx * 0.3 }), jsx("text", { className: styles$2.tick, x: placement.x, y: bottom + fontPx * 1.3, textAnchor: placement.anchor, fontSize: fontPx, children: label.text })] }, `c${index}`));
11379
+ })
11380
+ : chart.Categories.map((label, index) => {
11381
+ if (index % labelStep !== 0)
11382
+ return null;
11383
+ const text = truncate(label, band * labelStep - fontPx * 0.4, fontPx);
11384
+ const placement = placeAxisLabel(x(index), estimateTextWidth(text, fontPx), left, right);
11385
+ return (jsx("text", { className: styles$2.tick, x: placement.x, y: bottom + fontPx * 1.1, textAnchor: placement.anchor, fontSize: fontPx, children: text }, index));
11386
+ }), marks, hits] }));
11387
+ }
11388
+ /** Categories down the y axis, values to the right: horizontal bars. */
11389
+ function HorizontalPlot({ chart, colors, scale, fontPx, left, top, right, bottom, tickLabel }) {
11390
+ const tooltip = useChartTooltip();
11391
+ const count = Math.max(1, chart.Categories.length);
11392
+ const band = (bottom - top) / count;
11393
+ const x = (value) => scaleValue(value, scale, left, right);
11394
+ const baseline = x(Math.min(scale.max, Math.max(scale.min, 0)));
11395
+ const groupHeight = band * 0.75;
11396
+ const barHeight = chart.Series.length > 0 ? groupHeight / chart.Series.length : 0;
11397
+ const serverLabels = chart.CategoryAxisLabels ? categoryAxisLabels(chart.CategoryAxisLabels, count, top, band) : null;
11398
+ const categoryGrid = chart.CategoryAxisGridLines === false
11399
+ ? []
11400
+ : serverLabels?.map(label => label.at) ?? chart.Categories.map((_label, index) => top + band * (index + 0.5));
11401
+ return (jsxs(Fragment, { children: [categoryGrid.map((at, index) => jsx("line", { className: styles$2.grid, x1: left, x2: right, y1: at, y2: at }, `cg${index}`)), scale.ticks.map(tick => (jsxs("g", { children: [chart.ValueAxisGridLines !== false && jsx("line", { className: styles$2.grid, x1: x(tick), x2: x(tick), y1: top, y2: bottom }), jsx("text", { className: styles$2.tick, x: x(tick), y: bottom + fontPx * 1.1, textAnchor: "middle", fontSize: fontPx, children: tickLabel(tick) })] }, tick))), jsx("line", { className: styles$2.axis, x1: baseline, x2: baseline, y1: top, y2: bottom }), jsx("line", { className: styles$2.axis, x1: left, x2: right, y1: bottom, y2: bottom }), serverLabels
11402
+ ? serverLabels.map((label, index) => (jsxs("g", { children: [jsx("line", { className: styles$2.axis, x1: left - fontPx * 0.3, x2: left, y1: label.at, y2: label.at }), jsx("text", { className: styles$2.tick, x: left - fontPx * 0.4, y: label.at, textAnchor: "end", dominantBaseline: "central", fontSize: fontPx, children: truncate(label.text, left - fontPx, fontPx) })] }, `c${index}`)))
11403
+ : chart.Categories.map((label, index) => (jsx("text", { className: styles$2.tick, x: left - fontPx * 0.4, y: top + band * (index + 0.5), textAnchor: "end", dominantBaseline: "central", fontSize: fontPx, children: truncate(label, left - fontPx, fontPx) }, index))), chart.Series.map((series, index) => series.Values.map((value, category) => {
11404
+ if (value === null || !Number.isFinite(value))
11405
+ return null;
11406
+ const barY = top + band * category + (band - groupHeight) / 2 + barHeight * index;
11407
+ const valueX = x(value);
11408
+ const content = tooltipContent(series.Name, chart.Categories[category] ?? "", formatChartValue(value));
11409
+ return (jsxs("g", { children: [jsx("rect", { x: Math.min(valueX, baseline), y: barY, width: Math.max(0, Math.abs(valueX - baseline)), height: Math.max(1, barHeight - 1), fill: colors[index], onMouseEnter: tooltip.show(content), onMouseLeave: tooltip.hide }), series.ShowDataLabels && (jsx("text", { x: Math.max(valueX, baseline) + fontPx * 0.3, y: barY + barHeight / 2, dominantBaseline: "central", fontSize: fontPx, children: formatChartValue(value) }))] }, `${index}-${category}`));
11410
+ }))] }));
11411
+ }
11412
+ /**
11413
+ * A report chart over categories: Line (Smooth / Stepped), Area, Column and Scatter series share one
11414
+ * value axis; a chart made only of Bar series is drawn horizontally. Scatter series draw only their
11415
+ * markers, line series draw markers too when the report sets a marker type. Null values leave gaps.
11416
+ * The legend sits where the RDL legend Position says. Own SVG, no chart library; hover shows
11417
+ * category, series and value.
11418
+ */
11419
+ function CwReportLineChart({ chart, width, height, zoom = 1, culture }) {
11420
+ const fontPx = chartFontPx(zoom);
11421
+ const palette = chartPalette(chart.Palette);
11422
+ const colors = chart.Series.map((series, index) => seriesColor(series, index, palette));
11423
+ const titleHeight = titlesHeight(chart.Titles, fontPx);
11424
+ // The legend on the side its RDL Position names: a side legend is a column at most 30% wide.
11425
+ const placement = legendPlacement(chart.LegendPosition);
11426
+ const sideLegend = placement.edge === "left" || placement.edge === "right";
11427
+ const legend = layoutLegend(chart.LegendHidden ? [] : chart.Series.map((series, index) => ({
11428
+ label: series.Name,
11429
+ color: colors[index],
11430
+ marker: seriesMarker(series.MarkerType, seriesKind(series) === "scatter", index)
11431
+ })), sideLegend ? width * 0.3 : width, fontPx, sideLegend ? "start" : placement.align);
11432
+ const legendHeight = legend.height > 0 ? legend.height + fontPx * 0.5 : 0;
11433
+ const legendWidth = legend.width > 0 ? legend.width + fontPx : 0;
11434
+ const legendSpace = {
11435
+ top: placement.edge === "top" ? legendHeight : 0,
11436
+ bottom: placement.edge === "bottom" ? legendHeight : 0,
11437
+ left: placement.edge === "left" ? legendWidth : 0,
11438
+ right: placement.edge === "right" ? legendWidth : 0
11439
+ };
11440
+ const message = chart.Error
11441
+ ?? (chart.Categories.length === 0 || chart.Series.length === 0 ? (chart.NoRowsMessage ?? "No data") : null);
11442
+ if (message) {
11443
+ return (jsxs("svg", { className: styles$2.chart, width: width, height: height, role: "img", "aria-label": chart.Titles.join(" ") || chart.Name, children: [jsx(ChartTitles, { titles: chart.Titles, width: width, fontPx: fontPx }), jsx(ChartMessage, { text: message, width: width, height: height, fontPx: fontPx })] }));
11444
+ }
11445
+ const horizontal = chart.Series.every(series => seriesKind(series) === "bar");
11446
+ const scale = computeValueScale(chart.Series.flatMap(series => series.Values));
11447
+ // The axis <Format> with the report culture, as the server's PDF prints it; an unsupported format keeps the compact default.
11448
+ const tickLabel = (tick) => formatRdlNumber(tick, chart.ValueAxisFormat, culture) ?? formatChartValue(tick);
11449
+ const tickWidth = Math.max(...scale.ticks.map(tick => estimateTextWidth(tickLabel(tick), fontPx)));
11450
+ const categoryWidth = Math.min(width * 0.35, Math.max(...chart.Categories.map(label => estimateTextWidth(label, fontPx)), 0));
11451
+ const lineHeight = fontPx * 1.6;
11452
+ const valueTitleSpace = chart.ValueAxisTitle ? lineHeight : 0;
11453
+ const categoryTitleSpace = chart.CategoryAxisTitle ? lineHeight : 0;
11454
+ const left = legendSpace.left + (horizontal ? categoryTitleSpace + categoryWidth : valueTitleSpace + tickWidth) + fontPx * 0.8;
11455
+ const right = width - fontPx - legendSpace.right;
11456
+ const top = titleHeight + legendSpace.top + fontPx * 0.8;
11457
+ const bottom = height - legendSpace.bottom - lineHeight - (horizontal ? valueTitleSpace : categoryTitleSpace);
11458
+ const strokeWidth = Math.max(1, 1.5 * zoom);
11459
+ const plotProps = { chart, colors, scale, fontPx, left, top, right, bottom, strokeWidth, zoom, tickLabel };
11460
+ const verticalTitle = horizontal ? chart.CategoryAxisTitle : chart.ValueAxisTitle;
11461
+ const horizontalTitle = horizontal ? chart.ValueAxisTitle : chart.CategoryAxisTitle;
11462
+ const titleX = legendSpace.left + fontPx;
11463
+ const legendLeft = placement.edge === "left" ? fontPx * 0.4 : placement.edge === "right" ? width - legendWidth + fontPx * 0.4 : 0;
11464
+ const legendTop = (() => {
11465
+ switch (placement.edge) {
11466
+ case "top": return titleHeight;
11467
+ case "bottom": return height - legend.height;
11468
+ default:
11469
+ if (placement.align === "start")
11470
+ return top;
11471
+ if (placement.align === "end")
11472
+ return Math.max(top, bottom - legend.height);
11473
+ return Math.max(top, (top + bottom - legend.height) / 2);
11474
+ }
11475
+ })();
11476
+ return (jsxs("svg", { className: styles$2.chart, width: width, height: height, role: "img", "aria-label": chart.Titles.join(" ") || chart.Name, children: [jsx(ChartTitles, { titles: chart.Titles, width: width, fontPx: fontPx }), right - left > 10 && bottom - top > 10 && (horizontal ? jsx(HorizontalPlot, { ...plotProps }) : jsx(VerticalPlot, { ...plotProps })), verticalTitle && (jsx("text", { x: titleX, y: (top + bottom) / 2, textAnchor: "middle", dominantBaseline: "central", fontSize: fontPx, transform: `rotate(-90 ${titleX} ${(top + bottom) / 2})`, children: verticalTitle })), horizontalTitle && (jsx("text", { x: (left + right) / 2, y: bottom + lineHeight * 1.6, textAnchor: "middle", fontSize: fontPx, children: horizontalTitle })), jsx(ChartLegend, { layout: legend, top: legendTop, left: legendLeft, fontPx: fontPx })] }));
11477
+ }
11478
+
11479
+ /** A pie of the chart's first series over its categories (RDL series Type "Shape"). Own SVG. */
11480
+ function CwReportPieChart({ chart, width, height, zoom = 1 }) {
11481
+ const tooltip = useChartTooltip();
11482
+ const fontPx = chartFontPx(zoom);
11483
+ const palette = chartPalette(chart.Palette);
11484
+ const series = chart.Series[0];
11485
+ const colorOf = (index) => palette[index % palette.length];
11486
+ const titleHeight = titlesHeight(chart.Titles, fontPx);
11487
+ const legend = layoutLegend(chart.LegendHidden ? [] : chart.Categories.map((label, index) => ({ label, color: colorOf(index) })), width, fontPx);
11488
+ const legendHeight = legend.height > 0 ? legend.height + fontPx * 0.5 : 0;
11489
+ const slices = series ? pieSlices(series.Values) : [];
11490
+ const message = chart.Error ?? (slices.length === 0 ? (chart.NoRowsMessage ?? "No data") : null);
11491
+ const plotTop = titleHeight + fontPx * 0.5;
11492
+ const plotHeight = height - plotTop - legendHeight;
11493
+ const radius = Math.max(0, Math.min(width, plotHeight) / 2 - fontPx * 0.5);
11494
+ const cx = width / 2;
11495
+ const cy = plotTop + plotHeight / 2;
11496
+ return (jsxs("svg", { className: styles$2.chart, width: width, height: height, role: "img", "aria-label": chart.Titles.join(" ") || chart.Name, children: [jsx(ChartTitles, { titles: chart.Titles, width: width, fontPx: fontPx }), message ? (jsx(ChartMessage, { text: message, width: width, height: height, fontPx: fontPx })) : (slices.map(slice => {
11497
+ const category = chart.Categories[slice.index] ?? "";
11498
+ const percent = `${formatChartValue(slice.fraction * 100)}%`;
11499
+ const labelAt = polar(cx, cy, radius * 0.65, (slice.startAngle + slice.endAngle) / 2);
11500
+ return (jsxs("g", { children: [jsx("path", { className: styles$2.slice, d: arcPath(cx, cy, radius, 0, slice.startAngle, slice.endAngle), fill: colorOf(slice.index), onMouseEnter: tooltip.show(tooltipContent(series.Name, category, `${formatChartValue(slice.value)} (${percent})`)), onMouseLeave: tooltip.hide }), series.ShowDataLabels && slice.fraction >= 0.03 && (jsx("text", { x: labelAt.x, y: labelAt.y, textAnchor: "middle", dominantBaseline: "central", fontSize: fontPx, pointerEvents: "none", children: formatChartValue(slice.value) }))] }, slice.index));
11501
+ })), jsx(ChartLegend, { layout: legend, top: height - legend.height, fontPx: fontPx })] }));
11502
+ }
11503
+
11504
+ /** Indent of one list level, in points. */
11505
+ const RDL_LIST_INDENT_PT = 18;
11506
+ const BULLETS = ["•", "◦", "▪"];
11507
+ function listKind(paragraph) {
11508
+ switch ((paragraph.ListStyle ?? "").toLowerCase()) {
11509
+ case "bulleted": return "bulleted";
11510
+ case "numbered": return "numbered";
11511
+ default: return null;
11512
+ }
11513
+ }
11514
+ /**
11515
+ * The list marker of every paragraph (null = no list). Numbering counts consecutive numbered
11516
+ * paragraphs of the same level: a non-list paragraph resets every level, a paragraph at a level
11517
+ * resets the levels below it, and a bulleted paragraph resets the numbering of its own level.
11518
+ */
11519
+ function computeListMarkers(paragraphs) {
11520
+ const counters = [];
11521
+ return paragraphs.map(paragraph => {
11522
+ const kind = listKind(paragraph);
11523
+ if (!kind) {
11524
+ counters.length = 0;
11525
+ return null;
11526
+ }
11527
+ const level = Math.max(1, paragraph.ListLevel);
11528
+ counters.length = Math.min(counters.length, level);
11529
+ if (kind === "bulleted") {
11530
+ counters[level - 1] = 0;
11531
+ return BULLETS[(level - 1) % BULLETS.length];
11532
+ }
11533
+ counters[level - 1] = (counters[level - 1] ?? 0) + 1;
11534
+ return `${counters[level - 1]}.`;
11535
+ });
11536
+ }
11537
+ /** Left indent of a paragraph in points: one list indent per level (a list paragraph has at least level 1). */
11538
+ function paragraphIndentPt(paragraph) {
11539
+ const level = listKind(paragraph) ? Math.max(1, paragraph.ListLevel) : Math.max(0, paragraph.ListLevel);
11540
+ return level * RDL_LIST_INDENT_PT;
11541
+ }
11542
+
11543
+ const EMPTY_FLIPPED = new Set();
11544
+ const EMPTY_HIGHLIGHTS = new Map();
11545
+ const ReportRenderContext = createContext({
11546
+ zoom: 1,
11547
+ flipped: EMPTY_FLIPPED,
11548
+ highlights: EMPTY_HIGHLIGHTS,
11549
+ activeMatchIndex: -1
11550
+ });
11551
+ function useReportRender() {
11552
+ return useContext(ReportRenderContext);
11553
+ }
11554
+ /** Groups the page's matches by run key. */
11555
+ function highlightsByRun(matches) {
11556
+ const map = new Map();
11557
+ matches.forEach((match, matchIndex) => {
11558
+ const list = map.get(match.key) ?? [];
11559
+ list.push({ start: match.start, length: match.length, matchIndex });
11560
+ map.set(match.key, list);
11561
+ });
11562
+ return map;
11563
+ }
11564
+
11565
+ var styles$1 = {"sheet":"cw-report-page-module__sheet__MAL8a","section":"cw-report-page-module__section__rN7A3","item":"cw-report-page-module__item__VZFw8","table":"cw-report-page-module__table__SAZVC","textbox":"cw-report-page-module__textbox__iwVwk cw-report-page-module__item__VZFw8","textRow":"cw-report-page-module__textRow__3WIRX","textBody":"cw-report-page-module__textBody__Jp1-1","paragraph":"cw-report-page-module__paragraph__d6dYI","marker":"cw-report-page-module__marker__geRQt","link":"cw-report-page-module__link__YFX1h","match":"cw-report-page-module__match__sWdSD","inlineButton":"cw-report-page-module__inlineButton__m05OC","rectangle":"cw-report-page-module__rectangle__2PYyK cw-report-page-module__item__VZFw8","line":"cw-report-page-module__line__Vfus-","image":"cw-report-page-module__image__VEp5H cw-report-page-module__item__VZFw8","tableMessage":"cw-report-page-module__tableMessage__kWsAj","chart":"cw-report-page-module__chart__PP9oM cw-report-page-module__item__VZFw8","placeholder":"cw-report-page-module__placeholder__FK8kO cw-report-page-module__item__VZFw8"};
11566
+
11567
+ /** Size of the drilldown / sort icons, in points: a little below the default 10pt text. */
11568
+ const INLINE_ICON_PT = 9;
11569
+ const SAFE_LINK = /^(https?:|mailto:)/i;
11570
+ function highlightedText(text, highlights, activeMatchIndex) {
11571
+ if (!highlights || highlights.length === 0)
11572
+ return text;
11573
+ const parts = [];
11574
+ let cursor = 0;
11575
+ for (const highlight of highlights) {
11576
+ if (highlight.start > cursor)
11577
+ parts.push(text.slice(cursor, highlight.start));
11578
+ const active = highlight.matchIndex === activeMatchIndex;
11579
+ parts.push(jsx("mark", { className: styles$1.match, "data-active": active ? "true" : undefined, "data-active-match": active ? "true" : undefined, children: text.slice(highlight.start, highlight.start + highlight.length) }, highlight.matchIndex));
11580
+ cursor = highlight.start + highlight.length;
11581
+ }
11582
+ if (cursor < text.length)
11583
+ parts.push(text.slice(cursor));
11584
+ return parts;
11585
+ }
11586
+ function ReportRun({ run, runKey, paragraphStyle, textboxStyle }) {
11587
+ const { zoom, highlights, activeMatchIndex } = useReportRender();
11588
+ const css = rdlTextCss(resolveRdlTextStyle(run.Style, paragraphStyle, textboxStyle), zoom);
11589
+ const content = highlightedText(run.Text, highlights.get(runKey), activeMatchIndex);
11590
+ if (run.Href && SAFE_LINK.test(run.Href)) {
11591
+ return (jsx("a", { className: styles$1.link, href: run.Href, target: "_blank", rel: "noopener noreferrer", style: css, children: content }));
11592
+ }
11593
+ return jsx("span", { style: css, children: content });
11594
+ }
11595
+ function iconSizeStyle(zoom) {
11596
+ return { "--btn-size": `${ptToPx(INLINE_ICON_PT, zoom)}px` };
11597
+ }
11598
+ function sortIcon(direction) {
11599
+ switch ((direction ?? "").toLowerCase()) {
11600
+ case "ascending": return "sort-asc";
11601
+ case "descending": return "sort-desc";
11602
+ default: return "sortable";
11603
+ }
11604
+ }
11605
+ /** A textbox: paragraphs as blocks, runs as inline spans, plain text only (never HTML). */
11606
+ function ReportTextbox({ textbox, itemKey, frameStyle }) {
11607
+ const { zoom, flipped, onToggle, onSort } = useReportRender();
11608
+ const markers = computeListMarkers(textbox.Paragraphs);
11609
+ const paragraphs = textbox.Paragraphs.map((paragraph, p) => {
11610
+ const indent = ptToPx(paragraphIndentPt(paragraph), zoom);
11611
+ const marker = markers[p];
11612
+ const firstRun = paragraph.Runs[0];
11613
+ const paragraphCss = {
11614
+ ...rdlTextCss(resolveParagraphTextStyle(paragraph.Runs.map(run => run.Style), paragraph.Style, textbox.Style), zoom),
11615
+ textAlign: rdlTextAlign(paragraph.Style?.TextAlign ?? textbox.Style?.TextAlign),
11616
+ paddingLeft: indent || undefined
11617
+ };
11618
+ return (jsxs("p", { className: styles$1.paragraph, style: paragraphCss, children: [marker !== null && (jsx("span", { className: styles$1.marker, style: {
11619
+ ...rdlTextCss(resolveRdlTextStyle(firstRun?.Style, paragraph.Style, textbox.Style), zoom),
11620
+ left: indent - ptToPx(RDL_LIST_INDENT_PT, zoom),
11621
+ width: ptToPx(RDL_LIST_INDENT_PT, zoom)
11622
+ }, children: marker })), paragraph.Runs.map((run, r) => (jsx(ReportRun, { run: run, runKey: rdlRunKey(itemKey, p, r), paragraphStyle: paragraph.Style, textboxStyle: textbox.Style }, r)))] }, p));
11623
+ });
11624
+ const boxCss = {
11625
+ ...frameStyle,
11626
+ ...rdlBoxStyle(textbox.Style, zoom),
11627
+ color: rdlColor(textbox.Style?.Color),
11628
+ justifyContent: rdlVerticalAlign(textbox.Style?.VerticalAlign)
11629
+ };
11630
+ const toggleId = textbox.ToggleId;
11631
+ const sortId = textbox.SortId;
11632
+ if (!toggleId && !sortId) {
11633
+ return jsx("div", { className: styles$1.textbox, style: boxCss, children: paragraphs });
11634
+ }
11635
+ const expanded = isToggleExpanded(textbox, flipped);
11636
+ return (jsx("div", { className: styles$1.textbox, style: boxCss, children: jsxs("div", { className: styles$1.textRow, children: [toggleId && (jsx(CwButton, { variant: "icon", size: "small", icon: expanded ? "minus" : "plus", className: styles$1.inlineButton, style: iconSizeStyle(zoom), "aria-label": expanded ? "Collapse" : "Expand", "aria-expanded": expanded, "data-toggle-id": toggleId, onClick: () => onToggle?.(toggleId) })), jsx("div", { className: styles$1.textBody, children: paragraphs }), sortId && (jsx(CwButton, { variant: "icon", size: "small", icon: sortIcon(textbox.SortDirection), className: styles$1.inlineButton, style: iconSizeStyle(zoom), "aria-label": "Sort", onClick: () => onSort?.(sortId) }))] }) }));
11637
+ }
11638
+
11639
+ function frameOf(item) {
11640
+ return { top: item.Top, left: item.Left, width: item.Width, height: item.Height };
11641
+ }
11642
+ function frameCss(frame, zoom) {
11643
+ return {
11644
+ top: ptToPx(frame.top, zoom),
11645
+ left: ptToPx(frame.left, zoom),
11646
+ width: ptToPx(frame.width, zoom),
11647
+ height: ptToPx(frame.height, zoom)
11648
+ };
11649
+ }
11650
+ const SAFE_IMAGE_URL = /^https?:/i;
11651
+ function ReportRectangle({ item, itemKey, frame }) {
11652
+ const { zoom } = useReportRender();
11653
+ return (jsx("div", { className: styles$1.rectangle, style: { ...frameCss(frame, zoom), ...rdlBoxStyle(item.Style, zoom) }, children: jsx(ReportItems, { items: item.Items, parentKey: itemKey }) }));
11654
+ }
11655
+ function ReportLine({ item, frame }) {
11656
+ const { zoom } = useReportRender();
11657
+ const stroke = rdlLineStroke(item.Style, zoom);
11658
+ const x1 = ptToPx(frame.left, zoom);
11659
+ const y1 = ptToPx(frame.top, zoom);
11660
+ const x2 = ptToPx(frame.left + frame.width, zoom);
11661
+ const y2 = ptToPx(frame.top + frame.height, zoom);
11662
+ const pad = stroke.width;
11663
+ const left = Math.min(x1, x2) - pad;
11664
+ const top = Math.min(y1, y2) - pad;
11665
+ const width = Math.abs(x2 - x1) + pad * 2;
11666
+ const height = Math.abs(y2 - y1) + pad * 2;
11667
+ return (jsx("svg", { className: styles$1.line, style: { left, top, width, height }, width: width, height: height, "aria-hidden": "true", children: jsx("line", { x1: x1 - left, y1: y1 - top, x2: x2 - left, y2: y2 - top, stroke: stroke.color, strokeWidth: stroke.width, strokeDasharray: stroke.dash }) }));
11668
+ }
11669
+ function imageSizing(sizing) {
11670
+ switch (sizing.toLowerCase()) {
11671
+ case "fit": return "fit";
11672
+ case "fitproportional": return "proportional";
11673
+ default: return "natural";
11674
+ }
11675
+ }
11676
+ function ReportImage({ item, frame }) {
11677
+ const { zoom, getImageUrl } = useReportRender();
11678
+ const src = item.Url && SAFE_IMAGE_URL.test(item.Url)
11679
+ ? item.Url
11680
+ : item.ImageId && getImageUrl ? getImageUrl(item.ImageId) : null;
11681
+ const sizing = imageSizing(item.Sizing);
11682
+ return (jsx("div", { className: styles$1.image, style: { ...frameCss(frame, zoom), ...rdlBoxStyle(item.Style, zoom) }, children: src && (jsx("img", { src: src, alt: item.Name, referrerPolicy: "no-referrer", "data-sizing": sizing, style: sizing === "natural" ? { transform: `scale(${zoom})` } : undefined })) }));
11683
+ }
11684
+ function ReportTable({ item, itemKey, frame }) {
11685
+ const { zoom, flipped } = useReportRender();
11686
+ const message = item.Error ?? (item.Rows.length === 0 ? item.NoRowsMessage : null);
11687
+ if (message) {
11688
+ const textCss = rdlTextCss(resolveRdlTextStyle(null, null, item.Style), zoom);
11689
+ return (jsx("div", { className: styles$1.table, style: { ...frameCss(frame, zoom), height: undefined, ...rdlBoxStyle(item.Style, zoom) }, children: item.Error
11690
+ ? jsx(CwNote, { color: "danger", variant: "soft", fontSize: "small", content: item.Error })
11691
+ : jsx("p", { className: `${styles$1.tableMessage} cw-margin-none`, style: textCss, children: message }) }));
11692
+ }
11693
+ const layout = layoutRdlTable(item, flipped);
11694
+ return (jsx("div", { className: styles$1.table, style: { ...frameCss({ ...frame, width: layout.width, height: layout.height }, zoom), ...rdlBoxStyle(item.Style, zoom) }, children: layout.cells.map(box => {
11695
+ const content = box.cell.Content;
11696
+ if (!content)
11697
+ return null;
11698
+ const cellFrame = { top: box.top, left: box.left, width: box.width, height: box.height };
11699
+ const key = `${box.rowIndex}-${box.cellIndex}`;
11700
+ if (box.hidden) {
11701
+ // Drawn empty: the cell keeps its borders and background so the grid stays closed.
11702
+ return jsx("div", { className: styles$1.item, style: { ...frameCss(cellFrame, zoom), ...rdlBoxStyle(content.Style, zoom) } }, key);
11703
+ }
11704
+ return jsx(ReportItem, { item: content, itemKey: rdlCellKey(itemKey, box.rowIndex, box.cellIndex), frame: cellFrame }, key);
11705
+ }) }));
11706
+ }
11707
+ function ReportChart({ item, frame }) {
11708
+ const { zoom, culture } = useReportRender();
11709
+ const width = ptToPx(frame.width, zoom);
11710
+ const height = ptToPx(frame.height, zoom);
11711
+ const pie = item.Series[0]?.Type.toLowerCase() === "shape";
11712
+ return (jsx("div", { className: styles$1.chart, style: { ...frameCss(frame, zoom), ...rdlBoxStyle(item.Style, zoom) }, children: pie
11713
+ ? jsx(CwReportPieChart, { chart: item, width: width, height: height, zoom: zoom })
11714
+ : jsx(CwReportLineChart, { chart: item, width: width, height: height, zoom: zoom, culture: culture }) }));
11715
+ }
11716
+ function ReportGauge({ item, frame }) {
11717
+ const { zoom } = useReportRender();
11718
+ return (jsx("div", { className: styles$1.chart, style: { ...frameCss(frame, zoom), ...rdlBoxStyle(item.Style, zoom) }, children: jsx(CwReportGauge, { panel: item, width: ptToPx(frame.width, zoom), height: ptToPx(frame.height, zoom), zoom: zoom }) }));
11719
+ }
11720
+ function ReportPlaceholder({ item, frame }) {
11721
+ const { zoom } = useReportRender();
11722
+ return (jsx(CwTooltipNew, { content: `${item.Element}: ${item.Reason}`, position: "top", children: jsx("div", { className: styles$1.placeholder, style: frameCss(frame, zoom), "aria-label": `${item.Element}: ${item.Reason}`, children: item.Element }) }));
11723
+ }
11724
+ /** One render-tree item, absolutely positioned in its container; nothing when its toggles hide it. */
11725
+ function ReportItem({ item, itemKey, frame }) {
11726
+ const { zoom, flipped } = useReportRender();
11727
+ if (!isRdlVisible(item.Toggles, flipped))
11728
+ return null;
11729
+ const box = frame ?? frameOf(item);
11730
+ switch (item.Kind) {
11731
+ case "textbox": return jsx(ReportTextbox, { textbox: item, itemKey: itemKey, frameStyle: frameCss(box, zoom) });
11732
+ case "rectangle": return jsx(ReportRectangle, { item: item, itemKey: itemKey, frame: box });
11733
+ case "line": return jsx(ReportLine, { item: item, frame: box });
11734
+ case "image": return jsx(ReportImage, { item: item, frame: box });
11735
+ case "table": return jsx(ReportTable, { item: item, itemKey: itemKey, frame: box });
11736
+ case "chart": return jsx(ReportChart, { item: item, frame: box });
11737
+ case "gauge": return jsx(ReportGauge, { item: item, frame: box });
11738
+ case "placeholder": return jsx(ReportPlaceholder, { item: item, frame: box });
11739
+ default: return null;
11740
+ }
11741
+ }
11742
+ function ReportItems({ items, parentKey }) {
11743
+ return (jsx(Fragment, { children: items.map((item, index) => (jsx(ReportItem, { item: item, itemKey: rdlItemKey(parentKey, index) }, index))) }));
11744
+ }
11745
+
11746
+ const NO_FLIPS$1 = new Set();
11747
+ const NO_MATCHES = [];
11748
+ const DEFAULT_MARGINS = {
11749
+ top: DEFAULT_PAGE_MARGIN_PT,
11750
+ right: DEFAULT_PAGE_MARGIN_PT,
11751
+ bottom: DEFAULT_PAGE_MARGIN_PT,
11752
+ left: DEFAULT_PAGE_MARGIN_PT
11753
+ };
11754
+ function Band({ section, sectionKey, zoom, bodyWidth, as: Element }) {
11755
+ return (jsx(Element, { className: styles$1.section, style: { ...rdlBoxStyle(section.Style, zoom), width: ptToPx(bodyWidth, zoom), height: ptToPx(section.Height, zoom) }, children: jsx(ReportItems, { items: section.Items, parentKey: sectionKey }) }));
11756
+ }
11757
+ /**
11758
+ * One page of a rendered RDL report drawn as a sheet of paper: page header, body and page footer,
11759
+ * every item absolutely positioned in points scaled by the zoom. Presentational: toggle state,
11760
+ * sorting, images and find matches come from the host.
11761
+ */
11762
+ function CwReportPage({ page, bodyWidth, zoom = 1, culture, margins = DEFAULT_MARGINS, flippedToggles = NO_FLIPS$1, onToggle, onSort, getImageUrl, findMatches = NO_MATCHES, activeMatchIndex = -1, className }) {
11763
+ const sheetRef = useRef(null);
11764
+ const highlights = useMemo(() => highlightsByRun(findMatches), [findMatches]);
11765
+ const context = useMemo(() => ({
11766
+ zoom,
11767
+ culture,
11768
+ flipped: flippedToggles,
11769
+ onToggle,
11770
+ onSort,
11771
+ getImageUrl,
11772
+ highlights,
11773
+ activeMatchIndex
11774
+ }), [zoom, culture, flippedToggles, onToggle, onSort, getImageUrl, highlights, activeMatchIndex]);
11775
+ useEffect(() => {
11776
+ if (activeMatchIndex < 0)
11777
+ return;
11778
+ const active = sheetRef.current?.querySelector("[data-active-match='true']");
11779
+ active?.scrollIntoView?.({ block: "center", inline: "nearest" });
11780
+ }, [activeMatchIndex, findMatches]);
11781
+ const sheet = pageSheetSizePt(page, bodyWidth, margins);
11782
+ return (jsx(ReportRenderContext.Provider, { value: context, children: jsxs("div", { ref: sheetRef, className: `${styles$1.sheet}${className ? ` ${className}` : ""}`, style: {
11783
+ width: ptToPx(sheet.width, zoom),
11784
+ height: ptToPx(sheet.height, zoom),
11785
+ padding: `${ptToPx(margins.top, zoom)}px ${ptToPx(margins.right, zoom)}px ${ptToPx(margins.bottom, zoom)}px ${ptToPx(margins.left, zoom)}px`
11786
+ }, "data-page": page.Number, children: [page.Header && jsx(Band, { section: page.Header, sectionKey: RDL_SECTION_KEYS.header, zoom: zoom, bodyWidth: bodyWidth, as: "header" }), jsx("div", { className: styles$1.section, style: { width: ptToPx(bodyWidth, zoom), height: ptToPx(page.Height, zoom) }, children: jsx(ReportItems, { items: page.Items, parentKey: RDL_SECTION_KEYS.body }) }), page.Footer && jsx(Band, { section: page.Footer, sectionKey: RDL_SECTION_KEYS.footer, zoom: zoom, bodyWidth: bodyWidth, as: "footer" })] }) }));
11787
+ }
11788
+
11789
+ const DATE_PREFIX = /^(\d{4}-\d{2}-\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2}))?)?/;
11790
+ /** Reads the date and time of an ISO 8601 text (any offset is ignored, the wall clock is kept). Null when it is not a date. */
11791
+ function parseRdlDateTime(text) {
11792
+ const match = DATE_PREFIX.exec(text.trim());
11793
+ if (!match)
11794
+ return null;
11795
+ try {
11796
+ return Temporal.PlainDateTime.from(`${match[1]}T${match[2] ?? "00"}:${match[3] ?? "00"}:${match[4] ?? "00"}`);
11797
+ }
11798
+ catch {
11799
+ return null;
11800
+ }
11801
+ }
11802
+ /** A date-time as invariant text "YYYY-MM-DDTHH:mm:ss". */
11803
+ function formatRdlDateTime(value) {
11804
+ return value.toString({ smallestUnit: "second", calendarName: "never" });
11805
+ }
11806
+ /** A typed API value as the text of an option or an editor (null stays null). */
11807
+ function rdlValueToText(value) {
11808
+ if (value === null || value === undefined)
11809
+ return null;
11810
+ if (typeof value === "boolean")
11811
+ return value ? "true" : "false";
11812
+ if (typeof value === "number")
11813
+ return numberToInvariant(value);
11814
+ return value;
11815
+ }
11816
+ function numberToInvariant(value) {
11817
+ return Number.isFinite(value) ? value.toString() : "";
11818
+ }
11819
+ function isDateTime(parameter) {
11820
+ return parameter.DataType.toLowerCase() === "datetime" || parameter.InputType.toLowerCase() === "datetime";
11821
+ }
11822
+ function isBoolean(parameter) {
11823
+ return parameter.DataType.toLowerCase() === "boolean" || parameter.InputType.toLowerCase() === "boolean";
11824
+ }
11825
+ function isTextInput(parameter) {
11826
+ return parameter.InputType.toLowerCase() === "textbox";
11827
+ }
11828
+ function isNumeric(parameter) {
11829
+ const type = parameter.DataType.toLowerCase();
11830
+ return type === "integer" || type === "float";
11831
+ }
11832
+ function toEditorScalar(parameter, value) {
11833
+ if (isDateTime(parameter) && parameter.InputType.toLowerCase() !== "dropdownlist") {
11834
+ const text = String(value);
11835
+ return parseRdlDateTime(text) ?? text;
11836
+ }
11837
+ if (isBoolean(parameter) && parameter.InputType.toLowerCase() !== "dropdownlist") {
11838
+ return typeof value === "boolean" ? value : String(value).toLowerCase() === "true";
11839
+ }
11840
+ return rdlValueToText(value) ?? "";
11841
+ }
11842
+ /** The editor state of one parameter from the values the server sent; a NULL value is an empty field. */
11843
+ function initialParameterEdit(parameter) {
11844
+ const scalars = (parameter.Values ?? [])
11845
+ .filter((value) => value !== null && value !== undefined)
11846
+ .map(value => toEditorScalar(parameter, value));
11847
+ return { values: parameter.MultiValue ? scalars : scalars.slice(0, 1) };
11848
+ }
11849
+ /** The values that count: a multi-value text drops its empty lines, a single value keeps only the first. */
11850
+ function enteredValues(parameter, edit) {
11851
+ const values = edit.values.filter(value => value !== "");
11852
+ return parameter.MultiValue ? values : values.slice(0, 1);
11853
+ }
11854
+ /** The editor state of a whole form. */
11855
+ function initialParameterEdits(parameters) {
11856
+ const edits = {};
11857
+ for (const parameter of parameters)
11858
+ edits[parameter.Name] = initialParameterEdit(parameter);
11859
+ return edits;
11860
+ }
11861
+ /** One editor value as invariant text. */
11862
+ function editorScalarToInvariant(parameter, value) {
11863
+ if (typeof value === "boolean")
11864
+ return value ? "true" : "false";
11865
+ if (typeof value !== "string")
11866
+ return formatRdlDateTime(value);
11867
+ if (isNumeric(parameter))
11868
+ return value.trim().replace(",", ".");
11869
+ return value;
11870
+ }
11871
+ /**
11872
+ * The values the API takes (RdlParameterValuesRequest.Values): every parameter, each as an array of
11873
+ * invariant text. An empty field is [null] when the parameter is nullable, [""] for a single text,
11874
+ * else []. A parameter without an edit sends the values the server gave it.
11875
+ *
11876
+ * A nullable boolean whose value is NULL shows neither True nor False and keeps sending NULL until
11877
+ * the user picks one; from then on it sends "true" / "false" (a radio group cannot be emptied again).
11878
+ */
11879
+ function toRdlParameterValues(parameters, edits) {
11880
+ const result = {};
11881
+ for (const parameter of parameters) {
11882
+ const edit = edits[parameter.Name] ?? initialParameterEdit(parameter);
11883
+ const texts = enteredValues(parameter, edit).map(value => editorScalarToInvariant(parameter, value));
11884
+ if (texts.length > 0) {
11885
+ result[parameter.Name] = texts;
11886
+ }
11887
+ else if (parameter.Nullable) {
11888
+ result[parameter.Name] = [null];
11889
+ }
11890
+ else {
11891
+ result[parameter.Name] = !parameter.MultiValue && isTextInput(parameter) ? [""] : [];
11892
+ }
11893
+ }
11894
+ return result;
11895
+ }
11896
+ /** True when any other parameter lists `name` in its DependsOn: a change must re-resolve the form. */
11897
+ function hasDependentParameters(parameters, name) {
11898
+ return parameters.some(parameter => parameter.Name !== name && parameter.DependsOn.includes(name));
11899
+ }
11900
+ /** Whether the user edits the parameter (hidden and server-filled parameters are not editable). */
11901
+ function isEditableParameter(parameter) {
11902
+ return !parameter.Hidden && !parameter.ServerValue;
11903
+ }
11904
+ /** Whether the form has anything for the user to fill in (some parameter is neither hidden nor server-filled). */
11905
+ function hasEditableParameters(parameters) {
11906
+ return parameters.some(isEditableParameter);
11907
+ }
11908
+ /**
11909
+ * Client-side checks before "View report": a value is required unless the parameter is nullable
11910
+ * (empty = NULL) or allows blank text (AllowBlank), and numbers / dates must parse. Hidden and
11911
+ * server-filled parameters are the server's business. Returns parameter name to message.
11912
+ */
11913
+ function validateParameterEdits(parameters, edits) {
11914
+ const errors = {};
11915
+ for (const parameter of parameters) {
11916
+ if (!isEditableParameter(parameter))
11917
+ continue;
11918
+ const edit = edits[parameter.Name] ?? initialParameterEdit(parameter);
11919
+ const values = enteredValues(parameter, edit);
11920
+ if (values.length === 0) {
11921
+ const blankAllowed = parameter.Nullable
11922
+ || (parameter.AllowBlank && !parameter.MultiValue && isTextInput(parameter) && !isNumeric(parameter));
11923
+ if (!blankAllowed)
11924
+ errors[parameter.Name] = parameter.MultiValue ? "Select at least one value." : "A value is required.";
11925
+ continue;
11926
+ }
11927
+ if (isNumeric(parameter) && parameter.InputType.toLowerCase() !== "dropdownlist") {
11928
+ const integer = parameter.DataType.toLowerCase() === "integer";
11929
+ const invalid = values.some(value => {
11930
+ const text = editorScalarToInvariant(parameter, value);
11931
+ return integer ? !/^-?\d+$/.test(text) : !/^-?(\d+\.?\d*|\.\d+)$/.test(text);
11932
+ });
11933
+ if (invalid)
11934
+ errors[parameter.Name] = integer ? "Enter a whole number." : "Enter a number.";
11935
+ continue;
11936
+ }
11937
+ if (isDateTime(parameter) && parameter.InputType.toLowerCase() !== "dropdownlist"
11938
+ && values.some(value => typeof value === "string")) {
11939
+ errors[parameter.Name] = "Enter a valid date.";
11940
+ }
11941
+ }
11942
+ return errors;
11943
+ }
11944
+
11945
+ var styles = {"viewer":"cw-report-viewer-module__viewer__SYHSE","sidebar":"cw-report-viewer-module__sidebar__1ZSM2","resizer":"cw-report-viewer-module__resizer__JdnQI","main":"cw-report-viewer-module__main__qsPXX","parameterForm":"cw-report-viewer-module__parameterForm__H01sS","parameterFields":"cw-report-viewer-module__parameterFields__D2BuK","parameterActions":"cw-report-viewer-module__parameterActions__01RD4","viewButton":"cw-report-viewer-module__viewButton__1CMHL","parameterGrid":"cw-report-viewer-module__parameterGrid__Jyn0M","toolbar":"cw-report-viewer-module__toolbar__9gKXV","reportName":"cw-report-viewer-module__reportName__g5nsm","findStatus":"cw-report-viewer-module__findStatus__4gLGb","warningsButton":"cw-report-viewer-module__warningsButton__GIKjH","warningsPanel":"cw-report-viewer-module__warningsPanel__rFHBP","warningList":"cw-report-viewer-module__warningList__Ouk7x","menu":"cw-report-viewer-module__menu__ufxUU","menuItem":"cw-report-viewer-module__menuItem__hBmdD","canvas":"cw-report-viewer-module__canvas__9KuUT","canvasNote":"cw-report-viewer-module__canvasNote__K9XP0","sheetSkeleton":"cw-report-viewer-module__sheetSkeleton__DsSaA","emptyState":"cw-report-viewer-module__emptyState__pJyQ1"};
11946
+
11947
+ /** Above this many options a single-select dropdown gets a search box. */
11948
+ const SEARCH_THRESHOLD = 10;
11949
+ const LABEL_LAYOUT = { flexDirection: "column" };
11950
+ const BOOLEAN_OPTIONS = [
11951
+ { value: "true", label: "True" },
11952
+ { value: "false", label: "False" }
11953
+ ];
11954
+ function scalarText(value) {
11955
+ if (value === undefined)
11956
+ return "";
11957
+ if (typeof value === "boolean")
11958
+ return value ? "true" : "false";
11959
+ return typeof value === "string" ? value : value.toString();
11960
+ }
11961
+ function feedbackFor(parameter, clientError) {
11962
+ const messages = [];
11963
+ if (parameter.ValidValuesError)
11964
+ messages.push({ type: "danger", message: parameter.ValidValuesError });
11965
+ if (parameter.ValueError)
11966
+ messages.push({ type: "danger", message: parameter.ValueError });
11967
+ if (clientError)
11968
+ messages.push({ type: "danger", message: clientError });
11969
+ return messages.length > 0 ? messages : undefined;
11970
+ }
11971
+ function ParameterField({ parameter, edit, error, disabled, setEdit, commit }) {
11972
+ const label = { text: parameter.Prompt || parameter.Name };
11973
+ const feedback = feedbackFor(parameter, error);
11974
+ const testId = `report-parameter-${parameter.Name}`;
11975
+ // A NULL valid value is no option of its own: leaving the field empty is NULL.
11976
+ const options = parameter.ValidValues
11977
+ .filter(option => option.Value !== null && option.Value !== undefined)
11978
+ .map(option => ({ value: rdlValueToText(option.Value) ?? "", label: option.Label }));
11979
+ switch (parameter.InputType.toLowerCase()) {
11980
+ case "dropdownlist":
11981
+ if (parameter.MultiValue) {
11982
+ return (jsx(CwTagSelector, { id: testId, labelProps: label, alignProps: LABEL_LAYOUT, options: options, value: edit.values.map(scalarText), onChange: values => setEdit({ values }, true), showSelectAll: true, disabled: disabled, feedback: feedback }));
11983
+ }
11984
+ return (jsx(CwDropdown, { "data-testid": testId, labelProps: label, alignProps: LABEL_LAYOUT, options: options, value: scalarText(edit.values[0]), onChange: value => setEdit({ values: value === undefined ? [] : [String(value)] }, true), allowSearch: options.length > SEARCH_THRESHOLD, disabled: disabled, feedback: feedback }));
11985
+ case "datetime": {
11986
+ const value = edit.values[0];
11987
+ return (jsx(CwDateTimePickerTemporal, { "data-testid": testId, labelProps: label, alignProps: LABEL_LAYOUT, value: value instanceof Temporal.PlainDateTime ? value : undefined, onChange: dateTime => setEdit({ values: dateTime ? [dateTime] : [] }, true), disabled: disabled, feedback: feedback }));
11988
+ }
11989
+ case "boolean":
11990
+ return (jsx(CwRadioGroup, { "data-testid": testId, labelProps: label, groupLayout: { direction: "row" }, options: BOOLEAN_OPTIONS, value: edit.values.length > 0 ? scalarText(edit.values[0]) : undefined, onChange: value => setEdit({ values: [value === "true"] }, true), disabled: disabled, feedback: feedback }));
11991
+ case "integer":
11992
+ case "float":
11993
+ return (jsx(CwDigit, { "data-testid": testId, labelProps: label, alignProps: LABEL_LAYOUT, step: parameter.InputType.toLowerCase() === "integer" ? 1 : "any", value: scalarText(edit.values[0]), onChange: e => {
11994
+ const text = e.currentTarget.value;
11995
+ setEdit({ values: text === "" ? [] : [text] }, false);
11996
+ }, onBlur: commit, disabled: disabled, feedback: feedback }));
11997
+ default:
11998
+ if (parameter.MultiValue) {
11999
+ return (jsx(CwTextArea, { "data-testid": testId, labelProps: label, alignProps: LABEL_LAYOUT, value: edit.values.map(scalarText).join("\n"), onChange: e => {
12000
+ // Keep empty lines while typing (Enter must survive the re-render); they are dropped on serialization.
12001
+ setEdit({ values: e.currentTarget.value.split("\n") }, false);
12002
+ }, onBlur: commit, disabled: disabled, feedback: feedback ?? { type: "neutral", message: "One value per line." } }));
12003
+ }
12004
+ return (jsx(CwInputText, { "data-testid": testId, labelProps: label, alignProps: LABEL_LAYOUT, value: scalarText(edit.values[0]), onChange: e => {
12005
+ const text = e.currentTarget.value;
12006
+ setEdit({ values: [text] }, false);
12007
+ }, onBlur: commit, disabled: disabled, feedback: feedback }));
12008
+ }
12009
+ }
12010
+ /**
12011
+ * The report parameter form in the server's order: dropdowns (multi-value as tag selector with
12012
+ * select-all), date-time pickers, True/False, numbers and text. There is no NULL control: an empty
12013
+ * field of a nullable parameter is sent as NULL (see rdlParameterValues), as in the old WinOps
12014
+ * report page. Hidden parameters are not drawn; server-filled ones are read-only. Presentational:
12015
+ * the host owns the editor state (`useReportParameterForm`); a change to a parameter others depend
12016
+ * on calls its `onResolve`, "View report" its `onRender` with the values as invariant text
12017
+ * (`toRdlParameterValues`).
12018
+ *
12019
+ * The form fills its parent's height when the parent gives it one: the fields scroll and the
12020
+ * "View report" footer stays pinned at the bottom. In an unbounded parent it simply grows.
12021
+ */
12022
+ function CwReportParameterForm({ controller, loading = false, rendering = false }) {
12023
+ const { form } = controller;
12024
+ const visible = form?.Parameters.filter(parameter => !parameter.Hidden) ?? [];
12025
+ return (jsxs("form", { className: styles.parameterForm, "data-testid": "report-parameter-form", onSubmit: e => {
12026
+ e.preventDefault();
12027
+ controller.submit();
12028
+ }, children: [jsx("div", { className: styles.parameterFields, children: form ? (jsx(CwLoading, { isLoading: loading, size: "small", children: visible.length > 0 && (jsx("div", { className: `${styles.parameterGrid} cw-grid-base-auto`, children: visible.map(parameter => (jsx(ParameterField, { parameter: parameter, edit: controller.edits[parameter.Name] ?? { values: [] }, error: controller.errors[parameter.Name], disabled: loading || !!parameter.ServerValue, setEdit: (edit, commit) => controller.setEdit(parameter.Name, edit, commit), commit: () => controller.commit(parameter.Name) }, parameter.Name))) })) })) : (jsxs("div", { className: `${styles.parameterGrid} cw-grid-base-auto`, "aria-busy": "true", children: [jsx(CwSkeleton, { variant: "rect", height: "3.5rem" }), jsx(CwSkeleton, { variant: "rect", height: "3.5rem" }), jsx(CwSkeleton, { variant: "rect", height: "3.5rem" })] })) }), jsx("footer", { className: styles.parameterActions, children: jsx(CwButton, { type: "submit", text: "View report", icon: "file-view", className: styles.viewButton, disabled: !form || loading || rendering, "data-testid": "report-view-button" }) })] }));
12029
+ }
12030
+
12031
+ const REPORT_EXPORT_LABELS = {
12032
+ pdf: "PDF",
12033
+ xlsx: "Excel",
12034
+ docx: "Word"
12035
+ };
12036
+ /** A render with warnings asks before exporting or printing; without warnings the action runs at once. */
12037
+ function needsOutputConfirmation(warnings) {
12038
+ return (warnings?.length ?? 0) > 0;
12039
+ }
12040
+ /** Texts of the confirmation shown before an export or print of a render with warnings. */
12041
+ function outputConfirmation(action, warningCount) {
12042
+ const count = `${warningCount} warning${warningCount === 1 ? "" : "s"}`;
12043
+ if (action.kind === "print") {
12044
+ return {
12045
+ headline: "Print report",
12046
+ message: `This report has ${count}. The printout may not match the report exactly.`,
12047
+ confirmText: "Print anyway"
12048
+ };
12049
+ }
12050
+ const label = REPORT_EXPORT_LABELS[action.format];
12051
+ return {
12052
+ headline: `Export as ${label}`,
12053
+ message: `This report has ${count}. The ${label} export may not match the report exactly.`,
12054
+ confirmText: "Export anyway"
12055
+ };
12056
+ }
12057
+
12058
+ const EXPORTS = [
12059
+ { format: "pdf", label: REPORT_EXPORT_LABELS.pdf, icon: "file-pdf" },
12060
+ { format: "xlsx", label: REPORT_EXPORT_LABELS.xlsx, icon: "table" },
12061
+ { format: "docx", label: REPORT_EXPORT_LABELS.docx, icon: "document" }
12062
+ ];
12063
+ function zoomToValue(zoom) {
12064
+ return typeof zoom === "number" ? String(zoom) : zoom;
12065
+ }
12066
+ function valueToZoom(value) {
12067
+ if (value === "pageWidth" || value === "wholePage")
12068
+ return value;
12069
+ const factor = parseFloat(value);
12070
+ return Number.isFinite(factor) && factor > 0 ? factor : 1;
12071
+ }
12072
+ function closePopover(element) {
12073
+ element.closest("[popover]")?.hidePopover();
12074
+ }
12075
+ function PageInput({ pageNumber, pageCount, onPage, disabled }) {
12076
+ const [draft, setDraft] = useState({ page: pageNumber, text: String(pageNumber) });
12077
+ const text = draft.page === pageNumber ? draft.text : String(pageNumber);
12078
+ const commit = () => {
12079
+ const parsed = parseInt(text, 10);
12080
+ const target = Number.isFinite(parsed) ? Math.min(Math.max(1, parsed), Math.max(1, pageCount)) : pageNumber;
12081
+ setDraft({ page: pageNumber, text: String(target) });
12082
+ if (target !== pageNumber)
12083
+ onPage(target);
12084
+ };
12085
+ return (jsx(CwDigit, { "data-size": "tiny", "aria-label": "Page", min: 1, max: Math.max(1, pageCount), value: text, disabled: disabled, onChange: e => {
12086
+ const value = e.currentTarget.value;
12087
+ setDraft({ page: pageNumber, text: value });
12088
+ }, onKeyDown: (e) => {
12089
+ if (e.key === "Enter")
12090
+ commit();
12091
+ }, onBlur: commit }));
12092
+ }
12093
+ /**
12094
+ * The report viewer toolbar, like the old ReportViewer: page navigation, refresh, back, zoom,
12095
+ * find on the current page, export (PDF / Excel / Word) and print. Warnings stay invisible until
12096
+ * there are some (Dark Cockpit). Presentational: every action is a callback.
12097
+ */
12098
+ function CwReportToolbar({ pageNumber, pageCount, onPage, onRefresh, onBack, zoom, onZoomChange, findText, onFindTextChange, onFindNext, findMatchCount, findMatchIndex, onExport, onPrint, warnings = [], onToggleParameters, parametersVisible = true, disabled = false, reportName }) {
12099
+ const firstPage = disabled || pageNumber <= 1;
12100
+ const lastPage = disabled || pageNumber >= pageCount;
12101
+ const findStatus = findText.trim() === ""
12102
+ ? ""
12103
+ : findMatchCount === 0 ? "No matches" : `${Math.max(0, findMatchIndex) + 1} of ${findMatchCount}`;
12104
+ return (jsxs("header", { className: `${styles.toolbar} cw-flex-row cw-align-left-center cw-flex-wrap cw-gap-small`, "data-testid": "report-toolbar", children: [onBack && jsx(CwButton, { variant: "icon", icon: "arrow-left", title: "Back", onClick: onBack }), onToggleParameters && (jsx(CwButton, { variant: "icon", icon: "filter-list", title: parametersVisible ? "Hide parameters" : "Show parameters", pressed: parametersVisible, onClick: onToggleParameters })), jsxs("nav", { className: "cw-flex-row cw-align-left-center cw-gap-tiny", "aria-label": "Pages", children: [jsx(CwButton, { variant: "icon", icon: "chevron-left-double", title: "First page", disabled: firstPage, onClick: () => onPage(1) }), jsx(CwButton, { variant: "icon", icon: "chevron-left", title: "Previous page", disabled: firstPage, onClick: () => onPage(pageNumber - 1) }), jsx(PageInput, { pageNumber: pageNumber, pageCount: pageCount, onPage: onPage, disabled: disabled }), jsxs("span", { className: "cw-font-size-small", children: ["of ", disabled ? "-" : pageCount] }), jsx(CwButton, { variant: "icon", icon: "chevron-right", title: "Next page", disabled: lastPage, onClick: () => onPage(pageNumber + 1) }), jsx(CwButton, { variant: "icon", icon: "chevron-right-double", title: "Last page", disabled: lastPage, onClick: () => onPage(pageCount) })] }), onRefresh && jsx(CwButton, { variant: "icon", icon: "refresh", title: "Refresh", disabled: disabled, onClick: onRefresh }), jsxs(CwSelect, { "aria-label": "Zoom", value: zoomToValue(zoom), handleChange: value => onZoomChange(valueToZoom(value)), children: [REPORT_ZOOM_STEPS.map(step => (jsx(CwOption, { value: String(step), text: `${Math.round(step * 100)}%` }, step))), jsx(CwOption, { value: "pageWidth", text: "Page width" }), jsx(CwOption, { value: "wholePage", text: "Whole page" })] }), jsxs("div", { className: "cw-flex-row cw-align-left-center cw-gap-small", children: [jsx(CwInputText, { "aria-label": "Find text", placeholder: "Find", value: findText, disabled: disabled, onChange: e => onFindTextChange(e.currentTarget.value), onKeyDown: (e) => {
12105
+ if (e.key === "Enter")
12106
+ onFindNext();
12107
+ }, buttonProps: {
12108
+ text: "Next",
12109
+ variant: "outline",
12110
+ disabled: disabled || findMatchCount === 0,
12111
+ onClick: onFindNext
12112
+ } }), jsx("span", { className: `${styles.findStatus} cw-font-size-small`, "aria-live": "polite", children: findStatus })] }), jsx("div", { className: styles.reportName, children: reportName && (jsx(CwTooltipNew, { content: reportName, position: "bottom", children: jsx("strong", { className: "cw-text-ellipsis", "data-testid": "report-name", children: reportName }) })) }), warnings.length > 0 && (jsx(CwPopoverButton, { variant: "icon", icon: "warning", title: "Warnings", badge: { count: warnings.length, color: "warning" }, className: styles.warningsButton, placement: "bottom-end", panelClassName: styles.warningsPanel, children: jsx("ul", { className: styles.warningList, children: warnings.map((warning, index) => jsx("li", { children: warning }, index)) }) })), jsx(CwPopoverButton, { icon: "download", title: "Export", variant: "icon", disabled: disabled, placement: "bottom-end", children: jsx("div", { className: styles.menu, children: EXPORTS.map(item => (jsx(CwButton, { variant: "ghost", color: "neutral", text: item.label, icon: item.icon, className: styles.menuItem, onClick: e => {
12113
+ closePopover(e.currentTarget);
12114
+ onExport(item.format);
12115
+ } }, item.format))) }) }), jsx(CwButton, { variant: "icon", icon: "print", title: "Print", disabled: disabled, onClick: onPrint })] }));
12116
+ }
12117
+
12118
+ /** Width change of one arrow key press on the sidebar resize handle, in CSS pixels. */
12119
+ const SIDEBAR_KEY_STEP = 16;
12120
+ /** Keeps a sidebar width inside [min, max]; a max below min collapses to min. */
12121
+ function clampSidebarWidth(width, min, max) {
12122
+ const upper = Math.max(min, max);
12123
+ if (!Number.isFinite(width))
12124
+ return min;
12125
+ return Math.min(Math.max(width, min), upper);
12126
+ }
12127
+ /**
12128
+ * The sidebar width after a key press on the resize handle: arrows step, Home / End jump to the
12129
+ * bounds. Null for keys the handle does not use, so they keep their default behaviour.
12130
+ */
12131
+ function sidebarWidthForKey(key, current, min, max, step = SIDEBAR_KEY_STEP) {
12132
+ switch (key) {
12133
+ case "ArrowLeft":
12134
+ return clampSidebarWidth(current - step, min, max);
12135
+ case "ArrowRight":
12136
+ return clampSidebarWidth(current + step, min, max);
12137
+ case "Home":
12138
+ return clampSidebarWidth(min, min, max);
12139
+ case "End":
12140
+ return clampSidebarWidth(max, min, max);
12141
+ default:
12142
+ return null;
12143
+ }
12144
+ }
12145
+ /**
12146
+ * Whether the viewer shows the parameter sidebar. While the form loads for the first time it shows
12147
+ * the skeleton; once loaded only when the user has something to fill in. A report whose parameters
12148
+ * are all hidden or server-filled (or that has none) gets no sidebar.
12149
+ */
12150
+ function showsParameterSidebar(parameters, loadingParameters) {
12151
+ return parameters ? hasEditableParameters(parameters.Parameters) : loadingParameters;
12152
+ }
12153
+
12154
+ /**
12155
+ * Width of a left sidebar resized by dragging the handle on its right edge, like the master panel
12156
+ * of CwMasterDetail. The handle captures the pointer, so the drag keeps going outside it; the
12157
+ * keyboard steps the width for users who cannot drag.
12158
+ */
12159
+ function useSidebarResize(initialWidth, minWidth, maxWidth) {
12160
+ const [storedWidth, setStoredWidth] = useState(initialWidth);
12161
+ const [resizing, setResizing] = useState(false);
12162
+ const drag = useRef(null);
12163
+ const width = clampSidebarWidth(storedWidth, minWidth, maxWidth);
12164
+ const onPointerDown = useCallback((e) => {
12165
+ if (e.button !== 0)
12166
+ return;
12167
+ e.preventDefault();
12168
+ e.currentTarget.setPointerCapture(e.pointerId);
12169
+ drag.current = { startX: e.clientX, startWidth: width };
12170
+ setResizing(true);
12171
+ }, [width]);
12172
+ const onPointerMove = useCallback((e) => {
12173
+ const start = drag.current;
12174
+ if (!start)
12175
+ return;
12176
+ setStoredWidth(clampSidebarWidth(start.startWidth + e.clientX - start.startX, minWidth, maxWidth));
12177
+ }, [minWidth, maxWidth]);
12178
+ const endDrag = useCallback((e) => {
12179
+ if (!drag.current)
12180
+ return;
12181
+ drag.current = null;
12182
+ if (e.currentTarget.hasPointerCapture(e.pointerId))
12183
+ e.currentTarget.releasePointerCapture(e.pointerId);
12184
+ setResizing(false);
12185
+ }, []);
12186
+ const onKeyDown = useCallback((e) => {
12187
+ const next = sidebarWidthForKey(e.key, width, minWidth, maxWidth);
12188
+ if (next === null)
12189
+ return;
12190
+ e.preventDefault();
12191
+ setStoredWidth(next);
12192
+ }, [width, minWidth, maxWidth]);
12193
+ return {
12194
+ width,
12195
+ resizing,
12196
+ handleProps: { onPointerDown, onPointerMove, onPointerUp: endDrag, onPointerCancel: endDrag, onKeyDown }
12197
+ };
12198
+ }
12199
+
12200
+ /** Space the canvas keeps around the sheet when fitting it (its padding on both sides), in CSS pixels. */
12201
+ const CANVAS_GUTTER = 32;
12202
+ function useElementSize(ref) {
12203
+ const [size, setSize] = useState({ width: 0, height: 0 });
12204
+ useEffect(() => {
12205
+ const element = ref.current;
12206
+ if (!element || typeof ResizeObserver === "undefined")
12207
+ return;
12208
+ const observer = new ResizeObserver(() => {
12209
+ setSize({ width: element.clientWidth, height: element.clientHeight });
12210
+ });
12211
+ observer.observe(element);
12212
+ return () => observer.disconnect();
12213
+ }, [ref]);
12214
+ return size;
12215
+ }
12216
+ /**
12217
+ * The RDL report viewer: a resizable, collapsible parameter sidebar on the left, the toolbar and
12218
+ * the page on a neutral canvas on the right, like the old ReportViewer. The sidebar only exists
12219
+ * when the user has a parameter to fill in. Presentational: it fetches nothing and owns no report
12220
+ * state. The host calls `useReportViewerState` and `useReportParameterForm` and passes their results
12221
+ * as `state` and `parameterForm`; every request goes out through the callbacks given to those hooks
12222
+ * (or `onSort` / `onRefresh` / `onBack`) and comes back as their arguments.
12223
+ */
12224
+ function CwReportViewer({ definition, state, parameterForm, loadingParameters = false, loadingRender = false, error, onSort, onRefresh, onBack, getImageUrl, sidebarWidth = 320, minSidebarWidth = 240, maxSidebarWidth = 600, resizable = true, className }) {
12225
+ const { result } = state;
12226
+ const parameters = parameterForm.form;
12227
+ const sidebar = useSidebarResize(sidebarWidth, minSidebarWidth, maxSidebarWidth);
12228
+ const canvasRef = useRef(null);
12229
+ const canvasSize = useElementSize(canvasRef);
12230
+ const hasSidebar = showsParameterSidebar(parameters, loadingParameters);
12231
+ const sidebarOpen = hasSidebar && state.parametersVisible;
12232
+ const warnings = result?.Warnings ?? [];
12233
+ const reportName = result?.Name || definition?.Name || null;
12234
+ const confirmation = state.pendingOutput ? outputConfirmation(state.pendingOutput, warnings.length) : null;
12235
+ /** Where the clicked toggle sat in the canvas, so the re-rendered page keeps it in the same place. */
12236
+ const toggleAnchorRef = useRef(null);
12237
+ const handleToggle = (toggleId) => {
12238
+ if (state.serverToggles) {
12239
+ const canvas = canvasRef.current;
12240
+ const button = canvas?.querySelector(`[data-toggle-id="${CSS.escape(toggleId)}"]`);
12241
+ toggleAnchorRef.current = canvas && button
12242
+ ? { toggleId, offset: button.getBoundingClientRect().top - canvas.getBoundingClientRect().top }
12243
+ : null;
12244
+ }
12245
+ state.toggle(toggleId);
12246
+ };
12247
+ useLayoutEffect(() => {
12248
+ const anchor = toggleAnchorRef.current;
12249
+ const canvas = canvasRef.current;
12250
+ if (!anchor || !canvas || !result)
12251
+ return;
12252
+ toggleAnchorRef.current = null;
12253
+ const button = canvas.querySelector(`[data-toggle-id="${CSS.escape(anchor.toggleId)}"]`);
12254
+ if (button)
12255
+ canvas.scrollTop += button.getBoundingClientRect().top - canvas.getBoundingClientRect().top - anchor.offset;
12256
+ }, [result]);
12257
+ // Without a sidebar (nothing to fill in) the form's "View report" lives on the canvas instead.
12258
+ const runButton = !hasSidebar && parameters && !result ? (jsx(CwButton, { text: "View report", icon: "file-view", disabled: loadingParameters || loadingRender, onClick: parameterForm.submit, "data-testid": "report-view-button" })) : null;
12259
+ const zoomFactor = result
12260
+ ? resolveZoomFactor(state.zoom, pageSheetSizePt(result.Page, result.BodyWidth, SCREEN_PAGE_MARGINS), { width: canvasSize.width - CANVAS_GUTTER, height: canvasSize.height - CANVAS_GUTTER })
12261
+ : 1;
12262
+ const renderCanvas = () => {
12263
+ if (error) {
12264
+ return (jsxs(Fragment, { children: [jsx(CwNote, { color: "danger", variant: "soft", icon: "warning", content: error, className: styles.canvasNote }), runButton] }));
12265
+ }
12266
+ if (!result) {
12267
+ if (loadingRender) {
12268
+ return (jsx("div", { className: styles.sheetSkeleton, "aria-busy": "true", children: jsx(CwSkeleton, { variant: "text", count: 14 }) }));
12269
+ }
12270
+ return (jsxs("div", { className: `${styles.emptyState} cw-flex-column cw-align-center-center cw-gap-small`, children: [jsx(CwIcon, { iconId: "file-report", size: "huge", color: "neutral" }), jsx("p", { className: "cw-margin-none", children: hasSidebar ? "Set the parameters and select View report." : "Select View report to run the report." }), runButton] }));
12271
+ }
12272
+ return (jsx(CwLoading, { isLoading: loadingRender, children: jsx(CwReportPage, { page: result.Page, bodyWidth: result.BodyWidth, zoom: zoomFactor, culture: result.Culture, margins: SCREEN_PAGE_MARGINS, flippedToggles: state.drawnFlips, onToggle: handleToggle, onSort: onSort, getImageUrl: getImageUrl, findMatches: state.findMatches, activeMatchIndex: state.findIndex }) }));
12273
+ };
12274
+ return (jsxs("section", { className: `${styles.viewer}${className ? ` ${className}` : ""}`, "aria-label": result?.Name ?? definition?.Name ?? "Report", "data-resizing": sidebar.resizing || undefined, "data-testid": "report-viewer", children: [sidebarOpen && (jsxs(Fragment, { children: [jsx("aside", { className: styles.sidebar, style: { width: sidebar.width }, "aria-label": "Report parameters", "data-testid": "report-parameter-sidebar", children: jsx(CwReportParameterForm, { controller: parameterForm, loading: loadingParameters, rendering: loadingRender }) }), resizable && (jsx("div", { className: styles.resizer, role: "separator", "aria-orientation": "vertical", "aria-label": "Resize parameters", "aria-valuenow": sidebar.width, "aria-valuemin": minSidebarWidth, "aria-valuemax": Math.max(minSidebarWidth, maxSidebarWidth), tabIndex: 0, "data-resizing": sidebar.resizing, ...sidebar.handleProps }))] })), jsxs("div", { className: styles.main, children: [jsx(CwReportToolbar, { pageNumber: result?.Page.Number ?? 1, pageCount: result?.PageCount ?? 1, onPage: state.goToPage, onRefresh: onRefresh, onBack: onBack, zoom: state.zoom, onZoomChange: state.setZoom, findText: state.findText, onFindTextChange: state.setFindText, onFindNext: state.findNext, findMatchCount: state.findMatches.length, findMatchIndex: state.findIndex, onExport: format => state.requestOutput({ kind: "export", format }), onPrint: () => state.requestOutput({ kind: "print" }), warnings: warnings, reportName: reportName, onToggleParameters: hasSidebar ? state.toggleParameters : undefined, parametersVisible: state.parametersVisible, disabled: !result || loadingRender || !!error }), jsx("div", { ref: canvasRef, className: styles.canvas, "data-testid": "report-canvas", children: renderCanvas() })] }), confirmation && (jsx(CwDialog, { open: true, headline: confirmation.headline, width: "28rem", onClose: state.cancelOutput, customFooter: [
12275
+ jsx(CwButton, { text: "Cancel", variant: "outline", onClick: state.cancelOutput }, "cancel"),
12276
+ jsx(CwButton, { text: confirmation.confirmText, onClick: state.confirmOutput, "data-testid": "report-output-confirm" }, "confirm")
12277
+ ], "data-testid": "report-output-dialog", children: jsx("p", { className: "cw-margin-none", children: confirmation.message }) })), state.permissionDialogOpen && (jsx(CwDialog, { open: true, headline: "SQL ERROR", width: "30rem", onClose: state.closePermissionDialog, customFooter: [jsx(CwButton, { text: "OK", onClick: state.closePermissionDialog }, "ok")], "data-testid": "report-permission-dialog", children: jsx("p", { className: "cw-margin-none", children: "You do not have the database permission this report needs, so some of its data could not be read. Ask an administrator to grant access to the report data." }) }))] }));
12278
+ }
12279
+
12280
+ const NO_FLIPS = new Set();
12281
+ /**
12282
+ * Client-side state of the report viewer around one render result, owned by the host and handed to
12283
+ * `CwReportViewer` as `state`. The drilldown toggles belong to a render: a new RenderId (new render,
12284
+ * sort) starts with none flipped, paging and server views of the same render keep them. With
12285
+ * `onView` the host re-renders the page for the flipped toggles, so the page and find use it as drawn
12286
+ * (`drawnFlips` = none). The find position belongs to the query and the page shown. The permission
12287
+ * dialog is dismissed per render, and a pending export / print question is dropped by a new render.
12288
+ */
12289
+ function useReportViewerState(result, options) {
12290
+ const { onPage, onView, onExport, onPrint, initialZoom = 1 } = options;
12291
+ const renderId = result?.RenderId ?? null;
12292
+ const page = result?.Page ?? null;
12293
+ const pageNumber = page?.Number ?? 1;
12294
+ const warnings = result?.Warnings;
12295
+ const serverToggles = !!onView;
12296
+ const [zoom, setZoom] = useState(initialZoom);
12297
+ const [toggles, setToggles] = useState({ renderId: null, flipped: NO_FLIPS });
12298
+ const [findText, setFindText] = useState("");
12299
+ const [find, setFind] = useState({ key: "", index: 0 });
12300
+ const [parametersVisible, setParametersVisible] = useState(true);
12301
+ const [dismissedRenderId, setDismissedRenderId] = useState(null);
12302
+ const [output, setOutput] = useState(null);
12303
+ const flipped = toggles.renderId === renderId ? toggles.flipped : NO_FLIPS;
12304
+ const toggle = useCallback((toggleId) => {
12305
+ setToggles(previous => ({
12306
+ renderId,
12307
+ flipped: flipToggle(previous.renderId === renderId ? previous.flipped : NO_FLIPS, toggleId)
12308
+ }));
12309
+ if (onView)
12310
+ onView(toggledIds(flipped, toggleId), pageNumber);
12311
+ }, [renderId, onView, flipped, pageNumber]);
12312
+ const setFlipped = useCallback((toggleIds) => {
12313
+ setToggles({ renderId, flipped: new Set(toggleIds) });
12314
+ }, [renderId]);
12315
+ const goToPage = useCallback((target) => {
12316
+ if (onView && flipped.size > 0) {
12317
+ onView(flippedToggleIds(flipped), target);
12318
+ }
12319
+ else {
12320
+ onPage(target);
12321
+ }
12322
+ }, [onView, onPage, flipped]);
12323
+ // With server toggles the page arrives already drawn for the flipped toggles, so nothing is flipped again here.
12324
+ const drawnFlips = serverToggles ? NO_FLIPS : flipped;
12325
+ const findMatches = useMemo(() => (page ? findInPage(page, findText, drawnFlips) : []), [page, findText, drawnFlips]);
12326
+ const findKey = `${renderId ?? ""}|${page?.Number ?? 0}|${findText}`;
12327
+ const findIndex = activeMatchIndex(find.index, find.key === findKey, findMatches.length);
12328
+ const findNext = useCallback(() => {
12329
+ setFind({ key: findKey, index: nextMatchIndex(findIndex, findMatches.length) });
12330
+ }, [findKey, findIndex, findMatches.length]);
12331
+ const toggleParameters = useCallback(() => setParametersVisible(visible => !visible), []);
12332
+ const closePermissionDialog = useCallback(() => setDismissedRenderId(renderId), [renderId]);
12333
+ // A new render (refresh, sort) drops a question asked about the previous one.
12334
+ const pendingOutput = output && output.renderId === renderId ? output.action : null;
12335
+ const runOutput = useCallback((action) => {
12336
+ const toggleIds = flippedToggleIds(flipped);
12337
+ if (action.kind === "print") {
12338
+ onPrint(toggleIds);
12339
+ }
12340
+ else {
12341
+ onExport(action.format, toggleIds);
12342
+ }
12343
+ }, [flipped, onPrint, onExport]);
12344
+ const requestOutput = useCallback((action) => {
12345
+ if (needsOutputConfirmation(warnings)) {
12346
+ setOutput({ renderId, action });
12347
+ }
12348
+ else {
12349
+ runOutput(action);
12350
+ }
12351
+ }, [warnings, renderId, runOutput]);
12352
+ const confirmOutput = useCallback(() => {
12353
+ setOutput(null);
12354
+ if (pendingOutput)
12355
+ runOutput(pendingOutput);
12356
+ }, [pendingOutput, runOutput]);
12357
+ const cancelOutput = useCallback(() => setOutput(null), []);
12358
+ return {
12359
+ result,
12360
+ serverToggles,
12361
+ zoom,
12362
+ setZoom,
12363
+ flipped,
12364
+ drawnFlips,
12365
+ toggle,
12366
+ setFlipped,
12367
+ goToPage,
12368
+ findText,
12369
+ setFindText,
12370
+ findMatches,
12371
+ findIndex,
12372
+ findNext,
12373
+ parametersVisible,
12374
+ toggleParameters,
12375
+ permissionDialogOpen: !!result?.PermissionDenied && dismissedRenderId !== renderId,
12376
+ closePermissionDialog,
12377
+ pendingOutput,
12378
+ requestOutput,
12379
+ confirmOutput,
12380
+ cancelOutput
12381
+ };
12382
+ }
12383
+
12384
+ function stateFor(form) {
12385
+ return { source: form, edits: initialParameterEdits(form?.Parameters ?? []), pending: new Set(), showErrors: false };
12386
+ }
12387
+ /**
12388
+ * Editor state of the report parameter form, owned by the host and handed to `CwReportParameterForm`
12389
+ * as `controller`. A new form object from the host (after a resolve) resets the editors to the values
12390
+ * it carries; the server echoes the submitted values, so nothing is lost.
12391
+ */
12392
+ function useReportParameterForm(form, options) {
12393
+ const { onResolve, onRender } = options;
12394
+ const [state, setState] = useState(() => stateFor(form));
12395
+ const current = state.source === form ? state : stateFor(form);
12396
+ if (current !== state)
12397
+ setState(current);
12398
+ const parameters = form?.Parameters ?? [];
12399
+ const setEdit = useCallback((name, edit, commit) => {
12400
+ const params = form?.Parameters ?? [];
12401
+ const edits = { ...current.edits, [name]: edit };
12402
+ const pending = new Set(current.pending);
12403
+ if (commit) {
12404
+ pending.delete(name);
12405
+ }
12406
+ else {
12407
+ pending.add(name);
12408
+ }
12409
+ setState({ ...current, edits, pending });
12410
+ if (commit && hasDependentParameters(params, name))
12411
+ onResolve(toRdlParameterValues(params, edits));
12412
+ }, [current, form, onResolve]);
12413
+ const commit = useCallback((name) => {
12414
+ if (!current.pending.has(name))
12415
+ return;
12416
+ const params = form?.Parameters ?? [];
12417
+ const pending = new Set(current.pending);
12418
+ pending.delete(name);
12419
+ setState({ ...current, pending });
12420
+ if (hasDependentParameters(params, name))
12421
+ onResolve(toRdlParameterValues(params, current.edits));
12422
+ }, [current, form, onResolve]);
12423
+ const submit = useCallback(() => {
12424
+ const params = form?.Parameters ?? [];
12425
+ const errors = validateParameterEdits(params, current.edits);
12426
+ if (Object.keys(errors).length > 0) {
12427
+ setState({ ...current, showErrors: true });
12428
+ return;
12429
+ }
12430
+ onRender(toRdlParameterValues(params, current.edits));
12431
+ }, [current, form, onRender]);
12432
+ return {
12433
+ form,
12434
+ edits: current.edits,
12435
+ errors: current.showErrors ? validateParameterEdits(parameters, current.edits) : {},
12436
+ setEdit,
12437
+ commit,
12438
+ submit
12439
+ };
12440
+ }
12441
+
10124
12442
  /**
10125
12443
  * API-backed airport search input for WinOps.
10126
12444
  *
@@ -10555,4 +12873,4 @@ const CwFindCrewmember = ({ handleChange, placeHolder = "Search crew…", requir
10555
12873
  }, "data-direction": direction, children: [jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: "cw-search-input-wrapper", ref: wrapperRef, children: [jsx("input", { ref: inputRef, type: "text", value: inputValue, onChange: handleInputChange, onKeyDown: handleKeyDown, onFocus: handleInputFocus, placeholder: isInitialLoading ? "Loading…" : placeHolder, disabled: disabled, required: required, autoComplete: "off", "aria-expanded": showDropdown, "aria-haspopup": "listbox", role: "combobox", title: tooltipText }), (isLoading || isInitialLoading) && (jsx("div", { className: "cw-search-input-loading", children: jsx(CwIcon, { iconId: "spinner" }) })), jsx("div", { className: "cw-search-input-icons", children: inputValue && !disabled && !isInitialLoading ? (jsx(CwButton, { type: "button", onClick: handleClear, "aria-label": "Clear selected crewmember", variant: "icon", icon: "close", color: "neutral" })) : (jsx(CwIcon, { iconId: "person" })) })] })] }), renderPanel(jsx("div", { ref: panelRef, className: dropdownStyles.dropdown, style: panelStyle, role: "listbox", children: jsx("ul", { children: options.map((option, index) => (jsx("li", { className: `${dropdownStyles.option}${index === highlightedIndex ? ` ${dropdownStyles.optionFocused}` : ""}`, onClick: () => handleOptionSelect(option.value), onMouseDown: (e) => e.preventDefault(), onMouseEnter: () => setHighlightedIndex(index), role: "option", "aria-selected": index === highlightedIndex, children: option.text }, option.value))) }) }))] }));
10556
12874
  };
10557
12875
 
10558
- export { CwAccordionContainer, CwAlign, CwAnchoredMenu, CwBadge, CwBtnApprove, CwBtnCancel, CwBtnDelete, CwBtnEdit, CwBtnSave, CwButton, CwButtonSplit, CwButtonSwitch, CwCard, CwCardList, CwCheck, CwCheckbox, CwCheckboxGroup, CwChip, CwColorPicker, CwConfirmationPopup, CwContextMenu, CwDatePicker, CwDatePickerTemporal, CwDateRangePicker, CwDateRangePickerTemporal, CwDateTimePicker, CwDateTimePickerCompact, CwDateTimePickerTemporal, CwDialog, CwDigit, CwDisplayMessage, CwDropdown, CwDropdownFilter, CwExpandable, CwFileUploadMultiple, CwFindAirport, CwFindCrewmember, CwGenericTooltip, CwHeadingMain, CwHeadingSecond, CwIcon, CwImageArea, CwImageGallery, CwImageZoom, CwInput, CwInputColor, CwInputDateText, CwInputDatetime, CwInputImage, CwInputNumber, CwInputPhone, CwInputText, CwKeyValueList, CwLabel, CwLoading, CwMasterDetail, CwMessage, CwMessageManager, CwMessageType, CwModal, CwModalHover, CwModalReportFunctional, CwMultiFilter, CwMultiFilterTag, CwNavMenu, CwNote, CwOption, CwPopoverButton, CwProgress, CwRadioGroup, CwReportModal, CwSearchAsync, CwSearchInput, CwSelect, CwSelectList, CwSelectListItems, CwSkeleton, CwSortableList, CwSortableTable, CwTable, CwTableGrouped, CwTableServerSide, CwTabs, CwTagSelector, CwTextArea, CwTime, CwTimePicker, CwToggle, CwTooltipManager, CwTooltipNew, CwTreeView, CwWeekdaySelector, DefaultRowHeader, OnClearPinned, OnClickContextMenu, OnClickEvent, OnClickRowEvent, OnClickRowHeader, OnClickUtc, OnDoubleClickEvent, OnDoubleClickRowEvent, OnDragEvent, OnDropCtrlEvent, OnDropEvent, OnEndClickHeaderEvent, OnLeftDragStart, OnMultiClickEvent, OnPinRow, OnRangeClickEvent, OnRightClickEvent, OnRightClickRow, OnRightDragStart, OnStartClickHeaderEvent, OnUnpinRow, PRESET_LIBRARY_TEMPORAL, PinRowHeader, Scheduler, SchedulerEvent, SuperScheduler, TooltipConstraintContext, UiEvent, Weekdays, configureCwLoading, eventIsVisible, filterNavItems, filterVisibleEvents, getCwLoadingDefaults, getDefaultDivisions, getEventSizes, getPresetsByKeysTemporal, itemsToMultiFilterTags, sortNavItems, useCwMessage, useSortableList, useSortableTable, useTooltipConstraint };
12876
+ export { CwAccordionContainer, CwAlign, CwAnchoredMenu, CwBadge, CwBtnApprove, CwBtnCancel, CwBtnDelete, CwBtnEdit, CwBtnSave, CwButton, CwButtonSplit, CwButtonSwitch, CwCard, CwCardList, CwCheck, CwCheckbox, CwCheckboxGroup, CwChip, CwColorPicker, CwConfirmationPopup, CwContextMenu, CwDatePicker, CwDatePickerTemporal, CwDateRangePicker, CwDateRangePickerTemporal, CwDateTimePicker, CwDateTimePickerCompact, CwDateTimePickerTemporal, CwDialog, CwDigit, CwDisplayMessage, CwDropdown, CwDropdownFilter, CwExpandable, CwFileUploadMultiple, CwFindAirport, CwFindCrewmember, CwGenericTooltip, CwHeadingMain, CwHeadingSecond, CwIcon, CwImageArea, CwImageGallery, CwImageZoom, CwInput, CwInputColor, CwInputDateText, CwInputDatetime, CwInputImage, CwInputNumber, CwInputPhone, CwInputText, CwKeyValueList, CwLabel, CwLoading, CwMasterDetail, CwMessage, CwMessageManager, CwMessageType, CwModal, CwModalHover, CwModalReportFunctional, CwMultiFilter, CwMultiFilterTag, CwNavMenu, CwNote, CwOption, CwPopoverButton, CwProgress, CwRadioGroup, CwReportGauge, CwReportLineChart, CwReportModal, CwReportPage, CwReportParameterForm, CwReportPieChart, CwReportToolbar, CwReportViewer, CwSearchAsync, CwSearchInput, CwSelect, CwSelectList, CwSelectListItems, CwSkeleton, CwSortableList, CwSortableTable, CwTable, CwTableGrouped, CwTableServerSide, CwTabs, CwTagSelector, CwTextArea, CwTime, CwTimePicker, CwToggle, CwTooltipManager, CwTooltipNew, CwTreeView, CwWeekdaySelector, DefaultRowHeader, OnClearPinned, OnClickContextMenu, OnClickEvent, OnClickRowEvent, OnClickRowHeader, OnClickUtc, OnDoubleClickEvent, OnDoubleClickRowEvent, OnDragEvent, OnDropCtrlEvent, OnDropEvent, OnEndClickHeaderEvent, OnLeftDragStart, OnMultiClickEvent, OnPinRow, OnRangeClickEvent, OnRightClickEvent, OnRightClickRow, OnRightDragStart, OnStartClickHeaderEvent, OnUnpinRow, PRESET_LIBRARY_TEMPORAL, PinRowHeader, REPORT_ZOOM_STEPS, Scheduler, SchedulerEvent, SuperScheduler, TooltipConstraintContext, UiEvent, Weekdays, configureCwLoading, eventIsVisible, filterNavItems, filterVisibleEvents, findInPage, flipToggle, getCwLoadingDefaults, getDefaultDivisions, getEventSizes, getPresetsByKeysTemporal, initialParameterEdits, isRdlVisible, itemsToMultiFilterTags, sortNavItems, toRdlParameterValues, useCwMessage, useReportParameterForm, useReportViewerState, useSortableList, useSortableTable, useTooltipConstraint };