@@ -99,20 +99,20 @@ class CheckboxTree extends React.Component {
9999 this . deserializeLists ( { checked, expanded } ) ;
100100 }
101101
102- onCheck ( node ) {
103- // node is object from TreeNode
102+ onCheck ( nodeInfo ) {
104103 const { noCascade, onCheck } = this . props ;
104+ const node = this . flatNodes [ nodeInfo . value ] ;
105105
106- this . toggleChecked ( node , node . checked , noCascade ) ;
107- onCheck ( this . serializeList ( 'checked' ) , node ) ;
106+ this . toggleChecked ( nodeInfo , nodeInfo . checked , noCascade ) ;
107+ onCheck ( this . serializeList ( 'checked' ) , { ... nodeInfo , children : node . self . children } ) ;
108108 }
109109
110- onExpand ( node ) {
111- // node is object from TreeNode
110+ onExpand ( nodeInfo ) {
112111 const { onExpand } = this . props ;
112+ const node = this . flatNodes [ nodeInfo . value ] ;
113113
114- this . toggleNode ( 'expanded' , node , node . expanded ) ;
115- onExpand ( this . serializeList ( 'expanded' ) , node ) ;
114+ this . toggleNode ( nodeInfo . value , 'expanded' , nodeInfo . expanded ) ;
115+ onExpand ( this . serializeList ( 'expanded' ) , { ... nodeInfo , children : node . self . children } ) ;
116116 }
117117
118118 onExpandAll ( ) {
@@ -124,26 +124,24 @@ class CheckboxTree extends React.Component {
124124 }
125125
126126 getShallowCheckState ( node , noCascade ) {
127- // node is from props.nodes
128127 const flatNode = this . flatNodes [ node . value ] ;
129128
130129 if ( flatNode . isLeaf || noCascade ) {
131130 return flatNode . checked ? 1 : 0 ;
132131 }
133132
134- if ( node . children . every ( child => ( this . flatNodes [ child . value ] . checkState === 1 ) ) ) {
133+ if ( this . isEveryChildChecked ( node ) ) {
135134 return 1 ;
136135 }
137136
138- if ( node . children . some ( child => ( this . flatNodes [ child . value ] . checkState > 0 ) ) ) {
137+ if ( this . isSomeChildChecked ( node ) ) {
139138 return 2 ;
140139 }
141140
142141 return 0 ;
143142 }
144143
145144 getDisabledState ( node , parent , disabledProp , noCascade ) {
146- // node is from props.nodes
147145 if ( disabledProp ) {
148146 return true ;
149147 }
@@ -172,27 +170,24 @@ class CheckboxTree extends React.Component {
172170 }
173171
174172 toggleChecked ( node , isChecked , noCascade ) {
175- // node is object from TreeNode
176173 const flatNode = this . flatNodes [ node . value ] ;
177174
178175 if ( flatNode . isLeaf || noCascade ) {
179176 // Set the check status of a leaf node or an uncoupled parent
180- this . toggleNode ( 'checked' , node , isChecked ) ;
177+ this . toggleNode ( node . value , 'checked' , isChecked ) ;
181178 } else {
182- const { children } = flatNode . self ;
183179 // Percolate check status down to all children
184- children . forEach ( ( child ) => {
180+ flatNode . self . children . forEach ( ( child ) => {
185181 this . toggleChecked ( child , isChecked , noCascade ) ;
186182 } ) ;
187183 }
188184 }
189185
190- toggleNode ( key , node , toggleValue ) {
191- this . flatNodes [ node . value ] [ key ] = toggleValue ;
186+ toggleNode ( nodeValue , key , toggleValue ) {
187+ this . flatNodes [ nodeValue ] [ key ] = toggleValue ;
192188 }
193189
194190 flattenNodes ( nodes , parentNode = { } ) {
195- // nodes are from props.nodes
196191 if ( ! Array . isArray ( nodes ) || nodes . length === 0 ) {
197192 return ;
198193 }
@@ -241,8 +236,15 @@ class CheckboxTree extends React.Component {
241236 return list ;
242237 }
243238
239+ isEveryChildChecked ( node ) {
240+ return node . children . every ( child => this . flatNodes [ child . value ] . checkState === 1 ) ;
241+ }
242+
243+ isSomeChildChecked ( node ) {
244+ return node . children . some ( child => this . flatNodes [ child . value ] . checkState > 0 ) ;
245+ }
246+
244247 renderTreeNodes ( nodes , parent = { } ) {
245- // nodes are props.nodes
246248 const {
247249 disabled,
248250 expandDisabled,
@@ -260,57 +262,51 @@ class CheckboxTree extends React.Component {
260262
261263 const treeNodes = nodes . map ( ( node ) => {
262264 const key = `${ node . value } ` ;
263-
264265 const flatNode = this . flatNodes [ node . value ] ;
266+ const children = flatNode . isParent ? this . renderTreeNodes ( node . children , node ) : null ;
267+ const nodeDisabled = this . getDisabledState ( node , parent , disabled , noCascade ) ;
265268
266- let children = null ;
267- if ( ! flatNode . isLeaf ) {
268- children = this . renderTreeNodes ( node . children , node ) ;
269- }
270-
271- // set checkState here
272- // this can be "shallow" because checkState is updated for all
273- // nested children in the recursive call to renderTreeNodes above
269+ // Get the check state after all children check states are determined
274270 flatNode . checkState = this . getShallowCheckState ( node , noCascade ) ;
275271
276- const nodeDisabled = this . getDisabledState ( node , parent , disabled , noCascade ) ;
277-
278272 // Show checkbox only if this is a leaf node or showCheckbox is true
279273 const showCheckbox = onlyLeafCheckboxes ? flatNode . isLeaf : flatNode . showCheckbox ;
280274
281- // root of tree has no parent value and is expanded by default
275+ // Render only if parent is expanded or if there is no root parent
282276 const parentExpanded = parent . value ? this . flatNodes [ parent . value ] . expanded : true ;
283- if ( parentExpanded ) {
284- return (
285- < TreeNode
286- key = { key }
287- checked = { flatNode . checkState }
288- className = { node . className }
289- disabled = { nodeDisabled }
290- expandDisabled = { expandDisabled }
291- expandOnClick = { expandOnClick }
292- expanded = { flatNode . expanded }
293- icon = { node . icon }
294- icons = { { ...defaultIcons , ...icons } }
295- label = { node . label }
296- lang = { lang }
297- optimisticToggle = { optimisticToggle }
298- isLeaf = { flatNode . isLeaf }
299- showCheckbox = { showCheckbox }
300- showNodeIcon = { showNodeIcon }
301- title = { showNodeTitle ? node . title || node . label : node . title }
302- treeId = { this . id }
303- value = { node . value }
304- onCheck = { this . onCheck }
305- onClick = { onClick }
306- onExpand = { this . onExpand }
307- >
308- { children }
309- </ TreeNode >
310- ) ;
277+
278+ if ( ! parentExpanded ) {
279+ return null ;
311280 }
312281
313- return null ;
282+ return (
283+ < TreeNode
284+ key = { key }
285+ checked = { flatNode . checkState }
286+ className = { node . className }
287+ disabled = { nodeDisabled }
288+ expandDisabled = { expandDisabled }
289+ expandOnClick = { expandOnClick }
290+ expanded = { flatNode . expanded }
291+ icon = { node . icon }
292+ icons = { { ...defaultIcons , ...icons } }
293+ label = { node . label }
294+ lang = { lang }
295+ optimisticToggle = { optimisticToggle }
296+ isLeaf = { flatNode . isLeaf }
297+ isParent = { flatNode . isParent }
298+ showCheckbox = { showCheckbox }
299+ showNodeIcon = { showNodeIcon }
300+ title = { showNodeTitle ? node . title || node . label : node . title }
301+ treeId = { this . id }
302+ value = { node . value }
303+ onCheck = { this . onCheck }
304+ onClick = { onClick }
305+ onExpand = { this . onExpand }
306+ >
307+ { children }
308+ </ TreeNode >
309+ ) ;
314310 } ) ;
315311
316312 return (
0 commit comments