@cwellt_software/cwellt-reactjs-lib 1.1.7 → 1.2.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 (69) hide show
  1. package/dist/content/icons/new-cw-icons/NewCwIcons.html +13 -3
  2. package/dist/content/icons/new-cw-icons/NewCwIcons.json +10 -1
  3. package/dist/content/icons/new-cw-icons/css/new-cw-icons.css +39 -2
  4. package/dist/content/icons/new-cw-icons/fonts/NewCwIcons.woff +0 -0
  5. package/dist/index.cjs.js +891 -1373
  6. package/dist/index.css +1 -7
  7. package/dist/index.d.ts +218 -328
  8. package/dist/index.es.js +893 -1327
  9. package/dist/src/components/control/action/button/CwButton.d.ts +5 -2
  10. package/dist/src/components/control/action/button/CwButton.d.ts.map +1 -1
  11. package/dist/src/components/control/action/buttons/CwButtons.d.ts +24 -54
  12. package/dist/src/components/control/action/buttons/CwButtons.d.ts.map +1 -1
  13. package/dist/src/components/control/action/contextmenu/CwAnchoredMenu.d.ts +80 -0
  14. package/dist/src/components/control/action/contextmenu/CwAnchoredMenu.d.ts.map +1 -0
  15. package/dist/src/components/control/action/contextmenu/CwContextMenu.d.ts +0 -11
  16. package/dist/src/components/control/action/contextmenu/CwContextMenu.d.ts.map +1 -1
  17. package/dist/src/components/control/action/search/CwSearch.d.ts +6 -2
  18. package/dist/src/components/control/action/search/CwSearch.d.ts.map +1 -1
  19. package/dist/src/components/control/choice/multi-filter/CwMultiFilter.d.ts +1 -5
  20. package/dist/src/components/control/choice/multi-filter/CwMultiFilter.d.ts.map +1 -1
  21. package/dist/src/components/control/choice/multi-filter/components/tag/CwMultiFilterTag.d.ts +2 -2
  22. package/dist/src/components/control/choice/multi-filter/components/tag/CwMultiFilterTag.d.ts.map +1 -1
  23. package/dist/src/components/control/choice/toggle/CwToggle.d.ts.map +1 -1
  24. package/dist/src/components/control/input/file/CwFileUploadMultiple.d.ts +1 -0
  25. package/dist/src/components/control/input/file/CwFileUploadMultiple.d.ts.map +1 -1
  26. package/dist/src/components/control/input/new-dates/CwDatePicker.d.ts +5 -3
  27. package/dist/src/components/control/input/new-dates/CwDatePicker.d.ts.map +1 -1
  28. package/dist/src/components/control/input/new-dates/CwDateRangePicker.d.ts +3 -1
  29. package/dist/src/components/control/input/new-dates/CwDateRangePicker.d.ts.map +1 -1
  30. package/dist/src/components/control/input/new-dates/CwDateTimePicker.d.ts +2 -2
  31. package/dist/src/components/control/input/new-dates/CwDateTimePicker.d.ts.map +1 -1
  32. package/dist/src/components/control/input/new-dates/dateRangePresets.d.ts.map +1 -1
  33. package/dist/src/components/control/input/text/CwInputText.d.ts.map +1 -1
  34. package/dist/src/components/custom/find-airport/CwFindAirportComp.d.ts +4 -1
  35. package/dist/src/components/custom/find-airport/CwFindAirportComp.d.ts.map +1 -1
  36. package/dist/src/components/custom/scheduler/components/ResourceListRender.d.ts +1 -1
  37. package/dist/src/components/custom/scheduler/components/ResourceListRender.d.ts.map +1 -1
  38. package/dist/src/components/custom/scheduler-new/presentation/NewScheduler.d.ts +3 -4
  39. package/dist/src/components/custom/scheduler-new/presentation/NewScheduler.d.ts.map +1 -1
  40. package/dist/src/components/custom/scheduler-new/presentation/components/row/DefaultRowHeader.d.ts.map +1 -1
  41. package/dist/src/components/custom/scheduler-new/presentation/components/row/Event.d.ts +2 -2
  42. package/dist/src/components/custom/scheduler-new/presentation/components/row/Event.d.ts.map +1 -1
  43. package/dist/src/components/custom/scheduler-new/presentation/components/row/SchedulerRow.d.ts +2 -2
  44. package/dist/src/components/custom/scheduler-new/presentation/components/row/SchedulerRow.d.ts.map +1 -1
  45. package/dist/src/components/custom/scheduler-new/presentation/logic/getPercentageFromMouseEvent.d.ts +1 -0
  46. package/dist/src/components/custom/scheduler-new/presentation/logic/getPercentageFromMouseEvent.d.ts.map +1 -1
  47. package/dist/src/components/custom/super-scheduler/PinRowHeader.d.ts +2 -2
  48. package/dist/src/components/custom/super-scheduler/PinRowHeader.d.ts.map +1 -1
  49. package/dist/src/components/custom/super-scheduler/SuperScheduler.d.ts +2 -2
  50. package/dist/src/components/custom/super-scheduler/SuperScheduler.d.ts.map +1 -1
  51. package/dist/src/components/display/data/generic_tooltip/CwGenericTooltip.d.ts +1 -0
  52. package/dist/src/components/display/data/generic_tooltip/CwGenericTooltip.d.ts.map +1 -1
  53. package/dist/src/components/display/data/table/CwTable.d.ts +25 -20
  54. package/dist/src/components/display/data/table/CwTable.d.ts.map +1 -1
  55. package/dist/src/components/display/graphics/icon/CwIcon.d.ts.map +1 -1
  56. package/dist/src/components/display/graphics/icon/svg-icons.d.ts +6 -0
  57. package/dist/src/components/display/graphics/icon/svg-icons.d.ts.map +1 -0
  58. package/dist/src/components/display/text/label/CwLabel.d.ts +1 -4
  59. package/dist/src/components/display/text/label/CwLabel.d.ts.map +1 -1
  60. package/dist/src/components/display/text/tag/CwChip.d.ts.map +1 -1
  61. package/dist/src/components/layout/dialog/CwDialog.d.ts.map +1 -1
  62. package/dist/src/components/layout/modal/CwModalReportFunctional.d.ts.map +1 -1
  63. package/dist/src/components/layout/modal/legacy/cw_modal.d.ts +4 -0
  64. package/dist/src/components/layout/modal/legacy/cw_modal.d.ts.map +1 -1
  65. package/dist/src/components/layout/tabs/CwTabs.d.ts +2 -0
  66. package/dist/src/components/layout/tabs/CwTabs.d.ts.map +1 -1
  67. package/dist/src/index.d.ts +2 -11
  68. package/dist/src/index.d.ts.map +1 -1
  69. package/package.json +6 -11
package/dist/index.cjs.js CHANGED
@@ -11,7 +11,7 @@ var dateFns = require('date-fns');
11
11
  var locale = require('date-fns/locale');
12
12
  var reactDayPicker = require('react-day-picker');
13
13
  require('react-day-picker/dist/style.css');
14
- var lodash = require('lodash');
14
+ var lodashEs = require('lodash-es');
15
15
  var reactWindow = require('react-window');
16
16
 
