@@ -47,8 +47,9 @@ const OptionList: React.ForwardRefRenderFunction<ReviseRefOptionListProps> = (_,
47
47
treeExpandAction,
48
48
treeTitleRender,
49
49
onPopupScroll,
50
- displayValues,
51
- isOverMaxCount,
50
+ leftMaxCount,
51
+ leafCountOnly,
52
+ valueEntities,
52
53
} = React . useContext ( TreeSelectContext ) ;
53
54
54
55
const {
@@ -80,11 +81,6 @@ const OptionList: React.ForwardRefRenderFunction<ReviseRefOptionListProps> = (_,
80
81
( prev , next ) => next [ 0 ] && prev [ 1 ] !== next [ 1 ] ,
81
82
) ;
82
83
83
- const memoRawValues = React . useMemo (
84
- ( ) => ( displayValues || [ ] ) . map ( v => v . value ) ,
85
- [ displayValues ] ,
86
- ) ;
87
-
88
84
// ========================== Values ==========================
89
85
const mergedCheckedKeys = React . useMemo ( ( ) => {
90
86
if ( ! checkable ) {
@@ -163,8 +159,60 @@ const OptionList: React.ForwardRefRenderFunction<ReviseRefOptionListProps> = (_,
163
159
// eslint-disable-next-line react-hooks/exhaustive-deps
164
160
} , [ searchValue ] ) ;
165
161
162
+ // ========================= Disabled =========================
163
+ const disabledCacheRef = React . useRef < Map < string , boolean > > ( new Map ( ) ) ;
164
+
165
+ // Clear cache if `leftMaxCount` changed
166
+ React . useEffect ( ( ) => {
167
+ if ( leftMaxCount ) {
168
+ disabledCacheRef . current . clear ( ) ;
169
+ }
170
+ } , [ leftMaxCount ] ) ;
171
+
172
+ function getDisabledWithCache ( node : DataNode ) {
173
+ const value = node [ fieldNames . value ] ;
174
+ if ( ! disabledCacheRef . current . has ( value ) ) {
175
+ const entity = valueEntities . get ( value ) ;
176
+ const isLeaf = ( entity . children || [ ] ) . length === 0 ;
177
+
178
+ if ( ! isLeaf ) {
179
+ const checkableChildren = entity . children . filter (
180
+ childTreeNode =>
181
+ ! childTreeNode . node . disabled &&
182
+ ! childTreeNode . node . disableCheckbox &&
183
+ ! checkedKeys . includes ( childTreeNode . node [ fieldNames . value ] ) ,
184
+ ) ;
185
+
186
+ const checkableChildrenCount = checkableChildren . length ;
187
+ disabledCacheRef . current . set ( value , checkableChildrenCount > leftMaxCount ) ;
188
+ } else {
189
+ disabledCacheRef . current . set ( value , false ) ;
190
+ }
191
+ }
192
+ return disabledCacheRef . current . get ( value ) ;
193
+ }
194
+
166
195
const nodeDisabled = useEvent ( ( node : DataNode ) => {
167
- return isOverMaxCount && ! memoRawValues . includes ( node [ fieldNames . value ] ) ;
196
+ const nodeValue = node [ fieldNames . value ] ;
197
+
198
+ if ( checkedKeys . includes ( nodeValue ) ) {
199
+ return false ;
200
+ }
201
+
202
+ if ( leftMaxCount === null ) {
203
+ return false ;
204
+ }
205
+
206
+ if ( leftMaxCount <= 0 ) {
207
+ return true ;
208
+ }
209
+
210
+ // This is a low performance calculation
211
+ if ( leafCountOnly && leftMaxCount ) {
212
+ return getDisabledWithCache ( node ) ;
213
+ }
214
+
215
+ return false ;
168
216
} ) ;
169
217
170
218
// ========================== Get First Selectable Node ==========================
0 commit comments