funda-ui 4.7.711 → 4.7.723

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.
@@ -12,6 +12,7 @@ export declare type DynamicFieldsProps = {
12
12
  label?: React.ReactNode | string;
13
13
  data: DynamicFieldsValueProps | null;
14
14
  maxFields?: any;
15
+ defaultRows?: number;
15
16
  confirmText?: string;
16
17
  doNotRemoveDom?: boolean;
17
18
  iconAddBefore?: React.ReactNode | string;
@@ -495,7 +495,7 @@ __webpack_require__.r(__webpack_exports__);
495
495
  /* harmony import */ var funda_utils_dist_cjs_useComId__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(funda_utils_dist_cjs_useComId__WEBPACK_IMPORTED_MODULE_1__);
496
496
  /* harmony import */ var funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(188);
497
497
  /* harmony import */ var funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_2__);
498
- var _excluded = ["contentRef", "wrapperClassName", "btnAddWrapperClassName", "btnRemoveWrapperClassName", "label", "data", "maxFields", "iconAddBefore", "iconAddAfter", "iconAdd", "iconAddPosition", "iconRemove", "doNotRemoveDom", "id", "confirmText", "innerAppendClassName", "innerAppendCellClassName", "innerAppendLastCellClassName", "innerAppendHideClassName", "innerAppendBodyClassName", "innerAppendHeadData", "innerAppendHeadRowShowFirst", "innerAppendHeadRowClassName", "innerAppendHeadCellClassName", "innerAppendHeadCellStyles", "innerAppendEmptyContent", "onAdd", "onRemove", "onLoad"];
498
+ var _excluded = ["contentRef", "wrapperClassName", "btnAddWrapperClassName", "btnRemoveWrapperClassName", "label", "data", "maxFields", "defaultRows", "iconAddBefore", "iconAddAfter", "iconAdd", "iconAddPosition", "iconRemove", "doNotRemoveDom", "id", "confirmText", "innerAppendClassName", "innerAppendCellClassName", "innerAppendLastCellClassName", "innerAppendHideClassName", "innerAppendBodyClassName", "innerAppendHeadData", "innerAppendHeadRowShowFirst", "innerAppendHeadRowClassName", "innerAppendHeadCellClassName", "innerAppendHeadCellStyles", "innerAppendEmptyContent", "onAdd", "onRemove", "onLoad"];
499
499
  function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
500
500
  function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
501
501
  function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@@ -520,6 +520,7 @@ var DynamicFields = function DynamicFields(props) {
520
520
  label = props.label,
521
521
  data = props.data,
522
522
  maxFields = props.maxFields,
523
+ defaultRows = props.defaultRows,
523
524
  iconAddBefore = props.iconAddBefore,
524
525
  iconAddAfter = props.iconAddAfter,
525
526
  iconAdd = props.iconAdd,
@@ -564,6 +565,10 @@ var DynamicFields = function DynamicFields(props) {
564
565
  setTmpl = _useState4[1];
565
566
  var addBtnIdRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)('');
566
567
  addBtnIdRef.current = "dynamic-fields-add-".concat(idRes);
568
+ var defaultRowsInitializedRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(false);
569
+ var isInitializingDefaultRowsRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(false);
570
+ var rafIdRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
571
+ var timeoutIdsRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)([]);
567
572
 
568
573
  // exposes the following methods
569
574
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useImperativeHandle)(contentRef, function () {
@@ -629,18 +634,13 @@ var DynamicFields = function DynamicFields(props) {
629
634
  addBtnRef.current.style.setProperty('display', 'none', 'important');
630
635
  }
631
636
  }
632
- function handleClickAdd() {
633
- var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
634
- if (event !== null) {
635
- if (typeof event !== 'undefined') event.preventDefault();
636
- }
637
-
637
+ function addRowWithTemplate(template) {
638
638
  //button status
639
639
  checkMaxStatus();
640
640
 
641
641
  //
642
642
  setVal(function (prevState) {
643
- return [].concat(_toConsumableArray(prevState), _toConsumableArray(generateGroup(tmpl)));
643
+ return [].concat(_toConsumableArray(prevState), _toConsumableArray(generateGroup(template)));
644
644
  });
645
645
 
646
646
  //
@@ -667,6 +667,13 @@ var DynamicFields = function DynamicFields(props) {
667
667
  onAdd === null || onAdd === void 0 ? void 0 : onAdd(perRow, rootRef.current, addBtnRef.current, PER_ROW_DOM_STRING);
668
668
  }, 0);
669
669
  }
670
+ function handleClickAdd() {
671
+ var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
672
+ if (event !== null) {
673
+ if (typeof event !== 'undefined') event.preventDefault();
674
+ }
675
+ addRowWithTemplate(tmpl);
676
+ }
670
677
  function handleClickRemove(e) {
671
678
  if (e !== null && typeof e !== 'undefined') e.preventDefault();
672
679
  var $target = e.currentTarget.closest('.dynamic-fields__data__wrapper');
@@ -778,6 +785,99 @@ var DynamicFields = function DynamicFields(props) {
778
785
 
779
786
  //
780
787
  onLoad === null || onLoad === void 0 ? void 0 : onLoad(addBtnIdRef.current, rootRef.current, PER_ROW_DOM_STRING);
788
+
789
+ // Reset initialization flag when data becomes null
790
+ if (!data) {
791
+ defaultRowsInitializedRef.current = false;
792
+ isInitializingDefaultRowsRef.current = false;
793
+ }
794
+
795
+ // Add default rows if specified (only initialize once per data setup)
796
+ if (!defaultRowsInitializedRef.current && typeof defaultRows === 'number' && defaultRows > 0 && data && data.tmpl) {
797
+ // Get the initial data length
798
+ var initDataLength = Array.isArray(data.init) ? data.init.length : 0;
799
+
800
+ // Calculate how many rows need to be added
801
+ var maxRows = typeof maxFields !== 'undefined' ? parseFloat(maxFields) : Infinity;
802
+ var targetRows = Math.min(defaultRows, maxRows);
803
+ var rowsToAdd = Math.max(0, targetRows - initDataLength);
804
+
805
+ // Mark as initialized immediately to prevent re-adding
806
+ defaultRowsInitializedRef.current = true;
807
+
808
+ // Only add rows if needed
809
+ if (rowsToAdd > 0) {
810
+ // Mark that we're initializing default rows
811
+ isInitializingDefaultRowsRef.current = true;
812
+
813
+ // Clear any existing timeouts
814
+ timeoutIdsRef.current.forEach(function (id) {
815
+ return clearTimeout(id);
816
+ });
817
+ timeoutIdsRef.current = [];
818
+
819
+ // Use requestAnimationFrame to ensure DOM is ready and state is updated
820
+ rafIdRef.current = requestAnimationFrame(function () {
821
+ // Check if component is still mounted
822
+ if (!rootRef.current) {
823
+ isInitializingDefaultRowsRef.current = false;
824
+ return;
825
+ }
826
+ var timeoutId1 = setTimeout(function () {
827
+ // Check if component is still mounted
828
+ if (!rootRef.current) {
829
+ isInitializingDefaultRowsRef.current = false;
830
+ return;
831
+ }
832
+
833
+ // Add rows one by one with a small delay to ensure state updates
834
+ var addedCount = 0;
835
+ var addNextRow = function addNextRow() {
836
+ // Check if component is still mounted before each operation
837
+ if (addedCount < rowsToAdd && rootRef.current) {
838
+ // Use data.tmpl directly to avoid dependency on state
839
+ addRowWithTemplate(data.tmpl);
840
+ addedCount++;
841
+ // Wait a bit before adding the next row to ensure state updates
842
+ if (addedCount < rowsToAdd) {
843
+ var timeoutId2 = setTimeout(addNextRow, 10);
844
+ timeoutIdsRef.current.push(timeoutId2);
845
+ } else {
846
+ // All rows added, mark initialization as complete
847
+ isInitializingDefaultRowsRef.current = false;
848
+ }
849
+ } else {
850
+ // No more rows to add or component unmounted
851
+ isInitializingDefaultRowsRef.current = false;
852
+ }
853
+ };
854
+ addNextRow();
855
+ }, 50);
856
+ timeoutIdsRef.current.push(timeoutId1);
857
+ });
858
+ }
859
+ }
860
+
861
+ // Cleanup function to cancel requestAnimationFrame and timeouts
862
+ return function () {
863
+ // Don't cleanup if we're in the middle of initializing defaultRows
864
+ // This prevents the cleanup from canceling the async operations before they complete
865
+ if (isInitializingDefaultRowsRef.current) {
866
+ // Allow defaultRows initialization to complete
867
+ // The cleanup will happen naturally when initialization finishes
868
+ return;
869
+ }
870
+
871
+ // Normal cleanup for other cases
872
+ if (rafIdRef.current !== null) {
873
+ cancelAnimationFrame(rafIdRef.current);
874
+ rafIdRef.current = null;
875
+ }
876
+ timeoutIdsRef.current.forEach(function (id) {
877
+ return clearTimeout(id);
878
+ });
879
+ timeoutIdsRef.current = [];
880
+ };
781
881
  }, [data]);
782
882
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
783
883
  className: (0,funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_2__.clsWrite)(wrapperClassName, 'mb-3 position-relative'),
@@ -235,7 +235,7 @@
235
235
  }
