sag_components 2.0.0-beta236 → 2.0.0-beta238

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.esm.js CHANGED
@@ -9954,7 +9954,7 @@ const DatePickerFooter = styled.div`
9954
9954
  margin-inline-end: 10px;
9955
9955
  margin-top: 10px;
9956
9956
  `;
9957
- const ClearButton$2 = styled.button`
9957
+ const ClearButton$1 = styled.button`
9958
9958
  color: #568202;
9959
9959
  text-align: center;
9960
9960
  font-family: Poppins;
@@ -10133,7 +10133,7 @@ const DatePicker = ({
10133
10133
  return /*#__PURE__*/React$1.createElement(DateCell$2, null);
10134
10134
  }
10135
10135
  return null;
10136
- })), /*#__PURE__*/React$1.createElement(DatePickerFooter, null, /*#__PURE__*/React$1.createElement(ClearButton$2, {
10136
+ })), /*#__PURE__*/React$1.createElement(DatePickerFooter, null, /*#__PURE__*/React$1.createElement(ClearButton$1, {
10137
10137
  onClick: clearSelection
10138
10138
  }, "Clear")));
10139
10139
  };
@@ -10581,24 +10581,23 @@ const QuarterPopupPicker = ({
10581
10581
  };
10582
10582
 
10583
10583
  /* eslint-disable import/no-extraneous-dependencies */
10584
- const QuarterPicker = _ref => {
10585
- let {
10586
- availableQuarters,
10587
- // ["Q1-2024"]
10588
- label,
10589
- onChange,
10590
- borderRadius,
10591
- required,
10592
- width,
10593
- height,
10594
- placeholder,
10595
- disabled,
10596
- borderColor,
10597
- borderColorFocus,
10598
- textColor,
10599
- selectedValue,
10600
- startYear
10601
- } = _ref;
10584
+ const QuarterPicker = ({
10585
+ availableQuarters,
10586
+ // ["Q1-2024"]
10587
+ label,
10588
+ onChange,
10589
+ borderRadius,
10590
+ required,
10591
+ width,
10592
+ height,
10593
+ placeholder,
10594
+ disabled,
10595
+ borderColor,
10596
+ borderColorFocus,
10597
+ textColor,
10598
+ selectedValue,
10599
+ startYear
10600
+ }) => {
10602
10601
  const [isFocused, setIsFocused] = useState(false);
10603
10602
  const [isOpen, setIsOpen] = useState(false);
10604
10603
  const [value, setValue] = useState('');
@@ -11040,23 +11039,22 @@ const MonthPopupPicker = ({
11040
11039
  };
11041
11040
 
11042
11041
  /* eslint-disable import/no-extraneous-dependencies */
11043
- const MonthPicker = _ref => {
11044
- let {
11045
- availableMonths,
11046
- label,
11047
- onChange,
11048
- borderRadius,
11049
- required,
11050
- width,
11051
- height,
11052
- placeholder,
11053
- disabled,
11054
- borderColor,
11055
- borderColorFocus,
11056
- textColor,
11057
- selectedValue,
11058
- startYear
11059
- } = _ref;
11042
+ const MonthPicker = ({
11043
+ availableMonths,
11044
+ label,
11045
+ onChange,
11046
+ borderRadius,
11047
+ required,
11048
+ width,
11049
+ height,
11050
+ placeholder,
11051
+ disabled,
11052
+ borderColor,
11053
+ borderColorFocus,
11054
+ textColor,
11055
+ selectedValue,
11056
+ startYear
11057
+ }) => {
11060
11058
  const [isFocused, setIsFocused] = useState(false);
11061
11059
  const [isOpen, setIsOpen] = useState(false);
11062
11060
  const [value, setValue] = useState('');
@@ -35110,13 +35108,14 @@ const StyledInput$1 = styled.input`
35110
35108
  border-radius: ${props => props.borderRadius || '4px'};
35111
35109
  border: none;
35112
35110
  outline: none;
35111
+ background-color: ${props => props.isDarkerBackground ? '#F2F2F2' : 'white'} !important;
35113
35112
  width: ${props => props.width || '90%'};
35114
35113
  height: ${props => props.height || 'auto'};
35115
35114
  transition: border-color 0.3s ease;
35116
35115
  font-size: 14px;
35117
35116
  font-weight: 400;
35118
35117
  box-sizing: border-box;
35119
- color: ${props => props.disabled ? '#888' : (props.isFocused || props.value ? props.textColor : '#757575') || '#333'};
35118
+ color: ${props => props.disabled ? '#D0D0D0' : (props.isFocused || props.value ? props.textColor : '#757575') || '#333'};
35120
35119
  cursor: ${props => props.disabled ? 'not-allowed' : 'text'};
35121
35120
  `;
35122
35121
  const StyledLabel = styled.label`
@@ -35163,9 +35162,8 @@ const InputContainer$1 = styled.div`
35163
35162
  overflow: hidden;
35164
35163
  width: 100%;
35165
35164
  height: 100%;
35166
- box-sizing: border-box;
35167
- background-color: transparent;
35168
- border: 1px solid ${props => props.disabled ? '#bdbdbd' : props.error ? 'red' : '#B1B1B1'};
35165
+ box-sizing: border-box;
35166
+ border: 1px solid ${props => props.disabled ? '#D0D0D0' : props.error ? 'red' : '#B1B1B1'};
35169
35167
  font-weight: 400;
35170
35168
  font-size: 14px;
35171
35169
  border-radius: 12px;
@@ -35207,6 +35205,7 @@ const WeeksPicker = _ref => {
35207
35205
  withMarginBottom = true,
35208
35206
  onChange,
35209
35207
  selectedValue,
35208
+ isDarkerBackground = false,
35210
35209
  // New props for range restriction
35211
35210
  allowedWeekRange = null,
35212
35211
  // { startWeek: number, endWeek: number } or null
@@ -35403,7 +35402,8 @@ const WeeksPicker = _ref => {
35403
35402
  placeholder: isFocused ? placeholder : "",
35404
35403
  disabled: disabled,
35405
35404
  borderColor: borderColor,
35406
- textColor: textColor
35405
+ textColor: textColor,
35406
+ isDarkerBackground: isDarkerBackground
35407
35407
  }), /*#__PURE__*/React$1.createElement(CalendarDiv, {
35408
35408
  onClick: disabled ? undefined : handleToggle
35409
35409
  }, /*#__PURE__*/React$1.createElement(CalendarInOpen, {
@@ -36152,9 +36152,9 @@ const ToggleSlider = styled.span`
36152
36152
  }
36153
36153
  `;
36154
36154
 
36155
- /**
36156
- * ToggleSwitch component for on/off states.
36157
- * Supports small/large sizes and disabled state.
36155
+ /**
36156
+ * ToggleSwitch component for on/off states.
36157
+ * Supports small/large sizes and disabled state.
36158
36158
  */
36159
36159
  function ToggleSwitch(_ref) {
36160
36160
  let {
@@ -37491,7 +37491,7 @@ const TextField = styled.input`
37491
37491
  resize: none;
37492
37492
  text-indent: 8px;
37493
37493
  `;
37494
- const ClearButton$1 = styled.button`
37494
+ const ClearButton = styled.button`
37495
37495
  position: absolute;
37496
37496
  top: 50%;
37497
37497
  right: 10px;
@@ -37540,7 +37540,7 @@ const FieldPop = props => {
37540
37540
  placeholder: placeholder,
37541
37541
  value: value,
37542
37542
  onChange: handleInputChange
37543
- }), value && /*#__PURE__*/React$1.createElement(ClearButton$1, {
37543
+ }), value && /*#__PURE__*/React$1.createElement(ClearButton, {
37544
37544
  onClick: handleClear
37545
37545
  }, "\xD7")) : /*#__PURE__*/React$1.createElement("div", {
37546
37546
  style: {
@@ -37552,7 +37552,7 @@ const FieldPop = props => {
37552
37552
  placeholder: placeholder,
37553
37553
  value: value,
37554
37554
  onChange: handleInputChange
37555
- }), value && /*#__PURE__*/React$1.createElement(ClearButton$1, {
37555
+ }), value && /*#__PURE__*/React$1.createElement(ClearButton, {
37556
37556
  onClick: handleClear
37557
37557
  }, "\xD7")));
37558
37558
  };
@@ -37716,30 +37716,33 @@ const ResetButton$1 = styled.button`
37716
37716
 
37717
37717
  const FilterPop = props => {
37718
37718
  const {
37719
- menuName = '',
37720
- width = 'auto',
37721
- height = 'auto',
37722
- maxHeight = '400px',
37719
+ menuName = "",
37720
+ width = "auto",
37721
+ height = "auto",
37722
+ maxHeight = "400px",
37723
37723
  list = [],
37724
- color = '#007bff',
37724
+ color = "#007bff",
37725
37725
  onCheck = () => {},
37726
37726
  onReset = () => {},
37727
37727
  doubleColumn = false,
37728
37728
  isAsc = true,
37729
37729
  selectedAttributes: propSelectedAttributes = {},
37730
37730
  showSearch = true,
37731
- // New prop to enable/disable search
37732
- searchPlaceholder = 'Search...' // New prop for search placeholder
37731
+ searchPlaceholder = "Search..."
37733
37732
  } = props;
37734
37733
 
37735
37734
  // State for search term
37736
- const [searchTerm, setSearchTerm] = useState('');
37735
+ const [searchTerm, setSearchTerm] = useState("");
37736
+
37737
+ // CRITICAL FIX: Use internal state for selected attributes
37738
+ const [selectedAttributes, setSelectedAttributes] = useState({});
37739
+ const isInitialMount = useRef(true);
37737
37740
 
37738
37741
  // Add hardcoded "Select All" as first item
37739
- const fullList = [{
37740
- value: 'All',
37741
- label: 'Select All'
37742
- }, ...list];
37742
+ const fullList = useMemo(() => [{
37743
+ value: "All",
37744
+ label: "Select All"
37745
+ }, ...list], [list]);
37743
37746
 
37744
37747
  // Create initial state - all items selected by default
37745
37748
  const createInitialState = () => {
@@ -37750,12 +37753,66 @@ const FilterPop = props => {
37750
37753
  return initialState;
37751
37754
  };
37752
37755
 
37753
- // Use props directly, fallback to initial state only if props are empty
37754
- const selectedAttributes = Object.keys(propSelectedAttributes).length > 0 ? propSelectedAttributes : createInitialState();
37756
+ // CRITICAL: Initialize and sync with props only when necessary
37757
+ useEffect(() => {
37758
+ if (isInitialMount.current) {
37759
+ // First mount: use props or create initial state
37760
+ if (Object.keys(propSelectedAttributes).length > 0) {
37761
+ setSelectedAttributes(propSelectedAttributes);
37762
+ } else {
37763
+ setSelectedAttributes(createInitialState());
37764
+ }
37765
+ isInitialMount.current = false;
37766
+ } else {
37767
+ // After mount: only update if props explicitly changed and are non-empty
37768
+ // This prevents reset when parent re-renders
37769
+ if (Object.keys(propSelectedAttributes).length > 0) {
37770
+ const propsString = JSON.stringify(propSelectedAttributes);
37771
+ const currentString = JSON.stringify(selectedAttributes);
37772
+ if (propsString !== currentString) {
37773
+ setSelectedAttributes(propSelectedAttributes);
37774
+ }
37775
+ }
37776
+ }
37777
+ }, [propSelectedAttributes]); // Only depend on props
37778
+
37779
+ // Update selected attributes when list changes to include new items
37780
+ useEffect(() => {
37781
+ if (!isInitialMount.current && list.length > 0) {
37782
+ setSelectedAttributes(prev => {
37783
+ const updated = {
37784
+ ...prev
37785
+ };
37786
+ let hasChanges = false;
37787
+
37788
+ // Add any new items from the list that aren't in current selection
37789
+ fullList.forEach(item => {
37790
+ if (item.value !== "All" && !(item.value in updated)) {
37791
+ updated[item.value] = true; // New items default to selected
37792
+ hasChanges = true;
37793
+ }
37794
+ });
37795
+
37796
+ // Remove items that no longer exist in the list
37797
+ Object.keys(updated).forEach(key => {
37798
+ if (key !== "All" && !fullList.find(item => item.value === key)) {
37799
+ delete updated[key];
37800
+ hasChanges = true;
37801
+ }
37802
+ });
37803
+
37804
+ // Update "Select All" state
37805
+ if (hasChanges) {
37806
+ updated.All = areAllNonAllItemsSelected(updated);
37807
+ }
37808
+ return hasChanges ? updated : prev;
37809
+ });
37810
+ }
37811
+ }, [list]); // Only when list changes
37755
37812
 
37756
37813
  // Helper function to get non-"All" items
37757
37814
  const getNonAllItems = () => {
37758
- return fullList.filter(item => item.value !== 'All');
37815
+ return fullList.filter(item => item.value !== "All");
37759
37816
  };
37760
37817
 
37761
37818
  // Filter items based on search term
@@ -37765,22 +37822,20 @@ const FilterPop = props => {
37765
37822
  }
37766
37823
  const searchLower = searchTerm.toLowerCase().trim();
37767
37824
  const filteredNonAllItems = fullList.filter(item => {
37768
- if (item.value === 'All') return false; // Don't filter out "Select All" in search
37825
+ if (item.value === "All") return false;
37769
37826
  return item.label.toLowerCase().includes(searchLower);
37770
37827
  });
37771
-
37772
- // Always include "Select All" at the top when searching
37773
- return [fullList.find(item => item.value === 'All'), ...filteredNonAllItems];
37828
+ return [fullList.find(item => item.value === "All"), ...filteredNonAllItems];
37774
37829
  }, [fullList, searchTerm]);
37775
37830
 
37776
- // Sort the filtered list based on the `isAsc` prop, keeping 'All' as the first option
37831
+ // Sort the filtered list based on the `isAsc` prop
37777
37832
  const sortedList = useMemo(() => {
37778
- return [...filteredList.filter(item => item.value === 'All'), ...filteredList.filter(item => item.value !== 'All').sort((a, b) => {
37833
+ return [...filteredList.filter(item => item.value === "All"), ...filteredList.filter(item => item.value !== "All").sort((a, b) => {
37779
37834
  return isAsc ? a.label.localeCompare(b.label) : b.label.localeCompare(a.label);
37780
37835
  })];
37781
37836
  }, [filteredList, isAsc]);
37782
37837
 
37783
- // Helper functions for "Select All" logic based on ALL items (not just filtered)
37838
+ // Helper functions for "Select All" logic
37784
37839
  const areAllNonAllItemsSelected = function () {
37785
37840
  let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : selectedAttributes;
37786
37841
  const nonAllItems = getNonAllItems();
@@ -37789,7 +37844,7 @@ const FilterPop = props => {
37789
37844
 
37790
37845
  // Helper functions for visible filtered items
37791
37846
  const getVisibleNonAllItems = () => {
37792
- return sortedList.filter(item => item.value !== 'All');
37847
+ return sortedList.filter(item => item.value !== "All");
37793
37848
  };
37794
37849
  const areAllVisibleItemsSelected = function () {
37795
37850
  let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : selectedAttributes;
@@ -37803,7 +37858,7 @@ const FilterPop = props => {
37803
37858
  return visibleItems.some(item => attributes[item.value]);
37804
37859
  };
37805
37860
 
37806
- // New helper function to create the efficient data structure
37861
+ // Create the efficient data structure
37807
37862
  const createFilterData = attributes => {
37808
37863
  const nonAllItems = getNonAllItems();
37809
37864
  const selectedItems = nonAllItems.filter(item => attributes[item.value]);
@@ -37838,21 +37893,17 @@ const FilterPop = props => {
37838
37893
  }
37839
37894
  };
37840
37895
  const handleCheckboxChange = attribute => {
37841
- if (attribute === 'All') {
37842
- // "Select All" behavior - affects ALL visible filtered items
37896
+ if (attribute === "All") {
37843
37897
  const visibleNonAllItems = getVisibleNonAllItems();
37844
37898
  const allVisibleSelected = areAllVisibleItemsSelected();
37845
-
37846
- // Toggle all visible items
37847
37899
  const updatedAttributes = {
37848
37900
  ...selectedAttributes
37849
37901
  };
37850
37902
  visibleNonAllItems.forEach(item => {
37851
37903
  updatedAttributes[item.value] = !allVisibleSelected;
37852
37904
  });
37853
-
37854
- // Update "Select All" state based on all items (not just visible)
37855
37905
  updatedAttributes.All = areAllNonAllItemsSelected(updatedAttributes);
37906
+ setSelectedAttributes(updatedAttributes);
37856
37907
  const filterData = createFilterData(updatedAttributes);
37857
37908
  onCheck({
37858
37909
  changedItem: attribute,
@@ -37860,14 +37911,12 @@ const FilterPop = props => {
37860
37911
  allItems: updatedAttributes
37861
37912
  });
37862
37913
  } else {
37863
- // Individual item clicked
37864
37914
  const updatedAttributes = {
37865
37915
  ...selectedAttributes,
37866
37916
  [attribute]: !selectedAttributes[attribute]
37867
37917
  };
37868
-
37869
- // Update "Select All" state based on all items
37870
37918
  updatedAttributes.All = areAllNonAllItemsSelected(updatedAttributes);
37919
+ setSelectedAttributes(updatedAttributes);
37871
37920
  const filterData = createFilterData(updatedAttributes);
37872
37921
  onCheck({
37873
37922
  changedItem: attribute,
@@ -37877,21 +37926,19 @@ const FilterPop = props => {
37877
37926
  }
37878
37927
  };
37879
37928
  const handleReset = () => {
37880
- // Clear search when resetting
37881
- setSearchTerm('');
37882
-
37883
- // Reset to the original default state (all selected)
37929
+ setSearchTerm("");
37884
37930
  const resetState = createInitialState();
37931
+ setSelectedAttributes(resetState);
37885
37932
  onReset();
37886
37933
  const filterData = createFilterData(resetState);
37887
37934
  onCheck({
37888
- changedItem: 'reset',
37935
+ changedItem: "reset",
37889
37936
  filterData: filterData,
37890
37937
  allItems: resetState
37891
37938
  });
37892
37939
  };
37893
37940
 
37894
- // Function to determine checkbox state for "Select All" based on visible items
37941
+ // Function to determine checkbox state for "Select All"
37895
37942
  const getSelectAllCheckboxProps = () => {
37896
37943
  const visibleItems = getVisibleNonAllItems();
37897
37944
  if (visibleItems.length === 0) {
@@ -37920,15 +37967,11 @@ const FilterPop = props => {
37920
37967
  };
37921
37968
  }
37922
37969
  };
37923
-
37924
- // Handle search input change
37925
37970
  const handleSearchChange = e => {
37926
37971
  setSearchTerm(e.target.value);
37927
37972
  };
37928
-
37929
- // Clear search
37930
37973
  const clearSearch = () => {
37931
- setSearchTerm('');
37974
+ setSearchTerm("");
37932
37975
  };
37933
37976
  return /*#__PURE__*/React$1.createElement(FilterPopContainer, {
37934
37977
  width: width,
@@ -37943,20 +37986,22 @@ const FilterPop = props => {
37943
37986
  accentColor: color
37944
37987
  }), /*#__PURE__*/React$1.createElement(CheckboxGroup, {
37945
37988
  style: {
37946
- display: doubleColumn ? 'grid' : 'flex',
37947
- gridTemplateColumns: doubleColumn ? '1fr 1fr' : 'none',
37948
- gap: '8px'
37989
+ display: doubleColumn ? "grid" : "flex",
37990
+ gridTemplateColumns: doubleColumn ? "1fr 1fr" : "none",
37991
+ gap: "8px"
37949
37992
  }
37950
- }, sortedList.length === 1 ?
37951
- /*#__PURE__*/
37952
- // Only "Select All" is visible
37953
- React$1.createElement(NoResultsMessage, null, "No items match your search") : sortedList.map(item => {
37954
- const isSelectAll = item.value === 'All';
37993
+ }, sortedList.length === 1 ? /*#__PURE__*/React$1.createElement(NoResultsMessage, null, "No items match your search") : sortedList.map(item => {
37994
+ const isSelectAll = item.value === "All";
37955
37995
  const checkboxProps = isSelectAll ? getSelectAllCheckboxProps() : {};
37956
37996
  const isChecked = isSelectAll ? checkboxProps.checked : selectedAttributes[item.value] || false;
37957
37997
  return /*#__PURE__*/React$1.createElement(CheckboxLabel, {
37958
37998
  width: !doubleColumn ?? width,
37959
- key: `${item.value}-${JSON.stringify(selectedAttributes)}-${searchTerm}`
37999
+ key: item.value
38000
+ }, /*#__PURE__*/React$1.createElement("div", {
38001
+ style: {
38002
+ width: "20px",
38003
+ height: "20px"
38004
+ }
37960
38005
  }, /*#__PURE__*/React$1.createElement("input", {
37961
38006
  type: "checkbox",
37962
38007
  checked: isChecked,
@@ -37973,11 +38018,11 @@ const FilterPop = props => {
37973
38018
  onChange: e => {
37974
38019
  handleCheckboxChange(item.value);
37975
38020
  }
37976
- }), /*#__PURE__*/React$1.createElement("span", null, item.label));
38021
+ })), /*#__PURE__*/React$1.createElement("span", null, item.label));
37977
38022
  })), /*#__PURE__*/React$1.createElement(ButtonWrapper$2, null, showSearch && searchTerm && /*#__PURE__*/React$1.createElement(ResetButton$1, {
37978
38023
  onClick: clearSearch,
37979
38024
  style: {
37980
- marginRight: '8px'
38025
+ marginRight: "8px"
37981
38026
  }
37982
38027
  }, "Clear Search"), /*#__PURE__*/React$1.createElement(ResetButton$1, {
37983
38028
  onClick: handleReset,
@@ -37985,6 +38030,2224 @@ const FilterPop = props => {
37985
38030
  }, "Reset")));
37986
38031
  };
37987
38032
 
38033
+ var isCheckBoxInput = (element) => element.type === 'checkbox';
38034
+
38035
+ var isDateObject = (value) => value instanceof Date;
38036
+
38037
+ var isNullOrUndefined = (value) => value == null;
38038
+
38039
+ const isObjectType = (value) => typeof value === 'object';
38040
+ var isObject = (value) => !isNullOrUndefined(value) &&
38041
+ !Array.isArray(value) &&
38042
+ isObjectType(value) &&
38043
+ !isDateObject(value);
38044
+
38045
+ var getEventValue = (event) => isObject(event) && event.target
38046
+ ? isCheckBoxInput(event.target)
38047
+ ? event.target.checked
38048
+ : event.target.value
38049
+ : event;
38050
+
38051
+ var getNodeParentName = (name) => name.substring(0, name.search(/\.\d+(\.|$)/)) || name;
38052
+
38053
+ var isNameInFieldArray = (names, name) => names.has(getNodeParentName(name));
38054
+
38055
+ var isPlainObject = (tempObject) => {
38056
+ const prototypeCopy = tempObject.constructor && tempObject.constructor.prototype;
38057
+ return (isObject(prototypeCopy) && prototypeCopy.hasOwnProperty('isPrototypeOf'));
38058
+ };
38059
+
38060
+ var isWeb = typeof window !== 'undefined' &&
38061
+ typeof window.HTMLElement !== 'undefined' &&
38062
+ typeof document !== 'undefined';
38063
+
38064
+ function cloneObject(data) {
38065
+ let copy;
38066
+ const isArray = Array.isArray(data);
38067
+ const isFileListInstance = typeof FileList !== 'undefined' ? data instanceof FileList : false;
38068
+ if (data instanceof Date) {
38069
+ copy = new Date(data);
38070
+ }
38071
+ else if (data instanceof Set) {
38072
+ copy = new Set(data);
38073
+ }
38074
+ else if (!(isWeb && (data instanceof Blob || isFileListInstance)) &&
38075
+ (isArray || isObject(data))) {
38076
+ copy = isArray ? [] : {};
38077
+ if (!isArray && !isPlainObject(data)) {
38078
+ copy = data;
38079
+ }
38080
+ else {
38081
+ for (const key in data) {
38082
+ if (data.hasOwnProperty(key)) {
38083
+ copy[key] = cloneObject(data[key]);
38084
+ }
38085
+ }
38086
+ }
38087
+ }
38088
+ else {
38089
+ return data;
38090
+ }
38091
+ return copy;
38092
+ }
38093
+
38094
+ var compact = (value) => Array.isArray(value) ? value.filter(Boolean) : [];
38095
+
38096
+ var isUndefined = (val) => val === undefined;
38097
+
38098
+ var get = (object, path, defaultValue) => {
38099
+ if (!path || !isObject(object)) {
38100
+ return defaultValue;
38101
+ }
38102
+ const result = compact(path.split(/[,[\].]+?/)).reduce((result, key) => isNullOrUndefined(result) ? result : result[key], object);
38103
+ return isUndefined(result) || result === object
38104
+ ? isUndefined(object[path])
38105
+ ? defaultValue
38106
+ : object[path]
38107
+ : result;
38108
+ };
38109
+
38110
+ var isBoolean = (value) => typeof value === 'boolean';
38111
+
38112
+ var isKey = (value) => /^\w*$/.test(value);
38113
+
38114
+ var stringToPath = (input) => compact(input.replace(/["|']|\]/g, '').split(/\.|\[/));
38115
+
38116
+ var set = (object, path, value) => {
38117
+ let index = -1;
38118
+ const tempPath = isKey(path) ? [path] : stringToPath(path);
38119
+ const length = tempPath.length;
38120
+ const lastIndex = length - 1;
38121
+ while (++index < length) {
38122
+ const key = tempPath[index];
38123
+ let newValue = value;
38124
+ if (index !== lastIndex) {
38125
+ const objValue = object[key];
38126
+ newValue =
38127
+ isObject(objValue) || Array.isArray(objValue)
38128
+ ? objValue
38129
+ : !isNaN(+tempPath[index + 1])
38130
+ ? []
38131
+ : {};
38132
+ }
38133
+ if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
38134
+ return;
38135
+ }
38136
+ object[key] = newValue;
38137
+ object = object[key];
38138
+ }
38139
+ return object;
38140
+ };
38141
+
38142
+ const EVENTS = {
38143
+ BLUR: 'blur',
38144
+ FOCUS_OUT: 'focusout',
38145
+ CHANGE: 'change',
38146
+ };
38147
+ const VALIDATION_MODE = {
38148
+ onBlur: 'onBlur',
38149
+ onChange: 'onChange',
38150
+ onSubmit: 'onSubmit',
38151
+ onTouched: 'onTouched',
38152
+ all: 'all',
38153
+ };
38154
+ const INPUT_VALIDATION_RULES = {
38155
+ max: 'max',
38156
+ min: 'min',
38157
+ maxLength: 'maxLength',
38158
+ minLength: 'minLength',
38159
+ pattern: 'pattern',
38160
+ required: 'required',
38161
+ validate: 'validate',
38162
+ };
38163
+
38164
+ const HookFormContext = React$1.createContext(null);
38165
+ /**
38166
+ * This custom hook allows you to access the form context. useFormContext is intended to be used in deeply nested structures, where it would become inconvenient to pass the context as a prop. To be used with {@link FormProvider}.
38167
+ *
38168
+ * @remarks
38169
+ * [API](https://react-hook-form.com/docs/useformcontext) • [Demo](https://codesandbox.io/s/react-hook-form-v7-form-context-ytudi)
38170
+ *
38171
+ * @returns return all useForm methods
38172
+ *
38173
+ * @example
38174
+ * ```tsx
38175
+ * function App() {
38176
+ * const methods = useForm();
38177
+ * const onSubmit = data => console.log(data);
38178
+ *
38179
+ * return (
38180
+ * <FormProvider {...methods} >
38181
+ * <form onSubmit={methods.handleSubmit(onSubmit)}>
38182
+ * <NestedInput />
38183
+ * <input type="submit" />
38184
+ * </form>
38185
+ * </FormProvider>
38186
+ * );
38187
+ * }
38188
+ *
38189
+ * function NestedInput() {
38190
+ * const { register } = useFormContext(); // retrieve all hook methods
38191
+ * return <input {...register("test")} />;
38192
+ * }
38193
+ * ```
38194
+ */
38195
+ const useFormContext = () => React$1.useContext(HookFormContext);
38196
+
38197
+ var getProxyFormState = (formState, control, localProxyFormState, isRoot = true) => {
38198
+ const result = {
38199
+ defaultValues: control._defaultValues,
38200
+ };
38201
+ for (const key in formState) {
38202
+ Object.defineProperty(result, key, {
38203
+ get: () => {
38204
+ const _key = key;
38205
+ if (control._proxyFormState[_key] !== VALIDATION_MODE.all) {
38206
+ control._proxyFormState[_key] = !isRoot || VALIDATION_MODE.all;
38207
+ }
38208
+ localProxyFormState && (localProxyFormState[_key] = true);
38209
+ return formState[_key];
38210
+ },
38211
+ });
38212
+ }
38213
+ return result;
38214
+ };
38215
+
38216
+ var isEmptyObject = (value) => isObject(value) && !Object.keys(value).length;
38217
+
38218
+ var shouldRenderFormState = (formStateData, _proxyFormState, updateFormState, isRoot) => {
38219
+ updateFormState(formStateData);
38220
+ const { name, ...formState } = formStateData;
38221
+ return (isEmptyObject(formState) ||
38222
+ Object.keys(formState).length >= Object.keys(_proxyFormState).length ||
38223
+ Object.keys(formState).find((key) => _proxyFormState[key] ===
38224
+ (!isRoot || VALIDATION_MODE.all)));
38225
+ };
38226
+
38227
+ var convertToArrayPayload = (value) => (Array.isArray(value) ? value : [value]);
38228
+
38229
+ var shouldSubscribeByName = (name, signalName, exact) => !name ||
38230
+ !signalName ||
38231
+ name === signalName ||
38232
+ convertToArrayPayload(name).some((currentName) => currentName &&
38233
+ (exact
38234
+ ? currentName === signalName
38235
+ : currentName.startsWith(signalName) ||
38236
+ signalName.startsWith(currentName)));
38237
+
38238
+ function useSubscribe(props) {
38239
+ const _props = React$1.useRef(props);
38240
+ _props.current = props;
38241
+ React$1.useEffect(() => {
38242
+ const subscription = !props.disabled &&
38243
+ _props.current.subject &&
38244
+ _props.current.subject.subscribe({
38245
+ next: _props.current.next,
38246
+ });
38247
+ return () => {
38248
+ subscription && subscription.unsubscribe();
38249
+ };
38250
+ }, [props.disabled]);
38251
+ }
38252
+
38253
+ /**
38254
+ * This custom hook allows you to subscribe to each form state, and isolate the re-render at the custom hook level. It has its scope in terms of form state subscription, so it would not affect other useFormState and useForm. Using this hook can reduce the re-render impact on large and complex form application.
38255
+ *
38256
+ * @remarks
38257
+ * [API](https://react-hook-form.com/docs/useformstate) • [Demo](https://codesandbox.io/s/useformstate-75xly)
38258
+ *
38259
+ * @param props - include options on specify fields to subscribe. {@link UseFormStateReturn}
38260
+ *
38261
+ * @example
38262
+ * ```tsx
38263
+ * function App() {
38264
+ * const { register, handleSubmit, control } = useForm({
38265
+ * defaultValues: {
38266
+ * firstName: "firstName"
38267
+ * }});
38268
+ * const { dirtyFields } = useFormState({
38269
+ * control
38270
+ * });
38271
+ * const onSubmit = (data) => console.log(data);
38272
+ *
38273
+ * return (
38274
+ * <form onSubmit={handleSubmit(onSubmit)}>
38275
+ * <input {...register("firstName")} placeholder="First Name" />
38276
+ * {dirtyFields.firstName && <p>Field is dirty.</p>}
38277
+ * <input type="submit" />
38278
+ * </form>
38279
+ * );
38280
+ * }
38281
+ * ```
38282
+ */
38283
+ function useFormState(props) {
38284
+ const methods = useFormContext();
38285
+ const { control = methods.control, disabled, name, exact } = props || {};
38286
+ const [formState, updateFormState] = React$1.useState(control._formState);
38287
+ const _mounted = React$1.useRef(true);
38288
+ const _localProxyFormState = React$1.useRef({
38289
+ isDirty: false,
38290
+ isLoading: false,
38291
+ dirtyFields: false,
38292
+ touchedFields: false,
38293
+ validatingFields: false,
38294
+ isValidating: false,
38295
+ isValid: false,
38296
+ errors: false,
38297
+ });
38298
+ const _name = React$1.useRef(name);
38299
+ _name.current = name;
38300
+ useSubscribe({
38301
+ disabled,
38302
+ next: (value) => _mounted.current &&
38303
+ shouldSubscribeByName(_name.current, value.name, exact) &&
38304
+ shouldRenderFormState(value, _localProxyFormState.current, control._updateFormState) &&
38305
+ updateFormState({
38306
+ ...control._formState,
38307
+ ...value,
38308
+ }),
38309
+ subject: control._subjects.state,
38310
+ });
38311
+ React$1.useEffect(() => {
38312
+ _mounted.current = true;
38313
+ _localProxyFormState.current.isValid && control._updateValid(true);
38314
+ return () => {
38315
+ _mounted.current = false;
38316
+ };
38317
+ }, [control]);
38318
+ return React$1.useMemo(() => getProxyFormState(formState, control, _localProxyFormState.current, false), [formState, control]);
38319
+ }
38320
+
38321
+ var isString = (value) => typeof value === 'string';
38322
+
38323
+ var generateWatchOutput = (names, _names, formValues, isGlobal, defaultValue) => {
38324
+ if (isString(names)) {
38325
+ isGlobal && _names.watch.add(names);
38326
+ return get(formValues, names, defaultValue);
38327
+ }
38328
+ if (Array.isArray(names)) {
38329
+ return names.map((fieldName) => (isGlobal && _names.watch.add(fieldName), get(formValues, fieldName)));
38330
+ }
38331
+ isGlobal && (_names.watchAll = true);
38332
+ return formValues;
38333
+ };
38334
+
38335
+ /**
38336
+ * Custom hook to subscribe to field change and isolate re-rendering at the component level.
38337
+ *
38338
+ * @remarks
38339
+ *
38340
+ * [API](https://react-hook-form.com/docs/usewatch) • [Demo](https://codesandbox.io/s/react-hook-form-v7-ts-usewatch-h9i5e)
38341
+ *
38342
+ * @example
38343
+ * ```tsx
38344
+ * const { control } = useForm();
38345
+ * const values = useWatch({
38346
+ * name: "fieldName"
38347
+ * control,
38348
+ * })
38349
+ * ```
38350
+ */
38351
+ function useWatch(props) {
38352
+ const methods = useFormContext();
38353
+ const { control = methods.control, name, defaultValue, disabled, exact, } = props || {};
38354
+ const _name = React$1.useRef(name);
38355
+ _name.current = name;
38356
+ useSubscribe({
38357
+ disabled,
38358
+ subject: control._subjects.values,
38359
+ next: (formState) => {
38360
+ if (shouldSubscribeByName(_name.current, formState.name, exact)) {
38361
+ updateValue(cloneObject(generateWatchOutput(_name.current, control._names, formState.values || control._formValues, false, defaultValue)));
38362
+ }
38363
+ },
38364
+ });
38365
+ const [value, updateValue] = React$1.useState(control._getWatch(name, defaultValue));
38366
+ React$1.useEffect(() => control._removeUnmounted());
38367
+ return value;
38368
+ }
38369
+
38370
+ /**
38371
+ * Custom hook to work with controlled component, this function provide you with both form and field level state. Re-render is isolated at the hook level.
38372
+ *
38373
+ * @remarks
38374
+ * [API](https://react-hook-form.com/docs/usecontroller) • [Demo](https://codesandbox.io/s/usecontroller-0o8px)
38375
+ *
38376
+ * @param props - the path name to the form field value, and validation rules.
38377
+ *
38378
+ * @returns field properties, field and form state. {@link UseControllerReturn}
38379
+ *
38380
+ * @example
38381
+ * ```tsx
38382
+ * function Input(props) {
38383
+ * const { field, fieldState, formState } = useController(props);
38384
+ * return (
38385
+ * <div>
38386
+ * <input {...field} placeholder={props.name} />
38387
+ * <p>{fieldState.isTouched && "Touched"}</p>
38388
+ * <p>{formState.isSubmitted ? "submitted" : ""}</p>
38389
+ * </div>
38390
+ * );
38391
+ * }
38392
+ * ```
38393
+ */
38394
+ function useController(props) {
38395
+ const methods = useFormContext();
38396
+ const { name, disabled, control = methods.control, shouldUnregister } = props;
38397
+ const isArrayField = isNameInFieldArray(control._names.array, name);
38398
+ const value = useWatch({
38399
+ control,
38400
+ name,
38401
+ defaultValue: get(control._formValues, name, get(control._defaultValues, name, props.defaultValue)),
38402
+ exact: true,
38403
+ });
38404
+ const formState = useFormState({
38405
+ control,
38406
+ name,
38407
+ exact: true,
38408
+ });
38409
+ const _registerProps = React$1.useRef(control.register(name, {
38410
+ ...props.rules,
38411
+ value,
38412
+ ...(isBoolean(props.disabled) ? { disabled: props.disabled } : {}),
38413
+ }));
38414
+ const fieldState = React$1.useMemo(() => Object.defineProperties({}, {
38415
+ invalid: {
38416
+ enumerable: true,
38417
+ get: () => !!get(formState.errors, name),
38418
+ },
38419
+ isDirty: {
38420
+ enumerable: true,
38421
+ get: () => !!get(formState.dirtyFields, name),
38422
+ },
38423
+ isTouched: {
38424
+ enumerable: true,
38425
+ get: () => !!get(formState.touchedFields, name),
38426
+ },
38427
+ isValidating: {
38428
+ enumerable: true,
38429
+ get: () => !!get(formState.validatingFields, name),
38430
+ },
38431
+ error: {
38432
+ enumerable: true,
38433
+ get: () => get(formState.errors, name),
38434
+ },
38435
+ }), [formState, name]);
38436
+ const field = React$1.useMemo(() => ({
38437
+ name,
38438
+ value,
38439
+ ...(isBoolean(disabled) || formState.disabled
38440
+ ? { disabled: formState.disabled || disabled }
38441
+ : {}),
38442
+ onChange: (event) => _registerProps.current.onChange({
38443
+ target: {
38444
+ value: getEventValue(event),
38445
+ name: name,
38446
+ },
38447
+ type: EVENTS.CHANGE,
38448
+ }),
38449
+ onBlur: () => _registerProps.current.onBlur({
38450
+ target: {
38451
+ value: get(control._formValues, name),
38452
+ name: name,
38453
+ },
38454
+ type: EVENTS.BLUR,
38455
+ }),
38456
+ ref: (elm) => {
38457
+ const field = get(control._fields, name);
38458
+ if (field && elm) {
38459
+ field._f.ref = {
38460
+ focus: () => elm.focus(),
38461
+ select: () => elm.select(),
38462
+ setCustomValidity: (message) => elm.setCustomValidity(message),
38463
+ reportValidity: () => elm.reportValidity(),
38464
+ };
38465
+ }
38466
+ },
38467
+ }), [
38468
+ name,
38469
+ control._formValues,
38470
+ disabled,
38471
+ formState.disabled,
38472
+ value,
38473
+ control._fields,
38474
+ ]);
38475
+ React$1.useEffect(() => {
38476
+ const _shouldUnregisterField = control._options.shouldUnregister || shouldUnregister;
38477
+ const updateMounted = (name, value) => {
38478
+ const field = get(control._fields, name);
38479
+ if (field && field._f) {
38480
+ field._f.mount = value;
38481
+ }
38482
+ };
38483
+ updateMounted(name, true);
38484
+ if (_shouldUnregisterField) {
38485
+ const value = cloneObject(get(control._options.defaultValues, name));
38486
+ set(control._defaultValues, name, value);
38487
+ if (isUndefined(get(control._formValues, name))) {
38488
+ set(control._formValues, name, value);
38489
+ }
38490
+ }
38491
+ !isArrayField && control.register(name);
38492
+ return () => {
38493
+ (isArrayField
38494
+ ? _shouldUnregisterField && !control._state.action
38495
+ : _shouldUnregisterField)
38496
+ ? control.unregister(name)
38497
+ : updateMounted(name, false);
38498
+ };
38499
+ }, [name, control, isArrayField, shouldUnregister]);
38500
+ React$1.useEffect(() => {
38501
+ control._updateDisabledField({
38502
+ disabled,
38503
+ fields: control._fields,
38504
+ name,
38505
+ });
38506
+ }, [disabled, name, control]);
38507
+ return React$1.useMemo(() => ({
38508
+ field,
38509
+ formState,
38510
+ fieldState,
38511
+ }), [field, formState, fieldState]);
38512
+ }
38513
+
38514
+ /**
38515
+ * Component based on `useController` hook to work with controlled component.
38516
+ *
38517
+ * @remarks
38518
+ * [API](https://react-hook-form.com/docs/usecontroller/controller) • [Demo](https://codesandbox.io/s/react-hook-form-v6-controller-ts-jwyzw) • [Video](https://www.youtube.com/watch?v=N2UNk_UCVyA)
38519
+ *
38520
+ * @param props - the path name to the form field value, and validation rules.
38521
+ *
38522
+ * @returns provide field handler functions, field and form state.
38523
+ *
38524
+ * @example
38525
+ * ```tsx
38526
+ * function App() {
38527
+ * const { control } = useForm<FormValues>({
38528
+ * defaultValues: {
38529
+ * test: ""
38530
+ * }
38531
+ * });
38532
+ *
38533
+ * return (
38534
+ * <form>
38535
+ * <Controller
38536
+ * control={control}
38537
+ * name="test"
38538
+ * render={({ field: { onChange, onBlur, value, ref }, formState, fieldState }) => (
38539
+ * <>
38540
+ * <input
38541
+ * onChange={onChange} // send value to hook form
38542
+ * onBlur={onBlur} // notify when input is touched
38543
+ * value={value} // return updated value
38544
+ * ref={ref} // set ref for focus management
38545
+ * />
38546
+ * <p>{formState.isSubmitted ? "submitted" : ""}</p>
38547
+ * <p>{fieldState.isTouched ? "touched" : ""}</p>
38548
+ * </>
38549
+ * )}
38550
+ * />
38551
+ * </form>
38552
+ * );
38553
+ * }
38554
+ * ```
38555
+ */
38556
+ const Controller = (props) => props.render(useController(props));
38557
+
38558
+ var appendErrors = (name, validateAllFieldCriteria, errors, type, message) => validateAllFieldCriteria
38559
+ ? {
38560
+ ...errors[name],
38561
+ types: {
38562
+ ...(errors[name] && errors[name].types ? errors[name].types : {}),
38563
+ [type]: message || true,
38564
+ },
38565
+ }
38566
+ : {};
38567
+
38568
+ var getValidationModes = (mode) => ({
38569
+ isOnSubmit: !mode || mode === VALIDATION_MODE.onSubmit,
38570
+ isOnBlur: mode === VALIDATION_MODE.onBlur,
38571
+ isOnChange: mode === VALIDATION_MODE.onChange,
38572
+ isOnAll: mode === VALIDATION_MODE.all,
38573
+ isOnTouch: mode === VALIDATION_MODE.onTouched,
38574
+ });
38575
+
38576
+ var isWatched = (name, _names, isBlurEvent) => !isBlurEvent &&
38577
+ (_names.watchAll ||
38578
+ _names.watch.has(name) ||
38579
+ [..._names.watch].some((watchName) => name.startsWith(watchName) &&
38580
+ /^\.\w+/.test(name.slice(watchName.length))));
38581
+
38582
+ const iterateFieldsByAction = (fields, action, fieldsNames, abortEarly) => {
38583
+ for (const key of fieldsNames || Object.keys(fields)) {
38584
+ const field = get(fields, key);
38585
+ if (field) {
38586
+ const { _f, ...currentField } = field;
38587
+ if (_f) {
38588
+ if (_f.refs && _f.refs[0] && action(_f.refs[0], key) && !abortEarly) {
38589
+ return true;
38590
+ }
38591
+ else if (_f.ref && action(_f.ref, _f.name) && !abortEarly) {
38592
+ return true;
38593
+ }
38594
+ else {
38595
+ if (iterateFieldsByAction(currentField, action)) {
38596
+ break;
38597
+ }
38598
+ }
38599
+ }
38600
+ else if (isObject(currentField)) {
38601
+ if (iterateFieldsByAction(currentField, action)) {
38602
+ break;
38603
+ }
38604
+ }
38605
+ }
38606
+ }
38607
+ return;
38608
+ };
38609
+
38610
+ var updateFieldArrayRootError = (errors, error, name) => {
38611
+ const fieldArrayErrors = convertToArrayPayload(get(errors, name));
38612
+ set(fieldArrayErrors, 'root', error[name]);
38613
+ set(errors, name, fieldArrayErrors);
38614
+ return errors;
38615
+ };
38616
+
38617
+ var isFileInput = (element) => element.type === 'file';
38618
+
38619
+ var isFunction = (value) => typeof value === 'function';
38620
+
38621
+ var isHTMLElement = (value) => {
38622
+ if (!isWeb) {
38623
+ return false;
38624
+ }
38625
+ const owner = value ? value.ownerDocument : 0;
38626
+ return (value instanceof
38627
+ (owner && owner.defaultView ? owner.defaultView.HTMLElement : HTMLElement));
38628
+ };
38629
+
38630
+ var isMessage = (value) => isString(value);
38631
+
38632
+ var isRadioInput = (element) => element.type === 'radio';
38633
+
38634
+ var isRegex = (value) => value instanceof RegExp;
38635
+
38636
+ const defaultResult = {
38637
+ value: false,
38638
+ isValid: false,
38639
+ };
38640
+ const validResult = { value: true, isValid: true };
38641
+ var getCheckboxValue = (options) => {
38642
+ if (Array.isArray(options)) {
38643
+ if (options.length > 1) {
38644
+ const values = options
38645
+ .filter((option) => option && option.checked && !option.disabled)
38646
+ .map((option) => option.value);
38647
+ return { value: values, isValid: !!values.length };
38648
+ }
38649
+ return options[0].checked && !options[0].disabled
38650
+ ? // @ts-expect-error expected to work in the browser
38651
+ options[0].attributes && !isUndefined(options[0].attributes.value)
38652
+ ? isUndefined(options[0].value) || options[0].value === ''
38653
+ ? validResult
38654
+ : { value: options[0].value, isValid: true }
38655
+ : validResult
38656
+ : defaultResult;
38657
+ }
38658
+ return defaultResult;
38659
+ };
38660
+
38661
+ const defaultReturn = {
38662
+ isValid: false,
38663
+ value: null,
38664
+ };
38665
+ var getRadioValue = (options) => Array.isArray(options)
38666
+ ? options.reduce((previous, option) => option && option.checked && !option.disabled
38667
+ ? {
38668
+ isValid: true,
38669
+ value: option.value,
38670
+ }
38671
+ : previous, defaultReturn)
38672
+ : defaultReturn;
38673
+
38674
+ function getValidateError(result, ref, type = 'validate') {
38675
+ if (isMessage(result) ||
38676
+ (Array.isArray(result) && result.every(isMessage)) ||
38677
+ (isBoolean(result) && !result)) {
38678
+ return {
38679
+ type,
38680
+ message: isMessage(result) ? result : '',
38681
+ ref,
38682
+ };
38683
+ }
38684
+ }
38685
+
38686
+ var getValueAndMessage = (validationData) => isObject(validationData) && !isRegex(validationData)
38687
+ ? validationData
38688
+ : {
38689
+ value: validationData,
38690
+ message: '',
38691
+ };
38692
+
38693
+ var validateField$1 = async (field, disabledFieldNames, formValues, validateAllFieldCriteria, shouldUseNativeValidation, isFieldArray) => {
38694
+ const { ref, refs, required, maxLength, minLength, min, max, pattern, validate, name, valueAsNumber, mount, } = field._f;
38695
+ const inputValue = get(formValues, name);
38696
+ if (!mount || disabledFieldNames.has(name)) {
38697
+ return {};
38698
+ }
38699
+ const inputRef = refs ? refs[0] : ref;
38700
+ const setCustomValidity = (message) => {
38701
+ if (shouldUseNativeValidation && inputRef.reportValidity) {
38702
+ inputRef.setCustomValidity(isBoolean(message) ? '' : message || '');
38703
+ inputRef.reportValidity();
38704
+ }
38705
+ };
38706
+ const error = {};
38707
+ const isRadio = isRadioInput(ref);
38708
+ const isCheckBox = isCheckBoxInput(ref);
38709
+ const isRadioOrCheckbox = isRadio || isCheckBox;
38710
+ const isEmpty = ((valueAsNumber || isFileInput(ref)) &&
38711
+ isUndefined(ref.value) &&
38712
+ isUndefined(inputValue)) ||
38713
+ (isHTMLElement(ref) && ref.value === '') ||
38714
+ inputValue === '' ||
38715
+ (Array.isArray(inputValue) && !inputValue.length);
38716
+ const appendErrorsCurry = appendErrors.bind(null, name, validateAllFieldCriteria, error);
38717
+ const getMinMaxMessage = (exceedMax, maxLengthMessage, minLengthMessage, maxType = INPUT_VALIDATION_RULES.maxLength, minType = INPUT_VALIDATION_RULES.minLength) => {
38718
+ const message = exceedMax ? maxLengthMessage : minLengthMessage;
38719
+ error[name] = {
38720
+ type: exceedMax ? maxType : minType,
38721
+ message,
38722
+ ref,
38723
+ ...appendErrorsCurry(exceedMax ? maxType : minType, message),
38724
+ };
38725
+ };
38726
+ if (isFieldArray
38727
+ ? !Array.isArray(inputValue) || !inputValue.length
38728
+ : required &&
38729
+ ((!isRadioOrCheckbox && (isEmpty || isNullOrUndefined(inputValue))) ||
38730
+ (isBoolean(inputValue) && !inputValue) ||
38731
+ (isCheckBox && !getCheckboxValue(refs).isValid) ||
38732
+ (isRadio && !getRadioValue(refs).isValid))) {
38733
+ const { value, message } = isMessage(required)
38734
+ ? { value: !!required, message: required }
38735
+ : getValueAndMessage(required);
38736
+ if (value) {
38737
+ error[name] = {
38738
+ type: INPUT_VALIDATION_RULES.required,
38739
+ message,
38740
+ ref: inputRef,
38741
+ ...appendErrorsCurry(INPUT_VALIDATION_RULES.required, message),
38742
+ };
38743
+ if (!validateAllFieldCriteria) {
38744
+ setCustomValidity(message);
38745
+ return error;
38746
+ }
38747
+ }
38748
+ }
38749
+ if (!isEmpty && (!isNullOrUndefined(min) || !isNullOrUndefined(max))) {
38750
+ let exceedMax;
38751
+ let exceedMin;
38752
+ const maxOutput = getValueAndMessage(max);
38753
+ const minOutput = getValueAndMessage(min);
38754
+ if (!isNullOrUndefined(inputValue) && !isNaN(inputValue)) {
38755
+ const valueNumber = ref.valueAsNumber ||
38756
+ (inputValue ? +inputValue : inputValue);
38757
+ if (!isNullOrUndefined(maxOutput.value)) {
38758
+ exceedMax = valueNumber > maxOutput.value;
38759
+ }
38760
+ if (!isNullOrUndefined(minOutput.value)) {
38761
+ exceedMin = valueNumber < minOutput.value;
38762
+ }
38763
+ }
38764
+ else {
38765
+ const valueDate = ref.valueAsDate || new Date(inputValue);
38766
+ const convertTimeToDate = (time) => new Date(new Date().toDateString() + ' ' + time);
38767
+ const isTime = ref.type == 'time';
38768
+ const isWeek = ref.type == 'week';
38769
+ if (isString(maxOutput.value) && inputValue) {
38770
+ exceedMax = isTime
38771
+ ? convertTimeToDate(inputValue) > convertTimeToDate(maxOutput.value)
38772
+ : isWeek
38773
+ ? inputValue > maxOutput.value
38774
+ : valueDate > new Date(maxOutput.value);
38775
+ }
38776
+ if (isString(minOutput.value) && inputValue) {
38777
+ exceedMin = isTime
38778
+ ? convertTimeToDate(inputValue) < convertTimeToDate(minOutput.value)
38779
+ : isWeek
38780
+ ? inputValue < minOutput.value
38781
+ : valueDate < new Date(minOutput.value);
38782
+ }
38783
+ }
38784
+ if (exceedMax || exceedMin) {
38785
+ getMinMaxMessage(!!exceedMax, maxOutput.message, minOutput.message, INPUT_VALIDATION_RULES.max, INPUT_VALIDATION_RULES.min);
38786
+ if (!validateAllFieldCriteria) {
38787
+ setCustomValidity(error[name].message);
38788
+ return error;
38789
+ }
38790
+ }
38791
+ }
38792
+ if ((maxLength || minLength) &&
38793
+ !isEmpty &&
38794
+ (isString(inputValue) || (isFieldArray && Array.isArray(inputValue)))) {
38795
+ const maxLengthOutput = getValueAndMessage(maxLength);
38796
+ const minLengthOutput = getValueAndMessage(minLength);
38797
+ const exceedMax = !isNullOrUndefined(maxLengthOutput.value) &&
38798
+ inputValue.length > +maxLengthOutput.value;
38799
+ const exceedMin = !isNullOrUndefined(minLengthOutput.value) &&
38800
+ inputValue.length < +minLengthOutput.value;
38801
+ if (exceedMax || exceedMin) {
38802
+ getMinMaxMessage(exceedMax, maxLengthOutput.message, minLengthOutput.message);
38803
+ if (!validateAllFieldCriteria) {
38804
+ setCustomValidity(error[name].message);
38805
+ return error;
38806
+ }
38807
+ }
38808
+ }
38809
+ if (pattern && !isEmpty && isString(inputValue)) {
38810
+ const { value: patternValue, message } = getValueAndMessage(pattern);
38811
+ if (isRegex(patternValue) && !inputValue.match(patternValue)) {
38812
+ error[name] = {
38813
+ type: INPUT_VALIDATION_RULES.pattern,
38814
+ message,
38815
+ ref,
38816
+ ...appendErrorsCurry(INPUT_VALIDATION_RULES.pattern, message),
38817
+ };
38818
+ if (!validateAllFieldCriteria) {
38819
+ setCustomValidity(message);
38820
+ return error;
38821
+ }
38822
+ }
38823
+ }
38824
+ if (validate) {
38825
+ if (isFunction(validate)) {
38826
+ const result = await validate(inputValue, formValues);
38827
+ const validateError = getValidateError(result, inputRef);
38828
+ if (validateError) {
38829
+ error[name] = {
38830
+ ...validateError,
38831
+ ...appendErrorsCurry(INPUT_VALIDATION_RULES.validate, validateError.message),
38832
+ };
38833
+ if (!validateAllFieldCriteria) {
38834
+ setCustomValidity(validateError.message);
38835
+ return error;
38836
+ }
38837
+ }
38838
+ }
38839
+ else if (isObject(validate)) {
38840
+ let validationResult = {};
38841
+ for (const key in validate) {
38842
+ if (!isEmptyObject(validationResult) && !validateAllFieldCriteria) {
38843
+ break;
38844
+ }
38845
+ const validateError = getValidateError(await validate[key](inputValue, formValues), inputRef, key);
38846
+ if (validateError) {
38847
+ validationResult = {
38848
+ ...validateError,
38849
+ ...appendErrorsCurry(key, validateError.message),
38850
+ };
38851
+ setCustomValidity(validateError.message);
38852
+ if (validateAllFieldCriteria) {
38853
+ error[name] = validationResult;
38854
+ }
38855
+ }
38856
+ }
38857
+ if (!isEmptyObject(validationResult)) {
38858
+ error[name] = {
38859
+ ref: inputRef,
38860
+ ...validationResult,
38861
+ };
38862
+ if (!validateAllFieldCriteria) {
38863
+ return error;
38864
+ }
38865
+ }
38866
+ }
38867
+ }
38868
+ setCustomValidity(true);
38869
+ return error;
38870
+ };
38871
+
38872
+ function baseGet(object, updatePath) {
38873
+ const length = updatePath.slice(0, -1).length;
38874
+ let index = 0;
38875
+ while (index < length) {
38876
+ object = isUndefined(object) ? index++ : object[updatePath[index++]];
38877
+ }
38878
+ return object;
38879
+ }
38880
+ function isEmptyArray(obj) {
38881
+ for (const key in obj) {
38882
+ if (obj.hasOwnProperty(key) && !isUndefined(obj[key])) {
38883
+ return false;
38884
+ }
38885
+ }
38886
+ return true;
38887
+ }
38888
+ function unset(object, path) {
38889
+ const paths = Array.isArray(path)
38890
+ ? path
38891
+ : isKey(path)
38892
+ ? [path]
38893
+ : stringToPath(path);
38894
+ const childObject = paths.length === 1 ? object : baseGet(object, paths);
38895
+ const index = paths.length - 1;
38896
+ const key = paths[index];
38897
+ if (childObject) {
38898
+ delete childObject[key];
38899
+ }
38900
+ if (index !== 0 &&
38901
+ ((isObject(childObject) && isEmptyObject(childObject)) ||
38902
+ (Array.isArray(childObject) && isEmptyArray(childObject)))) {
38903
+ unset(object, paths.slice(0, -1));
38904
+ }
38905
+ return object;
38906
+ }
38907
+
38908
+ var createSubject = () => {
38909
+ let _observers = [];
38910
+ const next = (value) => {
38911
+ for (const observer of _observers) {
38912
+ observer.next && observer.next(value);
38913
+ }
38914
+ };
38915
+ const subscribe = (observer) => {
38916
+ _observers.push(observer);
38917
+ return {
38918
+ unsubscribe: () => {
38919
+ _observers = _observers.filter((o) => o !== observer);
38920
+ },
38921
+ };
38922
+ };
38923
+ const unsubscribe = () => {
38924
+ _observers = [];
38925
+ };
38926
+ return {
38927
+ get observers() {
38928
+ return _observers;
38929
+ },
38930
+ next,
38931
+ subscribe,
38932
+ unsubscribe,
38933
+ };
38934
+ };
38935
+
38936
+ var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
38937
+
38938
+ function deepEqual(object1, object2) {
38939
+ if (isPrimitive(object1) || isPrimitive(object2)) {
38940
+ return object1 === object2;
38941
+ }
38942
+ if (isDateObject(object1) && isDateObject(object2)) {
38943
+ return object1.getTime() === object2.getTime();
38944
+ }
38945
+ const keys1 = Object.keys(object1);
38946
+ const keys2 = Object.keys(object2);
38947
+ if (keys1.length !== keys2.length) {
38948
+ return false;
38949
+ }
38950
+ for (const key of keys1) {
38951
+ const val1 = object1[key];
38952
+ if (!keys2.includes(key)) {
38953
+ return false;
38954
+ }
38955
+ if (key !== 'ref') {
38956
+ const val2 = object2[key];
38957
+ if ((isDateObject(val1) && isDateObject(val2)) ||
38958
+ (isObject(val1) && isObject(val2)) ||
38959
+ (Array.isArray(val1) && Array.isArray(val2))
38960
+ ? !deepEqual(val1, val2)
38961
+ : val1 !== val2) {
38962
+ return false;
38963
+ }
38964
+ }
38965
+ }
38966
+ return true;
38967
+ }
38968
+
38969
+ var isMultipleSelect = (element) => element.type === `select-multiple`;
38970
+
38971
+ var isRadioOrCheckbox = (ref) => isRadioInput(ref) || isCheckBoxInput(ref);
38972
+
38973
+ var live = (ref) => isHTMLElement(ref) && ref.isConnected;
38974
+
38975
+ var objectHasFunction = (data) => {
38976
+ for (const key in data) {
38977
+ if (isFunction(data[key])) {
38978
+ return true;
38979
+ }
38980
+ }
38981
+ return false;
38982
+ };
38983
+
38984
+ function markFieldsDirty(data, fields = {}) {
38985
+ const isParentNodeArray = Array.isArray(data);
38986
+ if (isObject(data) || isParentNodeArray) {
38987
+ for (const key in data) {
38988
+ if (Array.isArray(data[key]) ||
38989
+ (isObject(data[key]) && !objectHasFunction(data[key]))) {
38990
+ fields[key] = Array.isArray(data[key]) ? [] : {};
38991
+ markFieldsDirty(data[key], fields[key]);
38992
+ }
38993
+ else if (!isNullOrUndefined(data[key])) {
38994
+ fields[key] = true;
38995
+ }
38996
+ }
38997
+ }
38998
+ return fields;
38999
+ }
39000
+ function getDirtyFieldsFromDefaultValues(data, formValues, dirtyFieldsFromValues) {
39001
+ const isParentNodeArray = Array.isArray(data);
39002
+ if (isObject(data) || isParentNodeArray) {
39003
+ for (const key in data) {
39004
+ if (Array.isArray(data[key]) ||
39005
+ (isObject(data[key]) && !objectHasFunction(data[key]))) {
39006
+ if (isUndefined(formValues) ||
39007
+ isPrimitive(dirtyFieldsFromValues[key])) {
39008
+ dirtyFieldsFromValues[key] = Array.isArray(data[key])
39009
+ ? markFieldsDirty(data[key], [])
39010
+ : { ...markFieldsDirty(data[key]) };
39011
+ }
39012
+ else {
39013
+ getDirtyFieldsFromDefaultValues(data[key], isNullOrUndefined(formValues) ? {} : formValues[key], dirtyFieldsFromValues[key]);
39014
+ }
39015
+ }
39016
+ else {
39017
+ dirtyFieldsFromValues[key] = !deepEqual(data[key], formValues[key]);
39018
+ }
39019
+ }
39020
+ }
39021
+ return dirtyFieldsFromValues;
39022
+ }
39023
+ var getDirtyFields = (defaultValues, formValues) => getDirtyFieldsFromDefaultValues(defaultValues, formValues, markFieldsDirty(formValues));
39024
+
39025
+ var getFieldValueAs = (value, { valueAsNumber, valueAsDate, setValueAs }) => isUndefined(value)
39026
+ ? value
39027
+ : valueAsNumber
39028
+ ? value === ''
39029
+ ? NaN
39030
+ : value
39031
+ ? +value
39032
+ : value
39033
+ : valueAsDate && isString(value)
39034
+ ? new Date(value)
39035
+ : setValueAs
39036
+ ? setValueAs(value)
39037
+ : value;
39038
+
39039
+ function getFieldValue(_f) {
39040
+ const ref = _f.ref;
39041
+ if (isFileInput(ref)) {
39042
+ return ref.files;
39043
+ }
39044
+ if (isRadioInput(ref)) {
39045
+ return getRadioValue(_f.refs).value;
39046
+ }
39047
+ if (isMultipleSelect(ref)) {
39048
+ return [...ref.selectedOptions].map(({ value }) => value);
39049
+ }
39050
+ if (isCheckBoxInput(ref)) {
39051
+ return getCheckboxValue(_f.refs).value;
39052
+ }
39053
+ return getFieldValueAs(isUndefined(ref.value) ? _f.ref.value : ref.value, _f);
39054
+ }
39055
+
39056
+ var getResolverOptions = (fieldsNames, _fields, criteriaMode, shouldUseNativeValidation) => {
39057
+ const fields = {};
39058
+ for (const name of fieldsNames) {
39059
+ const field = get(_fields, name);
39060
+ field && set(fields, name, field._f);
39061
+ }
39062
+ return {
39063
+ criteriaMode,
39064
+ names: [...fieldsNames],
39065
+ fields,
39066
+ shouldUseNativeValidation,
39067
+ };
39068
+ };
39069
+
39070
+ var getRuleValue = (rule) => isUndefined(rule)
39071
+ ? rule
39072
+ : isRegex(rule)
39073
+ ? rule.source
39074
+ : isObject(rule)
39075
+ ? isRegex(rule.value)
39076
+ ? rule.value.source
39077
+ : rule.value
39078
+ : rule;
39079
+
39080
+ const ASYNC_FUNCTION = 'AsyncFunction';
39081
+ var hasPromiseValidation = (fieldReference) => !!fieldReference &&
39082
+ !!fieldReference.validate &&
39083
+ !!((isFunction(fieldReference.validate) &&
39084
+ fieldReference.validate.constructor.name === ASYNC_FUNCTION) ||
39085
+ (isObject(fieldReference.validate) &&
39086
+ Object.values(fieldReference.validate).find((validateFunction) => validateFunction.constructor.name === ASYNC_FUNCTION)));
39087
+
39088
+ var hasValidation = (options) => options.mount &&
39089
+ (options.required ||
39090
+ options.min ||
39091
+ options.max ||
39092
+ options.maxLength ||
39093
+ options.minLength ||
39094
+ options.pattern ||
39095
+ options.validate);
39096
+
39097
+ function schemaErrorLookup(errors, _fields, name) {
39098
+ const error = get(errors, name);
39099
+ if (error || isKey(name)) {
39100
+ return {
39101
+ error,
39102
+ name,
39103
+ };
39104
+ }
39105
+ const names = name.split('.');
39106
+ while (names.length) {
39107
+ const fieldName = names.join('.');
39108
+ const field = get(_fields, fieldName);
39109
+ const foundError = get(errors, fieldName);
39110
+ if (field && !Array.isArray(field) && name !== fieldName) {
39111
+ return { name };
39112
+ }
39113
+ if (foundError && foundError.type) {
39114
+ return {
39115
+ name: fieldName,
39116
+ error: foundError,
39117
+ };
39118
+ }
39119
+ names.pop();
39120
+ }
39121
+ return {
39122
+ name,
39123
+ };
39124
+ }
39125
+
39126
+ var skipValidation = (isBlurEvent, isTouched, isSubmitted, reValidateMode, mode) => {
39127
+ if (mode.isOnAll) {
39128
+ return false;
39129
+ }
39130
+ else if (!isSubmitted && mode.isOnTouch) {
39131
+ return !(isTouched || isBlurEvent);
39132
+ }
39133
+ else if (isSubmitted ? reValidateMode.isOnBlur : mode.isOnBlur) {
39134
+ return !isBlurEvent;
39135
+ }
39136
+ else if (isSubmitted ? reValidateMode.isOnChange : mode.isOnChange) {
39137
+ return isBlurEvent;
39138
+ }
39139
+ return true;
39140
+ };
39141
+
39142
+ var unsetEmptyArray = (ref, name) => !compact(get(ref, name)).length && unset(ref, name);
39143
+
39144
+ const defaultOptions = {
39145
+ mode: VALIDATION_MODE.onSubmit,
39146
+ reValidateMode: VALIDATION_MODE.onChange,
39147
+ shouldFocusError: true,
39148
+ };
39149
+ function createFormControl(props = {}) {
39150
+ let _options = {
39151
+ ...defaultOptions,
39152
+ ...props,
39153
+ };
39154
+ let _formState = {
39155
+ submitCount: 0,
39156
+ isDirty: false,
39157
+ isLoading: isFunction(_options.defaultValues),
39158
+ isValidating: false,
39159
+ isSubmitted: false,
39160
+ isSubmitting: false,
39161
+ isSubmitSuccessful: false,
39162
+ isValid: false,
39163
+ touchedFields: {},
39164
+ dirtyFields: {},
39165
+ validatingFields: {},
39166
+ errors: _options.errors || {},
39167
+ disabled: _options.disabled || false,
39168
+ };
39169
+ let _fields = {};
39170
+ let _defaultValues = isObject(_options.defaultValues) || isObject(_options.values)
39171
+ ? cloneObject(_options.defaultValues || _options.values) || {}
39172
+ : {};
39173
+ let _formValues = _options.shouldUnregister
39174
+ ? {}
39175
+ : cloneObject(_defaultValues);
39176
+ let _state = {
39177
+ action: false,
39178
+ mount: false,
39179
+ watch: false,
39180
+ };
39181
+ let _names = {
39182
+ mount: new Set(),
39183
+ disabled: new Set(),
39184
+ unMount: new Set(),
39185
+ array: new Set(),
39186
+ watch: new Set(),
39187
+ };
39188
+ let delayErrorCallback;
39189
+ let timer = 0;
39190
+ const _proxyFormState = {
39191
+ isDirty: false,
39192
+ dirtyFields: false,
39193
+ validatingFields: false,
39194
+ touchedFields: false,
39195
+ isValidating: false,
39196
+ isValid: false,
39197
+ errors: false,
39198
+ };
39199
+ const _subjects = {
39200
+ values: createSubject(),
39201
+ array: createSubject(),
39202
+ state: createSubject(),
39203
+ };
39204
+ const validationModeBeforeSubmit = getValidationModes(_options.mode);
39205
+ const validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
39206
+ const shouldDisplayAllAssociatedErrors = _options.criteriaMode === VALIDATION_MODE.all;
39207
+ const debounce = (callback) => (wait) => {
39208
+ clearTimeout(timer);
39209
+ timer = setTimeout(callback, wait);
39210
+ };
39211
+ const _updateValid = async (shouldUpdateValid) => {
39212
+ if (!_options.disabled && (_proxyFormState.isValid || shouldUpdateValid)) {
39213
+ const isValid = _options.resolver
39214
+ ? isEmptyObject((await _executeSchema()).errors)
39215
+ : await executeBuiltInValidation(_fields, true);
39216
+ if (isValid !== _formState.isValid) {
39217
+ _subjects.state.next({
39218
+ isValid,
39219
+ });
39220
+ }
39221
+ }
39222
+ };
39223
+ const _updateIsValidating = (names, isValidating) => {
39224
+ if (!_options.disabled &&
39225
+ (_proxyFormState.isValidating || _proxyFormState.validatingFields)) {
39226
+ (names || Array.from(_names.mount)).forEach((name) => {
39227
+ if (name) {
39228
+ isValidating
39229
+ ? set(_formState.validatingFields, name, isValidating)
39230
+ : unset(_formState.validatingFields, name);
39231
+ }
39232
+ });
39233
+ _subjects.state.next({
39234
+ validatingFields: _formState.validatingFields,
39235
+ isValidating: !isEmptyObject(_formState.validatingFields),
39236
+ });
39237
+ }
39238
+ };
39239
+ const _updateFieldArray = (name, values = [], method, args, shouldSetValues = true, shouldUpdateFieldsAndState = true) => {
39240
+ if (args && method && !_options.disabled) {
39241
+ _state.action = true;
39242
+ if (shouldUpdateFieldsAndState && Array.isArray(get(_fields, name))) {
39243
+ const fieldValues = method(get(_fields, name), args.argA, args.argB);
39244
+ shouldSetValues && set(_fields, name, fieldValues);
39245
+ }
39246
+ if (shouldUpdateFieldsAndState &&
39247
+ Array.isArray(get(_formState.errors, name))) {
39248
+ const errors = method(get(_formState.errors, name), args.argA, args.argB);
39249
+ shouldSetValues && set(_formState.errors, name, errors);
39250
+ unsetEmptyArray(_formState.errors, name);
39251
+ }
39252
+ if (_proxyFormState.touchedFields &&
39253
+ shouldUpdateFieldsAndState &&
39254
+ Array.isArray(get(_formState.touchedFields, name))) {
39255
+ const touchedFields = method(get(_formState.touchedFields, name), args.argA, args.argB);
39256
+ shouldSetValues && set(_formState.touchedFields, name, touchedFields);
39257
+ }
39258
+ if (_proxyFormState.dirtyFields) {
39259
+ _formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
39260
+ }
39261
+ _subjects.state.next({
39262
+ name,
39263
+ isDirty: _getDirty(name, values),
39264
+ dirtyFields: _formState.dirtyFields,
39265
+ errors: _formState.errors,
39266
+ isValid: _formState.isValid,
39267
+ });
39268
+ }
39269
+ else {
39270
+ set(_formValues, name, values);
39271
+ }
39272
+ };
39273
+ const updateErrors = (name, error) => {
39274
+ set(_formState.errors, name, error);
39275
+ _subjects.state.next({
39276
+ errors: _formState.errors,
39277
+ });
39278
+ };
39279
+ const _setErrors = (errors) => {
39280
+ _formState.errors = errors;
39281
+ _subjects.state.next({
39282
+ errors: _formState.errors,
39283
+ isValid: false,
39284
+ });
39285
+ };
39286
+ const updateValidAndValue = (name, shouldSkipSetValueAs, value, ref) => {
39287
+ const field = get(_fields, name);
39288
+ if (field) {
39289
+ const defaultValue = get(_formValues, name, isUndefined(value) ? get(_defaultValues, name) : value);
39290
+ isUndefined(defaultValue) ||
39291
+ (ref && ref.defaultChecked) ||
39292
+ shouldSkipSetValueAs
39293
+ ? set(_formValues, name, shouldSkipSetValueAs ? defaultValue : getFieldValue(field._f))
39294
+ : setFieldValue(name, defaultValue);
39295
+ _state.mount && _updateValid();
39296
+ }
39297
+ };
39298
+ const updateTouchAndDirty = (name, fieldValue, isBlurEvent, shouldDirty, shouldRender) => {
39299
+ let shouldUpdateField = false;
39300
+ let isPreviousDirty = false;
39301
+ const output = {
39302
+ name,
39303
+ };
39304
+ if (!_options.disabled) {
39305
+ const disabledField = !!(get(_fields, name) &&
39306
+ get(_fields, name)._f &&
39307
+ get(_fields, name)._f.disabled);
39308
+ if (!isBlurEvent || shouldDirty) {
39309
+ if (_proxyFormState.isDirty) {
39310
+ isPreviousDirty = _formState.isDirty;
39311
+ _formState.isDirty = output.isDirty = _getDirty();
39312
+ shouldUpdateField = isPreviousDirty !== output.isDirty;
39313
+ }
39314
+ const isCurrentFieldPristine = disabledField || deepEqual(get(_defaultValues, name), fieldValue);
39315
+ isPreviousDirty = !!(!disabledField && get(_formState.dirtyFields, name));
39316
+ isCurrentFieldPristine || disabledField
39317
+ ? unset(_formState.dirtyFields, name)
39318
+ : set(_formState.dirtyFields, name, true);
39319
+ output.dirtyFields = _formState.dirtyFields;
39320
+ shouldUpdateField =
39321
+ shouldUpdateField ||
39322
+ (_proxyFormState.dirtyFields &&
39323
+ isPreviousDirty !== !isCurrentFieldPristine);
39324
+ }
39325
+ if (isBlurEvent) {
39326
+ const isPreviousFieldTouched = get(_formState.touchedFields, name);
39327
+ if (!isPreviousFieldTouched) {
39328
+ set(_formState.touchedFields, name, isBlurEvent);
39329
+ output.touchedFields = _formState.touchedFields;
39330
+ shouldUpdateField =
39331
+ shouldUpdateField ||
39332
+ (_proxyFormState.touchedFields &&
39333
+ isPreviousFieldTouched !== isBlurEvent);
39334
+ }
39335
+ }
39336
+ shouldUpdateField && shouldRender && _subjects.state.next(output);
39337
+ }
39338
+ return shouldUpdateField ? output : {};
39339
+ };
39340
+ const shouldRenderByError = (name, isValid, error, fieldState) => {
39341
+ const previousFieldError = get(_formState.errors, name);
39342
+ const shouldUpdateValid = _proxyFormState.isValid &&
39343
+ isBoolean(isValid) &&
39344
+ _formState.isValid !== isValid;
39345
+ if (_options.delayError && error) {
39346
+ delayErrorCallback = debounce(() => updateErrors(name, error));
39347
+ delayErrorCallback(_options.delayError);
39348
+ }
39349
+ else {
39350
+ clearTimeout(timer);
39351
+ delayErrorCallback = null;
39352
+ error
39353
+ ? set(_formState.errors, name, error)
39354
+ : unset(_formState.errors, name);
39355
+ }
39356
+ if ((error ? !deepEqual(previousFieldError, error) : previousFieldError) ||
39357
+ !isEmptyObject(fieldState) ||
39358
+ shouldUpdateValid) {
39359
+ const updatedFormState = {
39360
+ ...fieldState,
39361
+ ...(shouldUpdateValid && isBoolean(isValid) ? { isValid } : {}),
39362
+ errors: _formState.errors,
39363
+ name,
39364
+ };
39365
+ _formState = {
39366
+ ..._formState,
39367
+ ...updatedFormState,
39368
+ };
39369
+ _subjects.state.next(updatedFormState);
39370
+ }
39371
+ };
39372
+ const _executeSchema = async (name) => {
39373
+ _updateIsValidating(name, true);
39374
+ const result = await _options.resolver(_formValues, _options.context, getResolverOptions(name || _names.mount, _fields, _options.criteriaMode, _options.shouldUseNativeValidation));
39375
+ _updateIsValidating(name);
39376
+ return result;
39377
+ };
39378
+ const executeSchemaAndUpdateState = async (names) => {
39379
+ const { errors } = await _executeSchema(names);
39380
+ if (names) {
39381
+ for (const name of names) {
39382
+ const error = get(errors, name);
39383
+ error
39384
+ ? set(_formState.errors, name, error)
39385
+ : unset(_formState.errors, name);
39386
+ }
39387
+ }
39388
+ else {
39389
+ _formState.errors = errors;
39390
+ }
39391
+ return errors;
39392
+ };
39393
+ const executeBuiltInValidation = async (fields, shouldOnlyCheckValid, context = {
39394
+ valid: true,
39395
+ }) => {
39396
+ for (const name in fields) {
39397
+ const field = fields[name];
39398
+ if (field) {
39399
+ const { _f, ...fieldValue } = field;
39400
+ if (_f) {
39401
+ const isFieldArrayRoot = _names.array.has(_f.name);
39402
+ const isPromiseFunction = field._f && hasPromiseValidation(field._f);
39403
+ if (isPromiseFunction && _proxyFormState.validatingFields) {
39404
+ _updateIsValidating([name], true);
39405
+ }
39406
+ const fieldError = await validateField$1(field, _names.disabled, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation && !shouldOnlyCheckValid, isFieldArrayRoot);
39407
+ if (isPromiseFunction && _proxyFormState.validatingFields) {
39408
+ _updateIsValidating([name]);
39409
+ }
39410
+ if (fieldError[_f.name]) {
39411
+ context.valid = false;
39412
+ if (shouldOnlyCheckValid) {
39413
+ break;
39414
+ }
39415
+ }
39416
+ !shouldOnlyCheckValid &&
39417
+ (get(fieldError, _f.name)
39418
+ ? isFieldArrayRoot
39419
+ ? updateFieldArrayRootError(_formState.errors, fieldError, _f.name)
39420
+ : set(_formState.errors, _f.name, fieldError[_f.name])
39421
+ : unset(_formState.errors, _f.name));
39422
+ }
39423
+ !isEmptyObject(fieldValue) &&
39424
+ (await executeBuiltInValidation(fieldValue, shouldOnlyCheckValid, context));
39425
+ }
39426
+ }
39427
+ return context.valid;
39428
+ };
39429
+ const _removeUnmounted = () => {
39430
+ for (const name of _names.unMount) {
39431
+ const field = get(_fields, name);
39432
+ field &&
39433
+ (field._f.refs
39434
+ ? field._f.refs.every((ref) => !live(ref))
39435
+ : !live(field._f.ref)) &&
39436
+ unregister(name);
39437
+ }
39438
+ _names.unMount = new Set();
39439
+ };
39440
+ const _getDirty = (name, data) => !_options.disabled &&
39441
+ (name && data && set(_formValues, name, data),
39442
+ !deepEqual(getValues(), _defaultValues));
39443
+ const _getWatch = (names, defaultValue, isGlobal) => generateWatchOutput(names, _names, {
39444
+ ...(_state.mount
39445
+ ? _formValues
39446
+ : isUndefined(defaultValue)
39447
+ ? _defaultValues
39448
+ : isString(names)
39449
+ ? { [names]: defaultValue }
39450
+ : defaultValue),
39451
+ }, isGlobal, defaultValue);
39452
+ const _getFieldArray = (name) => compact(get(_state.mount ? _formValues : _defaultValues, name, _options.shouldUnregister ? get(_defaultValues, name, []) : []));
39453
+ const setFieldValue = (name, value, options = {}) => {
39454
+ const field = get(_fields, name);
39455
+ let fieldValue = value;
39456
+ if (field) {
39457
+ const fieldReference = field._f;
39458
+ if (fieldReference) {
39459
+ !fieldReference.disabled &&
39460
+ set(_formValues, name, getFieldValueAs(value, fieldReference));
39461
+ fieldValue =
39462
+ isHTMLElement(fieldReference.ref) && isNullOrUndefined(value)
39463
+ ? ''
39464
+ : value;
39465
+ if (isMultipleSelect(fieldReference.ref)) {
39466
+ [...fieldReference.ref.options].forEach((optionRef) => (optionRef.selected = fieldValue.includes(optionRef.value)));
39467
+ }
39468
+ else if (fieldReference.refs) {
39469
+ if (isCheckBoxInput(fieldReference.ref)) {
39470
+ fieldReference.refs.length > 1
39471
+ ? fieldReference.refs.forEach((checkboxRef) => (!checkboxRef.defaultChecked || !checkboxRef.disabled) &&
39472
+ (checkboxRef.checked = Array.isArray(fieldValue)
39473
+ ? !!fieldValue.find((data) => data === checkboxRef.value)
39474
+ : fieldValue === checkboxRef.value))
39475
+ : fieldReference.refs[0] &&
39476
+ (fieldReference.refs[0].checked = !!fieldValue);
39477
+ }
39478
+ else {
39479
+ fieldReference.refs.forEach((radioRef) => (radioRef.checked = radioRef.value === fieldValue));
39480
+ }
39481
+ }
39482
+ else if (isFileInput(fieldReference.ref)) {
39483
+ fieldReference.ref.value = '';
39484
+ }
39485
+ else {
39486
+ fieldReference.ref.value = fieldValue;
39487
+ if (!fieldReference.ref.type) {
39488
+ _subjects.values.next({
39489
+ name,
39490
+ values: { ..._formValues },
39491
+ });
39492
+ }
39493
+ }
39494
+ }
39495
+ }
39496
+ (options.shouldDirty || options.shouldTouch) &&
39497
+ updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty, true);
39498
+ options.shouldValidate && trigger(name);
39499
+ };
39500
+ const setValues = (name, value, options) => {
39501
+ for (const fieldKey in value) {
39502
+ const fieldValue = value[fieldKey];
39503
+ const fieldName = `${name}.${fieldKey}`;
39504
+ const field = get(_fields, fieldName);
39505
+ (_names.array.has(name) ||
39506
+ isObject(fieldValue) ||
39507
+ (field && !field._f)) &&
39508
+ !isDateObject(fieldValue)
39509
+ ? setValues(fieldName, fieldValue, options)
39510
+ : setFieldValue(fieldName, fieldValue, options);
39511
+ }
39512
+ };
39513
+ const setValue = (name, value, options = {}) => {
39514
+ const field = get(_fields, name);
39515
+ const isFieldArray = _names.array.has(name);
39516
+ const cloneValue = cloneObject(value);
39517
+ set(_formValues, name, cloneValue);
39518
+ if (isFieldArray) {
39519
+ _subjects.array.next({
39520
+ name,
39521
+ values: { ..._formValues },
39522
+ });
39523
+ if ((_proxyFormState.isDirty || _proxyFormState.dirtyFields) &&
39524
+ options.shouldDirty) {
39525
+ _subjects.state.next({
39526
+ name,
39527
+ dirtyFields: getDirtyFields(_defaultValues, _formValues),
39528
+ isDirty: _getDirty(name, cloneValue),
39529
+ });
39530
+ }
39531
+ }
39532
+ else {
39533
+ field && !field._f && !isNullOrUndefined(cloneValue)
39534
+ ? setValues(name, cloneValue, options)
39535
+ : setFieldValue(name, cloneValue, options);
39536
+ }
39537
+ isWatched(name, _names) && _subjects.state.next({ ..._formState });
39538
+ _subjects.values.next({
39539
+ name: _state.mount ? name : undefined,
39540
+ values: { ..._formValues },
39541
+ });
39542
+ };
39543
+ const onChange = async (event) => {
39544
+ _state.mount = true;
39545
+ const target = event.target;
39546
+ let name = target.name;
39547
+ let isFieldValueUpdated = true;
39548
+ const field = get(_fields, name);
39549
+ const getCurrentFieldValue = () => target.type ? getFieldValue(field._f) : getEventValue(event);
39550
+ const _updateIsFieldValueUpdated = (fieldValue) => {
39551
+ isFieldValueUpdated =
39552
+ Number.isNaN(fieldValue) ||
39553
+ (isDateObject(fieldValue) && isNaN(fieldValue.getTime())) ||
39554
+ deepEqual(fieldValue, get(_formValues, name, fieldValue));
39555
+ };
39556
+ if (field) {
39557
+ let error;
39558
+ let isValid;
39559
+ const fieldValue = getCurrentFieldValue();
39560
+ const isBlurEvent = event.type === EVENTS.BLUR || event.type === EVENTS.FOCUS_OUT;
39561
+ const shouldSkipValidation = (!hasValidation(field._f) &&
39562
+ !_options.resolver &&
39563
+ !get(_formState.errors, name) &&
39564
+ !field._f.deps) ||
39565
+ skipValidation(isBlurEvent, get(_formState.touchedFields, name), _formState.isSubmitted, validationModeAfterSubmit, validationModeBeforeSubmit);
39566
+ const watched = isWatched(name, _names, isBlurEvent);
39567
+ set(_formValues, name, fieldValue);
39568
+ if (isBlurEvent) {
39569
+ field._f.onBlur && field._f.onBlur(event);
39570
+ delayErrorCallback && delayErrorCallback(0);
39571
+ }
39572
+ else if (field._f.onChange) {
39573
+ field._f.onChange(event);
39574
+ }
39575
+ const fieldState = updateTouchAndDirty(name, fieldValue, isBlurEvent, false);
39576
+ const shouldRender = !isEmptyObject(fieldState) || watched;
39577
+ !isBlurEvent &&
39578
+ _subjects.values.next({
39579
+ name,
39580
+ type: event.type,
39581
+ values: { ..._formValues },
39582
+ });
39583
+ if (shouldSkipValidation) {
39584
+ if (_proxyFormState.isValid) {
39585
+ if (_options.mode === 'onBlur' && isBlurEvent) {
39586
+ _updateValid();
39587
+ }
39588
+ else if (!isBlurEvent) {
39589
+ _updateValid();
39590
+ }
39591
+ }
39592
+ return (shouldRender &&
39593
+ _subjects.state.next({ name, ...(watched ? {} : fieldState) }));
39594
+ }
39595
+ !isBlurEvent && watched && _subjects.state.next({ ..._formState });
39596
+ if (_options.resolver) {
39597
+ const { errors } = await _executeSchema([name]);
39598
+ _updateIsFieldValueUpdated(fieldValue);
39599
+ if (isFieldValueUpdated) {
39600
+ const previousErrorLookupResult = schemaErrorLookup(_formState.errors, _fields, name);
39601
+ const errorLookupResult = schemaErrorLookup(errors, _fields, previousErrorLookupResult.name || name);
39602
+ error = errorLookupResult.error;
39603
+ name = errorLookupResult.name;
39604
+ isValid = isEmptyObject(errors);
39605
+ }
39606
+ }
39607
+ else {
39608
+ _updateIsValidating([name], true);
39609
+ error = (await validateField$1(field, _names.disabled, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation))[name];
39610
+ _updateIsValidating([name]);
39611
+ _updateIsFieldValueUpdated(fieldValue);
39612
+ if (isFieldValueUpdated) {
39613
+ if (error) {
39614
+ isValid = false;
39615
+ }
39616
+ else if (_proxyFormState.isValid) {
39617
+ isValid = await executeBuiltInValidation(_fields, true);
39618
+ }
39619
+ }
39620
+ }
39621
+ if (isFieldValueUpdated) {
39622
+ field._f.deps &&
39623
+ trigger(field._f.deps);
39624
+ shouldRenderByError(name, isValid, error, fieldState);
39625
+ }
39626
+ }
39627
+ };
39628
+ const _focusInput = (ref, key) => {
39629
+ if (get(_formState.errors, key) && ref.focus) {
39630
+ ref.focus();
39631
+ return 1;
39632
+ }
39633
+ return;
39634
+ };
39635
+ const trigger = async (name, options = {}) => {
39636
+ let isValid;
39637
+ let validationResult;
39638
+ const fieldNames = convertToArrayPayload(name);
39639
+ if (_options.resolver) {
39640
+ const errors = await executeSchemaAndUpdateState(isUndefined(name) ? name : fieldNames);
39641
+ isValid = isEmptyObject(errors);
39642
+ validationResult = name
39643
+ ? !fieldNames.some((name) => get(errors, name))
39644
+ : isValid;
39645
+ }
39646
+ else if (name) {
39647
+ validationResult = (await Promise.all(fieldNames.map(async (fieldName) => {
39648
+ const field = get(_fields, fieldName);
39649
+ return await executeBuiltInValidation(field && field._f ? { [fieldName]: field } : field);
39650
+ }))).every(Boolean);
39651
+ !(!validationResult && !_formState.isValid) && _updateValid();
39652
+ }
39653
+ else {
39654
+ validationResult = isValid = await executeBuiltInValidation(_fields);
39655
+ }
39656
+ _subjects.state.next({
39657
+ ...(!isString(name) ||
39658
+ (_proxyFormState.isValid && isValid !== _formState.isValid)
39659
+ ? {}
39660
+ : { name }),
39661
+ ...(_options.resolver || !name ? { isValid } : {}),
39662
+ errors: _formState.errors,
39663
+ });
39664
+ options.shouldFocus &&
39665
+ !validationResult &&
39666
+ iterateFieldsByAction(_fields, _focusInput, name ? fieldNames : _names.mount);
39667
+ return validationResult;
39668
+ };
39669
+ const getValues = (fieldNames) => {
39670
+ const values = {
39671
+ ...(_state.mount ? _formValues : _defaultValues),
39672
+ };
39673
+ return isUndefined(fieldNames)
39674
+ ? values
39675
+ : isString(fieldNames)
39676
+ ? get(values, fieldNames)
39677
+ : fieldNames.map((name) => get(values, name));
39678
+ };
39679
+ const getFieldState = (name, formState) => ({
39680
+ invalid: !!get((formState || _formState).errors, name),
39681
+ isDirty: !!get((formState || _formState).dirtyFields, name),
39682
+ error: get((formState || _formState).errors, name),
39683
+ isValidating: !!get(_formState.validatingFields, name),
39684
+ isTouched: !!get((formState || _formState).touchedFields, name),
39685
+ });
39686
+ const clearErrors = (name) => {
39687
+ name &&
39688
+ convertToArrayPayload(name).forEach((inputName) => unset(_formState.errors, inputName));
39689
+ _subjects.state.next({
39690
+ errors: name ? _formState.errors : {},
39691
+ });
39692
+ };
39693
+ const setError = (name, error, options) => {
39694
+ const ref = (get(_fields, name, { _f: {} })._f || {}).ref;
39695
+ const currentError = get(_formState.errors, name) || {};
39696
+ // Don't override existing error messages elsewhere in the object tree.
39697
+ const { ref: currentRef, message, type, ...restOfErrorTree } = currentError;
39698
+ set(_formState.errors, name, {
39699
+ ...restOfErrorTree,
39700
+ ...error,
39701
+ ref,
39702
+ });
39703
+ _subjects.state.next({
39704
+ name,
39705
+ errors: _formState.errors,
39706
+ isValid: false,
39707
+ });
39708
+ options && options.shouldFocus && ref && ref.focus && ref.focus();
39709
+ };
39710
+ const watch = (name, defaultValue) => isFunction(name)
39711
+ ? _subjects.values.subscribe({
39712
+ next: (payload) => name(_getWatch(undefined, defaultValue), payload),
39713
+ })
39714
+ : _getWatch(name, defaultValue, true);
39715
+ const unregister = (name, options = {}) => {
39716
+ for (const fieldName of name ? convertToArrayPayload(name) : _names.mount) {
39717
+ _names.mount.delete(fieldName);
39718
+ _names.array.delete(fieldName);
39719
+ if (!options.keepValue) {
39720
+ unset(_fields, fieldName);
39721
+ unset(_formValues, fieldName);
39722
+ }
39723
+ !options.keepError && unset(_formState.errors, fieldName);
39724
+ !options.keepDirty && unset(_formState.dirtyFields, fieldName);
39725
+ !options.keepTouched && unset(_formState.touchedFields, fieldName);
39726
+ !options.keepIsValidating &&
39727
+ unset(_formState.validatingFields, fieldName);
39728
+ !_options.shouldUnregister &&
39729
+ !options.keepDefaultValue &&
39730
+ unset(_defaultValues, fieldName);
39731
+ }
39732
+ _subjects.values.next({
39733
+ values: { ..._formValues },
39734
+ });
39735
+ _subjects.state.next({
39736
+ ..._formState,
39737
+ ...(!options.keepDirty ? {} : { isDirty: _getDirty() }),
39738
+ });
39739
+ !options.keepIsValid && _updateValid();
39740
+ };
39741
+ const _updateDisabledField = ({ disabled, name, field, fields, }) => {
39742
+ if ((isBoolean(disabled) && _state.mount) ||
39743
+ !!disabled ||
39744
+ _names.disabled.has(name)) {
39745
+ disabled ? _names.disabled.add(name) : _names.disabled.delete(name);
39746
+ updateTouchAndDirty(name, getFieldValue(field ? field._f : get(fields, name)._f), false, false, true);
39747
+ }
39748
+ };
39749
+ const register = (name, options = {}) => {
39750
+ let field = get(_fields, name);
39751
+ const disabledIsDefined = isBoolean(options.disabled) || isBoolean(_options.disabled);
39752
+ set(_fields, name, {
39753
+ ...(field || {}),
39754
+ _f: {
39755
+ ...(field && field._f ? field._f : { ref: { name } }),
39756
+ name,
39757
+ mount: true,
39758
+ ...options,
39759
+ },
39760
+ });
39761
+ _names.mount.add(name);
39762
+ if (field) {
39763
+ _updateDisabledField({
39764
+ field,
39765
+ disabled: isBoolean(options.disabled)
39766
+ ? options.disabled
39767
+ : _options.disabled,
39768
+ name,
39769
+ });
39770
+ }
39771
+ else {
39772
+ updateValidAndValue(name, true, options.value);
39773
+ }
39774
+ return {
39775
+ ...(disabledIsDefined
39776
+ ? { disabled: options.disabled || _options.disabled }
39777
+ : {}),
39778
+ ...(_options.progressive
39779
+ ? {
39780
+ required: !!options.required,
39781
+ min: getRuleValue(options.min),
39782
+ max: getRuleValue(options.max),
39783
+ minLength: getRuleValue(options.minLength),
39784
+ maxLength: getRuleValue(options.maxLength),
39785
+ pattern: getRuleValue(options.pattern),
39786
+ }
39787
+ : {}),
39788
+ name,
39789
+ onChange,
39790
+ onBlur: onChange,
39791
+ ref: (ref) => {
39792
+ if (ref) {
39793
+ register(name, options);
39794
+ field = get(_fields, name);
39795
+ const fieldRef = isUndefined(ref.value)
39796
+ ? ref.querySelectorAll
39797
+ ? ref.querySelectorAll('input,select,textarea')[0] || ref
39798
+ : ref
39799
+ : ref;
39800
+ const radioOrCheckbox = isRadioOrCheckbox(fieldRef);
39801
+ const refs = field._f.refs || [];
39802
+ if (radioOrCheckbox
39803
+ ? refs.find((option) => option === fieldRef)
39804
+ : fieldRef === field._f.ref) {
39805
+ return;
39806
+ }
39807
+ set(_fields, name, {
39808
+ _f: {
39809
+ ...field._f,
39810
+ ...(radioOrCheckbox
39811
+ ? {
39812
+ refs: [
39813
+ ...refs.filter(live),
39814
+ fieldRef,
39815
+ ...(Array.isArray(get(_defaultValues, name)) ? [{}] : []),
39816
+ ],
39817
+ ref: { type: fieldRef.type, name },
39818
+ }
39819
+ : { ref: fieldRef }),
39820
+ },
39821
+ });
39822
+ updateValidAndValue(name, false, undefined, fieldRef);
39823
+ }
39824
+ else {
39825
+ field = get(_fields, name, {});
39826
+ if (field._f) {
39827
+ field._f.mount = false;
39828
+ }
39829
+ (_options.shouldUnregister || options.shouldUnregister) &&
39830
+ !(isNameInFieldArray(_names.array, name) && _state.action) &&
39831
+ _names.unMount.add(name);
39832
+ }
39833
+ },
39834
+ };
39835
+ };
39836
+ const _focusError = () => _options.shouldFocusError &&
39837
+ iterateFieldsByAction(_fields, _focusInput, _names.mount);
39838
+ const _disableForm = (disabled) => {
39839
+ if (isBoolean(disabled)) {
39840
+ _subjects.state.next({ disabled });
39841
+ iterateFieldsByAction(_fields, (ref, name) => {
39842
+ const currentField = get(_fields, name);
39843
+ if (currentField) {
39844
+ ref.disabled = currentField._f.disabled || disabled;
39845
+ if (Array.isArray(currentField._f.refs)) {
39846
+ currentField._f.refs.forEach((inputRef) => {
39847
+ inputRef.disabled = currentField._f.disabled || disabled;
39848
+ });
39849
+ }
39850
+ }
39851
+ }, 0, false);
39852
+ }
39853
+ };
39854
+ const handleSubmit = (onValid, onInvalid) => async (e) => {
39855
+ let onValidError = undefined;
39856
+ if (e) {
39857
+ e.preventDefault && e.preventDefault();
39858
+ e.persist && e.persist();
39859
+ }
39860
+ let fieldValues = cloneObject(_formValues);
39861
+ if (_names.disabled.size) {
39862
+ for (const name of _names.disabled) {
39863
+ set(fieldValues, name, undefined);
39864
+ }
39865
+ }
39866
+ _subjects.state.next({
39867
+ isSubmitting: true,
39868
+ });
39869
+ if (_options.resolver) {
39870
+ const { errors, values } = await _executeSchema();
39871
+ _formState.errors = errors;
39872
+ fieldValues = values;
39873
+ }
39874
+ else {
39875
+ await executeBuiltInValidation(_fields);
39876
+ }
39877
+ unset(_formState.errors, 'root');
39878
+ if (isEmptyObject(_formState.errors)) {
39879
+ _subjects.state.next({
39880
+ errors: {},
39881
+ });
39882
+ try {
39883
+ await onValid(fieldValues, e);
39884
+ }
39885
+ catch (error) {
39886
+ onValidError = error;
39887
+ }
39888
+ }
39889
+ else {
39890
+ if (onInvalid) {
39891
+ await onInvalid({ ..._formState.errors }, e);
39892
+ }
39893
+ _focusError();
39894
+ setTimeout(_focusError);
39895
+ }
39896
+ _subjects.state.next({
39897
+ isSubmitted: true,
39898
+ isSubmitting: false,
39899
+ isSubmitSuccessful: isEmptyObject(_formState.errors) && !onValidError,
39900
+ submitCount: _formState.submitCount + 1,
39901
+ errors: _formState.errors,
39902
+ });
39903
+ if (onValidError) {
39904
+ throw onValidError;
39905
+ }
39906
+ };
39907
+ const resetField = (name, options = {}) => {
39908
+ if (get(_fields, name)) {
39909
+ if (isUndefined(options.defaultValue)) {
39910
+ setValue(name, cloneObject(get(_defaultValues, name)));
39911
+ }
39912
+ else {
39913
+ setValue(name, options.defaultValue);
39914
+ set(_defaultValues, name, cloneObject(options.defaultValue));
39915
+ }
39916
+ if (!options.keepTouched) {
39917
+ unset(_formState.touchedFields, name);
39918
+ }
39919
+ if (!options.keepDirty) {
39920
+ unset(_formState.dirtyFields, name);
39921
+ _formState.isDirty = options.defaultValue
39922
+ ? _getDirty(name, cloneObject(get(_defaultValues, name)))
39923
+ : _getDirty();
39924
+ }
39925
+ if (!options.keepError) {
39926
+ unset(_formState.errors, name);
39927
+ _proxyFormState.isValid && _updateValid();
39928
+ }
39929
+ _subjects.state.next({ ..._formState });
39930
+ }
39931
+ };
39932
+ const _reset = (formValues, keepStateOptions = {}) => {
39933
+ const updatedValues = formValues ? cloneObject(formValues) : _defaultValues;
39934
+ const cloneUpdatedValues = cloneObject(updatedValues);
39935
+ const isEmptyResetValues = isEmptyObject(formValues);
39936
+ const values = isEmptyResetValues ? _defaultValues : cloneUpdatedValues;
39937
+ if (!keepStateOptions.keepDefaultValues) {
39938
+ _defaultValues = updatedValues;
39939
+ }
39940
+ if (!keepStateOptions.keepValues) {
39941
+ if (keepStateOptions.keepDirtyValues) {
39942
+ const fieldsToCheck = new Set([
39943
+ ..._names.mount,
39944
+ ...Object.keys(getDirtyFields(_defaultValues, _formValues)),
39945
+ ]);
39946
+ for (const fieldName of Array.from(fieldsToCheck)) {
39947
+ get(_formState.dirtyFields, fieldName)
39948
+ ? set(values, fieldName, get(_formValues, fieldName))
39949
+ : setValue(fieldName, get(values, fieldName));
39950
+ }
39951
+ }
39952
+ else {
39953
+ if (isWeb && isUndefined(formValues)) {
39954
+ for (const name of _names.mount) {
39955
+ const field = get(_fields, name);
39956
+ if (field && field._f) {
39957
+ const fieldReference = Array.isArray(field._f.refs)
39958
+ ? field._f.refs[0]
39959
+ : field._f.ref;
39960
+ if (isHTMLElement(fieldReference)) {
39961
+ const form = fieldReference.closest('form');
39962
+ if (form) {
39963
+ form.reset();
39964
+ break;
39965
+ }
39966
+ }
39967
+ }
39968
+ }
39969
+ }
39970
+ _fields = {};
39971
+ }
39972
+ _formValues = _options.shouldUnregister
39973
+ ? keepStateOptions.keepDefaultValues
39974
+ ? cloneObject(_defaultValues)
39975
+ : {}
39976
+ : cloneObject(values);
39977
+ _subjects.array.next({
39978
+ values: { ...values },
39979
+ });
39980
+ _subjects.values.next({
39981
+ values: { ...values },
39982
+ });
39983
+ }
39984
+ _names = {
39985
+ mount: keepStateOptions.keepDirtyValues ? _names.mount : new Set(),
39986
+ unMount: new Set(),
39987
+ array: new Set(),
39988
+ disabled: new Set(),
39989
+ watch: new Set(),
39990
+ watchAll: false,
39991
+ focus: '',
39992
+ };
39993
+ _state.mount =
39994
+ !_proxyFormState.isValid ||
39995
+ !!keepStateOptions.keepIsValid ||
39996
+ !!keepStateOptions.keepDirtyValues;
39997
+ _state.watch = !!_options.shouldUnregister;
39998
+ _subjects.state.next({
39999
+ submitCount: keepStateOptions.keepSubmitCount
40000
+ ? _formState.submitCount
40001
+ : 0,
40002
+ isDirty: isEmptyResetValues
40003
+ ? false
40004
+ : keepStateOptions.keepDirty
40005
+ ? _formState.isDirty
40006
+ : !!(keepStateOptions.keepDefaultValues &&
40007
+ !deepEqual(formValues, _defaultValues)),
40008
+ isSubmitted: keepStateOptions.keepIsSubmitted
40009
+ ? _formState.isSubmitted
40010
+ : false,
40011
+ dirtyFields: isEmptyResetValues
40012
+ ? {}
40013
+ : keepStateOptions.keepDirtyValues
40014
+ ? keepStateOptions.keepDefaultValues && _formValues
40015
+ ? getDirtyFields(_defaultValues, _formValues)
40016
+ : _formState.dirtyFields
40017
+ : keepStateOptions.keepDefaultValues && formValues
40018
+ ? getDirtyFields(_defaultValues, formValues)
40019
+ : keepStateOptions.keepDirty
40020
+ ? _formState.dirtyFields
40021
+ : {},
40022
+ touchedFields: keepStateOptions.keepTouched
40023
+ ? _formState.touchedFields
40024
+ : {},
40025
+ errors: keepStateOptions.keepErrors ? _formState.errors : {},
40026
+ isSubmitSuccessful: keepStateOptions.keepIsSubmitSuccessful
40027
+ ? _formState.isSubmitSuccessful
40028
+ : false,
40029
+ isSubmitting: false,
40030
+ });
40031
+ };
40032
+ const reset = (formValues, keepStateOptions) => _reset(isFunction(formValues)
40033
+ ? formValues(_formValues)
40034
+ : formValues, keepStateOptions);
40035
+ const setFocus = (name, options = {}) => {
40036
+ const field = get(_fields, name);
40037
+ const fieldReference = field && field._f;
40038
+ if (fieldReference) {
40039
+ const fieldRef = fieldReference.refs
40040
+ ? fieldReference.refs[0]
40041
+ : fieldReference.ref;
40042
+ if (fieldRef.focus) {
40043
+ fieldRef.focus();
40044
+ options.shouldSelect &&
40045
+ isFunction(fieldRef.select) &&
40046
+ fieldRef.select();
40047
+ }
40048
+ }
40049
+ };
40050
+ const _updateFormState = (updatedFormState) => {
40051
+ _formState = {
40052
+ ..._formState,
40053
+ ...updatedFormState,
40054
+ };
40055
+ };
40056
+ const _resetDefaultValues = () => isFunction(_options.defaultValues) &&
40057
+ _options.defaultValues().then((values) => {
40058
+ reset(values, _options.resetOptions);
40059
+ _subjects.state.next({
40060
+ isLoading: false,
40061
+ });
40062
+ });
40063
+ return {
40064
+ control: {
40065
+ register,
40066
+ unregister,
40067
+ getFieldState,
40068
+ handleSubmit,
40069
+ setError,
40070
+ _executeSchema,
40071
+ _getWatch,
40072
+ _getDirty,
40073
+ _updateValid,
40074
+ _removeUnmounted,
40075
+ _updateFieldArray,
40076
+ _updateDisabledField,
40077
+ _getFieldArray,
40078
+ _reset,
40079
+ _resetDefaultValues,
40080
+ _updateFormState,
40081
+ _disableForm,
40082
+ _subjects,
40083
+ _proxyFormState,
40084
+ _setErrors,
40085
+ get _fields() {
40086
+ return _fields;
40087
+ },
40088
+ get _formValues() {
40089
+ return _formValues;
40090
+ },
40091
+ get _state() {
40092
+ return _state;
40093
+ },
40094
+ set _state(value) {
40095
+ _state = value;
40096
+ },
40097
+ get _defaultValues() {
40098
+ return _defaultValues;
40099
+ },
40100
+ get _names() {
40101
+ return _names;
40102
+ },
40103
+ set _names(value) {
40104
+ _names = value;
40105
+ },
40106
+ get _formState() {
40107
+ return _formState;
40108
+ },
40109
+ set _formState(value) {
40110
+ _formState = value;
40111
+ },
40112
+ get _options() {
40113
+ return _options;
40114
+ },
40115
+ set _options(value) {
40116
+ _options = {
40117
+ ..._options,
40118
+ ...value,
40119
+ };
40120
+ },
40121
+ },
40122
+ trigger,
40123
+ register,
40124
+ handleSubmit,
40125
+ watch,
40126
+ setValue,
40127
+ getValues,
40128
+ reset,
40129
+ resetField,
40130
+ clearErrors,
40131
+ unregister,
40132
+ setError,
40133
+ setFocus,
40134
+ getFieldState,
40135
+ };
40136
+ }
40137
+
40138
+ /**
40139
+ * Custom hook to manage the entire form.
40140
+ *
40141
+ * @remarks
40142
+ * [API](https://react-hook-form.com/docs/useform) • [Demo](https://codesandbox.io/s/react-hook-form-get-started-ts-5ksmm) • [Video](https://www.youtube.com/watch?v=RkXv4AXXC_4)
40143
+ *
40144
+ * @param props - form configuration and validation parameters.
40145
+ *
40146
+ * @returns methods - individual functions to manage the form state. {@link UseFormReturn}
40147
+ *
40148
+ * @example
40149
+ * ```tsx
40150
+ * function App() {
40151
+ * const { register, handleSubmit, watch, formState: { errors } } = useForm();
40152
+ * const onSubmit = data => console.log(data);
40153
+ *
40154
+ * console.log(watch("example"));
40155
+ *
40156
+ * return (
40157
+ * <form onSubmit={handleSubmit(onSubmit)}>
40158
+ * <input defaultValue="test" {...register("example")} />
40159
+ * <input {...register("exampleRequired", { required: true })} />
40160
+ * {errors.exampleRequired && <span>This field is required</span>}
40161
+ * <button>Submit</button>
40162
+ * </form>
40163
+ * );
40164
+ * }
40165
+ * ```
40166
+ */
40167
+ function useForm(props = {}) {
40168
+ const _formControl = React$1.useRef(undefined);
40169
+ const _values = React$1.useRef(undefined);
40170
+ const [formState, updateFormState] = React$1.useState({
40171
+ isDirty: false,
40172
+ isValidating: false,
40173
+ isLoading: isFunction(props.defaultValues),
40174
+ isSubmitted: false,
40175
+ isSubmitting: false,
40176
+ isSubmitSuccessful: false,
40177
+ isValid: false,
40178
+ submitCount: 0,
40179
+ dirtyFields: {},
40180
+ touchedFields: {},
40181
+ validatingFields: {},
40182
+ errors: props.errors || {},
40183
+ disabled: props.disabled || false,
40184
+ defaultValues: isFunction(props.defaultValues)
40185
+ ? undefined
40186
+ : props.defaultValues,
40187
+ });
40188
+ if (!_formControl.current) {
40189
+ _formControl.current = {
40190
+ ...createFormControl(props),
40191
+ formState,
40192
+ };
40193
+ }
40194
+ const control = _formControl.current.control;
40195
+ control._options = props;
40196
+ useSubscribe({
40197
+ subject: control._subjects.state,
40198
+ next: (value) => {
40199
+ if (shouldRenderFormState(value, control._proxyFormState, control._updateFormState, true)) {
40200
+ updateFormState({ ...control._formState });
40201
+ }
40202
+ },
40203
+ });
40204
+ React$1.useEffect(() => control._disableForm(props.disabled), [control, props.disabled]);
40205
+ React$1.useEffect(() => {
40206
+ if (control._proxyFormState.isDirty) {
40207
+ const isDirty = control._getDirty();
40208
+ if (isDirty !== formState.isDirty) {
40209
+ control._subjects.state.next({
40210
+ isDirty,
40211
+ });
40212
+ }
40213
+ }
40214
+ }, [control, formState.isDirty]);
40215
+ React$1.useEffect(() => {
40216
+ if (props.values && !deepEqual(props.values, _values.current)) {
40217
+ control._reset(props.values, control._options.resetOptions);
40218
+ _values.current = props.values;
40219
+ updateFormState((state) => ({ ...state }));
40220
+ }
40221
+ else {
40222
+ control._resetDefaultValues();
40223
+ }
40224
+ }, [props.values, control]);
40225
+ React$1.useEffect(() => {
40226
+ if (props.errors) {
40227
+ control._setErrors(props.errors);
40228
+ }
40229
+ }, [props.errors, control]);
40230
+ React$1.useEffect(() => {
40231
+ if (!control._state.mount) {
40232
+ control._updateValid();
40233
+ control._state.mount = true;
40234
+ }
40235
+ if (control._state.watch) {
40236
+ control._state.watch = false;
40237
+ control._subjects.state.next({ ...control._formState });
40238
+ }
40239
+ control._removeUnmounted();
40240
+ });
40241
+ React$1.useEffect(() => {
40242
+ props.shouldUnregister &&
40243
+ control._subjects.values.next({
40244
+ values: control._getWatch(),
40245
+ });
40246
+ }, [props.shouldUnregister, control]);
40247
+ _formControl.current.formState = getProxyFormState(formState, control);
40248
+ return _formControl.current;
40249
+ }
40250
+
37988
40251
  const RangePopContainer = styled.div`
37989
40252
  font-family: 'Poppins', sans-serif;
37990
40253
  font-size: 14px;
@@ -37996,6 +40259,17 @@ const RangePopContainer = styled.div`
37996
40259
  border-radius: 4px;
37997
40260
  box-shadow: 0px 4px 20px 0px rgba(0, 0, 0, 0.10);
37998
40261
  `;
40262
+ // הוסף את זה לקובץ RangePop.style.js הקיים שלך:
40263
+
40264
+ const ErrorText = styled.span`
40265
+ color: #e53935;
40266
+ font-size: 11px;
40267
+ display: block;
40268
+ margin-top: 4px;
40269
+ line-height: 1.2;
40270
+ position: absolute;
40271
+ white-space: nowrap;
40272
+ `;
37999
40273
  const Title$4 = styled.h6`
38000
40274
  font-size: 16px;
38001
40275
  font-weight: 700;
@@ -38019,13 +40293,19 @@ const Input$1 = styled.input`
38019
40293
  width: 64px;
38020
40294
  padding: 10px 8px;
38021
40295
  border-radius: 8px;
38022
- border: 1px solid #8B8989;
38023
40296
  outline: none;
38024
40297
  transition: border 0.18s;
38025
40298
  ${props => props.error && `
38026
40299
  border-color: #e74c3c;
38027
40300
  background: #fff5f5;
38028
40301
  `}
40302
+
40303
+ border: 1px solid ${props => props.error ? '#e53935' : '#ccc'};
40304
+
40305
+ &:focus {
40306
+ outline: none;
40307
+ border-color: ${props => props.error ? '#e53935' : '#066768'};
40308
+ }
38029
40309
  `;
38030
40310
  const RadioWrapper = styled.div`
38031
40311
  display: flex;
@@ -38044,7 +40324,7 @@ const Actions$1 = styled.div`
38044
40324
  justify-content: space-between;
38045
40325
  padding-top: 12px;
38046
40326
  `;
38047
- const ClearButton = styled.button`
40327
+ styled.button`
38048
40328
  font-size: 16px;
38049
40329
  border: none;
38050
40330
  cursor: pointer;
@@ -38061,85 +40341,198 @@ styled.button`
38061
40341
  opacity: ${props => props.disabled ? 0.6 : 1};
38062
40342
  `;
38063
40343
 
38064
- function validateField$1(value, param) {
38065
- if (value === '' || value === null || value === undefined) return 'Required';
38066
- if (isNaN(value)) return 'Must be a number';
38067
- if (Number(value) < 0) return 'Must be positive';
38068
- if (param.type === 'percent' && Number(value) > 100) return 'Max 100%';
38069
- return null;
38070
- }
38071
40344
  const RangePop = props => {
38072
40345
  const {
38073
40346
  menuName,
38074
- width = '240px',
38075
- height = 'auto',
38076
- radioOptions = ['Absolute', 'Percent'],
40347
+ width = "240px",
40348
+ height = "auto",
40349
+ radioOptions = ["All weeks", "Custom Range"],
38077
40350
  params = [],
38078
- paramType = 'Week',
40351
+ paramType = "Week",
38079
40352
  onApply = () => {},
38080
- buttonColor = '#066768',
38081
- hoverColor = '#066768'
40353
+ buttonColor = "#066768",
40354
+ hoverColor = "#066768",
40355
+ initialValues = null
38082
40356
  } = props;
38083
- const [selectedRadio, setSelectedRadio] = useState(radioOptions[0].toLowerCase());
38084
- const [fields, setFields] = useState(() => params.map(() => ''));
38085
- const [touched, setTouched] = useState(() => params.map(() => false));
38086
- const errors = fields.map((val, idx) => touched[idx] ? validateField$1(val, params[idx]) : null);
38087
- const isValid = errors.every(e => !e);
38088
- const handleChange = (idx, val) => {
38089
- setFields(prev => prev.map((f, i) => i === idx ? val : f));
40357
+ const [selectedRadio, setSelectedRadio] = useState(initialValues?.selectedRadio || radioOptions[0].toLowerCase());
40358
+ const {
40359
+ control,
40360
+ handleSubmit,
40361
+ watch,
40362
+ reset,
40363
+ formState: {
40364
+ errors,
40365
+ isValid
40366
+ },
40367
+ trigger,
40368
+ setValue
40369
+ } = useForm({
40370
+ mode: "onChange",
40371
+ // Validate on change
40372
+ defaultValues: {
40373
+ ...params.reduce((acc, param, idx) => {
40374
+ acc[`field_${idx}`] = initialValues?.fields?.[idx] || "";
40375
+ return acc;
40376
+ }, {})
40377
+ }
40378
+ });
40379
+ const isCustomRange = selectedRadio.toLowerCase() === "custom range";
40380
+ const watchedFields = watch();
40381
+
40382
+ // Check if all fields are filled
40383
+ const allFieldsFilled = params.every((_, idx) => {
40384
+ const value = watchedFields[`field_${idx}`];
40385
+ return value !== "" && value !== null && value !== undefined;
40386
+ });
40387
+
40388
+ // Apply button logic
40389
+ const isApplyEnabled = isCustomRange ? allFieldsFilled && isValid : true;
40390
+
40391
+ // Update form when initialValues change
40392
+ useEffect(() => {
40393
+ if (initialValues) {
40394
+ if (initialValues.selectedRadio) {
40395
+ setSelectedRadio(initialValues.selectedRadio);
40396
+ }
40397
+ if (initialValues.fields) {
40398
+ initialValues.fields.forEach((value, idx) => {
40399
+ setValue(`field_${idx}`, value);
40400
+ });
40401
+ }
40402
+ }
40403
+ }, [initialValues, setValue]);
40404
+ const handleRadioChange = option => {
40405
+ setSelectedRadio(option.toLowerCase());
38090
40406
  };
38091
- const handleBlur = idx => {
38092
- setTouched(prev => prev.map((t, i) => i === idx ? true : t));
40407
+ const onSubmit = data => {
40408
+ if (isCustomRange) {
40409
+ const fields = params.map((_, idx) => data[`field_${idx}`]);
40410
+ onApply({
40411
+ selectedRadio,
40412
+ fields
40413
+ });
40414
+ } else {
40415
+ onApply({
40416
+ selectedRadio
40417
+ });
40418
+ }
40419
+ };
40420
+ const handleCancel = () => {
40421
+ reset();
40422
+ setSelectedRadio(radioOptions[0].toLowerCase());
40423
+ };
40424
+
40425
+ // Validation rules
40426
+ const getValidationRules = (param, idx) => {
40427
+ return {
40428
+ validate: {
40429
+ required: value => {
40430
+ if (!isCustomRange) return true;
40431
+ if (value === "" || value === null || value === undefined) {
40432
+ return "Required";
40433
+ }
40434
+ return true;
40435
+ },
40436
+ isNumber: value => {
40437
+ if (!isCustomRange || !value) return true;
40438
+ if (isNaN(value)) return "Invalid input. Numbers only";
40439
+ return true;
40440
+ },
40441
+ weekRange: value => {
40442
+ if (!isCustomRange || !value || param.type !== "week") return true;
40443
+ const numValue = Number(value);
40444
+ if (numValue < 1 || numValue > 53) return "Invalid Week";
40445
+ return true;
40446
+ },
40447
+ percentRange: value => {
40448
+ if (!isCustomRange || !value || param.type !== "percent") return true;
40449
+ const numValue = Number(value);
40450
+ if (numValue < 0) return "Must be positive";
40451
+ if (numValue > 100) return "Max 100%";
40452
+ return true;
40453
+ },
40454
+ rangeValidation: value => {
40455
+ if (!isCustomRange || !value || param.label !== "To") return true;
40456
+ const fromValue = watchedFields[`field_0`];
40457
+ if (fromValue && fromValue !== "") {
40458
+ const numFrom = Number(fromValue);
40459
+ const numTo = Number(value);
40460
+ if (!isNaN(numFrom) && !isNaN(numTo) && numTo < numFrom) {
40461
+ return "Invalid Range";
40462
+ }
40463
+ }
40464
+ return true;
40465
+ }
40466
+ }
40467
+ };
38093
40468
  };
38094
40469
  return /*#__PURE__*/React$1.createElement(RangePopContainer, {
38095
40470
  width: width,
38096
40471
  height: height
38097
40472
  }, /*#__PURE__*/React$1.createElement(Title$4, null, menuName), /*#__PURE__*/React$1.createElement("form", {
38098
- onSubmit: e => {
38099
- e.preventDefault();
38100
- if (isValid) onApply(fields);
38101
- }
38102
- }, /*#__PURE__*/React$1.createElement(RadioWrapper, null, radioOptions.map((option, idx) => /*#__PURE__*/React$1.createElement(Label$2, {
40473
+ onSubmit: handleSubmit(onSubmit)
40474
+ }, /*#__PURE__*/React$1.createElement(RadioWrapper, null, radioOptions.map(option => /*#__PURE__*/React$1.createElement(Label$2, {
38103
40475
  key: option
38104
40476
  }, /*#__PURE__*/React$1.createElement(Radio, {
38105
40477
  type: "radio",
38106
40478
  name: "range-type",
38107
40479
  value: option.toLowerCase(),
38108
40480
  checked: selectedRadio === option.toLowerCase(),
38109
- onChange: () => setSelectedRadio(option.toLowerCase()),
40481
+ onChange: () => handleRadioChange(option),
38110
40482
  style: {
38111
40483
  accentColor: buttonColor
38112
40484
  }
38113
- }), option))), /*#__PURE__*/React$1.createElement(FieldRow$1, null, params.map((param, idx) => /*#__PURE__*/React$1.createElement(React$1.Fragment, {
40485
+ }), option))), isCustomRange && /*#__PURE__*/React$1.createElement(FieldRow$1, null, params.map((param, idx) => /*#__PURE__*/React$1.createElement(React$1.Fragment, {
38114
40486
  key: param.label
38115
40487
  }, /*#__PURE__*/React$1.createElement(Label$2, {
38116
40488
  htmlFor: `param-${idx}`
38117
- }, param.label), /*#__PURE__*/React$1.createElement(Input$1, {
38118
- id: `param-${idx}`,
38119
- type: "number",
38120
- value: fields[idx],
38121
- error: !!errors[idx],
38122
- onChange: e => handleChange(idx, e.target.value),
38123
- onBlur: () => handleBlur(idx),
38124
- min: 0,
38125
- max: param.type === 'percent' ? 100 : undefined
38126
- }))), /*#__PURE__*/React$1.createElement(Label$2, null, paramType)), /*#__PURE__*/React$1.createElement(Actions$1, null, /*#__PURE__*/React$1.createElement(ClearButton, {
38127
- type: "button",
38128
- onClick: () => {
38129
- setFields(params.map(() => ''));
38130
- setTouched(params.map(() => false));
40489
+ }, param.label), /*#__PURE__*/React$1.createElement("div", {
40490
+ style: {
40491
+ position: "relative",
40492
+ display: "inline-block"
40493
+ }
40494
+ }, /*#__PURE__*/React$1.createElement(Controller, {
40495
+ name: `field_${idx}`,
40496
+ control: control,
40497
+ rules: getValidationRules(param),
40498
+ render: _ref => {
40499
+ let {
40500
+ field
40501
+ } = _ref;
40502
+ return /*#__PURE__*/React$1.createElement(Input$1, _extends$1({}, field, {
40503
+ id: `param-${idx}`,
40504
+ type: "number",
40505
+ error: !!errors[`field_${idx}`],
40506
+ onChange: e => {
40507
+ field.onChange(e.target.value);
40508
+ // Trigger validation on the "To" field when "From" changes
40509
+ if (param.label === "From") {
40510
+ trigger(`field_1`);
40511
+ }
40512
+ },
40513
+ min: param.type === "week" ? 1 : 0,
40514
+ max: param.type === "percent" ? 100 : param.type === "week" ? 53 : undefined
40515
+ }));
38131
40516
  }
38132
- }, "Cancel"), /*#__PURE__*/React$1.createElement(Button$1, {
40517
+ }), errors[`field_${idx}`] && /*#__PURE__*/React$1.createElement(ErrorText, null, errors[`field_${idx}`]?.message)))), /*#__PURE__*/React$1.createElement(Label$2, null, paramType)), /*#__PURE__*/React$1.createElement(Actions$1, null, /*#__PURE__*/React$1.createElement(LinkButton, {
40518
+ leftIcon: "none",
40519
+ onClick: handleCancel,
40520
+ rightIcon: "none",
40521
+ size: "small",
40522
+ text: "Cancel",
40523
+ textColor: "#000000",
40524
+ type: "primary"
40525
+ }), /*#__PURE__*/React$1.createElement(Button$1, {
38133
40526
  isSubmitButton: true,
38134
40527
  text: "Apply",
40528
+ size: "small",
38135
40529
  borderRadius: "8px",
38136
40530
  textColor: "#fff",
38137
40531
  backgroundColor: buttonColor,
38138
40532
  borderColor: buttonColor,
38139
40533
  hoverBackgroundColor: hoverColor,
38140
40534
  hoverBorderColor: hoverColor,
38141
- disabled: !isValid,
38142
- onClick: () => onApply(fields)
40535
+ disabled: !isApplyEnabled
38143
40536
  }))));
38144
40537
  };
38145
40538
 
@@ -38394,8 +40787,9 @@ const TableHeader = ({
38394
40787
  // Add persistent filter selections state
38395
40788
  const [filterSelections, setFilterSelections] = useState({});
38396
40789
 
38397
- // Add persistent sort selections state
38398
- const [sortSelections, setSortSelections] = useState({});
40790
+ // MODIFIED: Changed to track only ONE active sort (single column key and value)
40791
+ const [activeSortColumn, setActiveSortColumn] = useState(null); // Only one column key
40792
+ const [activeSortValue, setActiveSortValue] = useState(null); // Only one sort value
38399
40793
 
38400
40794
  // Refs to track icon button positions
38401
40795
  const iconRefs = useRef({});
@@ -38406,7 +40800,6 @@ const TableHeader = ({
38406
40800
  // Initialize filter selections for each column
38407
40801
  useEffect(() => {
38408
40802
  const initialFilterSelections = {};
38409
- const initialSortSelections = {};
38410
40803
  columns.forEach(column => {
38411
40804
  // Initialize filter selections
38412
40805
  if (column.filter && column.filterOptions) {
@@ -38421,14 +40814,8 @@ const TableHeader = ({
38421
40814
  });
38422
40815
  initialFilterSelections[column.key] = initialState;
38423
40816
  }
38424
-
38425
- // Initialize sort selections (null = no sort selected)
38426
- if (column.sort && column.sortOptions) {
38427
- initialSortSelections[column.key] = null;
38428
- }
38429
40817
  });
38430
40818
  setFilterSelections(initialFilterSelections);
38431
- setSortSelections(initialSortSelections);
38432
40819
  }, [columns]);
38433
40820
 
38434
40821
  // Helper function to check if filter is in default state (all items selected)
@@ -38438,6 +40825,11 @@ const TableHeader = ({
38438
40825
  return true; // No filter applied
38439
40826
  }
38440
40827
 
40828
+ // For range filters, check if "All weeks" is selected
40829
+ if (filterData.selectedRadio) {
40830
+ return filterData.selectedRadio === 'all weeks';
40831
+ }
40832
+
38441
40833
  // Check if it's in "select all" state with no exclusions
38442
40834
  return filterData.isSelectAll && filterData.excluded?.length === 0 && filterData.included?.length === 0;
38443
40835
  };
@@ -38551,8 +40943,6 @@ const TableHeader = ({
38551
40943
  }
38552
40944
  setVisibleSortPopWrapper(prevKey => prevKey === key ? null : key);
38553
40945
  setVisibleFilterPopWrapper(null); // Hide filter PopWrapper when sort PopWrapper is shown
38554
-
38555
- // Remove onSort call - we only want to call it when selection is made
38556
40946
  };
38557
40947
  useEffect(() => {
38558
40948
  if (Object.keys(filterState).length > 0) {
@@ -38569,12 +40959,18 @@ const TableHeader = ({
38569
40959
  setVisibleSortPopWrapper(null); // Hide sort PopWrapper when filter PopWrapper is shown
38570
40960
  };
38571
40961
 
38572
- // Handle sort selection changes - Updated to call onSort with both columnKey and sortValue
40962
+ // MODIFIED: Handle sort selection - Reset previous sort and apply new one
38573
40963
  const handleSortSelectionChange = (columnKey, sortValue) => {
38574
- setSortSelections(prev => ({
38575
- ...prev,
38576
- [columnKey]: sortValue
38577
- }));
40964
+ // If selecting a new column, reset the previous sort
40965
+ if (activeSortColumn && activeSortColumn !== columnKey) {
40966
+ // Clear the previous sort
40967
+ setActiveSortColumn(columnKey);
40968
+ setActiveSortValue(sortValue);
40969
+ } else {
40970
+ // Same column or first sort
40971
+ setActiveSortColumn(columnKey);
40972
+ setActiveSortValue(sortValue);
40973
+ }
38578
40974
 
38579
40975
  // Close the popup after selection
38580
40976
  setVisibleSortPopWrapper(null);
@@ -38585,12 +40981,11 @@ const TableHeader = ({
38585
40981
  }
38586
40982
  };
38587
40983
 
38588
- // Handle sort reset - Updated to call onSort when reset
40984
+ // MODIFIED: Handle sort reset - Clear the active sort
38589
40985
  const handleSortReset = columnKey => {
38590
- setSortSelections(prev => ({
38591
- ...prev,
38592
- [columnKey]: null
38593
- }));
40986
+ // Clear the active sort state
40987
+ setActiveSortColumn(null);
40988
+ setActiveSortValue(null);
38594
40989
 
38595
40990
  // Call onSort to notify that sort was reset
38596
40991
  if (onSort) {
@@ -38722,10 +41117,12 @@ const TableHeader = ({
38722
41117
  const shouldShowActiveIcon = key => {
38723
41118
  return isFilterActive(key) || isFilterFocused(key);
38724
41119
  };
41120
+
41121
+ // MODIFIED: Check if THIS specific column has an active sort
38725
41122
  const shouldShowActiveSortIcon = key => {
38726
41123
  const isFocused = focusedSort === key;
38727
41124
  const isActive = activeSorts.includes(key);
38728
- const hasSelection = sortSelections[key] !== null && sortSelections[key] !== undefined;
41125
+ const hasSelection = activeSortColumn === key && activeSortValue !== null;
38729
41126
  return isFocused || isActive || hasSelection;
38730
41127
  };
38731
41128
 
@@ -38743,7 +41140,7 @@ const TableHeader = ({
38743
41140
  }
38744
41141
  };
38745
41142
 
38746
- // Update showColumnFilter to pass current filterSelections to stateless FilterPop
41143
+ // UPDATED: showColumnFilter with fixed RangePop integration
38747
41144
  const showColumnFilter = column => {
38748
41145
  const {
38749
41146
  key,
@@ -38778,32 +41175,39 @@ const TableHeader = ({
38778
41175
  }
38779
41176
  });
38780
41177
  } else if (rangeFilter) {
41178
+ // Get the current filter state for this column to persist values
41179
+ const currentFilterState = filterState[key];
38781
41180
  return /*#__PURE__*/React$1.createElement(RangePop, {
38782
41181
  menuName: title,
38783
41182
  width: "300px",
38784
41183
  height: "auto",
38785
41184
  buttonColor: "#066768",
38786
- hoverColor: "#066768",
41185
+ hoverColor: "#044d4e",
38787
41186
  paramType: "Week",
38788
- range: rangeFilter,
38789
- selectedRange: filterState[key] || {},
38790
41187
  params: [{
38791
41188
  label: 'From',
38792
- type: 'date'
41189
+ type: 'week' // FIXED: Changed from 'date' to 'week'
38793
41190
  }, {
38794
41191
  label: 'To',
38795
- type: 'date'
41192
+ type: 'week' // FIXED: Changed from 'date' to 'week'
38796
41193
  }],
38797
- radioOptions: ['All weeks', 'Custom Range'],
38798
- onApply: range => {
41194
+ radioOptions: ['All weeks', 'Custom Range']
41195
+ // ADDED: Pass initialValues for persistence
41196
+ ,
41197
+ initialValues: currentFilterState ? {
41198
+ selectedRadio: currentFilterState.selectedRadio,
41199
+ fields: currentFilterState.fields
41200
+ } : null,
41201
+ onApply: data => {
41202
+ // data contains: { selectedRadio, fields }
38799
41203
  setFilterState(prev => ({
38800
41204
  ...prev,
38801
- [key]: range
41205
+ [key]: data
38802
41206
  }));
41207
+
41208
+ // Close the popup after applying
41209
+ setVisibleFilterPopWrapper(null);
38803
41210
  }
38804
- // onCancel={() => {
38805
- // setFilterState((prev) => ({ ...prev, [key]: {} }));
38806
- // }}
38807
41211
  });
38808
41212
  } else {
38809
41213
  return /*#__PURE__*/React$1.createElement(FilterPop, {
@@ -38820,6 +41224,8 @@ const TableHeader = ({
38820
41224
  });
38821
41225
  }
38822
41226
  };
41227
+
41228
+ // MODIFIED: Pass the selected value only for the active sort column
38823
41229
  const showColumnSort = column => {
38824
41230
  const {
38825
41231
  key,
@@ -38829,13 +41235,16 @@ const TableHeader = ({
38829
41235
  if (!sortOptions || sortOptions.length === 0) {
38830
41236
  return null;
38831
41237
  }
41238
+
41239
+ // Only show selected value if this is the active sort column
41240
+ const selectedValue = activeSortColumn === key ? activeSortValue : null;
38832
41241
  return /*#__PURE__*/React$1.createElement(SortPop, {
38833
41242
  width: "300px",
38834
41243
  height: "auto",
38835
41244
  color: "#066768",
38836
41245
  list: sortOptions,
38837
41246
  menuName: title,
38838
- selectedValue: sortSelections[key] || null,
41247
+ selectedValue: selectedValue,
38839
41248
  onCheck: sortValue => handleSortSelectionChange(key, sortValue),
38840
41249
  onReset: () => handleSortReset(key)
38841
41250
  });
@@ -38862,10 +41271,8 @@ const TableHeader = ({
38862
41271
  width: '18px',
38863
41272
  height: '18px',
38864
41273
  marginLeft: '10px',
38865
- // Moved 5px more to the right (was 5px)
38866
41274
  cursor: 'pointer',
38867
41275
  accentColor: '#066768',
38868
- // Use the same green color as row checkboxes
38869
41276
  display: 'flex',
38870
41277
  alignItems: 'center',
38871
41278
  justifyContent: 'center'
@@ -54853,7 +57260,7 @@ const DropdownContainer = styled.div`
54853
57260
  `;
54854
57261
  const DropdownButton = styled.button`
54855
57262
  width: 100%;
54856
- background: #fff;
57263
+ background: ${props => props.isDarkerBackground ? '#F2F2F2' : '#fff'};
54857
57264
  border: 1px solid #8B8989;
54858
57265
  border-radius: 12px;
54859
57266
  padding: 17px;
@@ -54866,7 +57273,7 @@ const DropdownButton = styled.button`
54866
57273
  ${props => props.disabled && css`
54867
57274
  color: #D0D0D0;
54868
57275
  cursor: not-allowed;
54869
- border: 1px solid #D0D0D0;
57276
+ border: 1px solid #D9D9D9;
54870
57277
  background: ${props => props.isDarkerBackground ? '#F2F2F2' : '#fff'};
54871
57278
  `}
54872
57279
  `;
@@ -54975,8 +57382,8 @@ const Label$1 = styled.label`
54975
57382
  padding-inline-start: 5px;
54976
57383
  margin-right: 10px;
54977
57384
  z-index: 2;
54978
- color: ${props => props.error ? 'red' : props.disabled ? '#888' : props.labelColor};
54979
- background-color: ${props => props.disabled ? '#F2F2F2' : props.showLabelOnTop ? 'white' : 'transparent'};
57385
+ color: ${props => props.error ? 'red' : props.disabled ? '#D0D0D0' : props.labelColor};
57386
+ background-color: ${props => props.isDarkerBackground ? '#F2F2F2' : props.showLabelOnTop ? 'white' : 'transparent'};
54980
57387
  position: absolute;
54981
57388
  top: ${props => props.isFocused || props.hasValue ? '0px' : '50%'};
54982
57389
  left: ${props => props.isFocused || props.hasValue ? '23px' : '14px'};
@@ -55507,7 +57914,8 @@ const OverlayDropdown = _ref => {
55507
57914
  labelColor: labelColor,
55508
57915
  hasValue: hasValue,
55509
57916
  disabled: disabled,
55510
- showLabelOnTop: showLabelOnTop
57917
+ showLabelOnTop: showLabelOnTop,
57918
+ isDarkerBackground: isDarkerBackground
55511
57919
  }, getLabel(), getRequired()), /*#__PURE__*/React$1.createElement(DropdownButton, {
55512
57920
  ref: buttonRef,
55513
57921
  onClick: toggleDropdown,