@openg2p/registry-widgets 1.1.0-dev.13 → 1.1.0-dev.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -808,6 +808,40 @@ const parseDateFromFormat = (dateString, format) => {
808
808
  }
809
809
  return parseDate(dateString);
810
810
  };
811
+ /**
812
+ * Resolve a stored date value (ISO or parseable string) to YYYY-MM-DD for comparisons.
813
+ */
814
+ const resolveDateBoundFromFieldValue = (fieldValue) => {
815
+ if (fieldValue == null || fieldValue === '') {
816
+ return undefined;
817
+ }
818
+ const iso = formatDateToISO(fieldValue);
819
+ return iso || undefined;
820
+ };
821
+ /**
822
+ * Pick the stricter (later) minimum when combining static and field-based bounds.
823
+ */
824
+ const mergeMinDateBounds = (boundA, boundB) => {
825
+ if (!boundA) {
826
+ return boundB;
827
+ }
828
+ if (!boundB) {
829
+ return boundA;
830
+ }
831
+ return boundA > boundB ? boundA : boundB;
832
+ };
833
+ /**
834
+ * Pick the stricter (earlier) maximum when combining static and field-based bounds.
835
+ */
836
+ const mergeMaxDateBounds = (boundA, boundB) => {
837
+ if (!boundA) {
838
+ return boundB;
839
+ }
840
+ if (!boundB) {
841
+ return boundA;
842
+ }
843
+ return boundA < boundB ? boundA : boundB;
844
+ };
811
845
  /**
812
846
  * Get min date based on constraint type
813
847
  */
@@ -850,10 +884,7 @@ const getMaxDate = (constraint, maxDate) => {
850
884
  }
851
885
  return undefined;
852
886
  };