236
236
  */
237
237
  /* cell */
238
- /* header */
238
+ /* The width of the left column header */
239
239
  /* event container */
240
240
  /* days container */
241
241
  /* remove empty cells */
@@ -466,10 +466,21 @@
466
466
  background-color: var(--custom-event-tl-table-divider-bg);
467
467
  border-left: var(--custom-event-tl-table-divider-border);
468
468
  border-right: var(--custom-event-tl-table-divider-border);
469
+ position: relative;
469
470
  }
470
471
  .custom-event-tl-table__timeline-table__wrapper .custom-event-tl-table__timeline-divider > div {
471
472
  width: var(--custom-event-tl-table-divider-w);
472
473
  }
474
+ .custom-event-tl-table__timeline-table__wrapper .custom-event-tl-table__timeline-divider--resizable {
475
+ cursor: col-resize;
476
+ user-select: none;
477
+ }
478
+ .custom-event-tl-table__timeline-table__wrapper .custom-event-tl-table__timeline-divider--resizable:hover {
479
+ background-color: rgba(0, 0, 0, 0.05);
480
+ }
481
+ .custom-event-tl-table__timeline-table__wrapper .custom-event-tl-table__timeline-divider--resizable:active {
482
+ background-color: rgba(0, 0, 0, 0.1);
483
+ }
473
484
  .custom-event-tl-table__timeline-table__wrapper .custom-event-tl-table__cell-cushion {
474
485
  padding: var(--custom-event-tl-table-cell-padding);
475
486
  }