17
17
  function _interopNamespaceDefault(e) {
@@ -71,70 +71,16 @@ function CwHeadingSecond(props) {
71
71
  return (jsxRuntime.jsx("div", { className: "cw-heading", children: jsxRuntime.jsx("h3", { className: "cwHeading_desc", ...headingProps, children: children }) }));
72
72
  }
73
73
 
74
- /**
75
- * General purpose aligner flex container, useful for column or row view.
76
- * @remarks
77
- * ```txt
78
- * flexDirection="row" (default):
79
- *
80
- * <Row A> | - item 1 - item 2 - item 3 |
81
- * <Row B> | - item 1 - item 2 - item 3 |
82
- *
83
- * flexDirection="column":
84
- *
85
- * <Col A> <Col B>
86
- * | - item 1 | - item 1 |
87
- * | - item 2 | - item 2 |
88
- * | - item 3 | - item 3 |
89
- *
90
- * ```
91
- * @example
92
- * <CwAlign flexDirection="column">
93
- * <div>
94
- * <h2>ColumnA</h2>
95
- * </div>
96
- * <div>
97
- * <h2>ColumnB</h2>
98
- * </div>
99
- * </CwAlign>
100
- */
101
- function CwAlign(props) {
102
- const { alignContent, alignItems, alignSelf, bottom, display, flexBasis, flexDirection, flexGrow, flexShrink, flexWrap, cssHeight, justifyContent, left, margin, order, padding, position, right, top, cssWidth, gap, ...divProps } = props;
103
- return (jsxRuntime.jsx("div", { className: "cw-align", ...divProps, style: {
104
- alignContent: alignContent,
105
- alignItems: alignItems,
106
- alignSelf: alignSelf,
107
- bottom: bottom,
108
- display: display ?? "flex",
109
- flexBasis: flexBasis,
110
- flexDirection: flexDirection,
111
- flexGrow: flexGrow,
112
- flexShrink: flexShrink,
113
- flexWrap: flexWrap,
114
- height: cssHeight,
115
- justifyContent: justifyContent,
116
- left: left,
117
- margin: margin,
118
- order: order,
119
- padding: padding,
120
- position: position,
121
- right: right,
122
- top: top,
123
- width: cssWidth,
124
- gap: gap
125
- }, children: props.children }));
126
- }
127
-
128
74
  /**
129
75
  * Label for form controls.
130
76
  * @example
131
77
  * ```tsx
132
- * <CwLabelForm justify="right" >Username:</CwLabelForm>
78
+ * <CwLabel justify="right" >Username:</CwLabel>
133
79
  * ```
134
80
  */
135
81
  function CwLabel(props) {
136
- const { justify, text, labelHeight, labelWidth, alignProps, margin, ...labelProps } = props;
137
- return (jsxRuntime.jsx("span", { className: "cw-label", children: jsxRuntime.jsx(CwAlign, { ...alignProps, children: jsxRuntime.jsx("label", { style: { textAlign: justify, width: labelWidth, height: labelHeight, margin: margin ?? "1px 0 0 0" }, ...labelProps, children: labelProps.children ?? text }) }) }));
82
+ const { justify, text, labelHeight, labelWidth, margin, ...labelProps } = props;
83
+ return (jsxRuntime.jsx("label", { className: "cw-label", style: { textAlign: justify, width: labelWidth, height: labelHeight, margin: margin ?? "1px 0 0 0" }, ...labelProps, children: labelProps.children ?? text }));
138
84
  }
139
85
 
140
86
  function CwTooltip(CwelltTooltipProps) {
@@ -218,6 +164,11 @@ function getContrastColor(color) {
218
164
  return `hsl(${hsl.h}, ${contrastS}%, ${contrastL}%)`;
219
165
  }
220
166
 
167
+ const SVG_ICONS = {
168
+ 'sortable-asc': (jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 128 128", fill: "currentColor", children: [jsxRuntime.jsx("path", { d: "M93.1675 73.1739C94.5691 74.5758 94.7323 76.7924 93.5515 78.3846L93.1675 78.8326L63.6741 108.326L34.1755 78.8326C32.6908 77.3518 32.6014 74.9761 33.9708 73.3881C35.3401 71.8001 37.7033 71.5391 39.3861 72.7899L39.8341 73.1739L63.6741 97.0137L87.5088 73.1739C88.9104 71.7726 91.1274 71.6092 92.7194 72.7899L93.1674 73.1739H93.1675Z", opacity: "0.3" }), jsxRuntime.jsx("path", { d: "M34.1714 55.1518C32.7697 53.7499 32.6066 51.5333 33.7874 49.9411L34.1714 49.4931L63.6647 20L93.1634 49.4931C94.6481 50.9739 94.7375 53.3496 93.3681 54.9376C91.9987 56.5256 89.6356 56.7866 87.9527 55.5358L87.5047 55.1517L63.6647 31.312L39.8301 55.1518C38.4285 56.5531 36.2115 56.7165 34.6195 55.5358L34.1715 55.1518L34.1714 55.1518Z", opacity: "1" })] })),
169
+ 'sortable-desc': (jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 128 128", fill: "currentColor", children: [jsxRuntime.jsx("path", { d: "M93.1675 73.1739C94.5691 74.5758 94.7323 76.7924 93.5515 78.3846L93.1675 78.8326L63.6741 108.326L34.1755 78.8326C32.6908 77.3518 32.6014 74.9761 33.9708 73.3881C35.3401 71.8001 37.7033 71.5391 39.3861 72.7899L39.8341 73.1739L63.6741 97.0137L87.5088 73.1739C88.9104 71.7726 91.1274 71.6092 92.7194 72.7899L93.1674 73.1739H93.1675Z", opacity: "1" }), jsxRuntime.jsx("path", { d: "M34.1714 55.1518C32.7697 53.7499 32.6066 51.5333 33.7874 49.9411L34.1714 49.4931L63.6647 20L93.1634 49.4931C94.6481 50.9739 94.7375 53.3496 93.3681 54.9376C91.9987 56.5256 89.6356 56.7866 87.9527 55.5358L87.5047 55.1517L63.6647 31.312L39.8301 55.1518C38.4285 56.5531 36.2115 56.7165 34.6195 55.5358L34.1715 55.1518L34.1714 55.1518Z", opacity: "0.3" })] })),
170
+ };
171
+
221
172
  /**
222
173
  * Icon component that supports both FontAwesome 4 and cwellt icon font
223
174
  * @example
@@ -233,6 +184,12 @@ function CwIcon(props) {
233
184
  size && `cw-font-size-${size}`
234
185
  ].filter(Boolean).join(' ');
235
186
  };
187
+ // Check if it's a special SVG icon
188
+ if (iconId in SVG_ICONS) {
189
+ const svgElement = SVG_ICONS[iconId];
190
+ const className = getClassName('cw-icon-svg');
191
+ return React.cloneElement(svgElement, { className });
192
+ }
236
193
  // Return appropriate icon based on source
237
194
  if (source === 'fontawesome') {
238
195
  return jsxRuntime.jsx("span", { ...iconProps, className: getClassName(`fa fa-${iconId}`) });
@@ -259,25 +216,15 @@ const CwChip = ({ label, colorScheme = 'info', customColor, variant = 'soft', cl
259
216
  // Calculate styles based on colorScheme, customColor and variant
260
217
  const chipStyle = React.useMemo(() => {
261
218
  if (customColor) {
262
- if (variant === 'outline') {
263
- // For outline, customColor is used for border and text
264
- return {
265
- color: customColor,
266
- borderColor: customColor,
267
- ...style
268
- };
269
- }
270
- else {
271
- // For soft/solid, customColor is used for background and we calculate contrast
272
- return {
273
- backgroundColor: customColor,
274
- color: getContrastColor(customColor),
275
- ...style
276
- };
277
- }
219
+ // Simply set the CSS custom properties, CSS handles the rest
220
+ return {
221
+ '--chip-accent': customColor,
222
+ '--chip-text': getContrastColor(customColor),
223
+ ...style
224
+ };
278
225
  }
279
226
  return style;
280
- }, [colorScheme, customColor, variant, style]);
227
+ }, [customColor, style]);
281
228
  // Handle click on close icon
282
229
  const handleClose = (e) => {
283
230
  e.stopPropagation();
@@ -291,29 +238,9 @@ const CwChip = ({ label, colorScheme = 'info', customColor, variant = 'soft', cl
291
238
  className,
292
239
  closable ? 'cw-chip-closable' : '',
293
240
  ].filter(Boolean).join(' ');
294
- return (jsxRuntime.jsxs("span", { className: chipClassNames, "data-color-scheme": colorScheme, "data-variant": variant, style: chipStyle, children: [icon && jsxRuntime.jsx(CwIcon, { iconId: icon }), label, closable && (jsxRuntime.jsx("button", { className: "cw-chip-close-button", onClick: handleClose, "aria-label": "Remove", type: "button", children: jsxRuntime.jsx("span", { className: "cwi-icons cwi-close" }) }))] }));
241
+ return (jsxRuntime.jsxs("span", { className: chipClassNames, "data-color-scheme": colorScheme, "data-variant": variant, style: chipStyle, children: [icon && jsxRuntime.jsx(CwIcon, { iconId: icon }), jsxRuntime.jsx("span", { children: label }), closable && (jsxRuntime.jsx("button", { className: "cw-chip-close-button", onClick: handleClose, "aria-label": "Remove", type: "button", children: jsxRuntime.jsx("span", { className: "cwi-icons cwi-close" }) }))] }));
295
242
  };
296
243
 
297
- function CwTag(tagProps) {
298
- const hideTag = (event_clickTag) => {
299
- const tag = event_clickTag.currentTarget.parentElement;
300
- tag?.classList.add("tag-hidden");
301
- };
302
- const onClickClosableCustomTag = (event_clickClosableT) => {
303
- hideTag(event_clickClosableT);
304
- if (tagProps.onClickClosableTag != undefined) {
305
- tagProps.onClickClosableTag(event_clickClosableT);
306
- }
307
- };
308
- const onClickCustomTag = (event_clickTag) => {
309
- // click option interface
310
- if (tagProps.onClickTag !== undefined) {
311
- tagProps.onClickTag(event_clickTag);
312
- }
313
- };
314
- return (jsxRuntime.jsxs("div", { className: "cw-tag", style: tagProps.styleTag, onClick: event_clickTag => onClickCustomTag(event_clickTag), id: tagProps.idTag, ref: tagProps.ref, children: [jsxRuntime.jsx("strong", { style: tagProps.styleTag_description, children: tagProps.children }), tagProps.closableTag && (jsxRuntime.jsx(CwIcon, { iconId: "close", onClick: event_clickClosableT => onClickClosableCustomTag(event_clickClosableT) }))] }));
315
- }
316
-
317
244
  const CW_DEFAULT_MESSAGE_DURATION = 2000;
318
245
  exports.CwMessageType = void 0;
319
246
  (function (CwMessageType) {
@@ -712,7 +639,7 @@ function CwLoadingSmall(CwelltLoadingAppointements) {
712
639
  jsxRuntime.jsx("div", {})) }));
713
640
  }
714
641
 
715
- var styles$k = {"cw-generic-tooltip-content":"cw-generic-tooltip-module_cw-generic-tooltip-content__la-Si"};
642
+ var styles$k = {"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"};
716
643
 
717
644
  // Constants moved outside to prevent recreation
718
645
  const margin = 16;
@@ -817,7 +744,7 @@ const useTooltipPosition = (isVisible, containerRef, preferredPosition, tooltipC
817
744
  return tooltipState;
818
745
  };
819
746
  // Main component with optimizations
820
- const CwGenericTooltip = ({ children, content = null, position = defaultPosition, dissapearsWhenHover = false, hide = false, overlayStyle = {}, showDelay = 0, }) => {
747
+ const CwGenericTooltip = ({ children, content = null, position = defaultPosition, dissapearsWhenHover = false, hide = false, overlayStyle = {}, showDelay = 0, displayInline = false, }) => {
821
748
  const [isVisible, setIsVisible] = React.useState(false);
822
749
  const containerRef = React.useRef(null);
823
750
  const { setTooltipTimeout, clearTooltipTimeout } = useTooltipDelay(() => {
@@ -828,7 +755,7 @@ const CwGenericTooltip = ({ children, content = null, position = defaultPosition
828
755
  const tooltipContent = React.useMemo(() => {
829
756
  if (hide || !isVisible || !content)
830
757
  return null;
831
- return reactDom.createPortal(jsxRuntime.jsx("div", { className: styles$k["cw-generic-tooltip-content"], "data-position": actualPosition, "data-visible": isVisible, style: {
758
+ return reactDom.createPortal(jsxRuntime.jsx("div", { className: styles$k["cw-generic-tooltip-content"], "data-position": actualPosition, "data-visible": isVisible, "data-inline": displayInline, style: {
832
759
  position: 'fixed',
833
760
  top: `${tooltipPosition.top}px`,
834
761
  left: `${tooltipPosition.left}px`,
@@ -843,10 +770,14 @@ const CwGenericTooltip = ({ children, content = null, position = defaultPosition
843
770
  clearTooltipTimeout();
844
771
  setIsVisible(false);
845
772
  }, [clearTooltipTimeout]);
846
- return (jsxRuntime.jsxs("div", { ref: containerRef, className: styles$k["cw-generic-tooltip"], onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, children: [tooltipContent, children] }));
773
+ return (jsxRuntime.jsxs("div", { ref: containerRef, className: styles$k["cw-generic-tooltip"], onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, children: [tooltipContent, children] }));
847
774
  };
848
775
 
849
776
  // Reference for draggable modal
777
+ /**
778
+ * **Note:** For new development, we recommend using {@link CwDialog} instead. CwModal remains supported for existing code.
779
+ * @see {@link CwDialog}
780
+ */
850
781
  function CwModal(custModalProps) {
851
782
  const draggableRef = React.useRef(null);
852
783
  // Hooks [ modal draggable ]
@@ -880,7 +811,7 @@ function CwModal(custModalProps) {
880
811
  };
881
812
  return (jsxRuntime.jsx("div", { children: custModalProps.modalState && (jsxRuntime.jsxs("div", { className: custModalProps.classNameModalOverlay + " cwelltModalOverlay", children: [jsxRuntime.jsx("div", { className: "cwelltModalOverlayBg", onClick: custModalProps.onCloseModal }), jsxRuntime.jsx(Draggable, { disabled: isModalDisabled, axis: "both", nodeRef: draggableRef, children: jsxRuntime.jsxs("div", { className: custModalProps.classNameModal + " cwelltContainerModal", ref: draggableRef, style: widthModalDef !== "40em" ? modalStyle.widthCustomStyle : modalStyle.widthDefStyle, children: [jsxRuntime.jsxs("div", { className: "cwelltModalHeader", onMouseOver: cwelltOnMouseOverModal, onMouseOut: cwelltOnMouseOutModal, children: [jsxRuntime.jsx("div", { className: "cwelltModalTitle", children: custModalProps.titleModal }), jsxRuntime.jsx("button", { className: "cwelltBtnCloseModal", onClick: custModalProps.onCloseModal, children: jsxRuntime.jsx("span", { className: "cwelltCloseIcon" }) })] }), jsxRuntime.jsx("div", { className: "cwelltModalBody", children: jsxRuntime.jsx("div", { className: "cwelltContainerModalBody", style: { position: "relative" }, children: custModalProps.children }) }), isHide === false ? (
882
813
  // [ false : show modal ]
883
- jsxRuntime.jsxs("div", { className: "cwelltModalFooter", onMouseOver: cwelltOnMouseOverModal, onMouseOut: cwelltOnMouseOutModal, children: [jsxRuntime.jsx(antd.Tooltip, { placement: "bottom", title: "Save", color: "#368ee0", children: jsxRuntime.jsx("div", { className: "cwellt_flex cwellt_justify_center cwelltModalFooterContButton", style: { width: "2em" }, children: jsxRuntime.jsx("button", { className: "btnModalFooterAction cwellt_btn_act cwellt_btn_act_df cwellt_btn_Nbg cwellt_btn_save ", onClick: custModalProps.onSaveModal, form: custModalProps.formSaveModal, hidden: custModalProps.HideBtnModal, type: custModalProps.HtmlSubmitModal }) }) }), isShowcustButton === true ? (jsxRuntime.jsx(antd.Tooltip, { placement: "bottom", title: custModalProps.custButtonTitle, color: custModalProps.custColorButtonTooltip, children: jsxRuntime.jsx("div", { className: "cwellt_flex cwellt_justify_center cwelltModalFooterContButton", style: { width: "2em" }, children: jsxRuntime.jsx("button", { className: "btnModalFooterAction cwellt_btn_act cwellt_btn_act_df cwellt_btn_Nbg " +
814
+ jsxRuntime.jsxs("div", { className: "cwelltModalFooter", onMouseOver: cwelltOnMouseOverModal, onMouseOut: cwelltOnMouseOutModal, children: [jsxRuntime.jsx(antd.Tooltip, { placement: "bottom", title: "Save", color: "#368ee0", children: jsxRuntime.jsx("div", { className: "cwellt_flex cwellt_justify_center ", style: { width: "2em" }, children: jsxRuntime.jsx("button", { className: "cw-button-icon cwi-save", onClick: custModalProps.onSaveModal, form: custModalProps.formSaveModal, hidden: custModalProps.HideBtnModal, type: custModalProps.HtmlSubmitModal }) }) }), isShowcustButton === true ? (jsxRuntime.jsx(antd.Tooltip, { placement: "bottom", title: custModalProps.custButtonTitle, color: custModalProps.custColorButtonTooltip, children: jsxRuntime.jsx("div", { className: "cwellt_flex cwellt_justify_center", style: { width: "2em" }, children: jsxRuntime.jsx("button", { className: "cw-button-icon " +
884
815
  custModalProps.custButtonClassName, onClick: custModalProps.custButtonClick }) }) })) : (jsxRuntime.jsx("div", {}))] })) : (
885
816
  // true [ do not show the modal ]
886
817
  jsxRuntime.jsx("div", { style: { display: "none" } }))] }) })] })) }));
@@ -958,80 +889,19 @@ function CwConfirmationPopup(props) {
958
889
  }, children: [jsxRuntime.jsx("p", { className: styles$j.message, children: message }), jsxRuntime.jsxs("div", { className: styles$j.buttons, children: [jsxRuntime.jsx("button", { className: `${styles$j.button} ${styles$j.confirmButton}`, onClick: onConfirm, children: confirmText }), jsxRuntime.jsx("button", { className: `${styles$j.button} ${styles$j.cancelButton}`, onClick: onCancel, children: cancelText })] })] }) }))] }));
959
890
  }
960
891
 
961
- // Reference for draggable modal
962
- const draggableRef = React.createRef();
963
- function CwModalConfirm(custModalProps) {
964
- const classNameOverlay = custModalProps.classNameModalOverlay !== null || custModalProps.classNameModalOverlay !== undefined
965
- ? ""
966
- : custModalProps.classNameModalOverlay;
967
- // Default size of modal
968
- const widthModalDef = custModalProps.widthModalConfirm !== null && custModalProps.widthModalConfirm !== undefined
969
- ? custModalProps.widthModalConfirm
970
- : "17em";
971
- const modalStyle = {
972
- // width default
973
- widthDefStyle: {
974
- width: "17em"
975
- },
976
- // width customizable
977
- widthCustomStyle: {
978
- width: custModalProps.widthModalConfirm
979
- }
980
- };
981
- // Hooks [ modal draggable ]
982
- const [ismodalDisabled, setModalDisabled] = React.useState(true);
983
- // [ onMouseOver ]
984
- const cwelltOnMouseOverModal = () => {
985
- setModalDisabled(false);
986
- };
987
- // [ OnMouseOut ]
988
- const cwelltOnMouseOutModal = () => {
989
- setModalDisabled(true);
990
- // finding parent element
991
- };
992
- return (jsxRuntime.jsx("div", { children: custModalProps.modalStateConfirm && (jsxRuntime.jsx("div", { className: classNameOverlay !== undefined ? custModalProps.classNameModalOverlay + " cwelltModalOverlay" : "", children: jsxRuntime.jsx(Draggable, { disabled: ismodalDisabled, children: jsxRuntime.jsxs("div", { className: " cwelltContainerModal", ref: draggableRef, style: widthModalDef !== "17em" ? modalStyle.widthCustomStyle : modalStyle.widthDefStyle, children: [jsxRuntime.jsxs("div", { className: "cwelltModalHeader", onMouseOver: cwelltOnMouseOverModal, onMouseOut: cwelltOnMouseOutModal, children: [jsxRuntime.jsx("div", { className: "cwelltModalTitle", children: custModalProps.headerTextConfirm }), jsxRuntime.jsx("button", { className: "cwelltBtnCloseModal", onClick: custModalProps.onCloseModalConfirm, children: jsxRuntime.jsx("span", { className: "cwelltCloseIcon" }) })] }), jsxRuntime.jsx("div", { className: "cwelltModalBody", children: jsxRuntime.jsxs("div", { className: "cwelltContainerModalBody", children: [jsxRuntime.jsx("div", { className: "cwellt_content_r_df_align", children: jsxRuntime.jsx("label", { className: "cwellt_modalConfirmDesc", children: custModalProps.descriptionModalConfirm }) }), jsxRuntime.jsx("div", { style: { display: "none" }, children: custModalProps.children })] }) }), jsxRuntime.jsx("div", { className: "cwelltModalFooter", onMouseOver: cwelltOnMouseOverModal, onMouseOut: cwelltOnMouseOutModal, children: jsxRuntime.jsx(antd.Tooltip, { placement: "bottom", title: custModalProps.confirmText, color: "#368ee0", children: jsxRuntime.jsx("div", { className: "cwellt_flex cwellt_justify_center", style: { width: "2em" }, children: jsxRuntime.jsx("button", { className: "btnModalFooterAction cwellt_btn_act cwellt_btn_act_df cwellt_btn_Nbg " +
993
- custModalProps.confirmClassName, onClick: custModalProps.onClickActionModalConfirm }) }) }) })] }) }) })) }));
994
- }
995
-
996
- class CwModalIframe extends React__namespace.Component {
997
- constructor(Props) {
998
- super(Props);
999
- this.state = {
1000
- disabled: true
1001
- };
892
+ function CwButton({ text, variant = 'solid', color = 'primary', className = '', icon = "", title, tooltipPosition = "bottom", children, ...buttonProps }) {
893
+ // Build CSS classes based on variant and props
894
+ let buttonClass = `cw-button-${variant}`;
895
+ // Add icon class only for icon variant without children
896
+ if (variant === 'icon' && icon && !children) {
897
+ buttonClass += ` cwi-${icon}`;
1002
898
  }
1003
- // For draggable modal
1004
- draggableRef = React__namespace.createRef();
1005
- handleCancel = () => {
1006
- this.props.SET_IFRAME_VISIBLE(false);
1007
- };
1008
- render() {
1009
- const { disabled } = this.state;
1010
- return (jsxRuntime.jsx(antd.Modal
1011
- // title={this.props.title}
1012
- , {
1013
- // title={this.props.title}
1014
- title: jsxRuntime.jsx("div", { style: {
1015
- width: "100%",
1016
- cursor: "move"
1017
- }, onMouseOver: () => {
1018
- if (this.state.disabled) {
1019
- this.setState({
1020
- disabled: false
1021
- });
1022
- }
1023
- }, onMouseOut: () => {
1024
- this.setState({
1025
- disabled: true
1026
- });
1027
- }, children: this.props.title }), visible: this.props.visible, width: this.props.width, footer: null, bodyStyle: {
1028
- padding: 0,
1029
- width: this.props.width + "px",
1030
- height: this.props.height + "px"
1031
- }, onCancel: () => {
1032
- this.handleCancel();
1033
- }, destroyOnClose: true, modalRender: modal => (jsxRuntime.jsx(Draggable, { disabled: disabled, children: jsxRuntime.jsxs("div", { ref: this.draggableRef, children: [" ", modal] }) })), children: jsxRuntime.jsx("div", { className: "videoWrapper", children: jsxRuntime.jsx("iframe", { id: "iframeAspx", title: this.props.title, src: this.props.cblConfig + "/SSO/SSORedirect?url=" + encodeURIComponent(this.props.url) }) }) }));
899
+ if (className) {
900
+ buttonClass += ` ${className}`;
1034
901
  }
902
+ const tooltipContent = title || (variant === 'icon' && text ? text : undefined);
903
+ const buttonElement = (jsxRuntime.jsx("button", { type: "button", className: buttonClass, ...buttonProps, "data-color": color, "aria-label": tooltipContent, children: variant === 'icon' ? null : (children ?? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [icon && jsxRuntime.jsx(CwIcon, { iconId: icon }), text && jsxRuntime.jsx("strong", { children: text })] }))) }));
904
+ return tooltipContent ? (jsxRuntime.jsx(CwGenericTooltip, { content: tooltipContent, position: tooltipPosition, displayInline: true, children: buttonElement })) : (buttonElement);
1035
905
  }
1036
906
 
1037
907
  var styles$i = {"cw-dialog-main":"cw-dialog-module_cw-dialog-main__cHxHt","cw-dialog-button-close":"cw-dialog-module_cw-dialog-button-close__9GRd8"};
@@ -1075,6 +945,8 @@ const convertFromPx = (px, unit) => {
1075
945
  const CwDialog = props => {
1076
946
  const { customFooter, customHeader, headline, width, height, dialogSize, scrim, onSave, onClose, hideFooter, children, open, autoReposition = false, ...domProps } = props;
1077
947
  const dialogRef = React.useRef(null);
948
+ const [isPressingScrim, setIsPressingScrim] = React.useState(false);
949
+ const pressTimerRef = React.useRef(0);
1078
950
  const initialSetup = React.useMemo(() => {
1079
951
  // Default width and height with units
1080
952
  const defaultWidth = 800;
@@ -1245,14 +1117,34 @@ const CwDialog = props => {
1245
1117
  e.stopPropagation();
1246
1118
  setResizeDirection(direction);
1247
1119
  }, []);
1248
- const handleScrimClick = React.useCallback((e) => {
1249
- if (e.target === e.currentTarget && onClose) {
1250
- onClose();
1251
- }
1120
+ // Click on scrim
1121
+ const handleScrimMouseDown = React.useCallback((e) => {
1122
+ if (e.target !== e.currentTarget)
1123
+ return;
1124
+ setIsPressingScrim(true);
1125
+ pressTimerRef.current = window.setTimeout(() => {
1126
+ if (onClose) {
1127
+ onClose();
1128
+ }
1129
+ }, 500);
1252
1130
  }, [onClose]);
1131
+ const handleScrimMouseUpOrLeave = React.useCallback(() => {
1132
+ if (pressTimerRef.current) {
1133
+ window.clearTimeout(pressTimerRef.current);
1134
+ }
1135
+ setIsPressingScrim(false);
1136
+ }, []);
1137
+ React.useEffect(() => {
1138
+ if (!open) {
1139
+ setIsPressingScrim(false);
1140
+ if (pressTimerRef.current) {
1141
+ window.clearTimeout(pressTimerRef.current);
1142
+ }
1143
+ }
1144
+ }, [open]);
1253
1145
  const header = React.useMemo(() => (jsxRuntime.jsxs("header", { onMouseDown: handleMouseDown, children: [jsxRuntime.jsx("span", { children: headline }), customHeader || (jsxRuntime.jsx("button", { className: styles$i["cw-dialog-button-close"], onClick: onClose }))] })), [handleMouseDown, headline, customHeader, onClose]);
1254
1146
  const content = React.useMemo(() => (jsxRuntime.jsx("section", { children: children })), [children]);
1255
- const footer = React.useMemo(() => (jsxRuntime.jsx("footer", { children: customFooter || (jsxRuntime.jsx("button", { className: "cw-button-icon cwi-save", onClick: onSave })) })), [customFooter, onSave]);
1147
+ const footer = React.useMemo(() => (jsxRuntime.jsx("footer", { children: customFooter || (jsxRuntime.jsx(CwButton, { variant: "icon", icon: "save", title: "Save", onClick: onSave, tooltipPosition: "top" })) })), [customFooter, onSave]);
1256
1148
  const resizeHandles = React.useMemo(() => size.autoHeight
1257
1149
  ? [
1258
1150
  // Only horizontal handles if autoHeight is true
@@ -1279,7 +1171,7 @@ const CwDialog = props => {
1279
1171
  : `${convertFromPx(size.height, size.heightUnit)}${size.heightUnit}`;
1280
1172
  return { displayWidth, displayHeight };
1281
1173
  }, [size.width, size.height, size.widthUnit, size.heightUnit, size.autoHeight]);
1282
- const dialogContent = (jsxRuntime.jsx("div", { "data-has-scrim": hasScrim, className: styles$i["cw-dialog-main"], onClick: handleScrimClick, children: jsxRuntime.jsxs("dialog", { ...domProps, ref: dialogRef, style: {
1174
+ const dialogContent = (jsxRuntime.jsx("div", { "data-has-scrim": hasScrim, className: styles$i["cw-dialog-main"], onMouseDown: handleScrimMouseDown, onMouseUp: handleScrimMouseUpOrLeave, onMouseLeave: handleScrimMouseUpOrLeave, "data-pressing": isPressingScrim, children: jsxRuntime.jsxs("dialog", { ...domProps, ref: dialogRef, style: {
1283
1175
  left: `${position.x}px`,
1284
1176
  top: `${position.y}px`,
1285
1177
  width: displayDimensions.displayWidth,
@@ -1306,7 +1198,7 @@ const CwModalReportFunctional = (props) => {
1306
1198
  return (jsxRuntime.jsxs("div", { children: ["Please add a(n) ", props.reportName, " report in ", props.moduleSettings, " Settings"] }));
1307
1199
  }
1308
1200
  };
1309
- return (jsxRuntime.jsx("div", { id: "cwelltModalReportContent", children: isModal ? (jsxRuntime.jsx(CwDialog, { open: props.visible, width: props.width, height: props.height, headline: props.title, onClose: props.onCloseModal, hideFooter: true, children: renderContentModal() })) : (jsxRuntime.jsx("div", { children: renderContentNotModal() })) }));
1201
+ return (jsxRuntime.jsx("div", { id: "modal-report-content", children: isModal ? (jsxRuntime.jsx(CwDialog, { open: props.visible, width: props.width, height: props.height, headline: props.title, onClose: props.onCloseModal, hideFooter: true, className: "modal-report-content", children: renderContentModal() })) : (jsxRuntime.jsx("div", { children: renderContentNotModal() })) }));
1310
1202
  };
1311
1203
 
1312
1204
  class CwReportModal extends React__namespace.Component {
@@ -1326,10 +1218,10 @@ class CwReportModal extends React__namespace.Component {
1326
1218
  };
1327
1219
  }
1328
1220
  render() {
1329
- return (jsxRuntime.jsx("div", { id: "cwelltModalReportContent", children: this.state.isModal === true ? (jsxRuntime.jsxs(CwDialog, { open: this.props.visible, width: this.props.width, height: this.props.height, headline: this.props.title, customFooter: new Array(jsxRuntime.jsx("div", {})), onClose: () => {
1221
+ return (jsxRuntime.jsx("div", { id: "modal-report-content", children: this.state.isModal === true ? (jsxRuntime.jsxs(CwDialog, { open: this.props.visible, width: this.props.width, height: this.props.height, headline: this.props.title, onClose: () => {
1330
1222
  this.formRef?.current?.resetFields();
1331
1223
  this.props.SET_MODAL_REPORT_VISIBLE(false);
1332
- }, hideFooter: true, children: [this.props.name !== "Empty.pdf" && (jsxRuntime.jsx("div", { style: { width: "100%", height: "100%", overflowX: "auto", overflowY: "auto" }, children: jsxRuntime.jsx("embed", { src: "data:application/pdf;base64," + this.props.content, type: "application/pdf", style: { width: "100%", height: "100%", display: "block" } }) })), this.props.name === "Empty.pdf" && (jsxRuntime.jsx("div", { children: jsxRuntime.jsxs("h1", { style: { marginLeft: "2em" }, children: [" ", "Please add a(n) ", this.props.reportName, " report in ", this.props.moduleSettings, " Settings"] }) }))] })) : (jsxRuntime.jsxs("div", { children: [this.props.name !== "Empty.pdf" && (jsxRuntime.jsx("embed", { src: "data:application/pdf;base64," + this.props.content, type: "application/pdf", width: "100%", height: "800px" })), this.props.name === "Empty.pdf" && (jsxRuntime.jsxs("div", { children: ["Please add a(n) ", this.props.reportName, " report in ", this.props.moduleSettings, " Settings"] }))] })) }));
1224
+ }, hideFooter: true, className: "modal-report-content", children: [this.props.name !== "Empty.pdf" && (jsxRuntime.jsx("div", { style: { width: "100%", height: "100%", overflowX: "auto", overflowY: "auto" }, children: jsxRuntime.jsx("embed", { src: "data:application/pdf;base64," + this.props.content, type: "application/pdf", style: { width: "100%", height: "100%", display: "block" } }) })), this.props.name === "Empty.pdf" && (jsxRuntime.jsx("div", { children: jsxRuntime.jsxs("h1", { style: { marginLeft: "2em" }, children: [" ", "Please add a(n) ", this.props.reportName, " report in ", this.props.moduleSettings, " Settings"] }) }))] })) : (jsxRuntime.jsxs("div", { children: [this.props.name !== "Empty.pdf" && (jsxRuntime.jsx("embed", { src: "data:application/pdf;base64," + this.props.content, type: "application/pdf", width: "100%", height: "800px" })), this.props.name === "Empty.pdf" && (jsxRuntime.jsxs("div", { children: ["Please add a(n) ", this.props.reportName, " report in ", this.props.moduleSettings, " Settings"] }))] })) }));
1333
1225
  }
1334
1226
  }
1335
1227
 
@@ -1430,17 +1322,58 @@ class CwDialogManager {
1430
1322
  }
1431
1323
  }
1432
1324
 
1433
- function CwButton({ text, variant = 'solid', color = 'primary', className = '', icon = "", children, ...buttonProps }) {
1434
- // Build CSS classes based on variant and props
1435
- let buttonClass = `cw-button-${variant}`;
1436
- // Add icon class only for icon variant without children
1437
- if (variant === 'icon' && icon && !children) {
1438
- buttonClass += ` cwi-${icon}`;
1439
- }
1440
- if (className) {
1441
- buttonClass += ` ${className}`;
1442
- }
1443
- return (jsxRuntime.jsx("button", { type: "button", className: buttonClass, ...buttonProps, "data-color": color, children: variant === 'icon' ? null : (children ?? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [icon && jsxRuntime.jsx("span", { className: `cwi-icons cwi-${icon}` }), text && jsxRuntime.jsx("strong", { children: text })] }))) }));
1325
+ /**
1326
+ * General purpose aligner flex container, useful for column or row view.
1327
+ * @remarks
1328
+ * ```txt
1329
+ * flexDirection="row" (default):
1330
+ *
1331
+ * <Row A> | - item 1 - item 2 - item 3 |
1332
+ * <Row B> | - item 1 - item 2 - item 3 |
1333
+ *
1334
+ * flexDirection="column":
1335
+ *
1336
+ * <Col A> <Col B>
1337
+ * | - item 1 | - item 1 |
1338
+ * | - item 2 | - item 2 |
1339
+ * | - item 3 | - item 3 |
1340
+ *
1341
+ * ```
1342
+ * @example
1343
+ * <CwAlign flexDirection="column">
1344
+ * <div>
1345
+ * <h2>ColumnA</h2>
1346
+ * </div>
1347
+ * <div>
1348
+ * <h2>ColumnB</h2>
1349
+ * </div>
1350
+ * </CwAlign>
1351
+ */
1352
+ function CwAlign(props) {
1353
+ const { alignContent, alignItems, alignSelf, bottom, display, flexBasis, flexDirection, flexGrow, flexShrink, flexWrap, cssHeight, justifyContent, left, margin, order, padding, position, right, top, cssWidth, gap, ...divProps } = props;
1354
+ return (jsxRuntime.jsx("div", { className: "cw-align", ...divProps, style: {
1355
+ alignContent: alignContent,
1356
+ alignItems: alignItems,
1357
+ alignSelf: alignSelf,
1358
+ bottom: bottom,
1359
+ display: display ?? "flex",
1360
+ flexBasis: flexBasis,
1361
+ flexDirection: flexDirection,
1362
+ flexGrow: flexGrow,
1363
+ flexShrink: flexShrink,
1364
+ flexWrap: flexWrap,
1365
+ height: cssHeight,
1366
+ justifyContent: justifyContent,
1367
+ left: left,
1368
+ margin: margin,
1369
+ order: order,
1370
+ padding: padding,
1371
+ position: position,
1372
+ right: right,
1373
+ top: top,
1374
+ width: cssWidth,
1375
+ gap: gap
1376
+ }, children: props.children }));
1444
1377
  }
1445
1378
 
1446
1379
  var styles$h = {"card":"cw-card-module_card__HJUT0","clickable":"cw-card-module_clickable__Y-V3X","disabled":"cw-card-module_disabled__0wHh1","loading":"cw-card-module_loading__-fzlx","content":"cw-card-module_content__ma9qy","headerContent":"cw-card-module_headerContent__x4Jfl","footerTags":"cw-card-module_footerTags__80sSW","loadingOverlay":"cw-card-module_loadingOverlay__8-zVV"};
@@ -1561,23 +1494,23 @@ function CwAccordionContainer(CwelltAccordionContainerProps) {
1561
1494
  * @example
1562
1495
  * const columns: Column<User>[] = [
1563
1496
  * {
1564
- * title: 'Name',
1565
- * dataIndex: 'name',
1566
- * key: 'name',
1497
+ * title: "Name",
1498
+ * dataIndex: "name",
1499
+ * key: "name",
1567
1500
  * sortable: true, // Column is sortable
1568
1501
  * width: 100 // You can define the width of the column
1569
1502
  * },
1570
1503
  * {
1571
- * title: 'Age',
1572
- * dataIndex: 'age',
1573
- * key: 'age',
1504
+ * title: "Age",
1505
+ * dataIndex: "age",
1506
+ * key: "age",
1574
1507
  * sortable: true,
1575
1508
  * render: (item) => <span>{item.age} years</span> // Custom rendering
1576
1509
  * },
1577
1510
  * {
1578
- * title: 'Address',
1579
- * dataIndex: 'address',
1580
- * key: 'address',
1511
+ * title: "Address",
1512
+ * dataIndex: "address",
1513
+ * key: "address",
1581
1514
  * render: (item) => (
1582
1515
  * <a href={`https://maps.google.com/?q=${encodeURIComponent(item.address)}`} target="_blank" rel="noreferrer">
1583
1516
  * {item.address}
@@ -1587,12 +1520,12 @@ function CwAccordionContainer(CwelltAccordionContainerProps) {
1587
1520
  * ];
1588
1521
  *
1589
1522
  * const data:User[] = [
1590
- * { key: '1', name: 'Mike', age: 32, address: '10 Downing Street' },
1591
- * { key: '2', name: 'John', age: 42, address: '11 Downing Street' },
1592
- * { key: '3', name: 'Andres', age: 33, address: '12 Downing Street' },
1593
- * { key: '4', name: 'Gabriel', age: 22, address: '13 Downing Street' },
1594
- * { key: '5', name: 'Sergio', age: 47, address: '14 Downing Street' },
1595
- * { key: '6', name: 'Zacarias', age: 61, address: '15 Downing Street' }
1523
+ * { key: "1", name: "Mike", age: 32, address: "10 Downing Street" },
1524
+ * { key: "2", name: "John", age: 42, address: "11 Downing Street" },
1525
+ * { key: "3", name: "Andres", age: 33, address: "12 Downing Street" },
1526
+ * { key: "4", name: "Gabriel", age: 22, address: "13 Downing Street" },
1527
+ * { key: "5", name: "Sergio", age: 47, address: "14 Downing Street" },
1528
+ * { key: "6", name: "Zacarias", age: 61, address: "15 Downing Street" }
1596
1529
  * ];
1597
1530
  *
1598
1531
  * const generateExpandedContent = (record) => (
@@ -1607,8 +1540,8 @@ function CwAccordionContainer(CwelltAccordionContainerProps) {
1607
1540
  * pagination={true}
1608
1541
  * pageSizeOptions={[3, 5, 10]} // Optional, defaults to [5, 10, 20, 50]
1609
1542
  * expandedRowRender={generateExpandedContent}
1610
- * onExpand={(item) => console.log('Expanded:', item)}
1611
- * rowKey="key" // Optional, defaults to 'key'
1543
+ * onExpand={(item) => console.log("Expanded:", item)}
1544
+ * rowKey="key" // Optional, defaults to "key"
1612
1545
  * textNoData="No data available" // Optional message when no data
1613
1546
  * loading={false} // Optional, shows loading indicator
1614
1547
  * scrollHeight={300} // Optional scroll height, defaults to 300
@@ -1617,12 +1550,12 @@ function CwAccordionContainer(CwelltAccordionContainerProps) {
1617
1550
  * className="my-table" // Optional table class
1618
1551
  * classNameRow="my-table-row" // Optional class for each row
1619
1552
  * id="custom-table-id" // Optional ID for the container
1620
- * style={{ border: '1px solid #ccc' }} // Optional inline styles
1553
+ * style={{ border: "1px solid #ccc" }} // Optional inline styles
1621
1554
  * />
1622
1555
  *
1623
1556
  * @returns React component
1624
1557
  */
1625
- function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10, 20, 50], expandedRowRender, onExpand, className, classNameRow, style, classNameContainer, id, textNoData = "No data available at the moment", rowKey = "key", loading = false, scrollHeight, stickyHeader = false, }) {
1558
+ function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10, 20, 50], expandedRowRender, onExpand, className, classNameRow, style, classNameContainer, id, textNoData = "No data available at the moment", rowKey = "key", loading = false, scrollHeight, stickyHeader = false, rowSelection }) {
1626
1559
  const [currentPage, setCurrentPage] = React.useState(1);
1627
1560
  const [expandedRowKey, setExpandedRowKey] = React.useState(null);
1628
1561
  const [sortConfig, setSortConfig] = React.useState({
@@ -1635,6 +1568,13 @@ function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10,
1635
1568
  acc[col.key] = col.width;
1636
1569
  return acc;
1637
1570
  }, {}));
1571
+ const [selectedKeys, setSelectedKeys] = React.useState(new Set(rowSelection?.selectedRowKeys || []));
1572
+ React.useEffect(() => {
1573
+ setCurrentPage(1);
1574
+ }, [data]);
1575
+ React.useEffect(() => {
1576
+ setSelectedKeys(new Set(rowSelection?.selectedRowKeys || []));
1577
+ }, [rowSelection?.selectedRowKeys]);
1638
1578
  const handleItemsPerPageChange = React.useCallback((e) => {
1639
1579
  setLocalItemsPerPage(parseInt(e.target.value, 10));
1640
1580
  setCurrentPage(1);
@@ -1669,9 +1609,9 @@ function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10,
1669
1609
  if (bVal == null)
1670
1610
  return -1;
1671
1611
  // Handle strings (case-insensitive)
1672
- if (typeof aVal === 'string' && typeof bVal === 'string') {
1612
+ if (typeof aVal === "string" && typeof bVal === "string") {
1673
1613
  const comparison = aVal.localeCompare(bVal, undefined, {
1674
- sensitivity: 'base',
1614
+ sensitivity: "base",
1675
1615
  numeric: true
1676
1616
  });
1677
1617
  return comparison * (sortConfig.direction === "asc" ? 1 : -1);
@@ -1682,6 +1622,41 @@ function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10,
1682
1622
  }
1683
1623
  return dataCopy;
1684
1624
  }, [data, sortConfig]);
1625
+ const handleRowClick = React.useCallback((item, e) => {
1626
+ // Prevent selection if the expand button is clicked
1627
+ if (e.target.closest(".cw-table-col-expand")) {
1628
+ return;
1629
+ }
1630
+ const itemKey = item[rowKey];
1631
+ setSelectedKeys(prev => {
1632
+ const newSet = new Set(prev);
1633
+ if (rowSelection?.type === "single") {
1634
+ // Single mode: only one row selected
1635
+ if (newSet.has(itemKey)) {
1636
+ newSet.clear(); // Deselect if already selected
1637
+ }
1638
+ else {
1639
+ newSet.clear();
1640
+ newSet.add(itemKey);
1641
+ }
1642
+ }
1643
+ else {
1644
+ // Multiple mode: several rows
1645
+ if (newSet.has(itemKey)) {
1646
+ newSet.delete(itemKey);
1647
+ }
1648
+ else {
1649
+ newSet.add(itemKey);
1650
+ }
1651
+ }
1652
+ const selectedRows = sortedData.filter(item => newSet.has(item[rowKey]));
1653
+ // Run after render to avoid "Cannot update a component while rendering another component"
1654
+ setTimeout(() => {
1655
+ rowSelection?.onChange?.(Array.from(newSet), selectedRows);
1656
+ }, 0);
1657
+ return newSet;
1658
+ });
1659
+ }, [rowSelection, rowKey, sortedData]);
1685
1660
  const paginatedData = React.useMemo(() => {
1686
1661
  if (!sortedData)
1687
1662
  return [];
@@ -1723,7 +1698,7 @@ function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10,
1723
1698
  }, [stickyHeader, scrollHeight]);
1724
1699
  const getColSpan = () => columns.length + (expandedRowRender ? 1 : 0);
1725
1700
  const hasClassNameRow = (item) => {
1726
- return typeof item === 'object' && item !== null && 'classNameRow' in item;
1701
+ return typeof item === "object" && item !== null && "classNameRow" in item;
1727
1702
  };
1728
1703
  const renderTableBody = () => {
1729
1704
  if (loading) {
@@ -1736,7 +1711,15 @@ function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10,
1736
1711
  const itemKey = item[rowKey];
1737
1712
  if (!itemKey)
1738
1713
  console.warn("Missing row key for item", item);
1739
- return (jsxRuntime.jsxs(React.Fragment, { children: [jsxRuntime.jsxs("tr", { className: `${classNameRow ?? ""} ${hasClassNameRow(item) ? item.classNameRow : ""}`, children: [expandedRowRender && (jsxRuntime.jsx("td", { className: "cw-table-col-action cw-table-col-expand", children: jsxRuntime.jsx("button", { onClick: () => handleRowExpand(item), className: `cw-button-icon ${expandedRowKey === itemKey
1714
+ const isSelected = selectedKeys.has(itemKey);
1715
+ const dynamicClassName = typeof classNameRow === "function"
1716
+ ? classNameRow(item)
1717
+ : classNameRow ?? "";
1718
+ return (jsxRuntime.jsxs(React.Fragment, { children: [jsxRuntime.jsxs("tr", { className: `${dynamicClassName} ${hasClassNameRow(item) ? item.classNameRow : ""} ${isSelected ? "cw-table-row-selected" : ""}`, onClick: (e) => rowSelection && handleRowClick(item, e), style: {
1719
+ cursor: rowSelection ? "pointer" : "default",
1720
+ backgroundColor: isSelected ? "var(--cw-color-info-container)" : undefined,
1721
+ transition: "background-color 0.2s ease",
1722
+ }, children: [expandedRowRender && (jsxRuntime.jsx("td", { className: "cw-table-col-action cw-table-col-expand", children: jsxRuntime.jsx("button", { onClick: () => handleRowExpand(item), className: `cw-button-icon ${expandedRowKey === itemKey
1740
1723
  ? "cwi-chevron-down"
1741
1724
  : "cwi-chevron-right"}` }) })), columns.map(col => (jsxRuntime.jsx("td", { className: col.className ?? "", children: col.render ? col.render(item) : col.dataIndex ? String(item[col.dataIndex]) : "" }, `${itemKey}_${col.key}`)))] }), expandedRowRender && expandedRowKey === itemKey && (jsxRuntime.jsx("tr", { className: "cw-table-row-expanded", children: jsxRuntime.jsx("td", { colSpan: getColSpan(), children: expandedRowRender(item) }) }))] }, String(itemKey)));
1742
1725
  });
@@ -1753,9 +1736,11 @@ function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10,
1753
1736
  minWidth: 50,
1754
1737
  maxWidth: columnWidths[col.key] ?? col.width
1755
1738
  }),
1756
- }, children: [jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxRuntime.jsx("span", { children: col.title }), col.sortable && col.dataIndex && (jsxRuntime.jsx("span", { style: { fontSize: "12px", marginLeft: "6px" }, children: sortConfig.key !== col.dataIndex ? "↕" : sortConfig.direction === "asc"
1757
- ? ""
1758
- : "↓" }))] }), jsxRuntime.jsx("span", { onMouseDown: (e) => startResize(e, col.key), className: "th-column-resizer" })] }, col.key)))] }) }), jsxRuntime.jsx("tbody", { children: renderTableBody() })] }) }), pagination && totalPages > 1 && (jsxRuntime.jsxs("footer", { className: "cw-table-pagination", children: [jsxRuntime.jsx("button", { onClick: () => handlePageChange(1), disabled: currentPage === 1 || totalPages === 1, className: "cw-button-icon cwi-chevron-left-double", title: "First" }), jsxRuntime.jsx("button", { onClick: () => handlePageChange(currentPage - 1), disabled: currentPage === 1 || totalPages === 1, className: "cw-button-icon cwi-chevron-left", title: "Previous" }), jsxRuntime.jsx("input", { type: "text", inputMode: "numeric", value: currentPage, onChange: (e) => {
1739
+ }, children: [jsxRuntime.jsxs("div", { className: "cw-flex-row cw-align-between-center", children: [jsxRuntime.jsx("span", { children: col.title }), col.sortable && col.dataIndex && (jsxRuntime.jsx(CwIcon, { size: "large", iconId: sortConfig.key !== col.dataIndex
1740
+ ? "sortable"
1741
+ : sortConfig.direction === "asc"
1742
+ ? "sortable-asc"
1743
+ : "sortable-desc" }))] }), jsxRuntime.jsx("span", { onMouseDown: (e) => startResize(e, col.key), className: "th-column-resizer" })] }, col.key)))] }) }), jsxRuntime.jsx("tbody", { children: renderTableBody() })] }) }), pagination && totalPages > 1 && (jsxRuntime.jsxs("footer", { className: "cw-table-pagination", children: [jsxRuntime.jsx("button", { onClick: () => handlePageChange(1), disabled: currentPage === 1 || totalPages === 1, className: "cw-button-icon cwi-chevron-left-double", title: "First" }), jsxRuntime.jsx("button", { onClick: () => handlePageChange(currentPage - 1), disabled: currentPage === 1 || totalPages === 1, className: "cw-button-icon cwi-chevron-left", title: "Previous" }), jsxRuntime.jsx("input", { type: "text", inputMode: "numeric", value: currentPage, onChange: (e) => {
1759
1744
  const value = parseInt(e.target.value, 10);
1760
1745
  if (!isNaN(value))
1761
1746
  handlePageChange(value);
@@ -1767,7 +1752,7 @@ function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10,
1767
1752
  }, min: 1, max: totalPages }), jsxRuntime.jsxs("span", { children: ["of ", totalPages] }), jsxRuntime.jsx("button", { onClick: () => handlePageChange(currentPage + 1), disabled: currentPage === totalPages || totalPages === 1, className: "cw-button-icon cwi-chevron-right", title: "Next" }), jsxRuntime.jsx("button", { onClick: () => handlePageChange(totalPages), disabled: currentPage === totalPages || totalPages === 1, className: "cw-button-icon cwi-chevron-right-double", title: "Last" }), jsxRuntime.jsx("select", { value: localItemsPerPage, onChange: handleItemsPerPageChange, children: pageSizeOptions.map(size => (jsxRuntime.jsxs("option", { value: size, children: [size, " / page"] }, size))) })] }))] }));
1768
1753
  }
1769
1754
 
1770
- var styles$e = {"cw-tabs":"cw-tabs-module_cw-tabs__1pmji","cw-tabs-content":"cw-tabs-module_cw-tabs-content__HTp8d"};
1755
+ var styles$e = {"cw-tabs":"cw-tabs-module_cw-tabs__1pmji","badge":"cw-tabs-module_badge__AmVxW","cw-tabs-content":"cw-tabs-module_cw-tabs-content__HTp8d"};
1771
1756
 
1772
1757
  const TabIcon = ({ icon }) => {
1773
1758
  if (!icon)
@@ -1817,7 +1802,7 @@ function CwTabs(CwTabsProps) {
1817
1802
  const tabsListStyle = position === 'left' && CwTabsProps.tabsListWidth
1818
1803
  ? { minWidth: CwTabsProps.tabsListWidth }
1819
1804
  : undefined;
1820
- return (jsxRuntime.jsxs("div", { id: CwTabsProps.id, className: styles$e['cw-tabs'], style: CwTabsProps.style, "data-tabs-position": position, children: [jsxRuntime.jsx("ul", { style: tabsListStyle, children: CwTabsProps.tabs.map(tab => (jsxRuntime.jsxs("li", { className: `${tab.key === activeTab ? "cw-tab-active" : ""}`, onClick: () => handleTabClick(tab), "data-active": tab.key === activeTab, children: [jsxRuntime.jsx(TabIcon, { icon: tab.icon }), tab.title] }, tab.key))) }), jsxRuntime.jsx("div", { className: styles$e['cw-tabs-content'], children: activeTab !== null && CwTabsProps.tabs.find(tab => tab.key === activeTab)?.content })] }));
1805
+ return (jsxRuntime.jsxs("div", { id: CwTabsProps.id, className: styles$e['cw-tabs'], style: CwTabsProps.style, "data-tabs-position": position, children: [jsxRuntime.jsx("ul", { style: tabsListStyle, children: CwTabsProps.tabs.map(tab => (jsxRuntime.jsxs("li", { className: `${tab.key === activeTab ? "cw-tab-active" : ""}`, onClick: () => handleTabClick(tab), "data-active": tab.key === activeTab, children: [jsxRuntime.jsx(TabIcon, { icon: tab.icon }), tab.title, tab.badge !== undefined && (jsxRuntime.jsx("span", { className: styles$e['badge'], style: tab.badgeColor ? { backgroundColor: tab.badgeColor, color: getContrastColor(tab.badgeColor) } : undefined, children: tab.badge }))] }, tab.key))) }), jsxRuntime.jsx("div", { className: styles$e['cw-tabs-content'], children: activeTab !== null && CwTabsProps.tabs.find(tab => tab.key === activeTab)?.content })] }));
1821
1806
  }
1822
1807
 
1823
1808
  /**
@@ -2118,6 +2103,10 @@ var styles$c = {"fileUploadContainer":"cw-file-upload-multiple-module_fileUpload
2118
2103
  function CwFileUploadMultiple(fileUploadProps) {
2119
2104
  const fileInputRef = React.useRef(null);
2120
2105
  const [selectedFiles, setSelectedFiles] = React.useState([]);
2106
+ const [existingFile, setExistingFile] = React.useState(fileUploadProps.initialFileName);
2107
+ React.useEffect(() => {
2108
+ setExistingFile(fileUploadProps.initialFileName);
2109
+ }, [fileUploadProps.initialFileName]);
2121
2110
  const getFileExtension = (filename) => {
2122
2111
  return filename.split('.').pop()?.toUpperCase() || '';
2123
2112
  };
@@ -2222,6 +2211,10 @@ function CwFileUploadMultiple(fileUploadProps) {
2222
2211
  }
2223
2212
  }
2224
2213
  };
2214
+ const handleFileSelectInternal = (event) => {
2215
+ setExistingFile(undefined);
2216
+ handleFileSelect(event);
2217
+ };
2225
2218
  const removeFile = (indexToRemove) => {
2226
2219
  const newFiles = selectedFiles.filter((_, index) => index !== indexToRemove);
2227
2220
  setSelectedFiles(newFiles);
@@ -2248,6 +2241,7 @@ function CwFileUploadMultiple(fileUploadProps) {
2248
2241
  event.stopPropagation();
2249
2242
  const files = event.dataTransfer.files;
2250
2243
  if (files && files.length > 0) {
2244
+ setExistingFile(undefined);
2251
2245
  const updatedFiles = processFiles(files, selectedFiles);
2252
2246
  if (updatedFiles.length > selectedFiles.length || !fileUploadProps.multiple) {
2253
2247
  setSelectedFiles(updatedFiles);
@@ -2255,7 +2249,12 @@ function CwFileUploadMultiple(fileUploadProps) {
2255
2249
  }
2256
2250
  }
2257
2251
  };
2258
- return (jsxRuntime.jsxs("div", { className: `${styles$c.fileUploadContainer} ${fileUploadProps.className}`, children: [jsxRuntime.jsx("input", { ref: fileInputRef, type: "file", name: fileUploadProps.name, accept: fileUploadProps.accept, multiple: fileUploadProps.multiple, onChange: handleFileSelect, disabled: fileUploadProps.disabled, "aria-label": "files", className: styles$c.hiddenInput }), selectedFiles.length === 0 ? (jsxRuntime.jsxs("div", { className: `${styles$c.uploadArea} ${fileUploadProps.disabled ? styles$c.uploadAreaDisabled : ''}`, onDragOver: handleDragOver, onDrop: handleDrop, onClick: !fileUploadProps.disabled ? handleButtonClick : undefined, children: [jsxRuntime.jsx(CwIcon, { iconId: "upload" }), jsxRuntime.jsx("p", { className: `${styles$c.uploadTitle}`, children: fileUploadProps.disabled ? 'Upload disabled' : 'Click to upload or drag and drop' }), jsxRuntime.jsxs("p", { className: `${styles$c.uploadSubtitle}`, children: [fileUploadProps.accept ? `Accepted files: ${fileUploadProps.accept}` : 'All file types accepted', !fileUploadProps.multiple && ' (Single file only)'] })] })) : (jsxRuntime.jsxs("div", { className: styles$c.filesContainer, children: [jsxRuntime.jsxs("div", { className: "cw-flex-row cw-align-between-center", children: [jsxRuntime.jsxs("small", { className: styles$c.filesCount, children: [selectedFiles.length, " file", selectedFiles.length !== 1 ? 's' : '', " selected"] }), jsxRuntime.jsx(CwButton, { onClick: removeAllFiles, disabled: fileUploadProps.disabled, color: "danger", variant: "outline", icon: "delete", text: "Clear all" })] }), selectedFiles.map((file, index) => (jsxRuntime.jsxs("div", { className: styles$c.fileItem, children: [jsxRuntime.jsxs("div", { className: styles$c.fileIcon, children: [jsxRuntime.jsx(CwIcon, { iconId: "page" }), jsxRuntime.jsx("span", { className: styles$c.fileExtension, children: getFileExtension(file.name) })] }), jsxRuntime.jsxs("div", { className: styles$c.fileInfo, children: [jsxRuntime.jsx("p", { className: styles$c.fileName, children: file.name }), jsxRuntime.jsxs("p", { className: styles$c.fileSize, children: [(file.size / 1024).toFixed(1), " KB"] })] }), jsxRuntime.jsx(CwButton, { variant: "icon", icon: "close", color: "neutral", onClick: () => removeFile(index), className: styles$c.smallButton })] }, index))), fileUploadProps.multiple && (jsxRuntime.jsx(CwButton, { text: "Add More Files", icon: "plus", variant: "outline", onClick: handleButtonClick, disabled: fileUploadProps.disabled })), !fileUploadProps.multiple && (jsxRuntime.jsx(CwButton, { text: "Change File", icon: "refresh", onClick: handleButtonClick, disabled: fileUploadProps.disabled }))] }))] }));
2252
+ return (jsxRuntime.jsxs("div", { className: `${styles$c.fileUploadContainer} ${fileUploadProps.className}`, children: [jsxRuntime.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$c.hiddenInput }), selectedFiles.length === 0 && !existingFile ? (jsxRuntime.jsxs("div", { className: `${styles$c.uploadArea} ${fileUploadProps.disabled ? styles$c.uploadAreaDisabled : ''}`, onDragOver: handleDragOver, onDrop: handleDrop, onClick: !fileUploadProps.disabled ? handleButtonClick : undefined, children: [jsxRuntime.jsx(CwIcon, { iconId: "upload" }), jsxRuntime.jsx("p", { className: `${styles$c.uploadTitle}`, children: fileUploadProps.disabled ? 'Upload disabled' : 'Click to upload or drag and drop' }), jsxRuntime.jsxs("p", { className: `${styles$c.uploadSubtitle}`, children: [fileUploadProps.accept ? `Accepted files: ${fileUploadProps.accept}` : 'All file types accepted', !fileUploadProps.multiple && ' (Single file only)'] })] })) : selectedFiles.length === 0 && existingFile ? (jsxRuntime.jsxs("div", { className: styles$c.filesContainer, children: [jsxRuntime.jsxs("div", { className: styles$c.fileItem, children: [jsxRuntime.jsxs("div", { className: styles$c.fileIcon, children: [jsxRuntime.jsx(CwIcon, { iconId: "page" }), jsxRuntime.jsx("span", { className: styles$c.fileExtension, children: getFileExtension(existingFile) })] }), jsxRuntime.jsx("div", { className: styles$c.fileInfo, children: jsxRuntime.jsx("p", { className: styles$c.fileName, children: existingFile }) }), jsxRuntime.jsx(CwButton, { variant: "icon", icon: "close", color: "neutral", onClick: () => {
2253
+ setExistingFile(undefined);
2254
+ if (fileUploadProps.onSelect) {
2255
+ fileUploadProps.onSelect(null);
2256
+ }
2257
+ }, disabled: fileUploadProps.disabled, className: styles$c.smallButton })] }), jsxRuntime.jsx(CwButton, { text: "Change File", icon: "refresh", onClick: handleButtonClick, disabled: fileUploadProps.disabled })] })) : (jsxRuntime.jsxs("div", { className: styles$c.filesContainer, children: [jsxRuntime.jsxs("div", { className: "cw-flex-row cw-align-between-center", children: [jsxRuntime.jsxs("small", { className: styles$c.filesCount, children: [selectedFiles.length, " file", selectedFiles.length !== 1 ? 's' : '', " selected"] }), jsxRuntime.jsx(CwButton, { onClick: removeAllFiles, disabled: fileUploadProps.disabled, color: "danger", variant: "outline", icon: "delete", text: "Clear all" })] }), selectedFiles.map((file, index) => (jsxRuntime.jsxs("div", { className: styles$c.fileItem, children: [jsxRuntime.jsxs("div", { className: styles$c.fileIcon, children: [jsxRuntime.jsx(CwIcon, { iconId: "page" }), jsxRuntime.jsx("span", { className: styles$c.fileExtension, children: getFileExtension(file.name) })] }), jsxRuntime.jsxs("div", { className: styles$c.fileInfo, children: [jsxRuntime.jsx("p", { className: styles$c.fileName, children: file.name }), jsxRuntime.jsxs("p", { className: styles$c.fileSize, children: [(file.size / 1024).toFixed(1), " KB"] })] }), jsxRuntime.jsx(CwButton, { variant: "icon", icon: "close", color: "neutral", onClick: () => removeFile(index), className: styles$c.smallButton })] }, index))), fileUploadProps.multiple && (jsxRuntime.jsx(CwButton, { text: "Add More Files", icon: "plus", variant: "outline", onClick: handleButtonClick, disabled: fileUploadProps.disabled })), !fileUploadProps.multiple && (jsxRuntime.jsx(CwButton, { text: "Change File", icon: "refresh", onClick: handleButtonClick, disabled: fileUploadProps.disabled }))] }))] }));
2259
2258
  }
2260
2259
 
2261
2260
  function CwInput(CwInputProps) {
@@ -2671,7 +2670,7 @@ function CwInputText(props) {
2671
2670
  const containerClassName = className
2672
2671
  ? `cw-input-text ${className}`
2673
2672
  : "cw-input-text";
2674
- return (jsxRuntime.jsx("div", { className: containerClassName, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: inputProps.required === true ? "required" : "", children: [labelProps && (jsxRuntime.jsxs(CwLabel, { ...labelProps, children: [iconProps && jsxRuntime.jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxRuntime.jsx("input", { type: props.type ?? "text", ...inputProps }), buttonProps && jsxRuntime.jsx(CwButton, { ...buttonProps })] }) }));
2673
+ return (jsxRuntime.jsx("div", { className: containerClassName, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: inputProps.required === true ? "required" : "", children: [labelProps && (jsxRuntime.jsxs(CwLabel, { ...labelProps, children: [iconProps && jsxRuntime.jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxRuntime.jsxs("div", { className: "cw-input-button", children: [jsxRuntime.jsx("input", { type: props.type ?? "text", ...inputProps }), buttonProps && jsxRuntime.jsx(CwButton, { ...buttonProps })] })] }) }));
2675
2674
  }
2676
2675
 
2677
2676
  /**
@@ -3296,9 +3295,9 @@ function CwCheckbox(CwCheckboxProps) {
3296
3295
  }
3297
3296
 
3298
3297
  function CwToggle(props) {
3299
- const { labelProps, labelText, iconProps, alignment = "row", className, ...inputProps } = props;
3298
+ const { labelProps, labelText, iconProps, alignment = "row", className, style, ...inputProps } = props;
3300
3299
  const displayText = labelText || labelProps?.text;
3301
- return (jsxRuntime.jsx("div", { className: `cw-toggle${className ? ` ${className}` : ''}`, children: jsxRuntime.jsxs("label", { className: "cw-toggle-label", "data-direction": alignment, children: [displayText && (jsxRuntime.jsxs("span", { className: "cw-icon-text", children: [iconProps && jsxRuntime.jsx(CwIcon, { ...iconProps }), displayText] })), jsxRuntime.jsx("input", {
3300
+ return (jsxRuntime.jsx("div", { className: `cw-toggle ${className ? ` ${className}` : ''}`, style: style, children: jsxRuntime.jsxs("label", { className: "cw-toggle-label", "data-direction": alignment, children: [displayText && (jsxRuntime.jsxs("span", { className: "cw-icon-text", children: [iconProps && jsxRuntime.jsx(CwIcon, { ...iconProps }), displayText] })), jsxRuntime.jsx("input", {
3302
3301
  //data-color={color}
3303
3302
  type: "checkbox", ...inputProps })] }) }));
3304
3303
  }
@@ -3344,64 +3343,10 @@ function CwOption(props) {
3344
3343
  * </CwSelect>
3345
3344
  */
3346
3345
  function CwSelect(props) {
3347
- const { alignProps, labelProps, buttonProps, iconProps, placeholder, children, ...selectProps } = props;
3346
+ const { alignProps, labelProps, buttonProps, iconProps, placeholder, children, style, ...selectProps } = props;
3348
3347
  const flexDirection = alignProps?.flexDirection;
3349
3348
  const dataDirection = flexDirection ? { 'data-direction': flexDirection } : {};
3350
- return (jsxRuntime.jsx("div", { className: "cw-select", ...dataDirection, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: selectProps.required === true ? "required" : "", children: [labelProps && (jsxRuntime.jsxs(CwLabel, { ...labelProps, children: [iconProps && jsxRuntime.jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxRuntime.jsxs("select", { ...selectProps, children: [placeholder && jsxRuntime.jsx(CwOption, { value: "", children: placeholder }), children] }), buttonProps && jsxRuntime.jsx(CwButton, { ...buttonProps })] }) }));
3351
- }
3352
-
3353
- function CwDropdown(optionsProps) {
3354
- const [selectedOption, setSelectedOption] = React.useState(optionsProps.defaultSelected || "");
3355
- React.useEffect(() => {
3356
- if (optionsProps.defaultSelected !== undefined && optionsProps.defaultSelected !== selectedOption) {
3357
- setSelectedOption(optionsProps.defaultSelected);
3358
- if (optionsProps.handleChange) {
3359
- optionsProps.handleChange(optionsProps.defaultSelected);
3360
- }
3361
- }
3362
- }, [optionsProps.defaultSelected, selectedOption, optionsProps.handleChange]);
3363
- const handleOptionSelect = (event) => {
3364
- const selectedValue = event.target.value;
3365
- setSelectedOption(selectedValue);
3366
- if (optionsProps.handleChange) {
3367
- optionsProps.handleChange(selectedValue);
3368
- }
3369
- };
3370
- return (jsxRuntime.jsxs("div", { className: optionsProps.labelPosition === "inline"
3371
- ? "cwellt_flex cwellt_flex_row cwellt_align_items_center cwDropDownComp" + " " + optionsProps.className
3372
- : optionsProps.labelPosition === "column"
3373
- ? "cwellt_flex cwellt_flex_column cwellt_align-items_baseline cwDropDownComp" + " " + optionsProps.className
3374
- : "cwellt_flex cwellt_flex_row cwellt_align_items_center cwDropDownComp" + " " + optionsProps.className, style: optionsProps.style, id: optionsProps.id, children: [jsxRuntime.jsx("label", { className: optionsProps.disabled === true
3375
- ? "cw_label_text cw_label_text_disabled" + " " + optionsProps.labelClassName
3376
- : "cw_label_text" + " " + optionsProps.labelClassName, children: optionsProps.labelName }), jsxRuntime.jsx("select", { value: selectedOption, onChange: handleOptionSelect, className: "cw_select", style: optionsProps.styleSelect, disabled: optionsProps.disabled || optionsProps.selectList.length === 0, children: optionsProps.selectList.length === 0 ? (jsxRuntime.jsx("option", { value: "", className: "cw_option", disabled: true, children: "No data" })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("option", { value: "", className: "cw_option", children: optionsProps.placeholder }), optionsProps.selectList.map(option => (jsxRuntime.jsx("option", { value: option.id, className: "cw_option", style: optionsProps.styleOption, children: option.description }, option.id)))] })) })] }));
3377
- }
3378
-
3379
- function CwDropdownContainer(dropDownContainerProps) {
3380
- // #region
3381
- // - Ref dropDownContainer
3382
- const dropDownContainer_ref = React__namespace.createRef();
3383
- // - Ref list container
3384
- const dropDown_listContainer = React__namespace.createRef();
3385
- // #endregion
3386
- // #region Functions
3387
- const onKeyPressDropDownContainer = (event_keyDown) => {
3388
- dropDownContainerProps.onKeyDownDropDownContainer(event_keyDown);
3389
- };
3390
- const onMouseLeaveDropDownContainer = (event_onMouseLeave) => {
3391
- if (typeof dropDownContainerProps.onMouseLeaveDropDownContainer === "function") {
3392
- dropDownContainerProps.onMouseLeaveDropDownContainer(event_onMouseLeave);
3393
- }
3394
- };
3395
- // #endregion
3396
- // #region UseEffect
3397
- React.useEffect(() => {
3398
- window.addEventListener("keydown", onKeyPressDropDownContainer);
3399
- return () => {
3400
- window.removeEventListener("keydown", onKeyPressDropDownContainer);
3401
- };
3402
- }, []);
3403
- // #endregion
3404
- return (jsxRuntime.jsx("div", { className: `cw-dropdown-container ${dropDownContainerProps.className || ''}`, onKeyDown: onKeyPressDropDownContainer, onMouseLeave: onMouseLeaveDropDownContainer, tabIndex: 0, hidden: !dropDownContainerProps.dropDownState, children: jsxRuntime.jsx("div", { className: "cw-dropdown-list", id: dropDownContainerProps.idDropDownContainer, ref: dropDownContainer_ref, children: jsxRuntime.jsx("div", { ref: dropDown_listContainer, children: dropDownContainerProps.children }) }) }));
3349
+ return (jsxRuntime.jsx("div", { className: "cw-select", ...dataDirection, style: style, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: selectProps.required === true ? "required" : "", children: [labelProps && (jsxRuntime.jsxs(CwLabel, { ...labelProps, children: [iconProps && jsxRuntime.jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxRuntime.jsxs("select", { ...selectProps, children: [placeholder && jsxRuntime.jsx(CwOption, { value: "", children: placeholder }), children] }), buttonProps && jsxRuntime.jsx(CwButton, { ...buttonProps })] }) }));
3405
3350
  }
3406
3351
 
3407
3352
  function CwDropdownFilter(props) {
@@ -3414,103 +3359,6 @@ function CwDropdownFilter(props) {
3414
3359
  return (jsxRuntime.jsxs("div", { id: props.IdContent, className: containerClassName, children: [props.children, isVisible && (jsxRuntime.jsx("nav", { className: "cw-dropdown-menu", style: inlineStyles, onMouseLeave: props.onMouseLeave, id: props.idDropDownFilter, role: "menu", children: jsxRuntime.jsx("ul", { role: "none", children: props.DataSourceDropDownItem?.map((item) => (jsxRuntime.jsx("li", { id: item.IdDropDown_filter, role: "menuitem", children: item.dropDownFilter_desc }, item.IdDropDown_filter))) }) }))] }));
3415
3360
  }
3416
3361
 
3417
- const { Option, OptGroup } = antd.Select;
3418
- class MultiSelect extends React__namespace.Component {
3419
- constructor(Props) {
3420
- super(Props);
3421
- this.state = {
3422
- selected: null,
3423
- isVisibleDropDown: false,
3424
- activeClassName: ""
3425
- };
3426
- }
3427
- componentDidMount() {
3428
- this.setState({
3429
- selected: this.props.selectedItems?.map((s) => ({
3430
- type: s.type,
3431
- id: s.id,
3432
- despription: s.despription,
3433
- color: s.color
3434
- }))
3435
- });
3436
- this.onClickSelect = this.onClickSelect.bind(this);
3437
- }
3438
- onClickSelect = () => {
3439
- this.setState({
3440
- isVisibleDropDown: !this.state.isVisibleDropDown
3441
- });
3442
- this.setState({
3443
- activeClassName: "cwelltSelectDropDown_active"
3444
- });
3445
- };
3446
- handleOnDropDownVisibleChange = () => {
3447
- const dropDown_content = document.getElementsByClassName("cwelltSelectDropDown");
3448
- for (let i = 0; i <= dropDown_content.length; i++) {
3449
- dropDown_content[i]?.addEventListener("mouseleave", () => {
3450
- this.setState({
3451
- isVisibleDropDown: false
3452
- });
3453
- });
3454
- }
3455
- };
3456
- onKeyUpSelect = (e_KeyUp_select) => {
3457
- if (e_KeyUp_select.key === "Enter" || e_KeyUp_select.key === "Escape") {
3458
- this.setState({
3459
- isVisibleDropDown: false
3460
- });
3461
- }
3462
- else {
3463
- this.setState({
3464
- isVisibleDropDown: true
3465
- });
3466
- }
3467
- };
3468
- // mouseHover dropDown active
3469
- onMouseHoverDropDownActive = () => {
3470
- const dropDown_active = document.getElementsByClassName("cwelltSelectDropDown_active");
3471
- const itemArray = () => {
3472
- Array.from(dropDown_active).forEach(index => {
3473
- const dropDown = index;
3474
- dropDown.addEventListener("mouseover", () => { });
3475
- });
3476
- return true;
3477
- };
3478
- if (dropDown_active.length > 0 && itemArray()) {
3479
- return true;
3480
- }
3481
- else {
3482
- return false;
3483
- }
3484
- };
3485
- // clicl cwelltDropDown
3486
- onMouseLeaveMultiSelect = (event_mouseLeave) => {
3487
- const post = event_mouseLeave.currentTarget.getBoundingClientRect();
3488
- const posCursorY = event_mouseLeave.clientY;
3489
- if (posCursorY > post.bottom && this.state.isVisibleDropDown === true) {
3490
- this.setState({
3491
- isVisibleDropDown: true
3492
- });
3493
- }
3494
- else {
3495
- this.setState({
3496
- isVisibleDropDown: false
3497
- });
3498
- }
3499
- };
3500
- render() {
3501
- return (jsxRuntime.jsx("div", { style: {
3502
- display: "flex",
3503
- flexDirection: "row",
3504
- alignItems: "flexStart",
3505
- width: "100%"
3506
- }, id: "contentMultiSelect", onMouseLeave: e => this.onMouseLeaveMultiSelect(e), children: jsxRuntime.jsx("div", { style: { flex: 1 }, children: jsxRuntime.jsx(antd.Select, { autoClearSearchValue: true, mode: "multiple", allowClear: true, style: { width: "100%" }, onChange: this.props.handleChange, optionFilterProp: "description", virtual: true, showArrow: true, size: "middle", className: this.props.selectedItems?.length === 0
3507
- ? "cwelltMultiSelect cwelltSelect cwelltSelectSimple cwelltMultiSelect_searchIcon"
3508
- : "cwelltMultiSelect cwelltSelect cwelltSelectSimple", placeholder: "Search or filter...", dropdownClassName: this.state.isVisibleDropDown
3509
- ? " cwelltSelectDropDown cwelltSelectDropDown_active"
3510
- : "cwelltSelectDropDown", value: this.props.selectedItems?.map(s => s.type + "_" + s.id), onClick: () => this.onClickSelect(), open: this.state.isVisibleDropDown, onDropdownVisibleChange: () => this.handleOnDropDownVisibleChange(), onKeyUp: e_KeyUp_select => this.onKeyUpSelect(e_KeyUp_select), children: this.props.selectLists.map((slArray, i) => (jsxRuntime.jsx(OptGroup, { label: slArray.length > 0 ? slArray[0]?.type : "", children: slArray.map(sl => (jsxRuntime.jsx(Option, { value: sl.type + "_" + sl.id, type: sl.type, description: sl.description, val: sl.id, children: jsxRuntime.jsx(antd.Tag, { color: sl.color, children: sl.description }) }, sl.type + "_" + sl.id))) }, "_" + i))) }) }) }));
3511
- }
3512
- }
3513
-
3514
3362
  function itemsToMultiFilterTags(items, nameKey, valueKey, category, primaryColor, onPrimaryColor) {
3515
3363
  const result = new Set();
3516
3364
  items.forEach((item, index) => {
@@ -3526,519 +3374,20 @@ function itemsToMultiFilterTags(items, nameKey, valueKey, category, primaryColor
3526
3374
  return result;
3527
3375
  }
3528
3376
 
3529
- function CwHeadFilter(cwelltFilterTabMultiSelectProps) {
3530
- // - Reference div content input search
3531
- const headContent_ref = React__namespace.createRef();
3532
- const optionList = document.getElementsByClassName("cw-multiselect-option-list");
3533
- const refContent = React.useRef(null);
3534
- // - Hooks show clear button
3535
- const [_isShowClearButton, setShowClearButton] = React.useState(false);
3536
- // - Hooks value of input search
3537
- const [inputValue, setInputValue] = React.useState("");
3538
- // Ref [ input ] ( cwellt_headFilterTab )
3539
- const headInputFitlerTab_ref = React.useRef(null);
3540
- const headFilter_content_tags_ref = React.useRef(null);
3541
- // cwellt_headFilterTab [ onclick ( show dropDown and enable input .focus() )]
3542
- const onClickHeaderFilterTab = () => {
3543
- // Show and hide dropDownContainer - onShowDropDown [ interface ]
3544
- cwelltFilterTabMultiSelectProps.onShowDropDown();
3545
- // Click on dropDown enable input - [ ref : headFitlerTab_ref ] and evaluating not null
3546
- if (headInputFitlerTab_ref.current) {
3547
- headInputFitlerTab_ref.current.focus();
3548
- }
3549
- };
3550
- // - on change input search
3551
- const onChangeInputSearch = (event_onChangeInput) => {
3552
- // let searchInput_length = event_onChangeInput.currentTarget.value.length;
3553
- // if (searchInput_length > 0) {
3554
- // setShowClearButton(true);
3555
- // } else {
3556
- // setShowClearButton(false);
3557
- // }
3558
- setInputValue(event_onChangeInput.currentTarget.value);
3559
- // - onChangeSearch
3560
- cwelltFilterTabMultiSelectProps.onChangeSearch(event_onChangeInput);
3561
- };
3562
- // - clear input value
3563
- const onClearInputValue = (e) => {
3564
- setInputValue("");
3565
- setShowClearButton(false);
3566
- // onClearValue
3567
- cwelltFilterTabMultiSelectProps.onClearValue(e);
3568
- };
3569
- // - onKeyPress
3570
- const onKeyPressInput = (event_keyPress) => {
3571
- if (typeof cwelltFilterTabMultiSelectProps.onKeypressInput === "function") {
3572
- cwelltFilterTabMultiSelectProps.onKeypressInput(event_keyPress);
3573
- // clear input field
3574
- if (event_keyPress.key === "Enter") {
3575
- setInputValue("");
3576
- }
3577
- }
3578
- };
3579
- const handleBlur = (event) => {
3580
- if (typeof cwelltFilterTabMultiSelectProps.onBlur === "function") {
3581
- cwelltFilterTabMultiSelectProps.onBlur(event);
3582
- }
3583
- };
3584
- const clickOptionList = () => {
3585
- if (optionList.length > 0) {
3586
- Array.from(optionList).forEach(index => {
3587
- const optionListItem = index;
3588
- optionListItem.addEventListener("click", () => {
3589
- setInputValue("");
3590
- });
3591
- });
3592
- }
3593
- };
3594
- //#region useEffect
3595
- React.useEffect(() => {
3596
- window.addEventListener("keypress", onKeyPressInput);
3597
- clickOptionList();
3598
- return () => {
3599
- window.removeEventListener("keypress", onKeyPressInput);
3600
- };
3601
- });
3602
- //#endregion
3603
- return (jsxRuntime.jsxs("div", { className: cwelltFilterTabMultiSelectProps.className + " cw-headfilter", style: cwelltFilterTabMultiSelectProps.style, id: cwelltFilterTabMultiSelectProps.Id, onMouseLeave: cwelltFilterTabMultiSelectProps.onMouseLeave, ref: refContent, children: [jsxRuntime.jsxs("div", { className: "cw-headfilter-wrapper", onClick: () => onClickHeaderFilterTab(), children: [jsxRuntime.jsx(CwIcon, { iconId: "search", size: "large" }), jsxRuntime.jsxs("div", { className: "cw-headfilter-content", children: [jsxRuntime.jsx("div", { className: "cw-flex-row cw-gap-small cw-align-left-center cw-flex-wrap", ref: headFilter_content_tags_ref, children: cwelltFilterTabMultiSelectProps.tagValueContent }), jsxRuntime.jsx("div", { className: "headFilter_search_content", ref: headContent_ref, children: jsxRuntime.jsx("input", { id: "headFilter_inputSearch", value: inputValue, onKeyPress: event_keyPress => onKeyPressInput(event_keyPress), onBlur: handleBlur, type: "search", onChange: event_onChangeInput => onChangeInputSearch(event_onChangeInput), placeholder: cwelltFilterTabMultiSelectProps.placeholder_desc, ref: headInputFitlerTab_ref }) })] }), jsxRuntime.jsx(CwIcon, { iconId: "close-circle", onClick: (e) => onClearInputValue(e) })] }), cwelltFilterTabMultiSelectProps.children] }));
3604
- }
3605
-
3606
- function CwOptionList(optionListProps) {
3607
- //#region References
3608
- // - Ref : optionList
3609
- const optionListSelected_ref = React__namespace.createRef();
3610
- const optionListSelected_input_ref = React__namespace.createRef();
3611
- //#endregion
3612
- //#region Hooks
3613
- // - Hooks : selected optionList
3614
- // const [isSelectedOptionList, setIsSelectedOptionList] = useState(optionListProps.isSelected || false);
3615
- //#endregion
3616
- //#region Functions
3617
- const onClickSelectOptionList = (event_click) => {
3618
- // - click of custom component
3619
- // onSelectedOptionList();
3620
- // - click of property interface
3621
- optionListProps.onClick(event_click);
3622
- };
3623
- const onKeyPressOptionList = (event_onKeyPress) => {
3624
- if (typeof optionListProps.onKeyPress === "function") {
3625
- optionListProps.onKeyPress(event_onKeyPress);
3626
- }
3627
- };
3628
- //#endregion
3629
- //#region Useffect
3630
- React.useEffect(() => {
3631
- window.addEventListener("keypress", onKeyPressOptionList);
3632
- return () => {
3633
- window.removeEventListener("keypress", onKeyPressOptionList);
3634
- };
3635
- }, []);
3636
- //#endregion
3637
- return (jsxRuntime.jsxs("div", { className: `cw-multiselect-option-list${optionListProps.isSelected ? ' option-active' : ''}`, onClick: event_click => onClickSelectOptionList(event_click), id: optionListProps.idOptionList, ref: optionListSelected_ref, "aria-value-text": optionListProps.value, onKeyPress: event_onKeyPress => onKeyPressOptionList(event_onKeyPress), style: optionListProps.style, children: [jsxRuntime.jsx("label", { htmlFor: optionListProps.idOptionList, children: optionListProps.children }), jsxRuntime.jsx("input", { type: "checkbox", value: optionListProps.value, ref: optionListSelected_input_ref, id: optionListProps.idOptionList, onClick: optionListProps.onChangeOptionList })] }));
3638
- }
3639
-
3640
- //#endregion
3641
- function CwMultiselect(CwelltCustomFilterTabProps) {
3642
- //#region Reference
3643
- const refOptionListContent = React.useRef(null);
3644
- const containerRef = React.useRef(null);
3645
- //#endregion
3646
- //#region Hooks
3647
- const [isShowDropDownfiltered, setShowDropDownfiltered] = React.useState(false);
3648
- // const [tagValue, setTagValue] = useState<{
3649
- // tagDesc: string;
3650
- // bgContent: string;
3651
- // bgTag: string;
3652
- // color: string;
3653
- // }[]>([]);
3654
- // Hook active label filter item tab [ All ]
3655
- const [isActive_filter_item_all, setActive_filter_item_all] = React.useState(true);
3656
- // Hook active laberl fitler item tab [ e.g.: Duty ]
3657
- const [isActive_filter_item, setActive_filter_item] = React.useState(null);
3658
- // Hook isSelected option list
3659
- //const [isSelected_optionList, setSelected_optionList] = useState<{ [key: string]: boolean }>({});
3660
- //#endregion
3661
- //#region Functions
3662
- //#region CwelltFilterTabMultiSelect [ properties functions ]
3663
- //#region onClearValue
3664
- const clearValue = (e_clear) => {
3665
- // List items to remove class and be visible
3666
- // Item searched
3667
- const itemSearched = document.getElementsByClassName("item-search");
3668
- // Item hidden
3669
- const itemHidden = document.getElementsByClassName("hidden-item");
3670
- // Item searcched
3671
- if (itemSearched.length > 0) {
3672
- for (let i = 0; i <= itemSearched.length; i++) {
3673
- itemSearched[i]?.classList.remove("item-search");
3674
- }
3675
- }
3676
- // Item hidden
3677
- if (itemHidden.length > 0) {
3678
- for (let i = 0; i <= itemHidden.length; i++) {
3679
- itemHidden[i]?.classList.remove("hidden-item");
3680
- }
3681
- }
3682
- // optionList [ disbaled active className according their text ]
3683
- const parent = e_clear.currentTarget.parentElement.parentElement;
3684
- const optionActive = parent.getElementsByClassName("option-active");
3685
- const valueIds = [];
3686
- const resultList = [];
3687
- if (optionActive.length > 0) {
3688
- CwelltCustomFilterTabProps.onclickHandleChange(valueIds, resultList);
3689
- Array.from(optionActive).forEach(index => {
3690
- const optionActive_array = index;
3691
- optionActive_array.classList.remove("option-active");
3692
- });
3693
- }
3694
- };
3695
- //#endregion
3696
- //#region onChangeSearch
3697
- const onChangeSearch = (e_onchange) => {
3698
- const filterText_lowerCase = e_onchange.currentTarget.value.toLowerCase();
3699
- // Tags for filtering
3700
- const listTag = document.getElementsByClassName("cw-multiselect-option-list");
3701
- for (let i = 0; i <= listTag.length; i++) {
3702
- if (listTag[i] !== undefined) {
3703
- const textTagValue = listTag[i].textContent;
3704
- // Writting
3705
- if (textTagValue?.toLowerCase().includes(filterText_lowerCase)) {
3706
- listTag[i].classList.add("item-search");
3707
- }
3708
- else {
3709
- listTag[i].classList.add("hidden-item");
3710
- }
3711
- // remove written
3712
- if (!textTagValue?.toLowerCase().includes(filterText_lowerCase)) {
3713
- listTag[i].classList.remove("item-search");
3714
- }
3715
- else {
3716
- listTag[i].classList.remove("hidden-item");
3717
- }
3718
- if (filterText_lowerCase === "") {
3719
- listTag[i].classList.remove("item-search");
3720
- }
3721
- }
3722
- }
3723
- // Length of string > 0 show dropDownContainerComp
3724
- if (e_onchange.currentTarget.value.length > 0) {
3725
- setShowDropDownfiltered(true);
3726
- }
3727
- };
3728
- //#endregion
3729
- //#region onKeyPressInput
3730
- const onKeyPressSearch = (event_onKeypress) => {
3731
- //#region Variables
3732
- const keyPressed = event_onKeypress.key;
3733
- const optionSearched = document.getElementsByClassName("item-search");
3734
- //#endregion
3735
- // first item selected or same text
3736
- const optionArray = Array.from(optionSearched);
3737
- if (optionArray.length > 0 && keyPressed === "Enter" && event_onKeypress.currentTarget.value !== "") {
3738
- const firstElement_optionList = optionArray[0];
3739
- const textContent = firstElement_optionList.textContent;
3740
- const elementList = CwelltCustomFilterTabProps.selectListsItems?.find(e => e.find(el => el.description === textContent));
3741
- const element = elementList?.find(el => el.description === textContent);
3742
- if (element !== undefined) {
3743
- const exist = CwelltCustomFilterTabProps.selectedListsItems?.some(s => s.description === textContent);
3744
- if (exist === false) {
3745
- handleClickTag(element);
3746
- }
3747
- }
3748
- const optionList_item_hidden = document.getElementsByClassName("hidden-item");
3749
- if (optionList_item_hidden.length > 0) {
3750
- Array.from(optionList_item_hidden).forEach(index => {
3751
- const optionList_hidden_array = index;
3752
- if (optionList_hidden_array.classList.contains("hidden-item")) {
3753
- optionList_hidden_array.classList.remove("hidden-item");
3754
- }
3755
- });
3756
- }
3757
- }
3758
- };
3759
- //#endregion
3760
- //#region ShowDropDownFilter
3761
- const showDropDownfiltered = () => {
3762
- setShowDropDownfiltered(!isShowDropDownfiltered);
3763
- };
3764
- //#endregion
3765
- class SelectListTest {
3766
- description;
3767
- key;
3768
- type;
3769
- typeName;
3770
- val;
3771
- value;
3772
- active;
3773
- }
3774
- const handleClickTag = (e) => {
3775
- const preList = CwelltCustomFilterTabProps.selectedListsItems || [];
3776
- const valueIds = [];
3777
- const resultList = preList?.map(s => {
3778
- const item = new SelectListTest();
3779
- item.description = s.description;
3780
- item.key = s.type + "_" + s.id;
3781
- item.type = s.type;
3782
- item.val = s.id;
3783
- item.value = item.key;
3784
- item.active = s.active ?? false;
3785
- valueIds.push(item.key);
3786
- return item;
3787
- });
3788
- const a = new SelectListTest();
3789
- a.description = e.description;
3790
- a.key = e.type + "_" + e.id;
3791
- a.type = e.type;
3792
- a.val = e.id;
3793
- a.value = a.key;
3794
- a.active = e.active;
3795
- const exist = resultList?.some(item => item.key === a.key);
3796
- if (exist) {
3797
- a.active = false;
3798
- const list = resultList?.filter(item => item.key !== a.key);
3799
- const values = valueIds.filter(v => v !== a.key);
3800
- CwelltCustomFilterTabProps.onclickHandleChange(values, list);
3801
- }
3802
- else {
3803
- a.active = true;
3804
- resultList?.push(a);
3805
- valueIds.push(a.key);
3806
- CwelltCustomFilterTabProps.onclickHandleChange(valueIds, resultList);
3807
- }
3808
- // // Selected item option list
3809
- // setSelected_optionList((prevSelectedStates) => ({
3810
- // ...prevSelectedStates,
3811
- // [a.key]: !prevSelectedStates[a.key],
3812
- // }));
3813
- // clear filter by text after clicked in option list
3814
- const optionList_item_hidden = document.getElementsByClassName("hidden-item");
3815
- if (optionList_item_hidden.length > 0) {
3816
- Array.from(optionList_item_hidden).forEach(index => {
3817
- const optionList_hidden_array = index;
3818
- if (optionList_hidden_array.classList.contains("hidden-item")) {
3819
- optionList_hidden_array.classList.remove("hidden-item");
3820
- }
3821
- });
3822
- }
3823
- // Check click from option list has custom tag header of custom filter tab
3824
- const tagActive = document.getElementsByClassName("multiselect-active-tag");
3825
- const optionList = document.getElementsByClassName("cw-multiselect-option-list");
3826
- if (tagActive.length > 0 && optionList.length > 0) {
3827
- Array.from(tagActive).forEach(_index => {
3828
- Array.from(optionList).forEach(index => {
3829
- const optionList_array = index;
3830
- const optionId = optionList_array.getAttribute('data-id');
3831
- if (optionId === (e.type + "_" + e.id)) {
3832
- optionList_array.classList.remove("option-active");
3833
- }
3834
- });
3835
- });
3836
- }
3837
- const optionList_desc = document.getElementsByClassName("option-active");
3838
- if (optionList_desc.length > 0) {
3839
- Array.from(optionList_desc).forEach(index => {
3840
- const optionList_desc_array = index;
3841
- if (optionList_desc_array.innerText === a.description) {
3842
- optionList_desc_array.classList.remove("option-active");
3843
- }
3844
- });
3845
- }
3846
- // Click to hide dropDownContainer
3847
- setShowDropDownfiltered(false);
3848
- };
3849
- // [ click custom tag ]
3850
- const closeTagHandle = (e) => {
3851
- const preList = CwelltCustomFilterTabProps.selectedListsItems;
3852
- const valueIds = [];
3853
- const resultList = preList?.map(s => {
3854
- const item = new SelectListTest();
3855
- item.description = s.description;
3856
- item.key = s.type + "_" + s.id;
3857
- item.type = s.type;
3858
- item.val = s.id;
3859
- item.value = item.key;
3860
- valueIds.push(item.key);
3861
- return item;
3862
- });
3863
- const a = new SelectListTest();
3864
- a.description = e.description;
3865
- a.key = e.type + "_" + e.id;
3866
- a.type = e.type;
3867
- a.val = e.id;
3868
- a.value = a.key;
3869
- const resultListFilter = resultList?.filter(item => item.key !== a.key);
3870
- const valueIdsFilter = valueIds.filter(item => item !== a.key);
3871
- CwelltCustomFilterTabProps.onclickHandleChange(valueIdsFilter, resultListFilter);
3872
- // // Selected item option list - remove active option list
3873
- // setSelected_optionList((prevSelectedStates) => ({
3874
- // ...prevSelectedStates,
3875
- // [a.key]: false[a.key],
3876
- // }));
3877
- const optionList_active = document.getElementsByClassName("option-active");
3878
- if (optionList_active.length > 0) {
3879
- Array.from(optionList_active).forEach(index => {
3880
- const optionList_active_array = index;
3881
- const optionId = optionList_active_array.getAttribute('data-id');
3882
- if (optionId === (e.type + "_" + e.id)) {
3883
- optionList_active_array.classList.remove("option-active");
3884
- }
3885
- });
3886
- }
3887
- };
3888
- //#endregion
3889
- //#region DropDownContainer [ properties functions ]
3890
- //#region onKeyDownDropDownContainer [ press ESC dropDownContainer dissapear - ArrowUp && ArrowDown ]
3891
- const onKeyDownDropDownContent = (event_onKeyDown) => {
3892
- const items = document.querySelectorAll(".cw-multiselect-option-list");
3893
- let optionIndex = Array.from(items).findIndex(item => item.classList.contains("keyboard-focus"));
3894
- if (event_onKeyDown.key === "Escape") {
3895
- // DropDown disappear
3896
- setShowDropDownfiltered(false);
3897
- }
3898
- // KeyDown
3899
- if (event_onKeyDown.key === "ArrowDown") {
3900
- event_onKeyDown.preventDefault();
3901
- removeHighlight();
3902
- optionIndex = getNextIndex(optionIndex, items.length);
3903
- highlightOption(optionIndex);
3904
- }
3905
- // KeyUp
3906
- if (event_onKeyDown.key === "ArrowUp") {
3907
- event_onKeyDown.preventDefault();
3908
- removeHighlight();
3909
- optionIndex = getPreviousIndex(optionIndex, items.length);
3910
- highlightOption(optionIndex);
3911
- }
3912
- };
3913
- const removeHighlight = () => {
3914
- const highlightedItem = document.querySelector(".keyboard-focus");
3915
- if (highlightedItem) {
3916
- highlightedItem.classList.remove("keyboard-focus");
3917
- }
3918
- };
3919
- const getNextIndex = (currentIndex, length) => {
3920
- return (currentIndex + 1) % length;
3921
- };
3922
- const getPreviousIndex = (currentIndex, length) => {
3923
- return (currentIndex - 1 + length) % length;
3924
- };
3925
- const highlightOption = (index) => {
3926
- const items = document.querySelectorAll(".cw-multiselect-option-list");
3927
- const item = items[index];
3928
- item.classList.add("keyboard-focus");
3929
- };
3930
- //#endregion
3931
- //#region onMouseLeave
3932
- const handleInputBlur = () => {
3933
- setTimeout(() => {
3934
- if (!containerRef.current?.contains(document.activeElement)) {
3935
- setShowDropDownfiltered(false);
3936
- }
3937
- }, 150);
3938
- };
3939
- React.useEffect(() => {
3940
- const handleClickOutside = (event) => {
3941
- if (containerRef.current && !containerRef.current.contains(event.target)) {
3942
- setShowDropDownfiltered(false);
3943
- }
3944
- };
3945
- document.addEventListener('mousedown', handleClickOutside);
3946
- return () => {
3947
- document.removeEventListener('mousedown', handleClickOutside);
3948
- };
3949
- }, []);
3950
- //#endregion
3951
- // Click filter item button
3952
- const clickFilter_item = (id) => {
3953
- // content items - looking for className by it - corresponded by their current group
3954
- const contentItems = document.getElementsByClassName(id);
3955
- const contentAll = document.getElementsByClassName("multiselect-tag-group");
3956
- if (contentAll.length > 0) {
3957
- Array.from(contentAll).forEach(index => {
3958
- const contentAll_array = index;
3959
- contentAll_array.classList.add("hidden-group");
3960
- });
3961
- }
3962
- if (contentItems.length > 0) {
3963
- Array.from(contentItems).forEach(index => {
3964
- const contentItems_array = index;
3965
- contentItems_array.classList.remove("hidden-group");
3966
- });
3967
- }
3968
- // Adding custom className acitive
3969
- setActive_filter_item(id);
3970
- // Remove active className [ label tab : ( ALL ) ]
3971
- setActive_filter_item_all(false);
3972
- };
3973
- const showAllItem = () => {
3974
- //let currentBtn = e.currentTarget;
3975
- const contentAll = document.getElementsByClassName("multiselect-tag-group");
3976
- if (contentAll.length > 0) {
3977
- Array.from(contentAll).forEach(index => {
3978
- const contentAll_array = index;
3979
- contentAll_array.classList.remove("hidden-group");
3980
- // active className - all
3981
- setActive_filter_item_all(true);
3982
- setActive_filter_item("");
3983
- });
3984
- }
3985
- };
3986
- //#endregion
3987
- React.useEffect(() => {
3988
- if (CwelltCustomFilterTabProps.selectedListsItems) {
3989
- const allOptions = document.getElementsByClassName("cw-multiselect-option-list");
3990
- Array.from(allOptions).forEach(option => {
3991
- option.classList.remove("option-active");
3992
- });
3993
- CwelltCustomFilterTabProps.selectedListsItems.forEach(selectedItem => {
3994
- Array.from(allOptions).forEach(option => {
3995
- const optionElement = option;
3996
- if (optionElement.innerText === selectedItem.description) {
3997
- optionElement.classList.add("option-active");
3998
- }
3999
- });
4000
- });
4001
- }
4002
- }, [CwelltCustomFilterTabProps.selectedListsItems]);
4003
- return (jsxRuntime.jsx("div", { ref: containerRef, children: jsxRuntime.jsx(CwHeadFilter, { Id: CwelltCustomFilterTabProps.id, onChangeSearch: (e_onchange) => onChangeSearch(e_onchange), onClearValue: (e_clear) => clearValue(e_clear), onKeypressInput: onKeyPressSearch, onShowDropDown: showDropDownfiltered, placeholder_desc: CwelltCustomFilterTabProps.placeholder, style: CwelltCustomFilterTabProps.style, onBlur: handleInputBlur,
4004
- // onMouseLeave={onMouseLeave_dropDownContainer}
4005
- className: CwelltCustomFilterTabProps.selectedListsItems?.length === 0
4006
- ? "cw-filter-tab-multi-select-show-icon"
4007
- : "cw-filter-tab-multi-select-hidden-icon", tagValueContent: jsxRuntime.jsx("div", { className: "cw-flex-row cw-gap-small", children: CwelltCustomFilterTabProps.selectedListsItems?.map((s, index) => {
4008
- return s.type !== undefined ? (jsxRuntime.jsx(CwTag, { styleTag: {
4009
- background: s.color,
4010
- color: getContrastColor(s.color),
4011
- }, idTag: s.type + "_" + s.id, closableTag: true, onClickClosableTag: () => closeTagHandle(s), "data-id": s.type + "_" + s.id, className: "multiselect-active-tag", children: s.description }, index)) : (jsxRuntime.jsx("div", {}));
4012
- }) }), children: jsxRuntime.jsx(CwDropdownContainer, { dropDownState: isShowDropDownfiltered, idDropDownContainer: CwelltCustomFilterTabProps.idDropDownContainer, onKeyDownDropDownContainer: (event_onKeyDown) => onKeyDownDropDownContent(event_onKeyDown), children: jsxRuntime.jsxs("div", { className: "cw-multiselect-dropdown", children: [jsxRuntime.jsxs("header", { children: [jsxRuntime.jsx("label", { "data-active": isActive_filter_item_all, onClick: showAllItem, children: "ALL" }), CwelltCustomFilterTabProps.selectListsItems?.map((slArray, i) => (jsxRuntime.jsx("label", { "data-active": isActive_filter_item === 'content_' + i,
4013
- // todo : giving parameter by id to search by their corresponding group it list options and className content with their id in this case key ( i ) by .map function
4014
- onClick: () => clickFilter_item("content_" + i), id: "content_" + i, children: slArray.length > 0 && slArray[0].typeName !== undefined
4015
- ? slArray[0].typeName
4016
- : slArray.length > 0
4017
- ? slArray[0].type
4018
- : "" }, i)))] }), jsxRuntime.jsx("div", { className: "cw-multiselect-tags-container", children: CwelltCustomFilterTabProps.selectListsItems?.map((slArray, i) => (jsxRuntime.jsx("div", { id: "content_" + i, className: `multiselect-tag-group content_${i}`, ref: refOptionListContent, children: slArray.map(sl => {
4019
- const isSelected = CwelltCustomFilterTabProps.selectedListsItems?.some(selected => selected.type === sl.type && selected.id === sl.id) || false;
4020
- return (jsxRuntime.jsx(CwOptionList, { idOptionList: sl.type + "_" + sl.id, value: sl.type + "_" + sl.id, title: sl.description, onClick: () => handleClickTag(sl), isSelected: sl.active, "data-id": sl.type + "_" + sl.id, children: jsxRuntime.jsx(CwTag, { styleTag: {
4021
- background: sl.color,
4022
- color: getContrastColor(sl.color),
4023
- }, closableTag: isSelected, children: sl.description }) }, sl.type + "_" + sl.id));
4024
- }) }, "group" + i))) })] }) }) }) }));
4025
- }
4026
-
4027
3377
  var styles$8 = {"cw-multifilter-tag":"cw-multi-filter-tag-module_cw-multifilter-tag__Epda-"};
4028
3378
 
4029
3379
  const CwMultiFilterTag = props => {
4030
- const { ID, Name, Value, Category, Removable, PrimaryColor, OnPrimaryColor, Selectable, Selected, OnSelect } = props;
4031
- const BackgroundColor = `rgb(${PrimaryColor.r},${PrimaryColor.g},${PrimaryColor.b})`;
4032
- const TextColor = `rgb(${OnPrimaryColor.r},${OnPrimaryColor.g},${OnPrimaryColor.b})`;
4033
- return (jsxRuntime.jsxs("li", { className: styles$8["cw-multifilter-tag"], "data-selected": !!props.Selected, "data-removable": !!props.Removable, style: {
4034
- color: TextColor,
4035
- backgroundColor: BackgroundColor,
4036
- opacity: Selected && !Removable ? "0.5" : "1",
4037
- outlineColor: TextColor
4038
- }, onClick: () => {
3380
+ const { ID, Name, Value, Category, Removable, PrimaryColor, Selectable, Selected } = props;
3381
+ const backgroundColor = `rgb(${PrimaryColor.r},${PrimaryColor.g},${PrimaryColor.b})`;
3382
+ const isOutlineMode = Selected && !Removable;
3383
+ return (jsxRuntime.jsx("li", { className: styles$8["cw-multifilter-tag"], id: ID, "data-value": Value, "data-category": Category, "data-selected": !!Selected, title: Name, onClick: () => {
4039
3384
  if (Selectable)
4040
- OnSelect?.(props);
4041
- }, children: [jsxRuntime.jsx("span", { id: ID, "data-value": Value, "data-category": Category, children: Name }), Removable && (jsxRuntime.jsx("span", { onClick: () => props.OnRemove?.(props), children: jsxRuntime.jsx(CwIcon, { iconId: "close" }) }))] }));
3385
+ props.OnSelect?.(props);
3386
+ }, children: jsxRuntime.jsx(CwChip, { label: Name, colorScheme: "custom", customColor: backgroundColor, variant: isOutlineMode ? "outline" : "soft", closable: Removable, onClose: () => props.OnRemove?.(props),
3387
+ // This style ensures the chip color is accessible over white background
3388
+ style: isOutlineMode ? {
3389
+ '--chip-accent': `hsl(from ${backgroundColor} h s 40)`
3390
+ } : undefined }) }));
4042
3391
  };
4043
3392
 
4044
3393
  var styles$7 = {"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","cw-multi-filter-search":"cw-multi-filter-module_cw-multi-filter-search__eyHr0"};
@@ -4056,7 +3405,7 @@ var styles$7 = {"cw-multi-filter-catalog-container":"cw-multi-filter-module_cw-m
4056
3405
  * - `Category`: Group the filter belongs to
4057
3406
  * - `ID`: Unique identifier for the filter
4058
3407
  * - `PrimaryColor`: Background color of the tag
4059
- * - `OnPrimaryColor`: Text color of the tag
3408
+ * - `OnPrimaryColor`: (Optional, deprecated) Text color of the tag - contrast is now calculated automatically
4060
3409
  *
4061
3410
  * ```
4062
3411
  * ╭───────────────────────────────────────────────────────────────╮
@@ -4098,7 +3447,6 @@ var styles$7 = {"cw-multi-filter-catalog-container":"cw-multi-filter-module_cw-m
4098
3447
  * Value: "admin",
4099
3448
  * Category: "Roles",
4100
3449
  * ID: "Roles_admin",
4101
- * OnPrimaryColor: hexToRGB("#2050a8"),
4102
3450
  * PrimaryColor: hexToRGB("#cedcff")
4103
3451
  * },
4104
3452
  * {
@@ -4106,7 +3454,6 @@ var styles$7 = {"cw-multi-filter-catalog-container":"cw-multi-filter-module_cw-m
4106
3454
  * Value: "user",
4107
3455
  * Category: "Roles",
4108
3456
  * ID: "Roles_user",
4109
- * OnPrimaryColor: hexToRGB("#2050a8"),
4110
3457
  * PrimaryColor: hexToRGB("#cedcff")
4111
3458
  * },
4112
3459
  * {
@@ -4114,7 +3461,6 @@ var styles$7 = {"cw-multi-filter-catalog-container":"cw-multi-filter-module_cw-m
4114
3461
  * Value: "IT",
4115
3462
  * Category: "Departments",
4116
3463
  * ID: "Departments_IT",
4117
- * OnPrimaryColor: hexToRGB("#a82037"),
4118
3464
  * PrimaryColor: hexToRGB("#ffceda")
4119
3465
  * },
4120
3466
  * {
@@ -4122,7 +3468,6 @@ var styles$7 = {"cw-multi-filter-catalog-container":"cw-multi-filter-module_cw-m
4122
3468
  * Value: "HR",
4123
3469
  * Category: "Departments",
4124
3470
  * ID: "Departments_HR",
4125
- * OnPrimaryColor: hexToRGB("#a82037"),
4126
3471
  * PrimaryColor: hexToRGB("#ffceda")
4127
3472
  * }
4128
3473
  * ]);
@@ -4226,9 +3571,10 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, style
4226
3571
  const getColor = (category) => {
4227
3572
  const test = categoriesMappedToTags().get(category)?.values().next().value;
4228
3573
  if (test !== undefined) {
3574
+ const primaryColor = rgbAString(test.PrimaryColor.r, test.PrimaryColor.g, test.PrimaryColor.b);
4229
3575
  return {
4230
- onPrimary: rgbAString(test.OnPrimaryColor.r, test.OnPrimaryColor.g, test.OnPrimaryColor.b),
4231
- primary: rgbAString(test.PrimaryColor.r, test.PrimaryColor.g, test.PrimaryColor.b),
3576
+ onPrimary: getContrastColor(primaryColor),
3577
+ primary: primaryColor,
4232
3578
  };
4233
3579
  }
4234
3580
  else {
@@ -4448,50 +3794,54 @@ function CwSearchInput(optionsProps) {
4448
3794
  const [filteredOptions, setFilteredOptions] = React.useState([]);
4449
3795
  const [_selectedOption, setSelectedOption] = React.useState(null);
4450
3796
  const [showDropdown, setShowDropdown] = React.useState(false);
3797
+ const [isLoading, setIsLoading] = React.useState(false);
3798
+ // Extract props
3799
+ const { labelProps, iconProps, alignProps, selectList, handleChange, placeholder = "Search…", disabled, renderOption, style, id, className, defaultValue, ...otherProps } = optionsProps;
3800
+ // Get direction for data attribute
3801
+ const direction = alignProps?.flexDirection || "row";
4451
3802
  // Make default value selection when loading the component
4452
3803
  React.useEffect(() => {
4453
- if (optionsProps.defaultValue && optionsProps.selectList && optionsProps.selectList.length > 0) {
4454
- const defaultOption = optionsProps.selectList.find(option => option.id === optionsProps.defaultValue?.toString());
3804
+ if (defaultValue && selectList && selectList.length > 0) {
3805
+ setIsLoading(true);
3806
+ const defaultOption = selectList.find(option => option.id === defaultValue?.toString());
4455
3807
  if (defaultOption) {
4456
3808
  setSearchText(defaultOption.description);
4457
3809
  setSelectedOption(defaultOption);
4458
- // Notify the parent component if there is a handleChange
4459
- if (optionsProps.handleChange) {
4460
- optionsProps.handleChange(defaultOption.id);
3810
+ if (handleChange) {
3811
+ handleChange(defaultOption.id);
4461
3812
  }
4462
3813
  }
3814
+ setIsLoading(false);
4463
3815
  }
4464
- }, [optionsProps.defaultValue, optionsProps.selectList]);
3816
+ }, [defaultValue, selectList]);
4465
3817
  const handleInputChange = (event) => {
4466
3818
  const text = event.target.value;
4467
3819
  setSearchText(text);
4468
3820
  setShowDropdown(true);
4469
3821
  if (text === "") {
4470
- setFilteredOptions(optionsProps.selectList);
3822
+ setFilteredOptions(selectList);
4471
3823
  setSelectedOption(null);
4472
- // Notify that there is no selection
4473
- if (optionsProps.handleChange) {
4474
- optionsProps.handleChange("");
3824
+ if (handleChange) {
3825
+ handleChange("");
4475
3826
  }
4476
3827
  }
4477
3828
  else {
4478
- // Filter options based on search text in any text property
4479
- const filtered = optionsProps.selectList.filter((option) => {
4480
- // Search all properties of the object
3829
+ setIsLoading(true);
3830
+ const filtered = selectList.filter((option) => {
4481
3831
  return Object.keys(option).some(key => {
4482
3832
  const value = option[key];
4483
- // Verify that the value is a string or number and contains the search text
4484
3833
  return (typeof value === 'string' || typeof value === 'number') &&
4485
3834
  String(value).toLowerCase().includes(text.toLowerCase());
4486
3835
  });
4487
3836
  });
4488
3837
  setFilteredOptions(filtered);
3838
+ setIsLoading(false);
4489
3839
  }
4490
3840
  };
4491
3841
  const handleInputFocus = () => {
4492
3842
  setShowDropdown(true);
4493
3843
  if (searchText === "") {
4494
- setFilteredOptions(optionsProps.selectList);
3844
+ setFilteredOptions(selectList);
4495
3845
  }
4496
3846
  };
4497
3847
  const handleInputBlur = () => {
@@ -4502,27 +3852,172 @@ function CwSearchInput(optionsProps) {
4502
3852
  const handleOptionSelect = (option) => {
4503
3853
  setSearchText(option.description);
4504
3854
  setSelectedOption(option);
4505
- if (optionsProps.handleChange) {
4506
- optionsProps.handleChange(option.id);
3855
+ if (handleChange) {
3856
+ handleChange(option.id);
3857
+ }
3858
+ setFilteredOptions([]);
3859
+ };
3860
+ const handleClearClick = () => {
3861
+ setSearchText("");
3862
+ setFilteredOptions([]);
3863
+ setSelectedOption(null);
3864
+ if (handleChange) {
3865
+ handleChange("");
3866
+ }
3867
+ };
3868
+ return (jsxRuntime.jsxs("div", { className: `cw-search-input ${className || ""}`, style: style, id: id, ...otherProps, "data-direction": direction, children: [jsxRuntime.jsxs(CwAlign, { ...alignProps, children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: "cw-search-input-wrapper", children: [jsxRuntime.jsx("input", { type: "text", value: searchText, onChange: handleInputChange, onFocus: handleInputFocus, onBlur: handleInputBlur, placeholder: placeholder, className: "cw-input-search", disabled: disabled }), isLoading && (jsxRuntime.jsx("div", { className: "cw-search-input-loading", children: jsxRuntime.jsx(CwIcon, { iconId: "spinner" }) })), jsxRuntime.jsx("div", { className: "cw-search-input-icons", children: searchText && !disabled && !isLoading ? (jsxRuntime.jsx(CwButton, { type: "button", onClick: handleClearClick, "aria-label": "Clear search", variant: "icon", icon: "close", color: "neutral" })) : (iconProps ? jsxRuntime.jsx(CwIcon, { ...iconProps }) : jsxRuntime.jsx(CwIcon, { iconId: "search" })) })] })] }), showDropdown && filteredOptions.length > 0 && (jsxRuntime.jsx("div", { className: "cw-input-search-dropdown", children: jsxRuntime.jsx("ul", { children: filteredOptions.map((option) => (jsxRuntime.jsx("li", { onClick: () => handleOptionSelect(option), onMouseDown: (e) => e.preventDefault(), children: renderOption ? renderOption(option) : option.description }, option.id))) }) }))] }));
3869
+ }
3870
+
3871
+ var styles$5 = {"menu":"cw-context-menu-module_menu__tXmun","item":"cw-context-menu-module_item__-ko8L","arrow":"cw-context-menu-module_arrow__LHZmQ"};
3872
+
3873
+ const ARROW_SIZE = 8;
3874
+ const SAFETY_MARGIN = 8;
3875
+ const VIEWPORT_PADDING = 10;
3876
+ const CwAnchoredMenu = ({ children, options, onSelect, placement = 'bottom', open: controlledOpen, onOpenChange, onContextMenu: onContextMenuCallback }) => {
3877
+ const [internalOpen, setInternalOpen] = React.useState(false);
3878
+ const [position, setPosition] = React.useState({ x: 0, y: 0 });
3879
+ const menuRef = React.useRef(null);
3880
+ const triggerRef = React.useRef(null);
3881
+ const arrowRef = React.useRef(null);
3882
+ const isControlled = controlledOpen !== undefined;
3883
+ const isOpen = isControlled ? controlledOpen : internalOpen;
3884
+ const setIsOpen = (value) => {
3885
+ isControlled ? onOpenChange?.(value) : setInternalOpen(value);
3886
+ };
3887
+ const normalizedOptions = options.map(opt => typeof opt === 'string' ? { key: opt, label: opt } : opt);
3888
+ const getActualTriggerElement = () => {
3889
+ let element = triggerRef.current;
3890
+ if (element.offsetHeight === 0 && element.children.length > 0) {
3891
+ element = element.children[0];
3892
+ }
3893
+ return element;
3894
+ };
3895
+ const calculateInitialPosition = (event, rect) => {
3896
+ const totalOffset = ARROW_SIZE + SAFETY_MARGIN;
3897
+ switch (placement) {
3898
+ case 'bottom':
3899
+ return { x: event.clientX, y: rect.bottom + totalOffset };
3900
+ case 'top':
3901
+ return { x: event.clientX, y: rect.top - totalOffset };
3902
+ case 'right':
3903
+ return { x: rect.right + totalOffset, y: event.clientY };
3904
+ case 'left':
3905
+ return { x: rect.left - totalOffset, y: event.clientY };
3906
+ }
3907
+ };
3908
+ const shouldFlipVertical = (currentPlacement, rect, menuHeight) => {
3909
+ const totalOffset = ARROW_SIZE + SAFETY_MARGIN;
3910
+ if (currentPlacement === 'bottom') {
3911
+ const spaceBelow = window.innerHeight - rect.bottom - totalOffset;
3912
+ const spaceAbove = rect.top - totalOffset;
3913
+ return spaceBelow < menuHeight && spaceAbove > spaceBelow ? 'top' : 'bottom';
3914
+ }
3915
+ else {
3916
+ const spaceAbove = rect.top - totalOffset;
3917
+ const spaceBelow = window.innerHeight - rect.bottom - totalOffset;
3918
+ return spaceAbove < menuHeight && spaceBelow > spaceAbove ? 'bottom' : 'top';
3919
+ }
3920
+ };
3921
+ const shouldFlipHorizontal = (currentPlacement, rect, menuWidth) => {
3922
+ const totalOffset = ARROW_SIZE + SAFETY_MARGIN;
3923
+ if (currentPlacement === 'right') {
3924
+ const spaceRight = window.innerWidth - rect.right - totalOffset;
3925
+ const spaceLeft = rect.left - totalOffset;
3926
+ return spaceRight < menuWidth && spaceLeft > spaceRight ? 'left' : 'right';
3927
+ }
3928
+ else {
3929
+ const spaceLeft = rect.left - totalOffset;
3930
+ const spaceRight = window.innerWidth - rect.right - totalOffset;
3931
+ return spaceLeft < menuWidth && spaceRight > spaceLeft ? 'right' : 'left';
4507
3932
  }
4508
- // Remove the filtered options when selecting one
4509
- setFilteredOptions([]);
4510
3933
  };
4511
- const handleClearClick = () => {
4512
- setSearchText("");
4513
- setFilteredOptions([]);
4514
- setSelectedOption(null);
3934
+ const handleContextMenu = (event) => {
3935
+ event.preventDefault();
3936
+ event.stopPropagation();
3937
+ onContextMenuCallback?.(event);
3938
+ setIsOpen(true);
3939
+ const actualElement = getActualTriggerElement();
3940
+ const rect = actualElement.getBoundingClientRect();
3941
+ const pos = calculateInitialPosition(event, rect);
3942
+ setPosition(pos);
4515
3943
  };
4516
- return (jsxRuntime.jsxs("div", { className: "cwSearchInputComp", style: optionsProps.style, id: optionsProps.id, children: [jsxRuntime.jsxs("div", { className: optionsProps.labelPosition === "inline"
4517
- ? "cw-flex-row cw-align-left-center"
4518
- : optionsProps.labelPosition === "column"
4519
- ? "cw-label-input-column"
4520
- : "cw-flex-row cw-align-left-center", children: [optionsProps.labelName && (jsxRuntime.jsx("label", { children: optionsProps.labelName })), jsxRuntime.jsx("input", { type: "text", value: searchText, onChange: handleInputChange, onFocus: handleInputFocus, onBlur: handleInputBlur, placeholder: "Search...", className: "cw_input_search", disabled: optionsProps.disabled }), searchText && (jsxRuntime.jsx("button", { className: "cw-button-icon cwi-close cw-input-search-clear", onClick: handleClearClick }))] }), showDropdown && filteredOptions.length > 0 && (jsxRuntime.jsx("div", { className: "cw-input-search-dropdown", children: jsxRuntime.jsx("ul", { children: filteredOptions.map((option) => (jsxRuntime.jsx("li", { onClick: () => handleOptionSelect(option), onMouseDown: (e) => e.preventDefault(), children: optionsProps.renderOption
4521
- ? optionsProps.renderOption(option)
4522
- : option.description }, option.id))) }) }))] }));
4523
- }
4524
-
4525
- var styles$5 = {"context-menu":"cw-context-menu-module_context-menu__dbxnO","context-menu-item":"cw-context-menu-module_context-menu-item__B2W-Q"};
3944
+ const handleOptionClick = (option) => {
3945
+ if (option.disabled)
3946
+ return;
3947
+ onSelect(option.key);
3948
+ setIsOpen(false);
3949
+ };
3950
+ // Calculate position before the browser paints the element
3951
+ React.useLayoutEffect(() => {
3952
+ if (!isOpen || !menuRef.current || !triggerRef.current)
3953
+ return;
3954
+ const actualElement = getActualTriggerElement();
3955
+ const rect = actualElement.getBoundingClientRect();
3956
+ const menuRect = menuRef.current.getBoundingClientRect();
3957
+ let { x, y } = position;
3958
+ let finalPlacement = placement;
3959
+ const totalOffset = ARROW_SIZE + SAFETY_MARGIN;
3960
+ // Calculate position based on placement and check for flips
3961
+ if (placement === 'bottom' || placement === 'top') {
3962
+ x = x - (menuRect.width / 2); // Center on click
3963
+ finalPlacement = shouldFlipVertical(placement, rect, menuRect.height);
3964
+ if (finalPlacement === 'top') {
3965
+ y = rect.top - totalOffset - menuRect.height;
3966
+ }
3967
+ else {
3968
+ y = rect.bottom + totalOffset;
3969
+ }
3970
+ }
3971
+ else { // left or right
3972
+ y = y - (menuRect.height / 2); // Center on click
3973
+ finalPlacement = shouldFlipHorizontal(placement, rect, menuRect.width);
3974
+ if (finalPlacement === 'left') {
3975
+ x = rect.left - totalOffset - menuRect.width;
3976
+ }
3977
+ else {
3978
+ x = rect.right + totalOffset;
3979
+ }
3980
+ }
3981
+ // Keep in viewport (fallback)
3982
+ x = Math.max(VIEWPORT_PADDING, Math.min(x, window.innerWidth - menuRect.width - VIEWPORT_PADDING));
3983
+ y = Math.max(VIEWPORT_PADDING, Math.min(y, window.innerHeight - menuRect.height - VIEWPORT_PADDING));
3984
+ // Position arrow
3985
+ if (arrowRef.current) {
3986
+ arrowRef.current.setAttribute('data-placement', finalPlacement);
3987
+ }
3988
+ if (x !== position.x || y !== position.y) {
3989
+ setPosition({ x, y });
3990
+ }
3991
+ }, [isOpen]);
3992
+ // Close handlers
3993
+ React.useEffect(() => {
3994
+ if (!isOpen)
3995
+ return;
3996
+ const handleOutsideClick = (event) => {
3997
+ if (menuRef.current && !menuRef.current.contains(event.target)) {
3998
+ setIsOpen(false);
3999
+ }
4000
+ };
4001
+ const handleEscape = (event) => {
4002
+ if (event.key === "Escape")
4003
+ setIsOpen(false);
4004
+ };
4005
+ document.addEventListener("mousedown", handleOutsideClick);
4006
+ document.addEventListener("keydown", handleEscape);
4007
+ return () => {
4008
+ document.removeEventListener("mousedown", handleOutsideClick);
4009
+ document.removeEventListener("keydown", handleEscape);
4010
+ };
4011
+ }, [isOpen]);
4012
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { ref: triggerRef, onContextMenu: handleContextMenu, style: { display: "contents" }, children: children }), isOpen && normalizedOptions.length > 0 && reactDom.createPortal(jsxRuntime.jsxs("div", { ref: menuRef, className: styles$5["menu"], style: {
4013
+ top: `${position.y}px`,
4014
+ left: `${position.x}px`,
4015
+ }, "data-has-arrow": "true", children: [jsxRuntime.jsx("div", { ref: arrowRef, className: styles$5["arrow"], "data-placement": placement }), normalizedOptions.map(option => (jsxRuntime.jsxs("div", { onClick: (e) => {
4016
+ e.stopPropagation();
4017
+ e.preventDefault();
4018
+ handleOptionClick(option);
4019
+ }, className: `${styles$5["item"]} ${option.disabled ? styles$5["disabled"] : ""}`, "data-disabled": option.disabled, children: [option.icon && jsxRuntime.jsx("span", { className: styles$5["icon"], children: option.icon }), option.label] }, option.key)))] }), document.body)] }));
4020
+ };
4526
4021
 
4527
4022
  /**
4528
4023
  * A context menu that is rendered when the user clicks on a button.
@@ -4535,276 +4030,91 @@ var styles$5 = {"context-menu":"cw-context-menu-module_context-menu__dbxnO","con
4535
4030
  * <div>Right-click me!</div>
4536
4031
  * </ContextMenu>
4537
4032
  */
4538
- const CwContextMenu = ({ children, options, offset, onSelect }) => {
4033
+ const DEFAULT_OFFSET = { x: 4, y: 4 };
4034
+ const CwContextMenu = ({ children, options, offset = DEFAULT_OFFSET, onSelect }) => {
4539
4035
  const [isOpen, setIsOpen] = React.useState(false);
4540
4036
  const [position, setPosition] = React.useState({ x: 0, y: 0 });
4541
4037
  const menuRef = React.useRef(null);
4542
4038
  const handleContextMenu = (event) => {
4543
4039
  event.preventDefault();
4544
4040
  setIsOpen(true);
4545
- setPosition({ x: event.clientX, y: event.clientY });
4041
+ const x = event.clientX + offset.x;
4042
+ const y = event.clientY + offset.y;
4043
+ setPosition({ x, y });
4546
4044
  };
4547
4045
  const handleOptionClick = (option) => {
4548
4046
  onSelect(option);
4549
4047
  setIsOpen(false);
4550
4048
  };
4049
+ // Position handler for when is too close to window edges
4050
+ React.useEffect(() => {
4051
+ if (isOpen && menuRef.current) {
4052
+ const rect = menuRef.current.getBoundingClientRect();
4053
+ const padding = 16;
4054
+ let { x, y } = position;
4055
+ if (rect.right > window.innerWidth) {
4056
+ x = window.innerWidth - rect.width - padding;
4057
+ }
4058
+ if (rect.bottom > window.innerHeight) {
4059
+ y = window.innerHeight - rect.height - padding;
4060
+ }
4061
+ if (x < padding) {
4062
+ x = padding;
4063
+ }
4064
+ if (y < padding) {
4065
+ y = padding;
4066
+ }
4067
+ if (x !== position.x || y !== position.y) {
4068
+ setPosition({ x, y });
4069
+ }
4070
+ }
4071
+ }, [isOpen, position.x, position.y]);
4551
4072
  React.useEffect(() => {
4552
4073
  const handleOutsideClick = (event) => {
4553
4074
  if (menuRef.current && !menuRef.current.contains(event.target)) {
4554
4075
  setIsOpen(false);
4555
4076
  }
4556
4077
  };
4557
- document.addEventListener("mousedown", handleOutsideClick);
4078
+ const handleEscape = (event) => {
4079
+ if (event.key === "Escape") {
4080
+ setIsOpen(false);
4081
+ }
4082
+ };
4083
+ if (isOpen) {
4084
+ document.addEventListener("mousedown", handleOutsideClick);
4085
+ document.addEventListener("keydown", handleEscape);
4086
+ }
4558
4087
  return () => {
4559
4088
  document.removeEventListener("mousedown", handleOutsideClick);
4089
+ document.removeEventListener("keydown", handleEscape);
4560
4090
  };
4561
- }, []);
4562
- return (jsxRuntime.jsxs("div", { onContextMenu: handleContextMenu, children: [children, isOpen && (jsxRuntime.jsx("div", { ref: menuRef, className: styles$5["context-menu"], style: {
4563
- top: position.y + (offset?.y || 0),
4564
- left: position.x + (offset?.x || 0),
4565
- }, children: options.map(option => (jsxRuntime.jsx("div", { onClick: () => handleOptionClick(option), className: styles$5["context-menu-item"], children: option }, option))) }))] }));
4091
+ }, [isOpen]);
4092
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { onContextMenu: handleContextMenu, children: children }), isOpen && reactDom.createPortal(jsxRuntime.jsx("div", { ref: menuRef, className: styles$5["menu"], style: {
4093
+ top: `${position.y}px`,
4094
+ left: `${position.x}px`,
4095
+ }, children: options.map(option => (jsxRuntime.jsx("div", { onClick: () => handleOptionClick(option), className: styles$5["item"], children: option }, option))) }), document.body)] }));
4566
4096
  };
4567
4097
 
4568
- function CwDataItem(cwBoxItemsProps) {
4569
- return (jsxRuntime.jsx("div", { id: cwBoxItemsProps.id, className: "cwelltBoxItems", style: cwBoxItemsProps.style, children: jsxRuntime.jsx("span", { className: "cwelltBoxItemsText cwelltFont1em_required", style: cwBoxItemsProps.styleDataItem, children: cwBoxItemsProps.children }) }));
4570
- }
4571
- function CwContextualMenu(CwelltRightClickProps) {
4572
- //#region Hooks
4573
- const [isVisibleContextMenu, setVisibleContextMenu] = React.useState(false);
4574
- const [resetClassName, setResetClassName] = React.useState("");
4575
- const [positionRightClick, setpositionRightClick] = React.useState({ x: 0, y: 0 });
4576
- //#endregion
4577
- //#region Functions
4578
- const onShowContextMenu = (e) => {
4579
- e.preventDefault();
4580
- setVisibleContextMenu(true);
4581
- const newPosition = {
4582
- x: e.clientX - e.currentTarget.getBoundingClientRect().left,
4583
- y: e.clientY - e.currentTarget.getBoundingClientRect().top
4584
- };
4585
- setpositionRightClick(newPosition);
4586
- toggleClassName();
4587
- };
4588
- const toggleClassName = () => {
4589
- setTimeout(() => {
4590
- setResetClassName("cwellt_fade_out");
4591
- });
4592
- setTimeout(() => {
4593
- setResetClassName("cwellt_fade_in");
4594
- }, 500);
4595
- };
4596
- const onMouseLeaveContextMenuContainer = () => {
4597
- setVisibleContextMenu(false);
4598
- };
4599
- const onClickContextMenuContainer = () => {
4600
- setVisibleContextMenu(false);
4601
- CwelltRightClickProps.onClick;
4602
- };
4603
- const onKeyUpContextMenu = (e) => {
4604
- if (e.key === "Escape") {
4605
- // context menu dissapear
4606
- setVisibleContextMenu(false);
4607
- }
4608
- if (e.key === "Enter") {
4609
- // context menu dissapear
4610
- setVisibleContextMenu(false);
4611
- }
4612
- };
4613
- //#endregion
4614
- return (jsxRuntime.jsxs("div", { className: "cwelltContextMenu_container", onContextMenu: onShowContextMenu, onMouseLeave: onMouseLeaveContextMenuContainer, onClick: onClickContextMenuContainer, style: { position: "relative" }, onKeyUp: e => onKeyUpContextMenu(e), tabIndex: 0, children: [CwelltRightClickProps.children, jsxRuntime.jsx("div", { id: "contextMenu", className: isVisibleContextMenu ? "cwelltContextMenu " + resetClassName : "cwelltContextMenuHide " + resetClassName, style: {
4615
- top: positionRightClick.y,
4616
- left: positionRightClick.x
4617
- }, children: CwelltRightClickProps.dataSourceContextMenu?.map(indexDataItem => {
4618
- return (jsxRuntime.jsx(CwDataItem, { id: indexDataItem.idDataItem, style: indexDataItem.style, styleDataItem: indexDataItem.styleDataItem, children: indexDataItem.dataItemContent }));
4619
- }) })] }));
4620
- }
4621
-
4622
- // Buttons components
4623
4098
  /**
4624
- * A floating button.
4625
- * @identifier cw_btnFloatingButton
4626
- * @classes cw_btnFloatingButtonActive
4627
- * @dependencies #CwScheduler #CwSchedulerActive #cwelltContentDuty #cwelltContentDutyActive
4099
+ * Save button wrapper
4100
+ * @deprecated Use <CwButton variant="icon" icon="save" onClick={...} /> instead
4628
4101
  */
4629
- // Floating button
4630
- function CwFloatingButton() {
4631
- const cwShowElement = () => {
4632
- // Content of List Duties
4633
- const cwContentDuty = document.getElementById("cwelltContentDuty");
4634
- cwContentDuty?.classList.toggle("cwelltContentDutyActive");
4635
- // Floating button
4636
- const cw_btnFloatingButton = document.getElementById("cw_btnFloatingButton");
4637
- cw_btnFloatingButton?.classList.toggle("cw_btnFloatingButtonActive");
4638
- // #CwScheduler [ scheduler container]
4639
- const cwScheduler = document.getElementById("CwelltScheduler");
4640
- cwScheduler?.classList.toggle("CwelltSchedulerActive");
4641
- };
4642
- return jsxRuntime.jsx("button", { className: "cw_btnFloatingButton", onClick: cwShowElement, id: "cw_btnFloatingButton" });
4643
- }
4644
- // Primary button => CwButtonDef
4645
- // CwButtonDef
4646
- function CwButtonDef({ cw_btn_desc, cw_btnOnclick, cw_btn_disabled }) {
4647
- return (jsxRuntime.jsx("button", { className: "cw-button cw_btn_primary", onClick: cw_btnOnclick, disabled: cw_btn_disabled, children: cw_btn_desc }));
4648
- }
4649
- // Cw add button
4650
- function CwBtnAdd({ cw_btnOnclick, cw_btn_disabled }) {
4651
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-plus", disabled: cw_btn_disabled });
4652
- }
4653
- // Cw Save button
4654
- function CwBtnSave({ cw_btnOnclick, cw_btn_disabled }) {
4655
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-save", disabled: cw_btn_disabled });
4656
- }
4657
- // Cw edit button
4658
- function CwBtnEdit({ cw_btnOnclick, cw_btn_disabled }) {
4659
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-edit", disabled: cw_btn_disabled });
4660
- }
4661
- // Cw search button
4662
- function CwBtnSearch({ cw_btnOnclick, cw_btn_disabled }) {
4663
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-search", disabled: cw_btn_disabled });
4664
- }
4665
- // Cw download button
4666
- function CwBtnDownload({ cw_btnOnclick, cw_btn_disabled }) {
4667
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-download", disabled: cw_btn_disabled });
4668
- }
4669
- // Cw view button
4670
- function CwBtnView({ cw_btnOnclick, cw_btn_disabled }) {
4671
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-eye-show", disabled: cw_btn_disabled });
4672
- }
4673
- // Cw Print button
4674
- function CwBtnPrint({ cw_btnOnclick, cw_btn_disabled }) {
4675
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-print", disabled: cw_btn_disabled });
4676
- }
4677
- // Cw cancel button
4678
- function CwBtnCancel({ cw_btnOnclick, cw_btn_disabled }) {
4679
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-cancel", disabled: cw_btn_disabled, "data-color": "danger" });
4680
- }
4681
- // Cw Delete button
4682
- function CwBtnDelete({ cw_btnOnclick, cw_btn_disabled }) {
4683
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-delete", disabled: cw_btn_disabled, "data-color": "danger" });
4684
- }
4685
- // CwRefresh
4686
- function CwBtnRefresh({ cw_btnOnclick, cw_btn_disabled }) {
4687
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-refresh", disabled: cw_btn_disabled });
4688
- }
4689
- // Cw hide
4690
- function CwBtnHide({ cw_btnOnclick, cw_btn_disabled }) {
4691
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-icons cwi-eye-hide", disabled: cw_btn_disabled });
4692
- }
4693
- // Cw Select
4694
- function CwBtnSelect({ cw_btnOnclick, cw_btn_disabled }) {
4695
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cw_btn_select", disabled: cw_btn_disabled });
4696
- }
4697
- // Cw Share
4698
- function CwBtnShare({ cw_btnOnclick, cw_btn_disabled }) {
4699
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-icons cwi-share", disabled: cw_btn_disabled });
4700
- }
4701
- // Cw Files
4702
- function CwBtnFiles({ cw_btnOnclick, cw_btn_disabled }) {
4703
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cw_btn_files", disabled: cw_btn_disabled });
4704
- }
4705
- // Cw Airport
4706
- function CwBtnAirport({ cw_btnOnclick, cw_btn_disabled }) {
4707
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cw_btn_airport", disabled: cw_btn_disabled });
4102
+ function CwBtnSave({ cw_btnOnclick, cw_btn_disabled, onClick, disabled, ...rest }) {
4103
+ return (jsxRuntime.jsx(CwButton, { ...rest, variant: "icon", icon: "save", onClick: onClick ?? cw_btnOnclick, disabled: disabled ?? cw_btn_disabled }));
4708
4104
  }
4709
- // DownLoadAllInfo
4710
- function CwBtnDownLoadAllInfo({ cw_btnOnclick, cw_btn_disabled }) {
4711
- return (jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-icons cwi-folder-download", disabled: cw_btn_disabled }));
4712
- }
4713
- // PropertyFolder
4714
- function CwBtnPropertyFolder({ cw_btnOnclick, cw_btn_disabled }) {
4715
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-icons cwi-directory", disabled: cw_btn_disabled });
4716
- }
4717
- // AddFolder
4718
- function CwBtnAddFolder({ cw_btnOnclick, cw_btn_disabled }) {
4719
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-icons cwi-folder-add", disabled: cw_btn_disabled });
4720
- }
4721
- // EditFolder
4722
- function CwBtnEditFolder({ cw_btnOnclick, cw_btn_disabled }) {
4723
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-icons cwi-folder-edit", disabled: cw_btn_disabled });
4724
- }
4725
- // UploadFiles
4726
- function CwBtnUploadFiles({ cw_btnOnclick, cw_btn_disabled }) {
4727
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-upload", disabled: cw_btn_disabled });
4728
- }
4729
- // GoBackSection [ Emanual ]
4730
- function CwBtnGoBackFolder({ cw_btnOnclick, cw_btn_disabled }) {
4731
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cwBtnGoBackFolder", disabled: cw_btn_disabled });
4732
- }
4733
- // BookMark [ Emanual ]
4734
- function CwBtnBookMark({ cw_btnOnclick, cw_btn_disabled }) {
4735
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-icons cwi-star", disabled: cw_btn_disabled });
4736
- }
4737
- // Publish
4738
- function CwBtnPublish({ cw_btnOnclick, cw_btn_disabled }) {
4739
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cw_btnPublish", disabled: cw_btn_disabled });
4740
- }
4741
- // Approve
4742
- function CwBtnApprove({ cw_btnOnclick, cw_btn_disabled }) {
4743
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cw_btnApprove", disabled: cw_btn_disabled });
4744
- }
4745
- // Bulk duty
4746
- function CwBtnBulkDuty({ cw_btnOnclick, cw_btn_disabled }) {
4747
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cw_btnBulkDuty", disabled: cw_btn_disabled });
4748
- }
4749
- // DropDownButtonCrewControl
4750
- function CwBtnDropDownMenu({ cw_btnOnclick, cw_btn_disabled }) {
4751
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cw_btnDropDownMenu", disabled: cw_btn_disabled });
4752
- }
4753
- // DropDownButtonCrewControl
4754
- function CwBtnAlert({ cw_btnOnclick, cw_btn_disabled, cw_name }) {
4755
- return (jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-icons cwi-alert", disabled: cw_btn_disabled, id: cw_name }));
4756
- }
4757
- // BtnNavFirstItemView
4758
- function CwBtnNavFirstItemView({ cw_btnOnclick, cw_btn_disabled }) {
4759
- return (jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cw_btnNavFirstItemView", disabled: cw_btn_disabled }));
4760
- }
4761
- // BtnNavLastItemView
4762
- function CwBtnNavLastItemView({ cw_btnOnclick, cw_btn_disabled }) {
4763
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cw_btnNavLastItemView", disabled: cw_btn_disabled });
4764
- }
4765
- // BtnNavbreviewItem
4766
- function CwBtnNavPreviewItem({ cw_btnOnclick, cw_btn_disabled }) {
4767
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cw_btnNavPreviewItem", disabled: cw_btn_disabled });
4768
- }
4769
- // BtnNavNextDay
4770
- function CwBtnNavNextDay({ cw_btnOnclick, cw_btn_disabled }) {
4771
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cw_btnNavNextDay", disabled: cw_btn_disabled });
4772
- }
4773
- // BtnNavNextDay
4774
- function CwBtnStatistic({ cw_btnOnclick, cw_btn_disabled }) {
4775
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-icons cwi-file-report", disabled: cw_btn_disabled });
4776
- }
4777
- // BtnNavNextDay
4778
- function CwBtnCrewPlanning({ cw_btnOnclick, cw_btn_disabled }) {
4779
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-icons cwi-calendar-view", disabled: cw_btn_disabled });
4780
- }
4781
- // BtnReleasePeriod
4782
- function CwBtnReleasePeriod({ cw_btnOnclick, cw_btn_disabled }) {
4783
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cw_btnReleasePeriod", disabled: cw_btn_disabled });
4784
- }
4785
- // BtnReleasePeriod
4786
- function CwBtnGeneratePairing({ cw_btnOnclick, cw_btn_disabled }) {
4787
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-icons cwi-plane-pairing", disabled: cw_btn_disabled });
4788
- }
4789
- // BtnImportRequests
4790
- function CwBtnImportRequests({ cw_btnOnclick, cw_btn_disabled }) {
4791
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cw_btnImportRequests", disabled: cw_btn_disabled });
4792
- }
4793
- // BtnPairing
4794
- function CwBtnPairing({ cw_btnOnclick, cw_btn_disabled }) {
4795
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-icons cwi-calendar-plane", disabled: cw_btn_disabled });
4796
- }
4797
- // BtnVacations
4798
- function CwBtnVacations({ cw_btnOnclick, cw_btn_disabled }) {
4799
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-icons cwi-luggage", disabled: cw_btn_disabled });
4800
- }
4801
- // BtnMVT
4802
- function CwBtnMVT({ cw_btnOnclick, cw_btn_disabled }) {
4803
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-icons cwi-plane-movement", disabled: cw_btn_disabled });
4105
+ /**
4106
+ * Edit button wrapper
4107
+ * @deprecated Use <CwButton variant="icon" icon="edit" onClick={...} /> instead
4108
+ */
4109
+ function CwBtnEdit({ cw_btnOnclick, cw_btn_disabled, onClick, disabled, ...rest }) {
4110
+ return (jsxRuntime.jsx(CwButton, { ...rest, variant: "icon", icon: "edit", onClick: onClick ?? cw_btnOnclick, disabled: disabled ?? cw_btn_disabled }));
4804
4111
  }
4805
- // BtnDelay
4806
- function CwBtnDelay({ cw_btnOnclick, cw_btn_disabled }) {
4807
- return jsxRuntime.jsx("button", { onClick: cw_btnOnclick, className: "cw-button-icon cwi-icons cwi-plane-delay", disabled: cw_btn_disabled });
4112
+ /**
4113
+ * Delete button wrapper
4114
+ * @deprecated Use <CwButton variant="icon" icon="delete" color="danger" onClick={...} /> instead
4115
+ */
4116
+ function CwBtnDelete({ cw_btnOnclick, cw_btn_disabled, onClick, disabled, ...rest }) {
4117
+ return (jsxRuntime.jsx(CwButton, { ...rest, variant: "icon", icon: "delete", color: "danger", onClick: onClick ?? cw_btnOnclick, disabled: disabled ?? cw_btn_disabled }));
4808
4118
  }
4809
4119
 
4810
4120
  var styles$4 = {"pickerWrapper":"cw-pickers-base-module_pickerWrapper__Fb9Zo","pickerIcons":"cw-pickers-base-module_pickerIcons__dyd2-","pickerPopup":"cw-pickers-base-module_pickerPopup__dkxJo","title":"cw-pickers-base-module_title__cE7qI"};
@@ -4813,12 +4123,12 @@ function CustomCaption$2({ displayMonth }) {
4813
4123
  const { goToMonth, nextMonth, previousMonth } = reactDayPicker.useNavigation();
4814
4124
  return (jsxRuntime.jsxs("header", { children: [jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", icon: "chevron-left", onClick: () => previousMonth && goToMonth(previousMonth), disabled: !previousMonth, "aria-label": "Previous month" }), jsxRuntime.jsx("div", { className: styles$4.title, children: dateFns.format(displayMonth, "MMMM yyyy", { locale: locale.enGB }) }), jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", icon: "chevron-right", onClick: () => nextMonth && goToMonth(nextMonth), disabled: !nextMonth, "aria-label": "Next month" })] }));
4815
4125
  }
4816
- function CwDatePicker({ value, onChange, minDate, maxDate, disabledDates, disabledMatcher, labelProps, alignProps, placeholder = "Select a date", displayFormat = "dd.MM.yyyy", disabled, required, className, showClear = true, popupPosition = "left-bottom", numberOfMonths = 1, showTodayButton = false, }) {
4126
+ function CwDatePicker({ value, onChange, minDate, maxDate, disabledDates, disabledMatcher, defaultMonth, labelProps, alignProps, placeholder = "Select a date", displayFormat = "dd.MM.yyyy", disabled, required, className, showClear = true, popupPosition = "left-bottom", numberOfMonths = 1, showTodayButton = false, }) {
4817
4127
  const [isOpen, setIsOpen] = React.useState(false);
4818
4128
  const [inputValue, setInputValue] = React.useState("");
4819
4129
  const containerRef = React.useRef(null);
4820
4130
  const inputRef = React.useRef(null);
4821
- const prevValueRef = React.useRef(value);
4131
+ const prevValueRef = React.useRef(undefined);
4822
4132
  // Parse date from string based on format
4823
4133
  const parseDate = React.useCallback((dateString, formatStr) => {
4824
4134
  try {
@@ -4889,11 +4199,12 @@ function CwDatePicker({ value, onChange, minDate, maxDate, disabledDates, disabl
4889
4199
  }, [parseDate, displayFormat, minDate, maxDate, onChange, normalizeDateForComparison]);
4890
4200
  // Sync input value with prop value - only when changed externally
4891
4201
  React.useEffect(() => {
4892
- const currentValue = value;
4893
- if (currentValue !== prevValueRef.current) {
4894
- prevValueRef.current = currentValue;
4895
- if (currentValue) {
4896
- setInputValue(dateFns.format(currentValue, displayFormat, { locale: locale.enGB }));
4202
+ const currentTime = value?.getTime();
4203
+ const prevTime = prevValueRef.current?.getTime();
4204
+ if (currentTime !== prevTime) {
4205
+ prevValueRef.current = value;
4206
+ if (value) {
4207
+ setInputValue(dateFns.format(value, displayFormat, { locale: locale.enGB }));
4897
4208
  }
4898
4209
  else {
4899
4210
  setInputValue("");
@@ -4994,7 +4305,7 @@ function CwDatePicker({ value, onChange, minDate, maxDate, disabledDates, disabl
4994
4305
  ...(maxDate ? [{ after: maxDate }] : []),
4995
4306
  ...(disabledMatcher ? [disabledMatcher] : []),
4996
4307
  ], [disabledDates, minDate, maxDate, disabledMatcher]);
4997
- return (jsxRuntime.jsx("div", { ref: containerRef, className: `cw-datepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, required: required }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClear, tabIndex: -1, "aria-label": "Clear date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) }), isOpen && (jsxRuntime.jsxs("div", { className: styles$4.pickerPopup, "data-position": popupPosition, children: [jsxRuntime.jsx(reactDayPicker.DayPicker, { mode: "single", selected: value || undefined, defaultMonth: value || undefined, onSelect: handleDaySelect, disabled: disabledDays, locale: locale.enGB, numberOfMonths: numberOfMonths, formatters: formatters, components: {
4308
+ return (jsxRuntime.jsx("div", { ref: containerRef, className: `cw-datepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, required: required }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClear, tabIndex: -1, "aria-label": "Clear date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) }), isOpen && (jsxRuntime.jsxs("div", { className: styles$4.pickerPopup, "data-position": popupPosition, children: [jsxRuntime.jsx(reactDayPicker.DayPicker, { mode: "single", selected: value || undefined, defaultMonth: defaultMonth || value || undefined, onSelect: handleDaySelect, disabled: disabledDays, locale: locale.enGB, numberOfMonths: numberOfMonths, formatters: formatters, components: {
4998
4309
  Caption: (props) => (jsxRuntime.jsx(CustomCaption$2, { ...props })),
4999
4310
  }, modifiers: {
5000
4311
  today: new Date(),
@@ -5007,6 +4318,54 @@ var rangeStyles = {"rangeWrapper":"cw-range-picker-module_rangeWrapper__1nIVs","
5007
4318
 
5008
4319
  const PRESET_LIBRARY = {
5009
4320
  // === PAST DAYS ===
4321
+ today: {
4322
+ key: 'today',
4323
+ label: 'Today',
4324
+ getValue: () => {
4325
+ const from = new Date();
4326
+ from.setHours(0, 0, 0, 0);
4327
+ const to = new Date();
4328
+ to.setHours(23, 59, 59, 999);
4329
+ return { from, to };
4330
+ }
4331
+ },
4332
+ yesterday: {
4333
+ key: 'yesterday',
4334
+ label: 'Yesterday',
4335
+ getValue: () => {
4336
+ const from = new Date();
4337
+ from.setDate(from.getDate() - 1);
4338
+ from.setHours(0, 0, 0, 0);
4339
+ const to = new Date();
4340
+ to.setDate(to.getDate() - 1);
4341
+ to.setHours(23, 59, 59, 999);
4342
+ return { from, to };
4343
+ }
4344
+ },
4345
+ past2Days: {
4346
+ key: 'past2Days',
4347
+ label: 'Past 2 Days',
4348
+ getValue: () => {
4349
+ const today = new Date();
4350
+ today.setHours(23, 59, 59, 999);
4351
+ const twoDaysAgo = new Date();
4352
+ twoDaysAgo.setDate(today.getDate() - 2);
4353
+ twoDaysAgo.setHours(0, 0, 0, 0);
4354
+ return { from: twoDaysAgo, to: today };
4355
+ }
4356
+ },
4357
+ past3Days: {
4358
+ key: 'past3Days',
4359
+ label: 'Past 3 Days',
4360
+ getValue: () => {
4361
+ const today = new Date();
4362
+ today.setHours(23, 59, 59, 999);
4363
+ const threeDaysAgo = new Date();
4364
+ threeDaysAgo.setDate(today.getDate() - 3);
4365
+ threeDaysAgo.setHours(0, 0, 0, 0);
4366
+ return { from: threeDaysAgo, to: today };
4367
+ }
4368
+ },
5010
4369
  past7Days: {
5011
4370
  key: 'past7Days',
5012
4371
  label: 'Past 7 days',
@@ -5230,7 +4589,7 @@ function CustomCaption$1({ displayMonth }) {
5230
4589
  const { goToMonth, nextMonth, previousMonth } = reactDayPicker.useNavigation();
5231
4590
  return (jsxRuntime.jsxs("header", { children: [jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", icon: "chevron-left", onClick: () => previousMonth && goToMonth(previousMonth), disabled: !previousMonth, "aria-label": "Previous month" }), jsxRuntime.jsx("div", { className: styles$4.title, children: dateFns.format(displayMonth, "MMMM yyyy", { locale: locale.enGB }) }), jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", icon: "chevron-right", onClick: () => nextMonth && goToMonth(nextMonth), disabled: !nextMonth, "aria-label": "Next month" })] }));
5232
4591
  }
5233
- function CwDateRangePicker({ value, onChange, minDate, maxDate, disabledDates, disabledMatcher, maxRangeDays, labelProps, alignProps, placeholderFrom = "From date", placeholderTo = "To date", displayFormat = "dd.MM.yyyy", disabled, required, className, showClear = true, popupPosition = "left-bottom", numberOfMonths = 2, showPresets = false, presetKeys, customPresets, }) {
4592
+ function CwDateRangePicker({ value, onChange, minDate, maxDate, disabledDates, disabledMatcher, maxRangeDays, defaultMonth, labelProps, alignProps, placeholderFrom = "From date", placeholderTo = "To date", displayFormat = "dd.MM.yyyy", disabled, required, className, showClear = true, popupPosition = "left-bottom", numberOfMonths = 2, showPresets = false, presetKeys, customPresets, }) {
5234
4593
  const [isOpen, setIsOpen] = React.useState(false);
5235
4594
  const [inputFromValue, setInputFromValue] = React.useState("");
5236
4595
  const [inputToValue, setInputToValue] = React.useState("");
@@ -5238,7 +4597,7 @@ function CwDateRangePicker({ value, onChange, minDate, maxDate, disabledDates, d
5238
4597
  const containerRef = React.useRef(null);
5239
4598
  const inputFromRef = React.useRef(null);
5240
4599
  const inputToRef = React.useRef(null);
5241
- const prevValueRef = React.useRef(value ?? null);
4600
+ const prevValueRef = React.useRef(undefined);
5242
4601
  // Calculate presets to render
5243
4602
  const presetsToRender = React.useMemo(() => {
5244
4603
  let presets = [];
@@ -5321,17 +4680,26 @@ function CwDateRangePicker({ value, onChange, minDate, maxDate, disabledDates, d
5321
4680
  }, [maxRangeDays]);
5322
4681
  // Sync input values with prop value
5323
4682
  React.useEffect(() => {
5324
- const currentValue = value ?? undefined;
5325
- if (currentValue !== prevValueRef.current) {
5326
- prevValueRef.current = currentValue ?? null;
5327
- if (currentValue?.from) {
5328
- setInputFromValue(dateFns.format(currentValue.from, displayFormat, { locale: locale.enGB }));
4683
+ const currentFromTime = value?.from?.getTime();
4684
+ const currentToTime = value?.to?.getTime();
4685
+ const prevFromTime = prevValueRef.current?.fromTime;
4686
+ const prevToTime = prevValueRef.current?.toTime;
4687
+ // Only update if times have actually changed
4688
+ if (currentFromTime !== prevFromTime || currentToTime !== prevToTime) {
4689
+ prevValueRef.current = {
4690
+ fromTime: currentFromTime,
4691
+ toTime: currentToTime
4692
+ };
4693
+ // Update "from" input
4694
+ if (value?.from) {
4695
+ setInputFromValue(dateFns.format(value.from, displayFormat, { locale: locale.enGB }));
5329
4696
  }
5330
4697
  else {
5331
4698
  setInputFromValue("");
5332
4699
  }
5333
- if (currentValue?.to) {
5334
- setInputToValue(dateFns.format(currentValue.to, displayFormat, { locale: locale.enGB }));
4700
+ // Update "to" input
4701
+ if (value?.to) {
4702
+ setInputToValue(dateFns.format(value.to, displayFormat, { locale: locale.enGB }));
5335
4703
  }
5336
4704
  else {
5337
4705
  setInputToValue("");
@@ -5353,26 +4721,60 @@ function CwDateRangePicker({ value, onChange, minDate, maxDate, disabledDates, d
5353
4721
  document.removeEventListener("mousedown", handleClickOutside);
5354
4722
  };
5355
4723
  }, [isOpen]);
5356
- const handleRangeSelect = React.useCallback((range) => {
5357
- if (!range) {
5358
- onChange(undefined);
5359
- return;
4724
+ const handleRangeSelect = React.useCallback((range, // El rango sugerido por react-day-picker
4725
+ selectedDay) => {
4726
+ let newRange;
4727
+ if (focusedInput === 'from') {
4728
+ newRange = { from: selectedDay, to: value?.to };
4729
+ if (newRange.to && selectedDay > newRange.to) {
4730
+ newRange.to = undefined;
4731
+ setFocusedInput('to');
4732
+ }
4733
+ else if (newRange.to) {
4734
+ setIsOpen(false);
4735
+ setFocusedInput(undefined);
4736
+ }
4737
+ else {
4738
+ setFocusedInput('to');
4739
+ }
5360
4740
  }
5361
- const newRange = {
5362
- from: range.from,
5363
- to: range.to
5364
- };
5365
- // Validate range
4741
+ else if (focusedInput === 'to') {
4742
+ newRange = { from: value?.from, to: selectedDay };
4743
+ if (newRange.from && selectedDay < newRange.from) {
4744
+ newRange.from = undefined;
4745
+ setFocusedInput('from');
4746
+ }
4747
+ else if (newRange.from) {
4748
+ setIsOpen(false);
4749
+ setFocusedInput(undefined);
4750
+ }
4751
+ else {
4752
+ setFocusedInput('from');
4753
+ }
4754
+ }
4755
+ else {
4756
+ if (!range) {
4757
+ onChange(undefined);
4758
+ return;
4759
+ }
4760
+ newRange = { from: range.from, to: range.to };
4761
+ if (range.from && range.to) {
4762
+ setIsOpen(false);
4763
+ setFocusedInput(undefined);
4764
+ }
4765
+ else if (range.from) {
4766
+ setFocusedInput('to');
4767
+ }
4768
+ else {
4769
+ setFocusedInput('from');
4770
+ }
4771
+ }
4772
+ // Validate range before sending
5366
4773
  if (newRange.from && newRange.to && !validateRange(newRange.from, newRange.to)) {
5367
- return; // Don't update if invalid
4774
+ return;
5368
4775
  }
5369
4776
  onChange(newRange);
5370
- // Close if both dates are selected
5371
- if (range.from && range.to) {
5372
- setIsOpen(false);
5373
- setFocusedInput(undefined);
5374
- }
5375
- }, [onChange, validateRange]);
4777
+ }, [onChange, validateRange, value, focusedInput]);
5376
4778
  const handleClearFrom = React.useCallback((e) => {
5377
4779
  e.stopPropagation();
5378
4780
  onChange({ from: undefined, to: value?.to });
@@ -5494,7 +4896,9 @@ function CwDateRangePicker({ value, onChange, minDate, maxDate, disabledDates, d
5494
4896
  }
5495
4897
  }, []);
5496
4898
  // Handle preset click
5497
- const handlePresetClick = React.useCallback((preset) => {
4899
+ const handlePresetClick = React.useCallback((preset, e) => {
4900
+ e.preventDefault();
4901
+ e.stopPropagation();
5498
4902
  onChange(preset.getValue());
5499
4903
  setIsOpen(false);
5500
4904
  }, [onChange]);
@@ -5512,10 +4916,24 @@ function CwDateRangePicker({ value, onChange, minDate, maxDate, disabledDates, d
5512
4916
  ...(disabledMatcher ? [disabledMatcher] : []),
5513
4917
  ];
5514
4918
  // If maxRangeDays is set and we have a "from" date, disable dates beyond the range
5515
- if (maxRangeDays && value?.from && !value?.to) {
5516
- const maxDate = new Date(value.from);
5517
- maxDate.setDate(maxDate.getDate() + maxRangeDays);
5518
- baseDisabled.push({ after: maxDate });
4919
+ if (maxRangeDays) {
4920
+ if (value?.from) {
4921
+ const maxAllowedDate = new Date(value.from);
4922
+ maxAllowedDate.setDate(maxAllowedDate.getDate() + maxRangeDays);
4923
+ if (focusedInput !== 'from') {
4924
+ baseDisabled.push({ after: maxAllowedDate });
4925
+ }
4926
+ if (focusedInput === 'to' && !value?.to) {
4927
+ const minAllowedDate = new Date(value.from);
4928
+ minAllowedDate.setDate(minAllowedDate.getDate() - maxRangeDays);
4929
+ baseDisabled.push({ before: minAllowedDate });
4930
+ }
4931
+ }
4932
+ if (value?.to && !value?.from && focusedInput === 'from') {
4933
+ const minAllowedDate = new Date(value.to);
4934
+ minAllowedDate.setDate(minAllowedDate.getDate() - maxRangeDays);
4935
+ baseDisabled.push({ before: minAllowedDate });
4936
+ }
5519
4937
  }
5520
4938
  return baseDisabled;
5521
4939
  }, [disabledDates, minDate, maxDate, disabledMatcher, maxRangeDays, value]);
@@ -5528,7 +4946,7 @@ function CwDateRangePicker({ value, onChange, minDate, maxDate, disabledDates, d
5528
4946
  }
5529
4947
  return undefined;
5530
4948
  }, [value]);
5531
- return (jsxRuntime.jsx("div", { ref: containerRef, className: `cw-rangepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: rangeStyles.rangeWrapper, children: [jsxRuntime.jsxs("div", { className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputFromRef, type: "text", value: inputFromValue, placeholder: placeholderFrom, onChange: handleInputFromChange, onBlur: () => handleInputBlur('from'), onClick: handleInputFromClick, onKeyDown: (e) => handleInputKeyDown(e, 'from'), disabled: disabled, required: required, "data-focused": focusedInput === 'from' }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.from && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearFrom, tabIndex: -1, "aria-label": "Clear from date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) })] }), jsxRuntime.jsx(CwIcon, { iconId: "arrow-right", size: "medium" }), jsxRuntime.jsxs("div", { className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputToRef, type: "text", value: inputToValue, placeholder: placeholderTo, onChange: handleInputToChange, onBlur: () => handleInputBlur('to'), onClick: handleInputToClick, onKeyDown: (e) => handleInputKeyDown(e, 'to'), disabled: disabled, required: required, "data-focused": focusedInput === 'to' }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.to && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearTo, tabIndex: -1, "aria-label": "Clear to date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) })] }), isOpen && (jsxRuntime.jsxs("div", { className: `${styles$4.pickerPopup} ${rangeStyles.rangePopup}`, "data-position": popupPosition, children: [showPresets && presetsToRender.length > 0 && (jsxRuntime.jsx("div", { className: rangeStyles.presetList, children: presetsToRender.map((preset) => (jsxRuntime.jsx("button", { type: "button", onClick: () => handlePresetClick(preset), children: preset.label }, preset.key))) })), jsxRuntime.jsx(reactDayPicker.DayPicker, { mode: "range", selected: selectedRange, onSelect: handleRangeSelect, disabled: disabledDays, locale: locale.enGB, numberOfMonths: numberOfMonths, formatters: formatters, components: {
4949
+ return (jsxRuntime.jsx("div", { ref: containerRef, className: `cw-rangepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: rangeStyles.rangeWrapper, children: [jsxRuntime.jsxs("div", { className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputFromRef, type: "text", value: inputFromValue, placeholder: placeholderFrom, onChange: handleInputFromChange, onBlur: () => handleInputBlur('from'), onClick: handleInputFromClick, onKeyDown: (e) => handleInputKeyDown(e, 'from'), disabled: disabled, required: required, "data-focused": focusedInput === 'from' }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.from && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearFrom, tabIndex: -1, "aria-label": "Clear from date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) })] }), jsxRuntime.jsx(CwIcon, { iconId: "arrow-right", size: "medium" }), jsxRuntime.jsxs("div", { className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputToRef, type: "text", value: inputToValue, placeholder: placeholderTo, onChange: handleInputToChange, onBlur: () => handleInputBlur('to'), onClick: handleInputToClick, onKeyDown: (e) => handleInputKeyDown(e, 'to'), disabled: disabled, required: required, "data-focused": focusedInput === 'to' }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.to && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearTo, tabIndex: -1, "aria-label": "Clear to date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) })] }), isOpen && (jsxRuntime.jsxs("div", { className: `${styles$4.pickerPopup} ${rangeStyles.rangePopup}`, "data-position": popupPosition, children: [showPresets && presetsToRender.length > 0 && (jsxRuntime.jsx("div", { className: rangeStyles.presetList, children: presetsToRender.map((preset) => (jsxRuntime.jsx("button", { type: "button", onClick: (e) => handlePresetClick(preset, e), children: preset.label }, preset.key))) })), jsxRuntime.jsx(reactDayPicker.DayPicker, { mode: "range", selected: selectedRange, onSelect: handleRangeSelect, disabled: disabledDays, locale: locale.enGB, numberOfMonths: numberOfMonths, defaultMonth: defaultMonth || value?.from || undefined, formatters: formatters, components: {
5532
4950
  Caption: (props) => jsxRuntime.jsx(CustomCaption$1, { ...props }),
5533
4951
  }, modifiers: {
5534
4952
  today: new Date(),
@@ -5706,10 +5124,52 @@ function CwTimePicker({ value, onChange, interval = 15, minTime, maxTime, labelP
5706
5124
  }
5707
5125
 
5708
5126
  function CwDateTimePicker({ value, onChange, minDateTime, maxDateTime, disabledDates, disabledMatcher, timeInterval = 15, minTime, maxTime, labelProps, alignProps, datePlaceholder = "dd.MM.yyyy", timePlaceholder = "HH:mm", disabled, required, className, showClear = true, popupPosition = "left-bottom", numberOfMonths = 1, showNowButton = false, }) {
5127
+ // ========================================
5128
+ // PROPS NORMALIZATION
5129
+ // ========================================
5130
+ /**
5131
+ * Normalize datetime prop to valid Date object
5132
+ * @returns Valid Date object or undefined if invalid
5133
+ */
5134
+ const normalizeDateTime = React.useCallback((dateTime, propName) => {
5135
+ if (!dateTime)
5136
+ return undefined;
5137
+ try {
5138
+ // Convert to Date object if not already
5139
+ const date = dateTime instanceof Date
5140
+ ? dateTime
5141
+ : new Date(dateTime);
5142
+ // Validate the Date object is valid
5143
+ if (isNaN(date.getTime())) {
5144
+ console.warn(`[CwDateTimePicker] Invalid ${propName} provided:`, dateTime);
5145
+ return undefined;
5146
+ }
5147
+ return date;
5148
+ }
5149
+ catch (error) {
5150
+ console.warn(`[CwDateTimePicker] Error parsing ${propName}:`, dateTime, error);
5151
+ return undefined;
5152
+ }
5153
+ }, []);
5154
+ // Normalize min/max datetime props using the helper
5155
+ const normalizedMinDateTime = React.useMemo(() => normalizeDateTime(minDateTime, 'minDateTime'), [minDateTime, normalizeDateTime]);
5156
+ const normalizedMaxDateTime = React.useMemo(() => normalizeDateTime(maxDateTime, 'maxDateTime'), [maxDateTime, normalizeDateTime]);
5157
+ // ========================================
5158
+ // INTERNAL STATE
5159
+ // ========================================
5709
5160
  const [selectedDate, setSelectedDate] = React.useState(value);
5710
5161
  const [selectedTime, setSelectedTime] = React.useState(value ? `${value.getHours().toString().padStart(2, "0")}:${value.getMinutes().toString().padStart(2, "0")}` : undefined);
5711
- const prevValueRef = React.useRef(value);
5712
- // Combine date and time into a single Date object
5162
+ // Track previous value to detect external changes
5163
+ const prevValueRef = React.useRef(undefined);
5164
+ // ========================================
5165
+ // COMBINATION AND VALIDATION LOGIC
5166
+ // ========================================
5167
+ /**
5168
+ * Combine date and time into a single Date object
5169
+ * Validates the combined datetime against min/max constraints
5170
+ *
5171
+ * @returns Combined Date object or undefined if invalid
5172
+ */
5713
5173
  const combineDateTime = React.useCallback((date, time) => {
5714
5174
  if (!date)
5715
5175
  return undefined;
@@ -5717,21 +5177,85 @@ function CwDateTimePicker({ value, onChange, minDateTime, maxDateTime, disabledD
5717
5177
  if (!time) {
5718
5178
  const combined = new Date(date);
5719
5179
  combined.setHours(0, 0, 0, 0);
5180
+ // Validate against min/max datetime
5181
+ if (normalizedMinDateTime && combined < normalizedMinDateTime)
5182
+ return undefined;
5183
+ if (normalizedMaxDateTime && combined > normalizedMaxDateTime)
5184
+ return undefined;
5720
5185
  return combined;
5721
5186
  }
5187
+ // Parse time and combine with date
5722
5188
  const [hours, minutes] = time.split(':').map(Number);
5723
5189
  const combined = new Date(date);
5724
5190
  combined.setHours(hours, minutes, 0, 0);
5191
+ // Validate against min/max datetime
5192
+ if (normalizedMinDateTime && combined < normalizedMinDateTime)
5193
+ return undefined;
5194
+ if (normalizedMaxDateTime && combined > normalizedMaxDateTime)
5195
+ return undefined;
5725
5196
  return combined;
5726
- }, []);
5727
- // Sync internal state with prop value - only when changed externally
5197
+ }, [normalizedMinDateTime, normalizedMaxDateTime]);
5198
+ /**
5199
+ * Calculate dynamic time restrictions based on selected date
5200
+ *
5201
+ * If the selected date matches the min/max date boundary, restrict times accordingly.
5202
+ * Allows users to manually type any valid time, not just interval-aligned times.
5203
+ * The timeInterval prop only affects the dropdown options, not manual input validation.
5204
+ *
5205
+ * @param selectedDate - Currently selected date
5206
+ * @returns Object with minTime and maxTime strings in "HH:mm" format
5207
+ */
5208
+ const calculateTimeRestrictions = React.useCallback((selectedDate) => {
5209
+ if (!selectedDate)
5210
+ return { minTime, maxTime };
5211
+ // Normalize selected date to date-only (ignore time component)
5212
+ const selectedDateOnly = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate());
5213
+ let calculatedMinTime = minTime;
5214
+ let calculatedMaxTime = maxTime;
5215
+ // If selected date matches minDateTime date, restrict minimum time
5216
+ if (normalizedMinDateTime) {
5217
+ const minDateOnly = new Date(normalizedMinDateTime.getFullYear(), normalizedMinDateTime.getMonth(), normalizedMinDateTime.getDate());
5218
+ if (selectedDateOnly.getTime() === minDateOnly.getTime()) {
5219
+ const hours = normalizedMinDateTime.getHours().toString().padStart(2, "0");
5220
+ const minutes = normalizedMinDateTime.getMinutes().toString().padStart(2, "0");
5221
+ calculatedMinTime = `${hours}:${minutes}`;
5222
+ }
5223
+ }
5224
+ // If selected date matches maxDateTime date, restrict maximum time
5225
+ if (normalizedMaxDateTime) {
5226
+ const maxDateOnly = new Date(normalizedMaxDateTime.getFullYear(), normalizedMaxDateTime.getMonth(), normalizedMaxDateTime.getDate());
5227
+ if (selectedDateOnly.getTime() === maxDateOnly.getTime()) {
5228
+ const hours = normalizedMaxDateTime.getHours().toString().padStart(2, "0");
5229
+ const minutes = normalizedMaxDateTime.getMinutes().toString().padStart(2, "0");
5230
+ calculatedMaxTime = `${hours}:${minutes}`;
5231
+ }
5232
+ }
5233
+ return {
5234
+ minTime: calculatedMinTime,
5235
+ maxTime: calculatedMaxTime
5236
+ };
5237
+ }, [normalizedMinDateTime, normalizedMaxDateTime, minTime, maxTime]);
5238
+ // Calculate current time restrictions based on selected date
5239
+ // Recalculates whenever selectedDate or the calculation function changes
5240
+ const timeRestrictions = React.useMemo(() => calculateTimeRestrictions(selectedDate), [selectedDate, calculateTimeRestrictions]);
5241
+ // ========================================
5242
+ // SYNC WITH EXTERNAL VALUE PROP
5243
+ // ========================================
5244
+ /**
5245
+ * Sync internal state with prop value - only when changed externally
5246
+ * Uses prevValueRef to detect if the change came from outside
5247
+ * (e.g., parent component updated the value programmatically)
5248
+ * vs. internal changes (user interaction)
5249
+ */
5728
5250
  React.useEffect(() => {
5729
- const currentValue = value ?? undefined;
5730
- if (currentValue !== prevValueRef.current) {
5731
- prevValueRef.current = currentValue;
5732
- if (currentValue) {
5733
- setSelectedDate(currentValue);
5734
- setSelectedTime(`${currentValue.getHours().toString().padStart(2, "0")}:${currentValue.getMinutes().toString().padStart(2, "0")}`);
5251
+ const currentTime = value?.getTime();
5252
+ const prevTime = prevValueRef.current?.getTime();
5253
+ // Only update if value actually changed
5254
+ if (currentTime !== prevTime) {
5255
+ prevValueRef.current = value;
5256
+ if (value) {
5257
+ setSelectedDate(value);
5258
+ setSelectedTime(`${value.getHours().toString().padStart(2, "0")}:${value.getMinutes().toString().padStart(2, "0")}`);
5735
5259
  }
5736
5260
  else {
5737
5261
  setSelectedDate(undefined);
@@ -5739,29 +5263,81 @@ function CwDateTimePicker({ value, onChange, minDateTime, maxDateTime, disabledD
5739
5263
  }
5740
5264
  }
5741
5265
  }, [value]);
5266
+ // ========================================
5267
+ // EVENT HANDLERS
5268
+ // ========================================
5269
+ /**
5270
+ * Handle date selection change
5271
+ *
5272
+ * When date changes, validates if the currently selected time is still valid.
5273
+ * If time becomes invalid (e.g., user switched from Mar 14 to Mar 15 with maxTime=16:27,
5274
+ * and had 18:00 selected), it resets the time to undefined.
5275
+ */
5742
5276
  const handleDateChange = React.useCallback((date) => {
5743
5277
  setSelectedDate(date);
5744
- const combined = combineDateTime(date, selectedTime);
5745
- onChange(combined);
5746
- }, [selectedTime, combineDateTime, onChange]);
5278
+ if (date && selectedTime) {
5279
+ const combined = combineDateTime(date, selectedTime);
5280
+ if (!combined) {
5281
+ // Time is no longer valid for this date
5282
+ // Auto-set to first valid time (minTime)
5283
+ const restrictions = calculateTimeRestrictions(date);
5284
+ const newTime = restrictions.minTime || undefined;
5285
+ setSelectedTime(newTime);
5286
+ onChange(combineDateTime(date, newTime));
5287
+ return;
5288
+ }
5289
+ onChange(combined);
5290
+ }
5291
+ else if (date) {
5292
+ // Just date selected, no time yet
5293
+ // Auto-set to minTime if available for better UX
5294
+ const restrictions = calculateTimeRestrictions(date);
5295
+ if (restrictions.minTime) {
5296
+ setSelectedTime(restrictions.minTime);
5297
+ onChange(combineDateTime(date, restrictions.minTime));
5298
+ }
5299
+ else {
5300
+ onChange(undefined);
5301
+ }
5302
+ }
5303
+ else {
5304
+ onChange(undefined);
5305
+ }
5306
+ }, [selectedTime, combineDateTime, onChange, calculateTimeRestrictions]);
5307
+ /**
5308
+ * Handle time selection change
5309
+ *
5310
+ * Combines the new time with the selected date and validates.
5311
+ * Only calls onChange if the combination is valid.
5312
+ */
5747
5313
  const handleTimeChange = React.useCallback((time) => {
5748
5314
  setSelectedTime(time);
5749
5315
  const combined = combineDateTime(selectedDate, time);
5750
- onChange(combined);
5316
+ // Only update if the combination is valid
5317
+ if (combined !== undefined || !time) {
5318
+ onChange(combined);
5319
+ }
5751
5320
  }, [selectedDate, combineDateTime, onChange]);
5321
+ /**
5322
+ * Handle "Now" button click
5323
+ * Sets the datetime to the current moment, if it's within the allowed min/max datetime range.
5324
+ */
5752
5325
  const handleNowClick = React.useCallback(() => {
5753
5326
  const now = new Date();
5754
5327
  // Check if now is within allowed range
5755
- const isNowValid = (!minDateTime || now >= minDateTime) &&
5756
- (!maxDateTime || now <= maxDateTime);
5328
+ const isNowValid = (!normalizedMinDateTime || now >= normalizedMinDateTime) &&
5329
+ (!normalizedMaxDateTime || now <= normalizedMaxDateTime);
5757
5330
  if (isNowValid) {
5758
5331
  onChange(now);
5759
5332
  }
5760
- }, [minDateTime, maxDateTime, onChange]);
5761
- // Extract min/max date from minDateTime/maxDateTime
5762
- const minDate = minDateTime;
5763
- const maxDate = maxDateTime;
5764
- return (jsxRuntime.jsx("div", { className: `cw-datetimepicker cw-datetimepicker-separate ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: "cw-flex-row cw-align-left-center cw-gap-small", children: [jsxRuntime.jsx(CwDatePicker, { value: selectedDate, onChange: handleDateChange, minDate: minDate, maxDate: maxDate, disabledDates: disabledDates, disabledMatcher: disabledMatcher, placeholder: datePlaceholder, disabled: disabled, required: required, showClear: showClear, numberOfMonths: numberOfMonths, popupPosition: popupPosition }), jsxRuntime.jsx(CwTimePicker, { value: selectedTime, onChange: handleTimeChange, interval: timeInterval, minTime: minTime, maxTime: maxTime, placeholder: timePlaceholder, disabled: disabled, required: required, showClear: showClear, popupPosition: popupPosition }), showNowButton && (jsxRuntime.jsx(CwButton, { type: "button", variant: "outline", onClick: handleNowClick, disabled: disabled, title: "Set to current date and time", text: "Now" }))] })] }) }));
5333
+ }, [normalizedMinDateTime, normalizedMaxDateTime, onChange]);
5334
+ // Extract min/max date from normalized datetime for DatePicker
5335
+ const minDate = normalizedMinDateTime;
5336
+ const maxDate = normalizedMaxDateTime;
5337
+ // ========================================
5338
+ // RENDER
5339
+ // ========================================
5340
+ return (jsxRuntime.jsx("div", { className: `cw-datetimepicker cw-datetimepicker-separate ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: "cw-flex-row cw-align-left-center cw-gap-small", children: [jsxRuntime.jsx(CwDatePicker, { value: selectedDate, onChange: handleDateChange, minDate: minDate, maxDate: maxDate, disabledDates: disabledDates, disabledMatcher: disabledMatcher, placeholder: datePlaceholder, disabled: disabled, required: required, showClear: showClear, numberOfMonths: numberOfMonths, popupPosition: popupPosition }), jsxRuntime.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 && (jsxRuntime.jsx(CwButton, { type: "button", variant: "outline", onClick: handleNowClick, disabled: disabled, title: "Set to current date and time", text: "Now" }))] })] }) }));
5765
5341
  }
5766
5342
 
5767
5343
  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"};
@@ -7066,8 +6642,8 @@ class CwScheduler2 extends React.Component {
7066
6642
  this.handleResize();
7067
6643
  }
7068
6644
  if (dateChange) {
7069
- const events = lodash.cloneDeep(this.props.events);
7070
- const resources = lodash.cloneDeep(this.props.resources);
6645
+ const events = lodashEs.cloneDeep(this.props.events);
6646
+ const resources = lodashEs.cloneDeep(this.props.resources);
7071
6647
  this.initOutside(events, resources, _nextProps, _nextProps.startDate, _nextProps.endDate);
7072
6648
  if (this.state.showConsoleLogs) {
7073
6649
  console.log("Schedule - componentWillReceiveProps - print on schedule, end: ", moment(new Date()).toString());
@@ -7190,6 +6766,12 @@ const PinButton = ({ canBePinned, resource, onCrewPinning }) => {
7190
6766
  return jsxRuntime.jsx("button", { className: "cw-button-icon cw-icon-pin", ...buttonProps });
7191
6767
  };
7192
6768
 
6769
+ const addMinutesToDateFromPx = (originalDate, leftPx, minutesPerPx) => {
6770
+ const minutes = leftPx / minutesPerPx;
6771
+ const datePlusMinutes = new Date(originalDate.getTime() + minutes * 60000);
6772
+ return datePlusMinutes;
6773
+ };
6774
+
7193
6775
  const doubleClickOnResource = (props, resource) => {
7194
6776
  if (props.scheduler_handleDblClickOnResourceInScheduler) {
7195
6777
  props.scheduler_handleDblClickOnResourceInScheduler(resource);
@@ -7356,12 +6938,6 @@ const EventRender = ({ event, schedulerProps }) => {
7356
6938
  return render;
7357
6939
  };
7358
6940
 
7359
- const addMinutesToDateFromPx = (originalDate, leftPx, minutesPerPx) => {
7360
- const minutes = leftPx / minutesPerPx;
7361
- const datePlusMinutes = new Date(originalDate.getTime() + minutes * 60000);
7362
- return datePlusMinutes;
7363
- };
7364
-
7365
6941
  const onDropEventToResource = (props, cblDragNDrop, resource) => {
7366
6942
  props.scheduler_handleOnDropCblEventsOnResource.call(props.parent, cblDragNDrop, resource);
7367
6943
  };
@@ -7461,12 +7037,25 @@ const ResourceRender = React.memo(({ res, schedulerProps, contentArea, state })
7461
7037
  }, className: "cwellt_divRow_schContent", children: res.events.map((evnt) => (jsxRuntime.jsx(EventRender, { event: evnt, schedulerProps: schedulerProps }, evnt.id))) }, res.id));
7462
7038
  }, arePropsEqual);
7463
7039
 
7464
- const ResourceListRender = ({ resources, schedulerProps, state, contentArea, onClickContextMenu, crewAssignmentSchedulerContextMenu, }) => {
7465
- return (jsxRuntime.jsx(React.Fragment, { children: resources.map((r, _i) => (jsxRuntime.jsx(antd.Dropdown, { placement: "topLeft", dropdownRender: () => {
7466
- return (jsxRuntime.jsx(antd.Menu, { style: { pointerEvents: "auto" }, onClick: (e) => {
7467
- onClickContextMenu(e, r);
7468
- }, children: crewAssignmentSchedulerContextMenu?.map((m) => (jsxRuntime.jsxs(antd.Menu.Item, { children: [jsxRuntime.jsx("span", { className: m.icon, style: { color: m.color } }), jsxRuntime.jsx("span", { className: "cwellt_contextMenu", children: m.text })] }, m.key))) }));
7469
- }, trigger: ["contextMenu"], children: jsxRuntime.jsx("span", { onDoubleClick: () => doubleClickOnResource(schedulerProps, r), id: schedulerProps.id + "_" + r.id, children: jsxRuntime.jsx(ResourceRender, { res: r, schedulerProps: schedulerProps, contentArea: contentArea, state: state, isInViewport: r.isInViewport }, r.id) }) }, r.id))) }));
7040
+ const ResourceListRender = ({ resources, schedulerProps, state, contentArea,
7041
+ // onClickContextMenu,
7042
+ crewAssignmentSchedulerContextMenu, }) => {
7043
+ return (jsxRuntime.jsx(React.Fragment, { children: resources.map((r, _i) => (jsxRuntime.jsx(CwAnchoredMenu, { placement: "bottom", onContextMenu: (e) => {
7044
+ // Dirty temporal solution to remove ANT design, this can be killed when this scheduler is deprecated
7045
+ const leftPos = e.currentTarget.getBoundingClientRect().left -
7046
+ (contentArea?.getBoundingClientRect()?.left ?? 0) -
7047
+ window.scrollX;
7048
+ const calculatedDatetime = addMinutesToDateFromPx(schedulerProps.startDate, leftPos, state.minutePx);
7049
+ r.__contextMenuDatetime = calculatedDatetime;
7050
+ }, options: crewAssignmentSchedulerContextMenu?.map(m => ({
7051
+ key: m.key,
7052
+ label: (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { className: m.icon, style: { color: m.color } }), jsxRuntime.jsx("span", { children: m.text })] }))
7053
+ })) ?? [], onSelect: (key) => {
7054
+ const datetime = r.__contextMenuDatetime ?? new Date();
7055
+ if (schedulerProps.scheduler_handleOnClickContextMenuResource) {
7056
+ schedulerProps.scheduler_handleOnClickContextMenuResource(datetime, r, key, schedulerProps.id);
7057
+ }
7058
+ }, children: jsxRuntime.jsx("span", { onDoubleClick: () => doubleClickOnResource(schedulerProps, r), id: schedulerProps.id + "_" + r.id, children: jsxRuntime.jsx(ResourceRender, { res: r, schedulerProps: schedulerProps, contentArea: contentArea, state: state, isInViewport: r.isInViewport }, r.id) }) }, r.id))) }));
7470
7059
  };
7471
7060
 
7472
7061
  const TimeLine$1 = ({ id, toolTipTitle, marginLeft, color = "rgba(255,0,0,.6)", pixels = 2, height = "100%", zIndex = 1, }) => {
@@ -8221,6 +7810,13 @@ function getPercentageFromMouseEvent(event) {
8221
7810
  const clickPercentage = x / totalWidth;
8222
7811
  return clickPercentage;
8223
7812
  }
7813
+ function getPercentageFromElement(clientX, element) {
7814
+ const rect = element.getBoundingClientRect();
7815
+ const x = clientX - rect.left;
7816
+ const totalWidth = rect.width;
7817
+ const clickPercentage = x / totalWidth;
7818
+ return clickPercentage;
7819
+ }
8224
7820
 
8225
7821
  class OnClickEvent {
8226
7822
  id;
@@ -8457,15 +8053,13 @@ const BackgroundEvent = ({ value, heightRem }) => {
8457
8053
 
8458
8054
  var styles$1 = {"scheduler-row-header":"scheduler-row-module_scheduler-row-header__S-iv4"};
8459
8055
 
8460
- 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"};
8461
-
8462
8056
  const DefaultRowHeader = ({ value, width, onEvent }) => {
8463
8057
  return (jsxRuntime.jsxs("div", { style: {
8464
8058
  width: width,
8465
8059
  // background: color,
8466
8060
  }, onClick: (_) => {
8467
8061
  onEvent(new OnClickRowHeader(value.rowId));
8468
- }, className: styles$1["scheduler-row-header"], children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("strong", { children: value.title }), value.title2 && jsxRuntime.jsxs("span", { children: ["-", value.title2] }), " ", jsxRuntime.jsx("strong", { children: value.subtitle })] }), value.subtitle && jsxRuntime.jsxs("div", { style: { opacity: 0.5 }, children: [value.title3 && jsxRuntime.jsxs("span", { className: styles["scheduler-crewmember-functions"], children: ["(", value.title3, ")"] }), value.subtitle2 && jsxRuntime.jsxs("span", { children: ["-", value.subtitle2] })] })] }));
8062
+ }, className: styles$1["scheduler-row-header"], children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("strong", { children: value.title }), value.title2 && jsxRuntime.jsxs("span", { children: ["-", value.title2] }), " ", jsxRuntime.jsx("strong", { children: value.subtitle })] }), value.subtitle && jsxRuntime.jsxs("div", { style: { opacity: 0.5 }, children: [value.title3 && jsxRuntime.jsxs("span", { className: styles$1["scheduler-crewmember-functions"], children: ["(", value.title3, ")"] }), value.subtitle2 && jsxRuntime.jsxs("span", { children: ["-", value.subtitle2] })] })] }));
8469
8063
  };
8470
8064
 
8471
8065
  function useSingleAndDoubleClicks(onClick, onDoubleClick) {
@@ -8510,7 +8104,7 @@ const SchedulerEvent = ({ value, heightRem, onEvent }) => {
8510
8104
  const [isOnDrag, setIsOnDrag] = React.useState(false);
8511
8105
  const [isContextMenuOpen, setIsContextMenuOpen] = React.useState(false);
8512
8106
  // Calculate colors of the event
8513
- const backColor = getHSLColor(value.color, value.alpha ?? 0.75);
8107
+ const backColor = getHSLColor(value.color, value.alpha ?? 1);
8514
8108
  const textColor = getContrastColor(value.color);
8515
8109
  const eventTransparent = value.alpha ? value.alpha < 0.7 : false;
8516
8110
  const canClick = value.isDraggable || value.isClickable === true;
@@ -8538,18 +8132,12 @@ const SchedulerEvent = ({ value, heightRem, onEvent }) => {
8538
8132
  e.preventDefault();
8539
8133
  onEvent(new OnDoubleClickEvent(value.id));
8540
8134
  });
8541
- return (jsxRuntime.jsx(antd.Dropdown, { open: isContextMenuOpen, onOpenChange: setIsContextMenuOpen, placement: "bottom", menu: {
8542
- items: value.contextMenuItems,
8543
- onClick: (e) => {
8544
- e.domEvent.nativeEvent.preventDefault();
8545
- e.domEvent.nativeEvent.stopPropagation();
8546
- e.domEvent.nativeEvent.stopImmediatePropagation();
8547
- e.domEvent.preventDefault();
8548
- e.domEvent.stopPropagation();
8549
- onEvent(new OnClickContextMenu(value.id, e.key));
8550
- },
8551
- onMouseLeave: () => setIsContextMenuOpen(false),
8552
- }, trigger: ["contextMenu"], overlayStyle: { animationDuration: "0" }, arrow: (value.contextMenuItems?.length ?? 0) > 0, children: jsxRuntime.jsx("div", { style: {
8135
+ return (jsxRuntime.jsx(CwAnchoredMenu, { open: isContextMenuOpen, onOpenChange: setIsContextMenuOpen, onContextMenu: (e) => {
8136
+ e.stopPropagation();
8137
+ // onEvent(new OnRightClickEvent(value.id));
8138
+ }, placement: "bottom", options: value.contextMenuItems ?? [], onSelect: (key) => {
8139
+ onEvent(new OnClickContextMenu(value.id, key));
8140
+ }, children: jsxRuntime.jsx("div", { style: {
8553
8141
  top: "2px",
8554
8142
  left: `${value.left}%`,
8555
8143
  width: `${value.width}%`,
@@ -8569,10 +8157,6 @@ const SchedulerEvent = ({ value, heightRem, onEvent }) => {
8569
8157
  }, onDragEnd: (_) => {
8570
8158
  if (value.isDraggable)
8571
8159
  setIsOnDrag(false);
8572
- }, onContextMenu: (e) => {
8573
- e.stopPropagation();
8574
- e.preventDefault();
8575
- onEvent(new OnRightClickEvent(value.id));
8576
8160
  }, children: jsxRuntime.jsx(CwGenericTooltip, { content: value.tooltip, position: "bottom", hide: isOnDrag, dissapearsWhenHover: true, showDelay: 200, children: jsxRuntime.jsxs("div", { style: {
8577
8161
  border: value.selected ? "2px solid black" : "none",
8578
8162
  backgroundColor: backColor,
@@ -8615,7 +8199,7 @@ const SchedulerEvent = ({ value, heightRem, onEvent }) => {
8615
8199
  backgroundColor: value.primaryTimeMarkerColor,
8616
8200
  } })), value.secondaryTimeMarkerColor && (jsxRuntime.jsx("div", { className: styles$2["time-marker"], style: {
8617
8201
  backgroundColor: value.secondaryTimeMarkerColor,
8618
- } }))] }) }) }, value.id) }, value.id));
8202
+ } }))] }) }) }, value.id) }));
8619
8203
  };
8620
8204
 
8621
8205
  const eventsCollide = (event1, event2) => {
@@ -8659,18 +8243,11 @@ const WeekEndLine = ({ left, top = "0px", height, widthPercentage }) => {
8659
8243
  return (jsxRuntime.jsx(TimeLine, { color: "rgba(0,0,0,0.05)", left: left + "%", height: height, width: widthPercentage + "%", top: top }));
8660
8244
  };
8661
8245
 
8662
- const onClickMenuItem$1 = (e, event) => {
8663
- e.domEvent.nativeEvent.preventDefault();
8664
- e.domEvent.nativeEvent.stopPropagation();
8665
- e.domEvent.nativeEvent.stopImmediatePropagation();
8666
- e.domEvent.preventDefault();
8667
- e.domEvent.stopPropagation();
8668
- event();
8669
- };
8670
8246
  const SchedulerRow = React.memo((props) => {
8671
8247
  const [isContextMenuOpen, setIsContextMenuOpen] = React.useState(false);
8672
8248
  const { events, backgroundEvents, rowHeader, contextMenuItems, RowTitleComp, EventComp, BackgroundEventComp, weekendLines, divisionLines, timeLinePercentage, selectedDate, visibleDays, onEvent, } = props;
8673
8249
  const internalRows = separateEventsToInnerRows(events);
8250
+ const schedulerDivRef = React.useRef(null);
8674
8251
  const { handleClick, handleDoubleClick } = useSingleAndDoubleClicks((e) => {
8675
8252
  e.stopPropagation();
8676
8253
  e.preventDefault();
@@ -8683,15 +8260,17 @@ const SchedulerRow = React.memo((props) => {
8683
8260
  return (jsxRuntime.jsxs("div", { style: {
8684
8261
  display: "flex",
8685
8262
  minHeight: props.rowHeightInRem + "rem",
8686
- }, children: [jsxRuntime.jsx(RowTitleComp, { ...rowHeader }), jsxRuntime.jsx(antd.Dropdown, { open: isContextMenuOpen, onOpenChange: setIsContextMenuOpen, placement: "bottom", menu: {
8687
- items: contextMenuItems,
8688
- onClick: (e) => {
8689
- onClickMenuItem$1(e, () => {
8690
- onEvent(new OnClickContextMenu(rowHeader.value.rowId, e.key));
8691
- });
8692
- },
8693
- onMouseLeave: () => setIsContextMenuOpen(false),
8694
- }, trigger: ["contextMenu"], overlayStyle: { animationDuration: "0" }, arrow: (contextMenuItems?.length ?? 0) > 0, children: jsxRuntime.jsxs("div", { style: {
8263
+ }, "data-name": "scheduler-row", children: [jsxRuntime.jsx(RowTitleComp, { ...rowHeader }), jsxRuntime.jsx(CwAnchoredMenu, { open: isContextMenuOpen, onOpenChange: setIsContextMenuOpen, placement: "bottom", options: contextMenuItems ?? [], onSelect: (key) => {
8264
+ onEvent(new OnClickContextMenu(rowHeader.value.rowId, key));
8265
+ }, onContextMenu: (e) => {
8266
+ // e.preventDefault();
8267
+ e.stopPropagation();
8268
+ if (!schedulerDivRef.current)
8269
+ return;
8270
+ const percentage = getPercentageFromElement(e.clientX, schedulerDivRef.current);
8271
+ const date = dateFromPercentage(selectedDate, visibleDays, percentage);
8272
+ onEvent(new OnRightClickRow(rowHeader.value.rowId, date));
8273
+ }, children: jsxRuntime.jsxs("div", { ref: schedulerDivRef, style: {
8695
8274
  flex: 1,
8696
8275
  display: "flex",
8697
8276
  flexDirection: "column",
@@ -8700,8 +8279,6 @@ const SchedulerRow = React.memo((props) => {
8700
8279
  e.preventDefault();
8701
8280
  const percentage = getPercentageFromMouseEvent(e);
8702
8281
  const date = dateFromPercentage(selectedDate, visibleDays, percentage);
8703
- // https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData/platform
8704
- // change for navigator.userAgentData.platform when acepted in all browsers
8705
8282
  const isMac = navigator.platform.toUpperCase().includes("MAC");
8706
8283
  const isCtrlOrAltPressed = isMac ? e.altKey : e.ctrlKey;
8707
8284
  if (isCtrlOrAltPressed) {
@@ -8712,13 +8289,7 @@ const SchedulerRow = React.memo((props) => {
8712
8289
  }
8713
8290
  }, onDragOver: (e) => {
8714
8291
  e.preventDefault();
8715
- }, onClick: handleClick, onDoubleClick: handleDoubleClick, onContextMenu: (e) => {
8716
- e.preventDefault();
8717
- e.stopPropagation();
8718
- const percentage = getPercentageFromMouseEvent(e);
8719
- const date = dateFromPercentage(selectedDate, visibleDays, percentage);
8720
- onEvent(new OnRightClickRow(rowHeader.value.rowId, date));
8721
- }, children: [weekendLines.map((weekend) => (jsxRuntime.jsx(WeekEndLine, { height: "100%", left: weekend.left, widthPercentage: weekend.width }, weekend.left))), divisionLines.map((division) => (jsxRuntime.jsx(DivisionLine, { height: "100%", left: division.left }, division.left))), backgroundEvents.length > 0 && backgroundEvents.some((e) => e.isVisible) && (jsxRuntime.jsx("div", { style: {
8292
+ }, onClick: handleClick, onDoubleClick: handleDoubleClick, children: [weekendLines.map((weekend) => (jsxRuntime.jsx(WeekEndLine, { height: "100%", left: weekend.left, widthPercentage: weekend.width }, weekend.left))), divisionLines.map((division) => (jsxRuntime.jsx(DivisionLine, { height: "100%", left: division.left }, division.left))), backgroundEvents.length > 0 && backgroundEvents.some((e) => e.isVisible) && (jsxRuntime.jsx("div", { style: {
8722
8293
  height: "100%",
8723
8294
  position: internalRows.length > 0 ? "absolute" : "relative",
8724
8295
  width: "100%",
@@ -8731,7 +8302,7 @@ const SchedulerRow = React.memo((props) => {
8731
8302
  height: props.rowHeightInRem + "rem",
8732
8303
  pointerEvents: "none"
8733
8304
  }, children: internalRow.map((event) => (jsxRuntime.jsx(EventComp, { value: event, heightRem: props.rowHeightInRem, onEvent: onEvent }, event.id))) }, index));
8734
- }), !(timeLinePercentage < 0 || timeLinePercentage > 100) && (jsxRuntime.jsx(TimeLine, { color: "red", left: `${timeLinePercentage}%`, top: "0px", height: `100%` }))] }) }, rowHeader.value.rowId)] }));
8305
+ }), !(timeLinePercentage < 0 || timeLinePercentage > 100) && (jsxRuntime.jsx(TimeLine, { color: "red", left: `${timeLinePercentage}%`, top: "0px", height: `100%` }))] }) })] }));
8735
8306
  }, (prevProps, nextProps) => {
8736
8307
  // This memo is necessary to prevent re-render all the rows when a user makes drag and drop
8737
8308
  const getEventKey = (event) => {
@@ -8991,6 +8562,8 @@ const getNow = (isUtc) => {
8991
8562
  return now;
8992
8563
  };
8993
8564
  const rowsHeight = 1.75; // rem
8565
+ const milliSecondsInSecond = 1000;
8566
+ const refreshMilliSeconds = 45 * milliSecondsInSecond;
8994
8567
  const Scheduler = (props) => {
8995
8568
  const { header: headerContent, id, events: eventsState, backgroundEvents, contextMenuItems, EventComp, RowTitleComp, orderCategories = ["title"], useOrderCategory, onEvent, groupRowColors, rowHeaderWidth = 180, } = props;
8996
8569
  const BackgroundEventComp = props.BackgroundEventComp ?? BackgroundEvent;
@@ -9034,7 +8607,7 @@ const Scheduler = (props) => {
9034
8607
  setTimeLinePercentage(percentage);
9035
8608
  };
9036
8609
  updateTimeLinePercentage();
9037
- const interval = setInterval(updateTimeLinePercentage, 10_000);
8610
+ const interval = setInterval(updateTimeLinePercentage, refreshMilliSeconds);
9038
8611
  return () => clearInterval(interval);
9039
8612
  }, [selectedDate, isUtc, totalHours]);
9040
8613
  // Memoized Row Component
@@ -9402,6 +8975,8 @@ class Resource {
9402
8975
  }
9403
8976
  }
9404
8977
 
8978
+ 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"};
8979
+
9405
8980
  class OnPinRow {
9406
8981
  id;
9407
8982
  constructor(id) {
@@ -9418,37 +8993,23 @@ class OnClearPinned {
9418
8993
  constructor() { }
9419
8994
  }
9420
8995
 
9421
- const onClickMenuItem = (e, event) => {
9422
- e.domEvent.nativeEvent.preventDefault();
9423
- e.domEvent.nativeEvent.stopPropagation();
9424
- e.domEvent.nativeEvent.stopImmediatePropagation();
9425
- e.domEvent.preventDefault();
9426
- e.domEvent.stopPropagation();
9427
- event();
9428
- };
9429
8996
  const PinRowHeader = ({ value, width, onEvent }) => {
9430
8997
  const [isContextMenuOpen, setIsContextMenuOpen] = React.useState(false);
9431
8998
  const { highlightColor, isLoading } = value;
9432
- return (jsxRuntime.jsx(antd.Dropdown, { open: isContextMenuOpen, onOpenChange: setIsContextMenuOpen, placement: "bottom", menu: {
9433
- items: value.contextMenuItems,
9434
- onClick: (e) => {
9435
- onClickMenuItem(e, () => {
9436
- onEvent(new OnClickContextMenu(value.rowId, e.key));
9437
- });
9438
- },
9439
- onMouseLeave: () => setIsContextMenuOpen(false),
9440
- }, trigger: ["contextMenu"], overlayStyle: { animationDuration: "0" }, arrow: (value.contextMenuItems?.length ?? 0) > 0, children: jsxRuntime.jsx("div", { children: jsxRuntime.jsx(CwGenericTooltip, { content: value.tooltip, position: "right", dissapearsWhenHover: true, overlayStyle: value.overlayTooltipStyle, children: jsxRuntime.jsxs("div", { style: {
9441
- width: width,
9442
- background: highlightColor,
9443
- }, className: styles["super-scheduler-row-header"], children: [jsxRuntime.jsx("button", { className: "cw-button-icon cwi-pin", "data-pinned": value.isPinned, onClick: (_) => {
9444
- onEvent(value.isPinned ? new OnUnpinRow(value.rowId) : new OnPinRow(value.rowId));
9445
- } }), jsxRuntime.jsx("div", { className: styles["indicators"], children: value.indicators ?? undefined }), jsxRuntime.jsxs("div", { style: {
9446
- display: "flex",
9447
- flexDirection: "column",
9448
- justifyContent: "center",
9449
- alignItems: "flex-start",
9450
- }, children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("strong", { children: value.title }), value.title2 && jsxRuntime.jsxs("span", { children: ["-", value.title2] }), " ", jsxRuntime.jsx("strong", { children: value.subtitle })] }), value.subtitle && jsxRuntime.jsxs("div", { style: { opacity: 0.5 }, children: [value.title3 &&
9451
- jsxRuntime.jsxs("span", { className: styles["scheduler-crewmember-functions"], children: ["(", value.title3, ")"] }), value.subtitle2 && jsxRuntime.jsxs("span", { children: ["-", value.subtitle2] })] })] }), isLoading ? jsxRuntime.jsx("span", { className: "cwi-icons cwi-spinner" }) : undefined] }) }, value.rowId) }) }, value.rowId));
8999
+ return (jsxRuntime.jsx(CwAnchoredMenu, { open: isContextMenuOpen, onOpenChange: setIsContextMenuOpen, placement: "right", options: value.contextMenuItems ?? [], onSelect: (key) => {
9000
+ onEvent(new OnClickContextMenu(value.rowId, key));
9001
+ }, children: jsxRuntime.jsx(CwGenericTooltip, { content: value.tooltip, position: "right", dissapearsWhenHover: true, overlayStyle: value.overlayTooltipStyle, children: jsxRuntime.jsxs("div", { style: {
9002
+ width: width,
9003
+ background: highlightColor,
9004
+ }, className: styles["super-scheduler-row-header"], children: [jsxRuntime.jsx("button", { className: "cw-button-icon cwi-pin", "data-pinned": value.isPinned, onClick: (_) => {
9005
+ onEvent(value.isPinned ? new OnUnpinRow(value.rowId) : new OnPinRow(value.rowId));
9006
+ } }), jsxRuntime.jsx("div", { className: styles["indicators"], children: value.indicators ?? undefined }), jsxRuntime.jsxs("div", { style: {
9007
+ display: "flex",
9008
+ flexDirection: "column",
9009
+ justifyContent: "center",
9010
+ alignItems: "flex-start",
9011
+ }, children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("strong", { children: value.title }), value.title2 && jsxRuntime.jsxs("span", { children: ["-", value.title2] }), " ", jsxRuntime.jsx("strong", { children: value.subtitle })] }), value.subtitle && jsxRuntime.jsxs("div", { style: { opacity: 0.5 }, children: [value.title3 &&
9012
+ jsxRuntime.jsxs("span", { className: styles["scheduler-crewmember-functions"], children: ["(", value.title3, ")"] }), value.subtitle2 && jsxRuntime.jsxs("span", { children: ["-", value.subtitle2] })] })] }), isLoading ? jsxRuntime.jsx("span", { className: "cwi-icons cwi-spinner" }) : undefined] }) }, value.rowId) }, value.rowId));
9452
9013
  };
9453
9014
 
9454
9015
  const SuperScheduler = ({ id, state, header, rows, events, pinnedOrderCategory, unPinnedOrderCategory, backgroundEvents, contextMenuItems, onEvent }) => {
@@ -9460,7 +9021,7 @@ const SuperScheduler = ({ id, state, header, rows, events, pinnedOrderCategory,
9460
9021
  }, children: "Clear pinned" }) })] })), jsxRuntime.jsx(Scheduler, { id: `${id}-notPinned`, state: { ...state, isHeaderVisible: !isFirstVisible }, header: header, rows: notPinnedRows, events: events, backgroundEvents: backgroundEvents, contextMenuItems: contextMenuItems, orderCategories: unPinnedOrderCategory, onEvent: onEvent, EventComp: SchedulerEvent, RowTitleComp: PinRowHeader })] }));
9461
9022
  };
9462
9023
 
9463
- const CwFindAirport = ({ handleChange, searchType = "OnlyDatabase", placeHolder = "Search airport…", required = false, cblConfig, className = "", value, disabled = false, displayMode, width }) => {
9024
+ const CwFindAirport = ({ handleChange, searchType = "OnlyDatabase", placeHolder = "Search airport…", required = false, cblConfig, className = "", value, disabled = false, displayMode, labelProps, alignProps, width }) => {
9464
9025
  // State
9465
9026
  const [inputValue, setInputValue] = React.useState("");
9466
9027
  const [options, setOptions] = React.useState([]);
@@ -9693,54 +9254,22 @@ const CwFindAirport = ({ handleChange, searchType = "OnlyDatabase", placeHolder
9693
9254
  handleChange(0); // or -1, depending on API expectations
9694
9255
  inputRef.current?.focus();
9695
9256
  };
9696
- return (jsxRuntime.jsxs("div", { className: `cw-find-airport ${className}`, style: width ? { width } : undefined, children: [jsxRuntime.jsxs("div", { className: "cw-find-airport-input-wrapper", children: [jsxRuntime.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) && (jsxRuntime.jsx("div", { className: "cw-find-airport-loading", children: jsxRuntime.jsx(CwIcon, { iconId: "spinner" }) })), inputValue && !disabled && !isInitialLoading && (jsxRuntime.jsx(CwButton, { type: "button", onClick: handleClear, "aria-label": "Clear selected airport", variant: "icon", icon: "close", color: "neutral" }))] }), showDropdown && options.length > 0 && (jsxRuntime.jsx("div", { ref: dropdownRef, className: "cw-find-airport-dropdown", role: "listbox", children: options.map((option, index) => (jsxRuntime.jsx("div", { className: `cw-find-airport-option ${index === highlightedIndex ? "highlighted" : ""}`, onClick: () => handleOptionSelect(option.value), role: "option", "aria-selected": index === highlightedIndex, children: option.text }, option.value))) }))] }));
9257
+ // Get direction for data attribute
9258
+ const direction = alignProps?.flexDirection || "row";
9259
+ return (jsxRuntime.jsxs("div", { className: `cw-search-input ${className}`, style: {
9260
+ ...(width ? { width } : {}),
9261
+ ...(labelProps?.labelWidth ? { '--label-width': labelProps.labelWidth } : {})
9262
+ }, "data-direction": direction, children: [jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: "cw-search-input-wrapper", children: [jsxRuntime.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) && (jsxRuntime.jsx("div", { className: "cw-search-input-loading", children: jsxRuntime.jsx(CwIcon, { iconId: "spinner" }) })), jsxRuntime.jsx("div", { className: "cw-search-input-icons", children: inputValue && !disabled && !isInitialLoading ? (jsxRuntime.jsx(CwButton, { type: "button", onClick: handleClear, "aria-label": "Clear selected airport", variant: "icon", icon: "close", color: "neutral" })) : (jsxRuntime.jsx(CwIcon, { iconId: "control-tower" })) })] })] }), showDropdown && options.length > 0 && (jsxRuntime.jsx("div", { ref: dropdownRef, className: "cw-input-search-dropdown", role: "listbox", children: jsxRuntime.jsx("ul", { children: options.map((option, index) => (jsxRuntime.jsx("li", { className: index === highlightedIndex ? "highlighted" : "", onClick: () => handleOptionSelect(option.value), onMouseDown: (e) => e.preventDefault(), role: "option", "aria-selected": index === highlightedIndex, children: option.text }, option.value))) }) }))] }));
9697
9263
  };
9698
9264
 
9699
9265
  exports.CblDragAndDrop = CblDragAndDrop;
9700
9266
  exports.CwAccordionContainer = CwAccordionContainer;
9701
9267
  exports.CwAlign = CwAlign;
9702
- exports.CwBtnAdd = CwBtnAdd;
9703
- exports.CwBtnAddFolder = CwBtnAddFolder;
9704
- exports.CwBtnAirport = CwBtnAirport;
9705
- exports.CwBtnAlert = CwBtnAlert;
9706
- exports.CwBtnApprove = CwBtnApprove;
9707
- exports.CwBtnBookMark = CwBtnBookMark;
9708
- exports.CwBtnBulkDuty = CwBtnBulkDuty;
9709
- exports.CwBtnCancel = CwBtnCancel;
9710
- exports.CwBtnCrewPlanning = CwBtnCrewPlanning;
9711
- exports.CwBtnDelay = CwBtnDelay;
9268
+ exports.CwAnchoredMenu = CwAnchoredMenu;
9712
9269
  exports.CwBtnDelete = CwBtnDelete;
9713
- exports.CwBtnDownLoadAllInfo = CwBtnDownLoadAllInfo;
9714
- exports.CwBtnDownload = CwBtnDownload;
9715
- exports.CwBtnDropDownMenu = CwBtnDropDownMenu;
9716
9270
  exports.CwBtnEdit = CwBtnEdit;
9717
- exports.CwBtnEditFolder = CwBtnEditFolder;
9718
- exports.CwBtnFiles = CwBtnFiles;
9719
- exports.CwBtnGeneratePairing = CwBtnGeneratePairing;
9720
- exports.CwBtnGoBackFolder = CwBtnGoBackFolder;
9721
- exports.CwBtnHide = CwBtnHide;
9722
- exports.CwBtnImportRequests = CwBtnImportRequests;
9723
- exports.CwBtnMVT = CwBtnMVT;
9724
- exports.CwBtnNavFirstItemView = CwBtnNavFirstItemView;
9725
- exports.CwBtnNavLastItemView = CwBtnNavLastItemView;
9726
- exports.CwBtnNavNextDay = CwBtnNavNextDay;
9727
- exports.CwBtnNavPreviewItem = CwBtnNavPreviewItem;
9728
- exports.CwBtnPairing = CwBtnPairing;
9729
- exports.CwBtnPrint = CwBtnPrint;
9730
- exports.CwBtnPropertyFolder = CwBtnPropertyFolder;
9731
- exports.CwBtnPublish = CwBtnPublish;
9732
- exports.CwBtnRefresh = CwBtnRefresh;
9733
- exports.CwBtnReleasePeriod = CwBtnReleasePeriod;
9734
9271
  exports.CwBtnSave = CwBtnSave;
9735
- exports.CwBtnSearch = CwBtnSearch;
9736
- exports.CwBtnSelect = CwBtnSelect;
9737
- exports.CwBtnShare = CwBtnShare;
9738
- exports.CwBtnStatistic = CwBtnStatistic;
9739
- exports.CwBtnUploadFiles = CwBtnUploadFiles;
9740
- exports.CwBtnVacations = CwBtnVacations;
9741
- exports.CwBtnView = CwBtnView;
9742
9272
  exports.CwButton = CwButton;
9743
- exports.CwButtonDef = CwButtonDef;
9744
9273
  exports.CwCard = CwCard;
9745
9274
  exports.CwCardList = CwCardList;
9746
9275
  exports.CwCheckbox = CwCheckbox;
@@ -9748,7 +9277,6 @@ exports.CwChip = CwChip;
9748
9277
  exports.CwColorPicker = CwColorPicker;
9749
9278
  exports.CwConfirmationPopup = CwConfirmationPopup;
9750
9279
  exports.CwContextMenu = CwContextMenu;
9751
- exports.CwContextualMenu = CwContextualMenu;
9752
9280
  exports.CwDatePicker = CwDatePicker;
9753
9281
  exports.CwDateRangePicker = CwDateRangePicker;
9754
9282
  exports.CwDateTimePicker = CwDateTimePicker;
@@ -9757,16 +9285,12 @@ exports.CwDialog = CwDialog;
9757
9285
  exports.CwDialogManager = CwDialogManager;
9758
9286
  exports.CwDigit = CwDigit;
9759
9287
  exports.CwDisplayMessage = CwDisplayMessage;
9760
- exports.CwDropdown = CwDropdown;
9761
- exports.CwDropdownContainer = CwDropdownContainer;
9762
9288
  exports.CwDropdownFilter = CwDropdownFilter;
9763
9289
  exports.CwExpandable = CwExpandable;
9764
9290
  exports.CwFileUpload = CwFileUpload;
9765
9291
  exports.CwFileUploadMultiple = CwFileUploadMultiple;
9766
9292
  exports.CwFindAirport = CwFindAirport;
9767
- exports.CwFloatingButton = CwFloatingButton;
9768
9293
  exports.CwGenericTooltip = CwGenericTooltip;
9769
- exports.CwHeadFilter = CwHeadFilter;
9770
9294
  exports.CwHeadingMain = CwHeadingMain;
9771
9295
  exports.CwHeadingSecond = CwHeadingSecond;
9772
9296
  exports.CwIcon = CwIcon;
@@ -9790,16 +9314,12 @@ exports.CwLoadingSmall = CwLoadingSmall;
9790
9314
  exports.CwMessage = CwMessage;
9791
9315
  exports.CwMessageManager = CwMessageManager;
9792
9316
  exports.CwModal = CwModal;
9793
- exports.CwModalConfirm = CwModalConfirm;
9794
9317
  exports.CwModalHover = CwModalHover;
9795
- exports.CwModalIframe = CwModalIframe;
9796
9318
  exports.CwModalReportFunctional = CwModalReportFunctional;
9797
9319
  exports.CwMultiFilter = CwMultiFilter;
9798
9320
  exports.CwMultiFilterTag = CwMultiFilterTag;
9799
- exports.CwMultiselect = CwMultiselect;
9800
9321
  exports.CwNote = CwNote;
9801
9322
  exports.CwOption = CwOption;
9802
- exports.CwOptionList = CwOptionList;
9803
9323
  exports.CwReportModal = CwReportModal;
9804
9324
  exports.CwScheduler = CwScheduler;
9805
9325
  exports.CwScheduler2 = CwScheduler2;
@@ -9812,7 +9332,6 @@ exports.CwSuperScheduler = CwSuperScheduler;
9812
9332
  exports.CwTable = CwTable;
9813
9333
  exports.CwTableGrouped = CwTableGrouped;
9814
9334
  exports.CwTabs = CwTabs;
9815
- exports.CwTag = CwTag;
9816
9335
  exports.CwTextArea = CwTextArea;
9817
9336
  exports.CwTime = CwTime;
9818
9337
  exports.CwTimePicker = CwTimePicker;
@@ -9821,7 +9340,6 @@ exports.CwTooltip = CwTooltip;
9821
9340
  exports.CwTreeView = CwTreeView;
9822
9341
  exports.CwWeekdaySelector = CwWeekdaySelector;
9823
9342
  exports.DefaultRowHeader = DefaultRowHeader;
9824
- exports.MultiSelect = MultiSelect;
9825
9343
  exports.OnClearPinned = OnClearPinned;
9826
9344
  exports.OnClickContextMenu = OnClickContextMenu;
9827
9345
  exports.OnClickEvent = OnClickEvent;