853
- /**
854
- * Validate date constraints
855
- */
856
- const validateDateConstraints = (date, minDate, maxDate, constraint) => {
887
+ const validateDateConstraints = (date, minDate, maxDate, constraint, messages) => {
857
888
  if (!date)
858
889
  return null;
859
890
  const dateObj = date instanceof Date ? date : parseDate(date);
@@ -872,15 +903,12 @@ const validateDateConstraints = (date, minDate, maxDate, constraint) => {
872
903
  return 'Date must be in the future';
873
904
  }
874
905
  }
875
- // Check minDate
876
- const effectiveMinDate = getMinDate(constraint, minDate);
877
- if (effectiveMinDate && dateISO < effectiveMinDate) {
878
- return `Date must be on or after ${effectiveMinDate}`;
906
+ // minDate / maxDate are effective bounds (static + field-based), resolved by the caller
907
+ if (minDate && dateISO < minDate) {
908
+ return messages?.minDateMessage ?? `Date must be on or after ${minDate}`;
879
909
  }
880
- // Check maxDate
881
- const effectiveMaxDate = getMaxDate(constraint, maxDate);
882
- if (effectiveMaxDate && dateISO > effectiveMaxDate) {
883
- return `Date must be on or before ${effectiveMaxDate}`;
910
+ if (maxDate && dateISO > maxDate) {
911
+ return messages?.maxDateMessage ?? `Date must be on or before ${maxDate}`;
884
912
  }
885
913
  return null;
886
914
  };
@@ -7648,42 +7676,76 @@ const BooleanWidget = ({ config }) => {
7648
7676
  };
7649
7677
 
7650
7678
  const DateInputWidget = ({ config }) => {
7651
- const { value, formattedValue, error, touched, isEnabled, onChange, onBlur, config: widgetConfig, } = useBaseWidget({ config });
7652
- const { translate, translateConfig } = useWidgetTranslation();
7679
+ const { value, error, touched, isEnabled, onChange, onBlur, setError, config: widgetConfig, } = useBaseWidget({ config });
7680
+ const formValues = reactRedux.useSelector((state) => state.widget.values);
7681
+ const { translateConfig } = useWidgetTranslation();
7653
7682
  const formatConfig = widgetConfig['widget-data-format'];
7654
7683
  const optionsConfig = widgetConfig['widget-data-options'];
7655
7684
  const dateFormat = formatConfig?.dateFormat || 'YYYY-MM-DD';
7656
- const inputMethod = formatConfig?.inputMethod || 'picker'; // Default to picker for better UX
7685
+ const inputMethod = formatConfig?.inputMethod || 'picker';
7657
7686
  const dateConstraint = formatConfig?.dateConstraint || 'any';
7658
7687
  const minDate = optionsConfig?.minDate;
7659
7688
  const maxDate = optionsConfig?.maxDate;
7689
+ const minDateField = optionsConfig?.minDateField;
7690
+ const maxDateField = optionsConfig?.maxDateField;
7691
+ const minDateMessage = optionsConfig?.minDateMessage
7692
+ ? translateConfig(optionsConfig.minDateMessage)
7693
+ : undefined;
7694
+ const maxDateMessage = optionsConfig?.maxDateMessage
7695
+ ? translateConfig(optionsConfig.maxDateMessage)
7696
+ : undefined;
7660
7697
  const defaultToToday = widgetConfig['widget-data-default'] === 'today';
7661
- // Track manual input value (for manual/hybrid modes)
7662
7698
  const [manualInputValue, setManualInputValue] = React.useState('');
7663
7699
  const [isFocused, setIsFocused] = React.useState(false);
7664
- // Initialize default value to today if configured
7700
+ const fieldMinDate = React.useMemo(() => {
7701
+ if (!minDateField) {
7702
+ return undefined;
7703
+ }
7704
+ return resolveDateBoundFromFieldValue(getValueByPath(formValues, minDateField));
7705
+ }, [formValues, minDateField]);
7706
+ const fieldMaxDate = React.useMemo(() => {
7707
+ if (!maxDateField) {
7708
+ return undefined;
7709
+ }
7710
+ return resolveDateBoundFromFieldValue(getValueByPath(formValues, maxDateField));
7711
+ }, [formValues, maxDateField]);
7712
+ const effectiveMinDate = React.useMemo(() => {
7713
+ const staticMin = getMinDate(dateConstraint, minDate);
7714
+ return mergeMinDateBounds(staticMin, fieldMinDate);
7715
+ }, [dateConstraint, minDate, fieldMinDate]);
7716
+ const effectiveMaxDate = React.useMemo(() => {
7717
+ const staticMax = getMaxDate(dateConstraint, maxDate);
7718
+ return mergeMaxDateBounds(staticMax, fieldMaxDate);
7719
+ }, [dateConstraint, maxDate, fieldMaxDate]);
7720
+ const constraintMessages = React.useMemo(() => ({ minDateMessage, maxDateMessage }), [minDateMessage, maxDateMessage]);
7721
+ const runDateConstraintValidation = React.useCallback((dateValue) => {
7722
+ if (!dateValue) {
7723
+ return null;
7724
+ }
7725
+ return validateDateConstraints(dateValue, effectiveMinDate, effectiveMaxDate, dateConstraint, constraintMessages);
7726
+ }, [effectiveMinDate, effectiveMaxDate, dateConstraint, constraintMessages]);
7665
7727
  React.useEffect(() => {
7666
7728
  if (defaultToToday && (value === null || value === undefined || value === '')) {
7667
7729
  const todayISO = formatDateToISO(new Date());
7668
7730
  onChange(todayISO);
7669
7731
  }
7670
7732
  }, [defaultToToday, value, onChange]);
7671
- // Get effective min/max dates
7672
- const effectiveMinDate = React.useMemo(() => {
7673
- return getMinDate(dateConstraint, minDate);
7674
- }, [dateConstraint, minDate]);
7675
- const effectiveMaxDate = React.useMemo(() => {
7676
- return getMaxDate(dateConstraint, maxDate);
7677
- }, [dateConstraint, maxDate]);
7678
- // Convert ISO value to display format
7733
+ // Re-validate when a relative bound field changes (e.g. start date set after end date)
7734
+ React.useEffect(() => {
7735
+ if (!value) {
7736
+ return;
7737
+ }
7738
+ const constraintError = runDateConstraintValidation(value);
7739
+ if (constraintError) {
7740
+ setError([constraintError]);
7741
+ }
7742
+ }, [fieldMinDate, fieldMaxDate, value, runDateConstraintValidation, setError]);
7679
7743
  const getDisplayValue = React.useCallback(() => {
7680
- // For picker mode, always use YYYY-MM-DD
7681
7744
  if (inputMethod === 'picker') {
7682
7745
  if (!value)
7683
7746
  return '';
7684
7747
  return formatDateToISO(value);
7685
7748
  }
7686
- // For manual/hybrid modes, use custom format
7687
7749
  if (isFocused && manualInputValue) {
7688
7750
  return manualInputValue;
7689
7751
  }
@@ -7694,7 +7756,6 @@ const DateInputWidget = ({ config }) => {
7694
7756
  }
7695
7757
  return formatDateToString(value, dateFormat);
7696
7758
  }, [value, inputMethod, dateFormat, isFocused, manualInputValue]);
7697
- // Initialize manual input value
7698
7759
  React.useEffect(() => {
7699
7760
  if (!isFocused && value) {
7700
7761
  if (dateFormat === 'YYYY-MM-DD') {
@@ -7705,66 +7766,81 @@ const DateInputWidget = ({ config }) => {
7705
7766
  }
7706
7767
  }
7707
7768
  }, [value, dateFormat, isFocused]);
7708
- // Handle input change
7769
+ const applyConstraintError = React.useCallback((dateValue) => {
7770
+ const constraintError = runDateConstraintValidation(dateValue);
7771
+ setError(constraintError ? [constraintError] : []);
7772
+ }, [runDateConstraintValidation, setError]);
7709
7773
  const handleChange = React.useCallback((e) => {
7710
7774
  const inputValue = e.target.value;
7711
7775
  if (inputMethod === 'picker') {
7712
- // Picker mode: input is always YYYY-MM-DD
7713
7776
  if (inputValue) {
7714
7777
  const date = parseDate(inputValue);
7715
7778
  if (date) {
7716
- onChange(formatDateToISO(date));
7779
+ const iso = formatDateToISO(date);
7780
+ onChange(iso);
7781
+ applyConstraintError(iso);
7717
7782
  }
7718
7783
  else {
7719
7784
  onChange('');
7785
+ setError([]);
7720
7786
  }
7721
7787
  }
7722
7788
  else {
7723
7789
  onChange('');
7790
+ setError([]);
7724
7791
  }
7725
7792
  }
7726
7793
  else {
7727
- // Manual/hybrid mode: parse custom format
7728
7794
  setManualInputValue(inputValue);
7729
7795
  if (inputValue) {
7730
7796
  const date = parseDateFromFormat(inputValue, dateFormat);
7731
7797
  if (date) {
7732
- // Validate constraints
7733
- const constraintError = validateDateConstraints(date, minDate, maxDate, dateConstraint);
7734
- if (!constraintError) {
7735
- onChange(formatDateToISO(date));
7736
- }
7737
- else {
7738
- // Still update the value but validation will catch it
7739
- onChange(formatDateToISO(date));
7740
- }
7798
+ const iso = formatDateToISO(date);
7799
+ onChange(iso);
7800
+ applyConstraintError(iso);
7741
7801
  }
7742
7802
  }
7743
7803
  else {
7744
7804
  onChange('');
7805
+ setError([]);
7745
7806
  }
7746
7807
  }
7747
- }, [inputMethod, dateFormat, onChange, minDate, maxDate, dateConstraint]);
7748
- // Handle blur - validate and format
7808
+ }, [inputMethod, dateFormat, onChange, applyConstraintError, setError]);
7749
7809
  const handleBlur = React.useCallback(() => {
7750
7810
  setIsFocused(false);
7751
7811
  if (inputMethod !== 'picker' && manualInputValue) {
7752
7812
  const date = parseDateFromFormat(manualInputValue, dateFormat);
7753
7813
  if (date) {
7754
- // Format the value according to the format
7755
7814
  const formatted = formatDateToString(date, dateFormat);
7756
7815
  setManualInputValue(formatted);
7757
- onChange(formatDateToISO(date));
7816
+ const iso = formatDateToISO(date);
7817
+ onChange(iso);
7818
+ applyConstraintError(iso);
7758
7819
  }
7759
7820
  else {
7760
- // Invalid date, clear it
7761
7821
  setManualInputValue('');
7762
7822
  onChange('');
7823
+ setError([]);
7763
7824
  }
7764
7825
  }
7765
7826
  onBlur();
7766
- }, [inputMethod, manualInputValue, dateFormat, onChange, onBlur]);
7767
- // Handle focus
7827
+ if (value) {
7828
+ const constraintError = runDateConstraintValidation(value);
7829
+ if (constraintError) {
7830
+ setError([constraintError]);
7831
+ }
7832
+ }
7833
+ }, [
7834
+ inputMethod,
7835
+ manualInputValue,
7836
+ dateFormat,
7837
+ onChange,
7838
+ onBlur,
7839
+ applyConstraintError,
7840
+ value,
7841
+ runDateConstraintValidation,
7842
+ setError,
7843
+ ]);
7768
7844
  const handleFocus = React.useCallback(() => {
7769
7845
  setIsFocused(true);
7770
7846
  if (value) {
@@ -7776,15 +7852,15 @@ const DateInputWidget = ({ config }) => {
7776
7852
  }
7777
7853
  }
7778
7854
  }, [value, dateFormat]);