@@ -60,6 +60,7 @@ export declare type EventCalendarTimelineProps = {
60
60
  onChangeWeek?: (startDate: string, endDate: string) => void;
61
61
  onListRenderComplete?: () => void;
62
62
  onChangeAppearanceMode?: (mode: string) => void;
63
+ enableHeaderResize?: boolean;
63
64
  modalMaskOpacity?: string;
64
65
  modalMaxWidth?: number | string;
65
66
  modalMinHeight?: number | string;
@@ -3986,6 +3986,7 @@ var EventCalendarTimeline = function EventCalendarTimeline(props) {
3986
3986
  onChangeWeek = props.onChangeWeek,
3987
3987
  onListRenderComplete = props.onListRenderComplete,
3988
3988
  onChangeAppearanceMode = props.onChangeAppearanceMode,
3989
+ enableHeaderResize = props.enableHeaderResize,
3989
3990
  modalMaskOpacity = props.modalMaskOpacity,
3990
3991
  modalMaxWidth = props.modalMaxWidth,
3991
3992
  modalMinHeight = props.modalMinHeight,
@@ -4117,12 +4118,18 @@ var EventCalendarTimeline = function EventCalendarTimeline(props) {
4117
4118
  var AUTO_SCROLL = autoScroll || false;
4118
4119
  var HEADER_SHOW_WEEK = headerShowWeek || false;
4119
4120
  var BODY_DRAG = draggable || false;
4121
+ var ENABLE_HEADER_RESIZE = enableHeaderResize || false;
4120
4122
  var tableGridRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
4121
4123
  var tableGridHeaderRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
4122
4124
  var scrollHeaderRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
4123
4125
  var scrollBodyRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
4124
4126
  var scrollListRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
4125
4127
 
4128
+ // header resize drag
4129
+ var isResizingRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(false);
4130
+ var resizeStartXRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(0);
4131
+ var resizeStartWidthRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(0);
4132
+
4126
4133
  // Temporary date
4127
4134
  var _useState27 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(''),
4128
4135
  _useState28 = _slicedToArray(_useState27, 2),
@@ -5783,10 +5790,7 @@ var EventCalendarTimeline = function EventCalendarTimeline(props) {
5783
5790
  }
5784
5791
  }
5785
5792
 
5786
- // ================================================================
5787
- //
5788
- // ================================================================
5789
- //if user change the selectedYear, then udate the years array that is displayed on year tab view
5793
+ // if user change the selectedYear, then udate the years array that is displayed on year tab view
5790
5794
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(function () {
5791
5795
  var years = [];
5792
5796
  for (var y = selectedYear - 10; y < selectedYear + 10; y++) {
@@ -5840,6 +5844,83 @@ var EventCalendarTimeline = function EventCalendarTimeline(props) {
5840
5844
  setCopiedCells(null);
5841
5845
  };
5842
5846
  }, []);
5847
+
5848
+ // ================================================================
5849
+ // Handle header resize drag
5850
+ // ================================================================
5851
+ var handleHeaderResizeMove = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(function (e) {
5852
+ var _e$touches$;
5853
+ if (!isResizingRef.current || !tableGridRef.current) return;
5854
+ var tableGridEl = tableGridRef.current;
5855
+ // Find the header title element that should have the CSS variable
5856
+ var headerTitleEl = tableGridEl.querySelector('.custom-event-tl-table__cell-cushion-headertitle');
5857
+ if (!headerTitleEl) return;
5858
+
5859
+ // Get clientX from either MouseEvent or TouchEvent
5860
+ var clientX = 'touches' in e ? (_e$touches$ = e.touches[0]) === null || _e$touches$ === void 0 ? void 0 : _e$touches$.clientX : e.clientX;
5861
+ if (clientX === undefined) return;
5862
+ var deltaX = clientX - resizeStartXRef.current;
5863
+ var newWidth = Math.max(100, resizeStartWidthRef.current + deltaX); // Minimum width 100px
5864
+
5865
+ // Update CSS variable on the header title element
5866
+ headerTitleEl.style.setProperty('--custom-event-tl-table-header-w', "".concat(newWidth, "px"));
5867
+ }, []);
5868
+ var handleHeaderResizeEnd = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(function () {
5869
+ if (!isResizingRef.current) return;
5870
+ isResizingRef.current = false;
5871
+ document.removeEventListener('mousemove', handleHeaderResizeMove);
5872
+ document.removeEventListener('mouseup', handleHeaderResizeEnd);
5873
+ document.removeEventListener('touchmove', handleHeaderResizeMove);
5874
+ document.removeEventListener('touchend', handleHeaderResizeEnd);
5875
+
5876
+ // Recalculate table grid after resize
5877
+ if (tableGridRef.current) {
5878
+ tableGridInit();
5879
+ }
5880
+ }, [handleHeaderResizeMove]);
5881
+ var handleHeaderResizeStart = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(function (e) {
5882
+ if (!ENABLE_HEADER_RESIZE || !tableGridRef.current) return;
5883
+ e.preventDefault();
5884
+ e.stopPropagation();
5885
+ isResizingRef.current = true;
5886
+ resizeStartXRef.current = e.clientX;
5887
+ var tableGridEl = tableGridRef.current;
5888
+ var headerTitleEl = tableGridEl.querySelector('.custom-event-tl-table__cell-cushion-headertitle');
5889
+ if (headerTitleEl) {
5890
+ resizeStartWidthRef.current = headerTitleEl.clientWidth;
5891
+ }
5892
+ document.addEventListener('mousemove', handleHeaderResizeMove);
5893
+ document.addEventListener('mouseup', handleHeaderResizeEnd);
5894
+ }, [ENABLE_HEADER_RESIZE, handleHeaderResizeMove, handleHeaderResizeEnd]);
5895
+ var handleHeaderResizeTouchStart = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(function (e) {
5896
+ if (!ENABLE_HEADER_RESIZE || !tableGridRef.current) return;
5897
+ e.preventDefault();
5898
+ e.stopPropagation();
5899
+ isResizingRef.current = true;
5900
+ var touch = e.touches[0];
5901
+ if (touch) {
5902
+ resizeStartXRef.current = touch.clientX;
5903
+ }
5904
+ var tableGridEl = tableGridRef.current;
5905
+ var headerTitleEl = tableGridEl.querySelector('.custom-event-tl-table__cell-cushion-headertitle');
5906
+ if (headerTitleEl) {
5907
+ resizeStartWidthRef.current = headerTitleEl.clientWidth;
5908
+ }
5909
+ document.addEventListener('touchmove', handleHeaderResizeMove, {
5910
+ passive: false
5911
+ });
5912
+ document.addEventListener('touchend', handleHeaderResizeEnd);
5913
+ }, [ENABLE_HEADER_RESIZE, handleHeaderResizeMove, handleHeaderResizeEnd]);
5914
+
5915
+ // Cleanup on unmount
5916
+ (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(function () {
5917
+ return function () {
5918
+ document.removeEventListener('mousemove', handleHeaderResizeMove);
5919
+ document.removeEventListener('mouseup', handleHeaderResizeEnd);
5920
+ document.removeEventListener('touchmove', handleHeaderResizeMove);
5921
+ document.removeEventListener('touchend', handleHeaderResizeEnd);
5922
+ };
5923
+ }, [handleHeaderResizeMove, handleHeaderResizeEnd]);
5843
5924
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
5844
5925
  className: (0,funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_7__.combinedCls)("custom-event-tl__wrapper custom-event-tl__wrapper--".concat(appearanceMode), calendarWrapperClassName)
5845
5926
  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
@@ -5985,7 +6066,13 @@ var EventCalendarTimeline = function EventCalendarTimeline(props) {
5985
6066
  className: "custom-event-tl-table__cell-cushion custom-event-tl-table__cell-cushion-headertitle"
5986
6067
  }, tableListSectionTitle || ''))))))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("th", {
5987
6068
  role: "presentation",
5988
- className: "custom-event-tl-table__timeline-divider"
6069
+ className: (0,funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_7__.combinedCls)('custom-event-tl-table__timeline-divider', ENABLE_HEADER_RESIZE ? 'custom-event-tl-table__timeline-divider--resizable' : ''),
6070
+ onMouseDown: ENABLE_HEADER_RESIZE ? handleHeaderResizeStart : undefined,
6071
+ onTouchStart: ENABLE_HEADER_RESIZE ? handleHeaderResizeTouchStart : undefined,
6072
+ style: ENABLE_HEADER_RESIZE ? {
6073
+ cursor: 'col-resize',
6074
+ userSelect: 'none'
6075
+ } : undefined
5989
6076
  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", null)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("th", {
5990
6077
  role: "presentation"
5991
6078
  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
@@ -6024,7 +6111,13 @@ var EventCalendarTimeline = function EventCalendarTimeline(props) {
6024
6111
  role: "presentation"
6025
6112
  }, generateListSectionUi()))))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("td", {
6026
6113
  role: "presentation",
6027
- className: (0,funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_7__.combinedCls)('custom-event-tl-table__timeline-divider', tableListDividerClassName)
6114
+ className: (0,funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_7__.combinedCls)('custom-event-tl-table__timeline-divider', tableListDividerClassName, ENABLE_HEADER_RESIZE ? 'custom-event-tl-table__timeline-divider--resizable' : ''),
6115
+ onMouseDown: ENABLE_HEADER_RESIZE ? handleHeaderResizeStart : undefined,
6116
+ onTouchStart: ENABLE_HEADER_RESIZE ? handleHeaderResizeTouchStart : undefined,
6117
+ style: ENABLE_HEADER_RESIZE ? {
6118
+ cursor: 'col-resize',
6119
+ userSelect: 'none'
6120
+ } : undefined
6028
6121
  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", null)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("td", {
6029
6122
  role: "presentation",
6030
6123
  className: (0,funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_7__.combinedCls)(tableListEndClassName)
@@ -12,6 +12,7 @@ export declare type DynamicFieldsProps = {
12
12
  label?: React.ReactNode | string;
13
13
  data: DynamicFieldsValueProps | null;
14
14
  maxFields?: any;
15
+ defaultRows?: number;
15
16
  confirmText?: string;
16
17
  doNotRemoveDom?: boolean;
17
18
  iconAddBefore?: React.ReactNode | string;
@@ -495,7 +495,7 @@ __webpack_require__.r(__webpack_exports__);
495
495
  /* harmony import */ var funda_utils_dist_cjs_useComId__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(funda_utils_dist_cjs_useComId__WEBPACK_IMPORTED_MODULE_1__);
496
496
  /* harmony import */ var funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(188);
497
497
  /* harmony import */ var funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_2__);
498
- var _excluded = ["contentRef", "wrapperClassName", "btnAddWrapperClassName", "btnRemoveWrapperClassName", "label", "data", "maxFields", "iconAddBefore", "iconAddAfter", "iconAdd", "iconAddPosition", "iconRemove", "doNotRemoveDom", "id", "confirmText", "innerAppendClassName", "innerAppendCellClassName", "innerAppendLastCellClassName", "innerAppendHideClassName", "innerAppendBodyClassName", "innerAppendHeadData", "innerAppendHeadRowShowFirst", "innerAppendHeadRowClassName", "innerAppendHeadCellClassName", "innerAppendHeadCellStyles", "innerAppendEmptyContent", "onAdd", "onRemove", "onLoad"];
498
+ var _excluded = ["contentRef", "wrapperClassName", "btnAddWrapperClassName", "btnRemoveWrapperClassName", "label", "data", "maxFields", "defaultRows", "iconAddBefore", "iconAddAfter", "iconAdd", "iconAddPosition", "iconRemove", "doNotRemoveDom", "id", "confirmText", "innerAppendClassName", "innerAppendCellClassName", "innerAppendLastCellClassName", "innerAppendHideClassName", "innerAppendBodyClassName", "innerAppendHeadData", "innerAppendHeadRowShowFirst", "innerAppendHeadRowClassName", "innerAppendHeadCellClassName", "innerAppendHeadCellStyles", "innerAppendEmptyContent", "onAdd", "onRemove", "onLoad"];
499
499
  function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
500
500
  function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
501
501
  function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@@ -520,6 +520,7 @@ var DynamicFields = function DynamicFields(props) {
520
520
  label = props.label,
521
521
  data = props.data,
522
522
  maxFields = props.maxFields,
523
+ defaultRows = props.defaultRows,
523
524
  iconAddBefore = props.iconAddBefore,
524
525
  iconAddAfter = props.iconAddAfter,
525
526
  iconAdd = props.iconAdd,
@@ -564,6 +565,10 @@ var DynamicFields = function DynamicFields(props) {
564
565
  setTmpl = _useState4[1];
565
566
  var addBtnIdRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)('');
566
567
  addBtnIdRef.current = "dynamic-fields-add-".concat(idRes);
568
+ var defaultRowsInitializedRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(false);
569
+ var isInitializingDefaultRowsRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(false);
570
+ var rafIdRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
571
+ var timeoutIdsRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)([]);
567
572
 
568
573
  // exposes the following methods
569
574
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useImperativeHandle)(contentRef, function () {
@@ -629,18 +634,13 @@ var DynamicFields = function DynamicFields(props) {
629
634
  addBtnRef.current.style.setProperty('display', 'none', 'important');
630
635
  }
631
636
  }
632
- function handleClickAdd() {
633
- var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
634
- if (event !== null) {
635
- if (typeof event !== 'undefined') event.preventDefault();
636
- }
637
-
637
+ function addRowWithTemplate(template) {
638
638
  //button status
639
639
  checkMaxStatus();
640
640
 
641
641
  //
642
642
  setVal(function (prevState) {
643
- return [].concat(_toConsumableArray(prevState), _toConsumableArray(generateGroup(tmpl)));
643
+ return [].concat(_toConsumableArray(prevState), _toConsumableArray(generateGroup(template)));
644
644
  });
645
645
 
646
646
  //
@@ -667,6 +667,13 @@ var DynamicFields = function DynamicFields(props) {
667
667
  onAdd === null || onAdd === void 0 ? void 0 : onAdd(perRow, rootRef.current, addBtnRef.current, PER_ROW_DOM_STRING);
668
668
  }, 0);
669
669
  }
670
+ function handleClickAdd() {
671
+ var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
672
+ if (event !== null) {
673
+ if (typeof event !== 'undefined') event.preventDefault();
674
+ }
675
+ addRowWithTemplate(tmpl);
676
+ }
670
677
  function handleClickRemove(e) {
671
678
  if (e !== null && typeof e !== 'undefined') e.preventDefault();
672
679
  var $target = e.currentTarget.closest('.dynamic-fields__data__wrapper');
@@ -778,6 +785,99 @@ var DynamicFields = function DynamicFields(props) {
778
785
 
779
786
  //
780
787
  onLoad === null || onLoad === void 0 ? void 0 : onLoad(addBtnIdRef.current, rootRef.current, PER_ROW_DOM_STRING);
788
+
789
+ // Reset initialization flag when data becomes null
790
+ if (!data) {
791
+ defaultRowsInitializedRef.current = false;
792
+ isInitializingDefaultRowsRef.current = false;
793
+ }
794
+
795
+ // Add default rows if specified (only initialize once per data setup)
796
+ if (!defaultRowsInitializedRef.current && typeof defaultRows === 'number' && defaultRows > 0 && data && data.tmpl) {
797
+ // Get the initial data length
798
+ var initDataLength = Array.isArray(data.init) ? data.init.length : 0;
799
+
800
+ // Calculate how many rows need to be added
801
+ var maxRows = typeof maxFields !== 'undefined' ? parseFloat(maxFields) : Infinity;
802
+ var targetRows = Math.min(defaultRows, maxRows);
803
+ var rowsToAdd = Math.max(0, targetRows - initDataLength);
804
+
805
+ // Mark as initialized immediately to prevent re-adding
806
+ defaultRowsInitializedRef.current = true;
807
+
808
+ // Only add rows if needed
809
+ if (rowsToAdd > 0) {
810
+ // Mark that we're initializing default rows
811
+ isInitializingDefaultRowsRef.current = true;
812
+
813
+ // Clear any existing timeouts
814
+ timeoutIdsRef.current.forEach(function (id) {
815
+ return clearTimeout(id);
816
+ });
817
+ timeoutIdsRef.current = [];
818
+
819
+ // Use requestAnimationFrame to ensure DOM is ready and state is updated
820
+ rafIdRef.current = requestAnimationFrame(function () {
821
+ // Check if component is still mounted
822
+ if (!rootRef.current) {
823
+ isInitializingDefaultRowsRef.current = false;
824
+ return;
825
+ }
826
+ var timeoutId1 = setTimeout(function () {
827
+ // Check if component is still mounted
828
+ if (!rootRef.current) {
829
+ isInitializingDefaultRowsRef.current = false;
830
+ return;
831
+ }
832
+
833
+ // Add rows one by one with a small delay to ensure state updates
834
+ var addedCount = 0;
835
+ var addNextRow = function addNextRow() {
836
+ // Check if component is still mounted before each operation
837
+ if (addedCount < rowsToAdd && rootRef.current) {
838
+ // Use data.tmpl directly to avoid dependency on state
839
+ addRowWithTemplate(data.tmpl);
840
+ addedCount++;
841
+ // Wait a bit before adding the next row to ensure state updates
842
+ if (addedCount < rowsToAdd) {
843
+ var timeoutId2 = setTimeout(addNextRow, 10);
844
+ timeoutIdsRef.current.push(timeoutId2);
845
+ } else {
846
+ // All rows added, mark initialization as complete
847
+ isInitializingDefaultRowsRef.current = false;
848
+ }
849
+ } else {
850
+ // No more rows to add or component unmounted
851
+ isInitializingDefaultRowsRef.current = false;
852
+ }
853
+ };
854
+ addNextRow();
855
+ }, 50);
856
+ timeoutIdsRef.current.push(timeoutId1);
857
+ });
858
+ }
859
+ }
860
+
861
+ // Cleanup function to cancel requestAnimationFrame and timeouts
862
+ return function () {
863
+ // Don't cleanup if we're in the middle of initializing defaultRows
864
+ // This prevents the cleanup from canceling the async operations before they complete
865
+ if (isInitializingDefaultRowsRef.current) {
866
+ // Allow defaultRows initialization to complete
867
+ // The cleanup will happen naturally when initialization finishes
868
+ return;
869
+ }
870
+
871
+ // Normal cleanup for other cases
872
+ if (rafIdRef.current !== null) {
873
+ cancelAnimationFrame(rafIdRef.current);
874
+ rafIdRef.current = null;
875
+ }
876
+ timeoutIdsRef.current.forEach(function (id) {
877
+ return clearTimeout(id);
878
+ });
879
+ timeoutIdsRef.current = [];
880
+ };
781
881
  }, [data]);
782
882
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
783
883
  className: (0,funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_2__.clsWrite)(wrapperClassName, 'mb-3 position-relative'),
@@ -60,6 +60,7 @@ export declare type EventCalendarTimelineProps = {
60
60
  onChangeWeek?: (startDate: string, endDate: string) => void;
61
61
  onListRenderComplete?: () => void;
62
62
  onChangeAppearanceMode?: (mode: string) => void;
63
+ enableHeaderResize?: boolean;
63
64
  modalMaskOpacity?: string;
64
65
  modalMaxWidth?: number | string;
65
66
  modalMinHeight?: number | string;
@@ -3986,6 +3986,7 @@ var EventCalendarTimeline = function EventCalendarTimeline(props) {
3986
3986
  onChangeWeek = props.onChangeWeek,
3987
3987
  onListRenderComplete = props.onListRenderComplete,
3988
3988
  onChangeAppearanceMode = props.onChangeAppearanceMode,
3989
+ enableHeaderResize = props.enableHeaderResize,
3989
3990
  modalMaskOpacity = props.modalMaskOpacity,
3990
3991
  modalMaxWidth = props.modalMaxWidth,
3991
3992
  modalMinHeight = props.modalMinHeight,
@@ -4117,12 +4118,18 @@ var EventCalendarTimeline = function EventCalendarTimeline(props) {
4117
4118
  var AUTO_SCROLL = autoScroll || false;
4118
4119
  var HEADER_SHOW_WEEK = headerShowWeek || false;
4119
4120
  var BODY_DRAG = draggable || false;
4121
+ var ENABLE_HEADER_RESIZE = enableHeaderResize || false;
4120
4122
  var tableGridRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
4121
4123
  var tableGridHeaderRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
4122
4124
  var scrollHeaderRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
4123
4125
  var scrollBodyRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
4124
4126
  var scrollListRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
4125
4127
 
4128
+ // header resize drag
4129
+ var isResizingRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(false);
4130
+ var resizeStartXRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(0);
4131
+ var resizeStartWidthRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(0);
4132
+
4126
4133
  // Temporary date
4127
4134
  var _useState27 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(''),
4128
4135
  _useState28 = _slicedToArray(_useState27, 2),
@@ -5783,10 +5790,7 @@ var EventCalendarTimeline = function EventCalendarTimeline(props) {
5783
5790
  }
5784
5791
  }
5785
5792
 
5786
- // ================================================================
5787
- //
5788
- // ================================================================
5789
- //if user change the selectedYear, then udate the years array that is displayed on year tab view
5793
+ // if user change the selectedYear, then udate the years array that is displayed on year tab view
5790
5794
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(function () {
5791
5795
  var years = [];
5792
5796
  for (var y = selectedYear - 10; y < selectedYear + 10; y++) {
@@ -5840,6 +5844,83 @@ var EventCalendarTimeline = function EventCalendarTimeline(props) {
5840
5844
  setCopiedCells(null);
5841
5845
  };
5842
5846
  }, []);
5847
+
5848
+ // ================================================================
5849
+ // Handle header resize drag
5850
+ // ================================================================
5851
+ var handleHeaderResizeMove = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(function (e) {
5852
+ var _e$touches$;
5853
+ if (!isResizingRef.current || !tableGridRef.current) return;
5854
+ var tableGridEl = tableGridRef.current;
5855
+ // Find the header title element that should have the CSS variable
5856
+ var headerTitleEl = tableGridEl.querySelector('.custom-event-tl-table__cell-cushion-headertitle');
5857
+ if (!headerTitleEl) return;
5858
+
5859
+ // Get clientX from either MouseEvent or TouchEvent
5860
+ var clientX = 'touches' in e ? (_e$touches$ = e.touches[0]) === null || _e$touches$ === void 0 ? void 0 : _e$touches$.clientX : e.clientX;
5861
+ if (clientX === undefined) return;
5862
+ var deltaX = clientX - resizeStartXRef.current;
5863
+ var newWidth = Math.max(100, resizeStartWidthRef.current + deltaX); // Minimum width 100px
5864
+
5865
+ // Update CSS variable on the header title element
5866
+ headerTitleEl.style.setProperty('--custom-event-tl-table-header-w', "".concat(newWidth, "px"));
5867
+ }, []);
5868
+ var handleHeaderResizeEnd = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(function () {
5869
+ if (!isResizingRef.current) return;
5870
+ isResizingRef.current = false;
5871
+ document.removeEventListener('mousemove', handleHeaderResizeMove);
5872
+ document.removeEventListener('mouseup', handleHeaderResizeEnd);
5873
+ document.removeEventListener('touchmove', handleHeaderResizeMove);
5874
+ document.removeEventListener('touchend', handleHeaderResizeEnd);
5875
+
5876
+ // Recalculate table grid after resize
5877
+ if (tableGridRef.current) {
5878
+ tableGridInit();
5879
+ }
5880
+ }, [handleHeaderResizeMove]);
5881
+ var handleHeaderResizeStart = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(function (e) {
5882
+ if (!ENABLE_HEADER_RESIZE || !tableGridRef.current) return;
5883
+ e.preventDefault();
5884
+ e.stopPropagation();
5885
+ isResizingRef.current = true;
5886
+ resizeStartXRef.current = e.clientX;
5887
+ var tableGridEl = tableGridRef.current;
5888
+ var headerTitleEl = tableGridEl.querySelector('.custom-event-tl-table__cell-cushion-headertitle');
5889
+ if (headerTitleEl) {
5890
+ resizeStartWidthRef.current = headerTitleEl.clientWidth;
5891
+ }
5892
+ document.addEventListener('mousemove', handleHeaderResizeMove);
5893
+ document.addEventListener('mouseup', handleHeaderResizeEnd);
5894
+ }, [ENABLE_HEADER_RESIZE, handleHeaderResizeMove, handleHeaderResizeEnd]);
5895
+ var handleHeaderResizeTouchStart = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(function (e) {
5896
+ if (!ENABLE_HEADER_RESIZE || !tableGridRef.current) return;
5897
+ e.preventDefault();
5898
+ e.stopPropagation();
5899
+ isResizingRef.current = true;
5900
+ var touch = e.touches[0];
5901
+ if (touch) {
5902
+ resizeStartXRef.current = touch.clientX;
5903
+ }
5904
+ var tableGridEl = tableGridRef.current;
5905
+ var headerTitleEl = tableGridEl.querySelector('.custom-event-tl-table__cell-cushion-headertitle');
5906
+ if (headerTitleEl) {
5907
+ resizeStartWidthRef.current = headerTitleEl.clientWidth;
5908
+ }
5909
+ document.addEventListener('touchmove', handleHeaderResizeMove, {
5910
+ passive: false
5911
+ });
5912
+ document.addEventListener('touchend', handleHeaderResizeEnd);
5913
+ }, [ENABLE_HEADER_RESIZE, handleHeaderResizeMove, handleHeaderResizeEnd]);
5914
+
5915
+ // Cleanup on unmount
5916
+ (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(function () {
5917
+ return function () {
5918
+ document.removeEventListener('mousemove', handleHeaderResizeMove);
5919
+ document.removeEventListener('mouseup', handleHeaderResizeEnd);
5920
+ document.removeEventListener('touchmove', handleHeaderResizeMove);
5921
+ document.removeEventListener('touchend', handleHeaderResizeEnd);
5922
+ };
5923
+ }, [handleHeaderResizeMove, handleHeaderResizeEnd]);
5843
5924
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
5844
5925
  className: (0,funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_7__.combinedCls)("custom-event-tl__wrapper custom-event-tl__wrapper--".concat(appearanceMode), calendarWrapperClassName)
5845
5926
  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
@@ -5985,7 +6066,13 @@ var EventCalendarTimeline = function EventCalendarTimeline(props) {
5985
6066
  className: "custom-event-tl-table__cell-cushion custom-event-tl-table__cell-cushion-headertitle"
5986
6067
  }, tableListSectionTitle || ''))))))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("th", {
5987
6068
  role: "presentation",
5988
- className: "custom-event-tl-table__timeline-divider"
6069
+ className: (0,funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_7__.combinedCls)('custom-event-tl-table__timeline-divider', ENABLE_HEADER_RESIZE ? 'custom-event-tl-table__timeline-divider--resizable' : ''),
6070
+ onMouseDown: ENABLE_HEADER_RESIZE ? handleHeaderResizeStart : undefined,
6071
+ onTouchStart: ENABLE_HEADER_RESIZE ? handleHeaderResizeTouchStart : undefined,
6072
+ style: ENABLE_HEADER_RESIZE ? {
6073
+ cursor: 'col-resize',
6074
+ userSelect: 'none'
6075
+ } : undefined
5989
6076
  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", null)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("th", {
5990
6077
  role: "presentation"
5991
6078
  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
@@ -6024,7 +6111,13 @@ var EventCalendarTimeline = function EventCalendarTimeline(props) {
6024
6111
  role: "presentation"
6025
6112
  }, generateListSectionUi()))))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("td", {
6026
6113
  role: "presentation",
6027
- className: (0,funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_7__.combinedCls)('custom-event-tl-table__timeline-divider', tableListDividerClassName)
6114
+ className: (0,funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_7__.combinedCls)('custom-event-tl-table__timeline-divider', tableListDividerClassName, ENABLE_HEADER_RESIZE ? 'custom-event-tl-table__timeline-divider--resizable' : ''),
6115
+ onMouseDown: ENABLE_HEADER_RESIZE ? handleHeaderResizeStart : undefined,
6116
+ onTouchStart: ENABLE_HEADER_RESIZE ? handleHeaderResizeTouchStart : undefined,
6117
+ style: ENABLE_HEADER_RESIZE ? {
6118
+ cursor: 'col-resize',
6119
+ userSelect: 'none'
6120
+ } : undefined
6028
6121
  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", null)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("td", {
6029
6122
  role: "presentation",
6030
6123
  className: (0,funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_7__.combinedCls)(tableListEndClassName)
@@ -235,7 +235,7 @@
235
235
  }
236
236
  */
237
237
  /* cell */
238
- /* header */
238
+ /* The width of the left column header */
239
239
  /* event container */
240
240
  /* days container */
241
241
  /* remove empty cells */
@@ -466,10 +466,21 @@
466
466
  background-color: var(--custom-event-tl-table-divider-bg);
467
467
  border-left: var(--custom-event-tl-table-divider-border);
468
468
  border-right: var(--custom-event-tl-table-divider-border);
469
+ position: relative;
469
470
  }
