@@ -44,6 +44,22 @@ const folder = {
4444 { name : "Onions" } ,
4545 ] ,
4646 } ,
47+ {
48+ name : "Deserts" ,
49+ children : [
50+ { name : "Cookies" } ,
51+ {
52+ name : "Cakes" ,
53+ children : [
54+ {
55+ name : "Cheesecake" ,
56+ children : [ { name : "Classic" } , { name : "Chocolate" } ] ,
57+ } ,
58+ { name : "Vanilla" } ,
59+ ] ,
60+ } ,
61+ ] ,
62+ } ,
4763 ] ,
4864} ;
4965
@@ -171,6 +187,7 @@ function MultiSelectCheckboxControlledWithStateInside() {
171187 < MultiSelectCheckboxControlled
172188 selectedIds = { selectedIds }
173189 data = { dataWithoutIds }
190+ defaultExpandedIds = { [ 1 , 7 , 11 , 16 , 22 , 24 , 25 ] }
174191 />
175192 </ div >
176193 ) ;
@@ -372,6 +389,70 @@ describe("Data without ids", () => {
372389 expect ( nodes [ 6 ] ) . toHaveAttribute ( "aria-checked" , "false" ) ;
373390 } ) ;
374391
392+ test ( "SelectedIds should clear selection and half-selection after manual selection of top level parent and deselection of low level child" , ( ) => {
393+ const { queryAllByRole, queryAllByTestId } = render (
394+ < MultiSelectCheckboxControlledWithStateInside />
395+ ) ;
396+
397+ const nodes = queryAllByRole ( "treeitem" ) ;
398+
399+ expect ( nodes [ 11 ] ) . toHaveAttribute ( "aria-checked" , "true" ) ;
400+
401+ fireEvent . click ( queryAllByTestId ( "clear-selected-nodes" ) [ 0 ] ) ;
402+
403+ expect ( nodes [ 11 ] ) . toHaveAttribute ( "aria-checked" , "false" ) ;
404+
405+ fireEvent . click ( queryAllByTestId ( "select-only-vegetables" ) [ 0 ] ) ;
406+
407+ expect ( nodes [ 15 ] ) . toHaveAttribute ( "aria-checked" , "true" ) ;
408+ expect ( nodes [ 16 ] ) . toHaveAttribute ( "aria-checked" , "true" ) ;
409+ expect ( nodes [ 17 ] ) . toHaveAttribute ( "aria-checked" , "true" ) ;
410+ expect ( nodes [ 18 ] ) . toHaveAttribute ( "aria-checked" , "true" ) ;
411+ expect ( nodes [ 19 ] ) . toHaveAttribute ( "aria-checked" , "true" ) ;
412+ expect ( nodes [ 20 ] ) . toHaveAttribute ( "aria-checked" , "true" ) ;
413+
414+ nodes [ 21 ] . focus ( ) ;
415+ if ( document . activeElement == null )
416+ throw new Error (
417+ `Expected to find an active element on the document (after focusing the second element with role["treeitem"]), but did not.`
418+ ) ;
419+ fireEvent . click ( nodes [ 21 ] . getElementsByClassName ( "checkbox-icon" ) [ 0 ] ) ; // select Deserts
420+
421+ expect ( nodes [ 21 ] ) . toHaveAttribute ( "aria-checked" , "true" ) ; // Deserts
422+ expect ( nodes [ 22 ] ) . toHaveAttribute ( "aria-checked" , "true" ) ; // Cookies
423+ expect ( nodes [ 23 ] ) . toHaveAttribute ( "aria-checked" , "true" ) ; // Cakes
424+ expect ( nodes [ 24 ] ) . toHaveAttribute ( "aria-checked" , "true" ) ; // Cheesecake
425+ expect ( nodes [ 25 ] ) . toHaveAttribute ( "aria-checked" , "true" ) ; // Classic cheesecake
426+ expect ( nodes [ 26 ] ) . toHaveAttribute ( "aria-checked" , "true" ) ; // Chocolate cheesecake
427+ expect ( nodes [ 27 ] ) . toHaveAttribute ( "aria-checked" , "true" ) ; // Vanilla
428+
429+ nodes [ 26 ] . focus ( ) ;
430+ if ( document . activeElement == null )
431+ throw new Error (
432+ `Expected to find an active element on the document (after focusing the second element with role["treeitem"]), but did not.`
433+ ) ;
434+ fireEvent . click ( nodes [ 26 ] . getElementsByClassName ( "checkbox-icon" ) [ 0 ] ) ; // deselect Chocolate cheesecake
435+
436+ expect ( nodes [ 21 ] ) . toHaveAttribute ( "aria-checked" , "mixed" ) ; // Deserts
437+ expect ( nodes [ 22 ] ) . toHaveAttribute ( "aria-checked" , "true" ) ; // Cookies
438+ expect ( nodes [ 23 ] ) . toHaveAttribute ( "aria-checked" , "mixed" ) ; // Cakes
439+ expect ( nodes [ 24 ] ) . toHaveAttribute ( "aria-checked" , "mixed" ) ; // Cheesecake
440+ expect ( nodes [ 25 ] ) . toHaveAttribute ( "aria-checked" , "true" ) ; // Classic cheesecake
441+ expect ( nodes [ 26 ] ) . toHaveAttribute ( "aria-checked" , "false" ) ; // Chocolate cheesecake
442+ expect ( nodes [ 27 ] ) . toHaveAttribute ( "aria-checked" , "true" ) ; // Vanilla
443+
444+ fireEvent . click ( queryAllByTestId ( "select-only-vegetables" ) [ 0 ] ) ;
445+
446+ expect ( nodes [ 21 ] ) . toHaveAttribute ( "aria-checked" , "false" ) ; // Deserts
447+ expect ( nodes [ 22 ] ) . toHaveAttribute ( "aria-checked" , "false" ) ; // Cookies
448+ expect ( nodes [ 23 ] ) . toHaveAttribute ( "aria-checked" , "false" ) ; // Cakes
449+ expect ( nodes [ 24 ] ) . toHaveAttribute ( "aria-checked" , "false" ) ; // Cheesecake
450+ expect ( nodes [ 25 ] ) . toHaveAttribute ( "aria-checked" , "false" ) ; // Classic cheesecake
451+ expect ( nodes [ 26 ] ) . toHaveAttribute ( "aria-checked" , "false" ) ; // Chocolate cheesecake
452+ expect ( nodes [ 27 ] ) . toHaveAttribute ( "aria-checked" , "false" ) ; // Vanilla
453+ expect ( nodes [ 15 ] ) . toHaveAttribute ( "aria-checked" , "true" ) ;
454+ } ) ;
455+
375456 test ( "SelectedIds should select all children if parent node selected" , ( ) => {
376457 const { queryAllByRole } = render (
377458 < MultiSelectCheckboxControlled selectedIds = { [ 16 ] } data = { dataWithoutIds } />
0 commit comments