7779
- // Determine placeholder
7780
7855
  const placeholder = React.useMemo(() => {
7781
- const hasValue = getDisplayValue() && getDisplayValue().trim().length > 0;
7856
+ const display = getDisplayValue();
7857
+ const hasValue = display && display.trim().length > 0;
7782
7858
  const placeholderText = translateConfig(widgetConfig['widget-data-placeholder']);
7783
- return hasValue ? undefined : (placeholderText || dateFormat);
7859
+ return hasValue ? undefined : placeholderText || dateFormat;
7784
7860
  }, [getDisplayValue, widgetConfig, translateConfig, dateFormat]);
7785
- // Determine input type
7786
7861
  const inputType = inputMethod === 'picker' ? 'date' : 'text';
7787
- // For readonly mode, render as display text
7862
+ const showRequiredError = widgetConfig['widget-required'] && (!value || value === '');
7863
+ const showValidationError = touched && error.length > 0;
7788
7864
  if (widgetConfig['widget-readonly']) {
7789
7865
  const label = translateConfig(widgetConfig['widget-label']);
7790
7866
  let displayValue = '';
@@ -7801,9 +7877,9 @@ const DateInputWidget = ({ config }) => {
7801
7877
  }
7802
7878
  return (jsxRuntimeExports.jsxs("div", { className: "mb-[10px] DateDisplayWidget flex flex-col sm:flex-row sm:items-start", children: [label && (jsxRuntimeExports.jsxs("div", { className: "text-base text-gray-600 font-medium md:min-w-[120px] sm:pr-4 mb-1 sm:mb-0", style: { fontFamily: 'Roboto, sans-serif' }, title: label, children: [label, ":"] })), jsxRuntimeExports.jsx("div", { className: "flex-1", children: jsxRuntimeExports.jsx("div", { className: "text-base text-gray-900 font-medium", title: String(displayValue ?? ''), children: displayValue }) })] }));
7803
7879
  }
