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