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