7804
- return (jsxRuntimeExports.jsx("div", { className: "mb-[10px]", children: jsxRuntimeExports.jsxs("div", { className: "flex flex-col sm:flex-row sm:items-start", children: [jsxRuntimeExports.jsxs("label", { className: "text-base font-medium text-gray-700 md:min-w-[120px] sm:pr-4 sm:pt-1 mb-1 sm:mb-0", style: { fontFamily: 'Roboto, sans-serif' }, title: translateConfig(widgetConfig['widget-label']), children: [translateConfig(widgetConfig['widget-label']), widgetConfig['widget-required'] && (jsxRuntimeExports.jsx("span", { className: "text-red-500 ml-1", children: "*" }))] }), jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [jsxRuntimeExports.jsx("input", { type: inputType, value: getDisplayValue(), onChange: handleChange, onBlur: handleBlur, onFocus: handleFocus, disabled: !isEnabled || widgetConfig['widget-readonly'], placeholder: placeholder, min: inputMethod === 'picker' ? effectiveMinDate : undefined, max: inputMethod === 'picker' ? effectiveMaxDate : undefined, className: `w-full sm:w-[180px] max-w-full h-[30px] px-3 border shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 ${(touched && error.length > 0) || (widgetConfig['widget-required'] && (!value || value === ''))
7880
+ return (jsxRuntimeExports.jsx("div", { className: "mb-[10px]", children: jsxRuntimeExports.jsxs("div", { className: "flex flex-col sm:flex-row sm:items-start", children: [jsxRuntimeExports.jsxs("label", { className: "text-base font-medium text-gray-700 md:min-w-[120px] sm:pr-4 sm:pt-1 mb-1 sm:mb-0", style: { fontFamily: 'Roboto, sans-serif' }, title: translateConfig(widgetConfig['widget-label']), children: [translateConfig(widgetConfig['widget-label']), widgetConfig['widget-required'] && jsxRuntimeExports.jsx("span", { className: "text-red-500 ml-1", children: "*" })] }), jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [jsxRuntimeExports.jsx("input", { type: inputType, value: getDisplayValue(), onChange: handleChange, onBlur: handleBlur, onFocus: handleFocus, disabled: !isEnabled || widgetConfig['widget-readonly'], placeholder: placeholder, min: inputMethod === 'picker' ? effectiveMinDate : undefined, max: inputMethod === 'picker' ? effectiveMaxDate : undefined, className: `w-full sm:w-[180px] max-w-full h-[30px] px-3 border shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 ${showValidationError || showRequiredError
7805
7881
  ? 'border-red-500 focus:ring-red-500 focus:border-red-500'
7806
- : 'border-gray-300'} ${!isEnabled || widgetConfig['widget-readonly'] ? 'bg-gray-100 cursor-not-allowed' : 'bg-white'}`, style: { borderRadius: '10px' }, title: translateConfig(widgetConfig['widget-data-tooltip']) }), touched && error.length > 0 && (jsxRuntimeExports.jsx("p", { className: "text-red-500 text-sm mt-1", children: error[0] }))] })] }) }));
7882
+ : 'border-gray-300'} ${!isEnabled || widgetConfig['widget-readonly'] ? 'bg-gray-100 cursor-not-allowed' : 'bg-white'}`, style: { borderRadius: '10px' }, title: translateConfig(widgetConfig['widget-data-tooltip']) }), showValidationError && jsxRuntimeExports.jsx("p", { className: "text-red-500 text-sm mt-1", children: error[0] })] })] }) }));
7807
7883
  };