470
471
  .custom-event-tl-table__timeline-table__wrapper .custom-event-tl-table__timeline-divider > div {
471
472
  width: var(--custom-event-tl-table-divider-w);
472
473
  }
474
+ .custom-event-tl-table__timeline-table__wrapper .custom-event-tl-table__timeline-divider--resizable {
475
+ cursor: col-resize;
476
+ user-select: none;
477
+ }
478
+ .custom-event-tl-table__timeline-table__wrapper .custom-event-tl-table__timeline-divider--resizable:hover {
479
+ background-color: rgba(0, 0, 0, 0.05);
480
+ }
481
+ .custom-event-tl-table__timeline-table__wrapper .custom-event-tl-table__timeline-divider--resizable:active {
482
+ background-color: rgba(0, 0, 0, 0.1);
483
+ }
473
484
  .custom-event-tl-table__timeline-table__wrapper .custom-event-tl-table__cell-cushion {
474
485
  padding: var(--custom-event-tl-table-cell-padding);
475
486
  }
@@ -20,6 +20,7 @@ export type DynamicFieldsProps = {
20
20
  label?: React.ReactNode | string;
21
21
  data: DynamicFieldsValueProps | null;
22
22
  maxFields?: any;
23
+ defaultRows?: number;
23
24
  confirmText?: string;
24
25
  doNotRemoveDom?: boolean;
25
26
  iconAddBefore?: React.ReactNode | string;
@@ -55,6 +56,7 @@ const DynamicFields = (props: DynamicFieldsProps) => {
55
56
  label,
56
57
  data,
57
58
  maxFields,
59
+ defaultRows,
58
60
  iconAddBefore,
59
61
  iconAddAfter,
60
62
  iconAdd,
@@ -96,6 +98,10 @@ const DynamicFields = (props: DynamicFieldsProps) => {
96
98
  const [tmpl, setTmpl] = useState<React.ReactNode>([]);
97
99
  const addBtnIdRef = useRef<string>('');
98
100
  addBtnIdRef.current = `dynamic-fields-add-${idRes}`;
101
+ const defaultRowsInitializedRef = useRef<boolean>(false);
102
+ const isInitializingDefaultRowsRef = useRef<boolean>(false);
103
+ const rafIdRef = useRef<number | null>(null);
104
+ const timeoutIdsRef = useRef<ReturnType<typeof setTimeout>[]>([]);
99
105
 
100
106
  // exposes the following methods
101
107
  useImperativeHandle(
@@ -169,17 +175,12 @@ const DynamicFields = (props: DynamicFieldsProps) => {
169
175
  }
170
176
  }
171
177
 
172
-
173
- function handleClickAdd(event: any = null) {
174
- if (event !== null) {
175
- if (typeof event !== 'undefined') event.preventDefault();
176
- }
177
-
178
+ function addRowWithTemplate(template: React.ReactNode) {
178
179
  //button status
179
180
  checkMaxStatus();
180
181
 
181
182
  //
182
- setVal((prevState: any[]) => [...prevState, ...generateGroup(tmpl)]);
183
+ setVal((prevState: any[]) => [...prevState, ...generateGroup(template)]);
183
184
 
184
185
 
185
186
  //
@@ -209,6 +210,14 @@ const DynamicFields = (props: DynamicFieldsProps) => {
209
210
  }, 0);
210
211
  }
211
212
 
213
+ function handleClickAdd(event: any = null) {
214
+ if (event !== null) {
215
+ if (typeof event !== 'undefined') event.preventDefault();
216
+ }
217
+
218
+ addRowWithTemplate(tmpl);
219
+ }
220
+
212
221
 
213
222
  function handleClickRemove(e: React.MouseEvent) {
214
223
  if (e !== null && typeof e !== 'undefined') e.preventDefault();
@@ -331,6 +340,96 @@ const DynamicFields = (props: DynamicFieldsProps) => {
331
340
 
332
341
  //
333
342
  onLoad?.(addBtnIdRef.current, rootRef.current, PER_ROW_DOM_STRING);
343
+
344
+ // Reset initialization flag when data becomes null
345
+ if (!data) {
346
+ defaultRowsInitializedRef.current = false;
347
+ isInitializingDefaultRowsRef.current = false;
348
+ }
349
+
350
+ // Add default rows if specified (only initialize once per data setup)
351
+ if (!defaultRowsInitializedRef.current && typeof defaultRows === 'number' && defaultRows > 0 && data && data.tmpl) {
352
+ // Get the initial data length
353
+ const initDataLength = Array.isArray(data.init) ? data.init.length : 0;
354
+
355
+ // Calculate how many rows need to be added
356
+ const maxRows = typeof maxFields !== 'undefined' ? parseFloat(maxFields) : Infinity;
357
+ const targetRows = Math.min(defaultRows, maxRows);
358
+ const rowsToAdd = Math.max(0, targetRows - initDataLength);
359
+
360
+ // Mark as initialized immediately to prevent re-adding
361
+ defaultRowsInitializedRef.current = true;
362
+
363
+ // Only add rows if needed
364
+ if (rowsToAdd > 0) {
365
+ // Mark that we're initializing default rows
366
+ isInitializingDefaultRowsRef.current = true;
367
+
368
+ // Clear any existing timeouts
369
+ timeoutIdsRef.current.forEach(id => clearTimeout(id));
370
+ timeoutIdsRef.current = [];
371
+
372
+ // Use requestAnimationFrame to ensure DOM is ready and state is updated
373
+ rafIdRef.current = requestAnimationFrame(() => {
374
+ // Check if component is still mounted
375
+ if (!rootRef.current) {
376
+ isInitializingDefaultRowsRef.current = false;
377
+ return;
378
+ }
379
+
380
+ const timeoutId1 = setTimeout(() => {
381
+ // Check if component is still mounted
382
+ if (!rootRef.current) {
383
+ isInitializingDefaultRowsRef.current = false;
384
+ return;
385
+ }
386
+
387
+ // Add rows one by one with a small delay to ensure state updates
388
+ let addedCount = 0;
389
+ const addNextRow = () => {
390
+ // Check if component is still mounted before each operation
391
+ if (addedCount < rowsToAdd && rootRef.current) {
392
+ // Use data.tmpl directly to avoid dependency on state
393
+ addRowWithTemplate(data.tmpl);
394
+ addedCount++;
395
+ // Wait a bit before adding the next row to ensure state updates
396
+ if (addedCount < rowsToAdd) {
397
+ const timeoutId2 = setTimeout(addNextRow, 10);
398
+ timeoutIdsRef.current.push(timeoutId2);
399
+ } else {
400
+ // All rows added, mark initialization as complete
401
+ isInitializingDefaultRowsRef.current = false;
402
+ }
403
+ } else {
404
+ // No more rows to add or component unmounted
405
+ isInitializingDefaultRowsRef.current = false;
406
+ }
407
+ };
408
+ addNextRow();
409
+ }, 50);
410
+ timeoutIdsRef.current.push(timeoutId1);
411
+ });
412
+ }
413
+ }
414
+
415
+ // Cleanup function to cancel requestAnimationFrame and timeouts
416
+ return () => {
417
+ // Don't cleanup if we're in the middle of initializing defaultRows
418
+ // This prevents the cleanup from canceling the async operations before they complete
419
+ if (isInitializingDefaultRowsRef.current) {
420
+ // Allow defaultRows initialization to complete
421
+ // The cleanup will happen naturally when initialization finishes
422
+ return;
423
+ }
424
+
425
+ // Normal cleanup for other cases
426
+ if (rafIdRef.current !== null) {
427
+ cancelAnimationFrame(rafIdRef.current);
428
+ rafIdRef.current = null;
429
+ }
430
+ timeoutIdsRef.current.forEach(id => clearTimeout(id));
431
+ timeoutIdsRef.current = [];
432
+ };
334
433
  }, [data]);
335
434
 
336
435
 
@@ -406,4 +505,4 @@ const DynamicFields = (props: DynamicFieldsProps) => {
406
505
  )
407
506
  };
408
507
 
409
- export default DynamicFields;
508
+ export default DynamicFields;
@@ -470,7 +470,7 @@
470
470
  word-break: break-word;
471
471
  }
472
472
 
473
- /* header */
473
+ /* The width of the left column header */
474
474
  .custom-event-tl-table__cell-cushion-headertitle {
475
475
  width: var(--custom-event-tl-table-header-w);
476
476
  }
@@ -614,10 +614,24 @@
614
614
  background-color: var(--custom-event-tl-table-divider-bg);
615
615
  border-left: var(--custom-event-tl-table-divider-border);
616
616
  border-right: var(--custom-event-tl-table-divider-border);
617
+ position: relative;
617
618
 
618
619
  > div {
619
620
  width: var(--custom-event-tl-table-divider-w);
620
621
  }
622
+
623
+ &--resizable {
624
+ cursor: col-resize;
625
+ user-select: none;
626
+
627
+ &:hover {
628
+ background-color: rgba(0, 0, 0, 0.05);
629
+ }
630
+
631
+ &:active {
632
+ background-color: rgba(0, 0, 0, 0.1);
633
+ }
634
+ }
621
635
  }
