@@ -47,8 +47,9 @@ const OptionList: React.ForwardRefRenderFunction<ReviseRefOptionListProps> = (_,
4747 treeExpandAction,
4848 treeTitleRender,
4949 onPopupScroll,
50- displayValues,
51- isOverMaxCount,
50+ leftMaxCount,
51+ leafCountOnly,
52+ valueEntities,
5253 } = React . useContext ( TreeSelectContext ) ;
5354
5455 const {
@@ -80,11 +81,6 @@ const OptionList: React.ForwardRefRenderFunction<ReviseRefOptionListProps> = (_,
8081 ( prev , next ) => next [ 0 ] && prev [ 1 ] !== next [ 1 ] ,
8182 ) ;
8283
83- const memoRawValues = React . useMemo (
84- ( ) => ( displayValues || [ ] ) . map ( v => v . value ) ,
85- [ displayValues ] ,
86- ) ;
87-
8884 // ========================== Values ==========================
8985 const mergedCheckedKeys = React . useMemo ( ( ) => {
9086 if ( ! checkable ) {
@@ -163,8 +159,60 @@ const OptionList: React.ForwardRefRenderFunction<ReviseRefOptionListProps> = (_,
163159 // eslint-disable-next-line react-hooks/exhaustive-deps
164160 } , [ searchValue ] ) ;
165161
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+
166195 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 ;
168216 } ) ;
169217
170218 // ========================== Get First Selectable Node ==========================
0 commit comments