7808
7884
 
7809
7885
  /**
@@ -8747,16 +8823,70 @@ const TableCellNumber = ({ config, value, onValueChange }) => {
8747
8823
  backgroundColor: isReadonly ? 'var(--owt-color-bg-alt, #F6F6F6)' : 'var(--owt-color-bg, #FFFFFF)',
8748
8824
  } }));
8749
8825
  };
8750
- const TableCellDate = ({ config, value, onValueChange }) => {
8826
+ const TableCellDate = ({ config, value, rowValues, onValueChange }) => {
8827
+ const { translateConfig } = useWidgetTranslation();
8751
8828
  const isReadonly = config['widget-readonly'] || false;
8752
8829
  const placeholder = config['widget-data-placeholder'] || '';
8830
+ const optionsConfig = config['widget-data-options'];
8831
+ const formatConfig = config['widget-data-format'];
8832
+ const dateConstraint = formatConfig?.dateConstraint || 'any';
8833
+ const minDate = optionsConfig?.minDate;
8834
+ const maxDate = optionsConfig?.maxDate;
8835
+ const minDateField = optionsConfig?.minDateField;
8836
+ const maxDateField = optionsConfig?.maxDateField;
8837
+ const minDateMessage = optionsConfig?.minDateMessage
8838
+ ? translateConfig(optionsConfig.minDateMessage)
8839
+ : undefined;
8840
+ const maxDateMessage = optionsConfig?.maxDateMessage
8841
+ ? translateConfig(optionsConfig.maxDateMessage)
8842
+ : undefined;
8843
+ const [constraintError, setConstraintError] = React.useState(null);
8844
+ const resolveSiblingDate = (fieldRef) => {
8845
+ if (!fieldRef || !rowValues) {
8846
+ return undefined;
8847
+ }
8848
+ const raw = getValueByPath(rowValues, fieldRef) ?? rowValues[fieldRef];
8849
+ return resolveDateBoundFromFieldValue(raw);
8850
+ };
8851
+ const fieldMinDate = React.useMemo(() => resolveSiblingDate(minDateField), [minDateField, rowValues]);
8852
+ const fieldMaxDate = React.useMemo(() => resolveSiblingDate(maxDateField), [maxDateField, rowValues]);
8853
+ const effectiveMinDate = React.useMemo(() => {
8854
+ const staticMin = getMinDate(dateConstraint, minDate);
8855
+ return mergeMinDateBounds(staticMin, fieldMinDate);
8856
+ }, [dateConstraint, minDate, fieldMinDate]);
8857
+ const effectiveMaxDate = React.useMemo(() => {
8858
+ const staticMax = getMaxDate(dateConstraint, maxDate);
8859
+ return mergeMaxDateBounds(staticMax, fieldMaxDate);
8860
+ }, [dateConstraint, maxDate, fieldMaxDate]);
8861
+ const constraintMessages = React.useMemo(() => ({ minDateMessage, maxDateMessage }), [minDateMessage, maxDateMessage]);
8753
8862
  // input type="date" requires YYYY-MM-DD format
8754
8863
  const displayValue = value && typeof value === 'string' ? value.split('T')[0] : '';
8755
- return (jsxRuntimeExports.jsx("input", { type: "date", value: displayValue, onChange: (e) => onValueChange(e.target.value), disabled: isReadonly, placeholder: placeholder, className: `w-full h-[28px] px-2 text-sm border focus:outline-none ${isReadonly ? 'cursor-not-allowed' : ''} table-cell-input`, style: {
8756
- borderRadius: '10px',
8757
- borderColor: 'var(--owt-widget-input-border, #C4C4C4)',
8758
- backgroundColor: isReadonly ? 'var(--owt-color-bg-alt, #F6F6F6)' : 'var(--owt-color-bg, #FFFFFF)',
8759
- } }));
8864
+ React.useEffect(() => {
8865
+ if (!displayValue) {
8866
+ setConstraintError(null);
8867
+ return;
8868
+ }
8869
+ const error = validateDateConstraints(displayValue, effectiveMinDate, effectiveMaxDate, dateConstraint, constraintMessages);
8870
+ setConstraintError(error);
8871
+ }, [displayValue, effectiveMinDate, effectiveMaxDate, dateConstraint, constraintMessages]);
8872
+ const handleChange = (e) => {
8873
+ const nextValue = e.target.value;
8874
+ onValueChange(nextValue);
8875
+ if (!nextValue) {
8876
+ setConstraintError(null);
8877
+ return;
8878
+ }
8879
+ const error = validateDateConstraints(nextValue, effectiveMinDate, effectiveMaxDate, dateConstraint, constraintMessages);
8880
+ setConstraintError(error);
8881
+ };
8882
+ const hasError = Boolean(constraintError);
8883
+ return (jsxRuntimeExports.jsxs("div", { className: "w-full", children: [jsxRuntimeExports.jsx("input", { type: "date", value: displayValue, onChange: handleChange, disabled: isReadonly, placeholder: placeholder, min: effectiveMinDate, max: effectiveMaxDate, title: constraintError || translateConfig(config['widget-data-tooltip']), className: `w-full h-[28px] px-2 text-sm border focus:outline-none ${isReadonly ? 'cursor-not-allowed' : ''} ${hasError ? 'border-red-500' : ''} table-cell-input`, style: {
8884
+ borderRadius: '10px',
8885
+ borderColor: hasError
8886
+ ? 'var(--owt-color-error, #B91C1C)'
8887
+ : 'var(--owt-widget-input-border, #C4C4C4)',
8888
+ backgroundColor: isReadonly ? 'var(--owt-color-bg-alt, #F6F6F6)' : 'var(--owt-color-bg, #FFFFFF)',
8889
+ } }), hasError && (jsxRuntimeExports.jsx("p", { className: "text-red-500 text-xs mt-0.5 leading-tight", children: constraintError }))] }));
8760
8890
  };
8761
8891
  const TableWidget = ({ config }) => {
8762
8892
  const { value, error, touched, isEnabled, onChange, config: widgetConfig, } = useBaseWidget({ config });
@@ -9115,11 +9245,21 @@ const TableWidget = ({ config }) => {
9115
9245
  });
9116
9246
  }
9117
9247
  }, [isAdding, newRowData, columns, widgetConfig, rows.length, dispatch]);
9248
+ const getRowValuesForEdit = React.useCallback((rowIndex) => {
9249
+ if (editingState && editingState.rowIndex === rowIndex) {
9250
+ return editingState.currentValue ?? {};
9251
+ }
9252
+ if (isAdding && rowIndex === rows.length && newRowData) {
9253
+ return newRowData;
9254
+ }
9255
+ return rows[rowIndex] ?? {};
9256
+ }, [editingState, isAdding, rows, newRowData]);
9118
9257
  // Lightweight cell renderer for table cells (no labels, compact)
9119
9258
  const renderTableCell = React.useCallback((rowIndex, column, cellValue, isReadonly) => {
9120
9259
  const columnKey = column['column-key'];
9121
9260
  const widgetType = column.widget || 'text';
9122
9261
  const cellWidgetId = `${widgetConfig['widget-id']}-row-${rowIndex}-col-${columnKey}`;
9262
+ const rowValues = getRowValuesForEdit(rowIndex);
9123
9263
  // Use lightweight cell config (no label, minimal styling)
9124
9264
  const cellConfig = {
9125
9265
  ...column,
@@ -9142,7 +9282,7 @@ const TableWidget = ({ config }) => {
9142
9282
  return jsxRuntimeExports.jsx(TableCellNumber, { config: cellConfig, value: cellValue, onValueChange: (newValue) => updateCellValue(columnKey, newValue, rowIndex) });
9143
9283
  }
9144
9284
  else if (widgetType === 'date') {
9145
- return jsxRuntimeExports.jsx(TableCellDate, { config: cellConfig, value: cellValue, onValueChange: (newValue) => updateCellValue(columnKey, newValue, rowIndex) });
9285
+ return jsxRuntimeExports.jsx(TableCellDate, { config: cellConfig, value: cellValue, rowValues: rowValues, onValueChange: (newValue) => updateCellValue(columnKey, newValue, rowIndex) });
9146
9286
  }
9147
9287
  // For other widget types, use WidgetRenderer but with compact styling
9148
9288
  return (jsxRuntimeExports.jsx("div", { className: "table-cell-widget", style: { margin: 0, padding: 0 }, children: jsxRuntimeExports.jsx(WidgetRenderer, { config: cellConfig, schemaData: {
@@ -9150,7 +9290,7 @@ const TableWidget = ({ config }) => {
9150
9290
  }, onValueChange: (widgetId, newValue) => {
9151
9291
  updateCellValue(columnKey, newValue, rowIndex);
9152
9292
  } }) }));
9153
- }, [widgetConfig, updateCellValue]);
9293
+ }, [widgetConfig, updateCellValue, getRowValuesForEdit]);
9154
9294
  // Render cell content (widget in edit mode, formatted value in view mode)
9155
9295
  const renderCell = React.useCallback((rowIndex, column, row) => {
9156
9296
  const columnKey = column['column-key'];