622
636
 
623
637
  /* cell */
@@ -14,6 +14,7 @@ import { clsWrite, combinedCls } from 'funda-utils/dist/cjs/cls';
14
14
  import getOs from 'funda-utils//dist/cjs/os';
15
15
 
16
16
 
17
+
17
18
  export interface EventsValueConfig {
18
19
  id: string | number;
19
20
  date: string,
@@ -79,7 +80,7 @@ export type EventCalendarTimelineProps = {
79
80
  onChangeWeek?: (startDate: string, endDate: string) => void;
80
81
  onListRenderComplete?: () => void;
81
82
  onChangeAppearanceMode?: (mode: string) => void;
82
-
83
+ enableHeaderResize?: boolean;
83
84
 
84
85
 
85
86
  // modal dialog
@@ -169,6 +170,7 @@ const EventCalendarTimeline = (props: EventCalendarTimelineProps) => {
169
170
  onChangeWeek,
170
171
  onListRenderComplete,
171
172
  onChangeAppearanceMode,
173
+ enableHeaderResize,
172
174
 
173
175
  //
174
176
  modalMaskOpacity,
@@ -273,11 +275,17 @@ const EventCalendarTimeline = (props: EventCalendarTimelineProps) => {
273
275
  const AUTO_SCROLL = autoScroll || false;
274
276
  const HEADER_SHOW_WEEK = headerShowWeek || false;
275
277
  const BODY_DRAG = draggable || false;
278
+ const ENABLE_HEADER_RESIZE = enableHeaderResize || false;
276
279
  const tableGridRef = useRef<any>(null);
277
280
  const tableGridHeaderRef = useRef<any>(null);
278
281
  const scrollHeaderRef = useRef(null);
279
282
  const scrollBodyRef = useRef(null);
280
283
  const scrollListRef = useRef(null);
284
+
285
+ // header resize drag
286
+ const isResizingRef = useRef<boolean>(false);
287
+ const resizeStartXRef = useRef<number>(0);
288
+ const resizeStartWidthRef = useRef<number>(0);
281
289
 
282
290
  // Temporary date
283
291
  const [tempDate, setTempDate] = useState<string>('');
@@ -2121,7 +2129,6 @@ const EventCalendarTimeline = (props: EventCalendarTimelineProps) => {
2121
2129
 
2122
2130
  }
2123
2131
 
2124
-
2125
2132
  function tableGridReset() {
2126
2133
  if (tableGridRef.current === null) return;
2127
2134
 
@@ -2153,13 +2160,7 @@ const EventCalendarTimeline = (props: EventCalendarTimelineProps) => {
2153
2160
 
2154
2161
  }
2155
2162
 
2156
-
2157
-
2158
-
2159
- // ================================================================
2160
- //
2161
- // ================================================================
2162
- //if user change the selectedYear, then udate the years array that is displayed on year tab view
2163
+ // if user change the selectedYear, then udate the years array that is displayed on year tab view
2163
2164
  useEffect(() => {
2164
2165
  const years: number[] = [];
2165
2166
  for (let y = selectedYear - 10; y < selectedYear + 10; y++) {
@@ -2230,6 +2231,102 @@ const EventCalendarTimeline = (props: EventCalendarTimelineProps) => {
2230
2231
  }
2231
2232
 
2232
2233
  }, []);
2234
+
2235
+
2236
+ // ================================================================
2237
+ // Handle header resize drag
2238
+ // ================================================================
2239
+ const handleHeaderResizeMove = useCallback((e: MouseEvent | TouchEvent) => {
2240
+ if (!isResizingRef.current || !tableGridRef.current) return;
2241
+
2242
+ const tableGridEl: any = tableGridRef.current;
2243
+ // Find the header title element that should have the CSS variable
2244
+ const headerTitleEl = tableGridEl.querySelector('.custom-event-tl-table__cell-cushion-headertitle') as HTMLElement;
2245
+ if (!headerTitleEl) return;
2246
+
2247
+ // Get clientX from either MouseEvent or TouchEvent
2248
+ const clientX = 'touches' in e ? e.touches[0]?.clientX : e.clientX;
2249
+ if (clientX === undefined) return;
2250
+
2251
+ const deltaX = clientX - resizeStartXRef.current;
2252
+ const newWidth = Math.max(100, resizeStartWidthRef.current + deltaX); // Minimum width 100px
2253
+
2254
+ // Update CSS variable on the header title element
2255
+ headerTitleEl.style.setProperty('--custom-event-tl-table-header-w', `${newWidth}px`);
2256
+ }, []);
2257
+
2258
+ const handleHeaderResizeEnd = useCallback(() => {
2259
+ if (!isResizingRef.current) return;
2260
+
2261
+ isResizingRef.current = false;
2262
+ document.removeEventListener('mousemove', handleHeaderResizeMove);
2263
+ document.removeEventListener('mouseup', handleHeaderResizeEnd);
2264
+ document.removeEventListener('touchmove', handleHeaderResizeMove);
2265
+ document.removeEventListener('touchend', handleHeaderResizeEnd);
2266
+
2267
+ // Recalculate table grid after resize
2268
+ if (tableGridRef.current) {
2269
+ tableGridInit();
2270
+ }
2271
+ }, [handleHeaderResizeMove]);
2272
+
2273
+ const handleHeaderResizeStart = useCallback((e: React.MouseEvent) => {
2274
+ if (!ENABLE_HEADER_RESIZE || !tableGridRef.current) return;
2275
+
2276
+ e.preventDefault();
2277
+ e.stopPropagation();
2278
+
2279
+ isResizingRef.current = true;
2280
+ resizeStartXRef.current = e.clientX;
2281
+
2282
+ const tableGridEl: any = tableGridRef.current;
2283
+ const headerTitleEl = tableGridEl.querySelector('.custom-event-tl-table__cell-cushion-headertitle') as HTMLElement;
2284
+ if (headerTitleEl) {
2285
+ resizeStartWidthRef.current = headerTitleEl.clientWidth;
2286
+ }
2287
+
2288
+ document.addEventListener('mousemove', handleHeaderResizeMove);
2289
+ document.addEventListener('mouseup', handleHeaderResizeEnd);
2290
+ }, [ENABLE_HEADER_RESIZE, handleHeaderResizeMove, handleHeaderResizeEnd]);
2291
+
2292
+ const handleHeaderResizeTouchStart = useCallback((e: React.TouchEvent) => {
2293
+ if (!ENABLE_HEADER_RESIZE || !tableGridRef.current) return;
2294
+
2295
+ e.preventDefault();
2296
+ e.stopPropagation();
2297
+
2298
+ isResizingRef.current = true;
2299
+ const touch = e.touches[0];
2300
+ if (touch) {
2301
+ resizeStartXRef.current = touch.clientX;
2302
+ }
2303
+
2304
+ const tableGridEl: any = tableGridRef.current;
2305
+ const headerTitleEl = tableGridEl.querySelector('.custom-event-tl-table__cell-cushion-headertitle') as HTMLElement;
2306
+ if (headerTitleEl) {
2307
+ resizeStartWidthRef.current = headerTitleEl.clientWidth;
2308
+ }
2309
+
2310
+ document.addEventListener('touchmove', handleHeaderResizeMove, { passive: false });
2311
+ document.addEventListener('touchend', handleHeaderResizeEnd);
2312
+ }, [ENABLE_HEADER_RESIZE, handleHeaderResizeMove, handleHeaderResizeEnd]);
2313
+
2314
+
2315
+
2316
+ // Cleanup on unmount
2317
+ useEffect(() => {
2318
+ return () => {
2319
+ document.removeEventListener('mousemove', handleHeaderResizeMove);
2320
+ document.removeEventListener('mouseup', handleHeaderResizeEnd);
2321
+ document.removeEventListener('touchmove', handleHeaderResizeMove);
2322
+ document.removeEventListener('touchend', handleHeaderResizeEnd);
2323
+ };
2324
+ }, [handleHeaderResizeMove, handleHeaderResizeEnd]);
2325
+
2326
+
2327
+
2328
+
2329
+
2233
2330
  return (
2234
2331
  <>
2235
2332
 
@@ -2417,6 +2514,9 @@ const EventCalendarTimeline = (props: EventCalendarTimelineProps) => {
2417
2514
  <thead role="presentation">
2418
2515
  <tr role="row">
2419
2516
  <th role="columnheader">
2517
+ {/**
2518
+ * The width of the left column header is set using ".custom-event-tl-table__cell-cushion-headertitle".
2519
+ */}
2420
2520
  <div className="custom-event-tl-table__cell-cushion custom-event-tl-table__cell-cushion-headertitle">
2421
2521
  {tableListSectionTitle || ''}
2422
2522
  </div>
@@ -2431,7 +2531,18 @@ const EventCalendarTimeline = (props: EventCalendarTimelineProps) => {
2431
2531
 
2432
2532
 
2433
2533
  </th>
2434
- <th role="presentation" className="custom-event-tl-table__timeline-divider"><div></div></th>
2534
+ <th
2535
+ role="presentation"
2536
+ className={combinedCls(
2537
+ 'custom-event-tl-table__timeline-divider',
2538
+ ENABLE_HEADER_RESIZE ? 'custom-event-tl-table__timeline-divider--resizable' : ''
2539
+ )}
2540
+ onMouseDown={ENABLE_HEADER_RESIZE ? handleHeaderResizeStart : undefined}
2541
+ onTouchStart={ENABLE_HEADER_RESIZE ? handleHeaderResizeTouchStart : undefined}
2542
+ style={ENABLE_HEADER_RESIZE ? { cursor: 'col-resize', userSelect: 'none' } : undefined}
2543
+ >
2544
+ <div></div>
2545
+ </th>
2435
2546
  <th role="presentation">
2436
2547
  <div
2437
2548
  ref={scrollHeaderRef}
@@ -2507,12 +2618,20 @@ const EventCalendarTimeline = (props: EventCalendarTimelineProps) => {
2507
2618
 
2508
2619
 
2509
2620
  </td>
2621
+
2622
+ {/**
2623
+ * The dividing line between the left title column and the right content
2624
+ */}
2510
2625
  <td
2511
2626
  role="presentation"
2512
2627
  className={combinedCls(
2513
2628
  'custom-event-tl-table__timeline-divider',
2514
- tableListDividerClassName
2629
+ tableListDividerClassName,
2630
+ ENABLE_HEADER_RESIZE ? 'custom-event-tl-table__timeline-divider--resizable' : ''
2515
2631
  )}
2632
+ onMouseDown={ENABLE_HEADER_RESIZE ? handleHeaderResizeStart : undefined}
2633
+ onTouchStart={ENABLE_HEADER_RESIZE ? handleHeaderResizeTouchStart : undefined}
2634
+ style={ENABLE_HEADER_RESIZE ? { cursor: 'col-resize', userSelect: 'none' } : undefined}
2516
2635
  >
2517
2636
  <div></div>
2518
2637
  </td>
@@ -13,7 +13,6 @@ import {
13
13
  } from 'funda-utils/dist/cjs/bodyScrollLock';
14
14
 
15
15
 
16
-
17
16
  declare global {
18
17
  interface Window {
19
18
  curVideo?: any;
package/package.json CHANGED
@@ -1 +1 @@
1
- {"author":"UIUX Lab","email":"uiuxlab@gmail.com","name":"funda-ui","version":"4.7.711","description":"React components using pure Bootstrap 5+ which does not contain any external style and script libraries.","repository":{"type":"git","url":"git+https://github.com/xizon/funda-ui.git"},"scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"keywords":["bootstrap","react-bootstrap","react-components","components","components-react","react-bootstrap-components","react","funda-ui","fundaui","uikit","ui-kit","ui-components"],"bugs":{"url":"https://github.com/xizon/funda-ui/issues"},"homepage":"https://github.com/xizon/funda-ui#readme","main":"all.js","license":"MIT","dependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"types":"all.d.ts","publishConfig":{"directory":"lib"},"directories":{"lib":"lib"}}
1
+ {"author":"UIUX Lab","email":"uiuxlab@gmail.com","name":"funda-ui","version":"4.7.723","description":"React components using pure Bootstrap 5+ which does not contain any external style and script libraries.","repository":{"type":"git","url":"git+https://github.com/xizon/funda-ui.git"},"scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"keywords":["bootstrap","react-bootstrap","react-components","components","components-react","react-bootstrap-components","react","funda-ui","fundaui","uikit","ui-kit","ui-components"],"bugs":{"url":"https://github.com/xizon/funda-ui/issues"},"homepage":"https://github.com/xizon/funda-ui#readme","main":"all.js","license":"MIT","dependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"types":"all.d.ts","publishConfig":{"directory":"lib"},"directories":{"lib":"lib"}}