@@ -341,6 +341,7 @@ const useTree = ({
341
341
) {
342
342
idsToUpdate . add ( lastInteractedWith ) ;
343
343
}
344
+
344
345
//========START FILTER OUT NOT EXISTING IDS=========
345
346
// This block of code filters out from propagation check ids that aren't in data anymore
346
347
const idsNotInData : NodeId [ ] = [ ] ;
@@ -351,6 +352,7 @@ const useTree = ({
351
352
} ) ;
352
353
idsNotInData . forEach ( ( id ) => idsToUpdate . delete ( id ) ) ;
353
354
//========END FILTER OUT NOT EXISTING IDS===========
355
+
354
356
const { every, some, none } = propagateSelectChange (
355
357
data ,
356
358
idsToUpdate ,
@@ -359,6 +361,20 @@ const useTree = ({
359
361
halfSelectedIds ,
360
362
multiSelect
361
363
) ;
364
+
365
+ // when controlling select ids, ensure that propagatedIds are selected when controlledSelectedIds are changed.
366
+ if ( controlledSelectedIds ) {
367
+ idsToUpdate . forEach ( ( id ) => {
368
+ if ( isBranchNode ( data , id ) ) {
369
+ const descendantIds = getDescendants ( data , id , new Set < number > ( ) ) ;
370
+ const isPropagatedId = descendantIds . every ( ( childId ) =>
371
+ selectedIds . has ( childId )
372
+ ) ;
373
+ isPropagatedId && every . add ( id ) ;
374
+ }
375
+ } ) ;
376
+ }
377
+
362
378
for ( const id of every ) {
363
379
if ( ! selectedIds . has ( id ) ) {
364
380
dispatch ( {
@@ -554,128 +570,125 @@ export interface ITreeViewProps<M extends IFlatMetadata = IFlatMetadata> {
554
570
focusedId ?: NodeId ;
555
571
}
556
572
557
- const TreeView = React . forwardRef (
558
- function TreeView < M extends IFlatMetadata = IFlatMetadata > (
559
- {
560
- data,
561
- selectedIds,
562
- nodeRenderer,
563
- onSelect = noop ,
564
- onNodeSelect = noop ,
565
- onExpand = noop ,
566
- onLoadData,
567
- className = "" ,
568
- multiSelect = false ,
569
- propagateSelect = false ,
570
- propagateSelectUpwards = false ,
571
- propagateCollapse = false ,
572
- expandOnKeyboardSelect = false ,
573
- togglableSelect = false ,
574
- defaultExpandedIds = [ ] ,
575
- defaultSelectedIds = [ ] ,
576
- defaultDisabledIds = [ ] ,
577
- clickAction = clickActions . select ,
578
- nodeAction = "select" ,
579
- expandedIds,
580
- focusedId,
581
- onBlur,
582
- ...other
583
- } : ITreeViewProps < M > ,
584
- ref : React . ForwardedRef < HTMLUListElement >
585
- ) {
586
- validateTreeViewData ( data ) ;
587
- const nodeRefs = useRef ( { } ) ;
588
- const leafRefs = useRef ( { } ) ;
589
- let innerRef = useRef < HTMLUListElement | null > ( null ) ;
590
- if ( ref != null ) {
591
- innerRef = ref as React . MutableRefObject < HTMLUListElement > ;
592
- }
593
- const [ state , dispatch ] = useTree ( {
594
- data,
595
- controlledSelectedIds : selectedIds ,
596
- controlledExpandedIds : expandedIds ,
597
- defaultExpandedIds,
598
- defaultSelectedIds,
599
- defaultDisabledIds,
600
- nodeRefs,
601
- leafRefs,
602
- onSelect,
603
- onNodeSelect,
604
- onExpand,
605
- onLoadData,
606
- togglableSelect,
607
- multiSelect,
608
- propagateSelect,
609
- propagateSelectUpwards,
610
- treeRef : innerRef ,
611
- focusedId,
612
- } ) ;
613
- propagateSelect = propagateSelect && multiSelect ;
614
-
615
- return (
616
- < ul
617
- className = { cx ( baseClassNames . root , className ) }
618
- role = "tree"
619
- aria-multiselectable = { nodeAction === "select" ? multiSelect : undefined }
620
- ref = { innerRef }
621
- onBlur = { ( event ) => {
622
- onComponentBlur ( event , innerRef . current , ( ) => {
623
- onBlur &&
624
- onBlur ( {
625
- treeState : state ,
626
- dispatch,
627
- } ) ;
628
- dispatch ( { type : treeTypes . blur } ) ;
629
- } ) ;
630
- } }
631
- onKeyDown = { handleKeyDown ( {
632
- data,
633
- tabbableId : state . tabbableId ,
634
- expandedIds : state . expandedIds ,
635
- selectedIds : state . selectedIds ,
636
- disabledIds : state . disabledIds ,
637
- halfSelectedIds : state . halfSelectedIds ,
638
- clickAction,
639
- dispatch,
640
- propagateCollapse,
641
- propagateSelect,
642
- multiSelect,
643
- expandOnKeyboardSelect,
644
- togglableSelect,
645
- } ) }
646
- { ...other }
647
- >
648
- { getTreeParent ( data ) . children . map ( ( x , index ) => (
649
- < Node
650
- key = { `${ x } -${ typeof x } ` }
651
- data = { data }
652
- element = { getTreeNode ( data , x ) as INode < M > }
653
- setsize = { getTreeParent ( data ) . children . length }
654
- posinset = { index + 1 }
655
- level = { 1 }
656
- { ...state }
657
- state = { state }
658
- dispatch = { dispatch }
659
- nodeRefs = { nodeRefs }
660
- leafRefs = { leafRefs }
661
- baseClassNames = { baseClassNames }
662
- nodeRenderer = { nodeRenderer }
663
- propagateCollapse = { propagateCollapse }
664
- propagateSelect = { propagateSelect }
665
- propagateSelectUpwards = { propagateSelectUpwards }
666
- multiSelect = { multiSelect }
667
- togglableSelect = { togglableSelect }
668
- clickAction = { clickAction }
669
- nodeAction = { nodeAction }
670
- />
671
- ) ) }
672
- </ ul >
673
- )
674
- } )
675
-
676
-
677
-
573
+ const TreeView = React . forwardRef ( function TreeView <
574
+ M extends IFlatMetadata = IFlatMetadata
575
+ > (
576
+ {
577
+ data,
578
+ selectedIds,
579
+ nodeRenderer,
580
+ onSelect = noop ,
581
+ onNodeSelect = noop ,
582
+ onExpand = noop ,
583
+ onLoadData,
584
+ className = "" ,
585
+ multiSelect = false ,
586
+ propagateSelect = false ,
587
+ propagateSelectUpwards = false ,
588
+ propagateCollapse = false ,
589
+ expandOnKeyboardSelect = false ,
590
+ togglableSelect = false ,
591
+ defaultExpandedIds = [ ] ,
592
+ defaultSelectedIds = [ ] ,
593
+ defaultDisabledIds = [ ] ,
594
+ clickAction = clickActions . select ,
595
+ nodeAction = "select" ,
596
+ expandedIds,
597
+ focusedId,
598
+ onBlur,
599
+ ...other
600
+ } : ITreeViewProps < M > ,
601
+ ref : React . ForwardedRef < HTMLUListElement >
602
+ ) {
603
+ validateTreeViewData ( data ) ;
604
+ const nodeRefs = useRef ( { } ) ;
605
+ const leafRefs = useRef ( { } ) ;
606
+ let innerRef = useRef < HTMLUListElement | null > ( null ) ;
607
+ if ( ref != null ) {
608
+ innerRef = ref as React . MutableRefObject < HTMLUListElement > ;
609
+ }
610
+ const [ state , dispatch ] = useTree ( {
611
+ data,
612
+ controlledSelectedIds : selectedIds ,
613
+ controlledExpandedIds : expandedIds ,
614
+ defaultExpandedIds,
615
+ defaultSelectedIds,
616
+ defaultDisabledIds,
617
+ nodeRefs,
618
+ leafRefs,
619
+ onSelect,
620
+ onNodeSelect,
621
+ onExpand,
622
+ onLoadData,
623
+ togglableSelect,
624
+ multiSelect,
625
+ propagateSelect,
626
+ propagateSelectUpwards,
627
+ treeRef : innerRef ,
628
+ focusedId,
629
+ } ) ;
630
+ propagateSelect = propagateSelect && multiSelect ;
678
631
632
+ return (
633
+ < ul
634
+ className = { cx ( baseClassNames . root , className ) }
635
+ role = "tree"
636
+ aria-multiselectable = { nodeAction === "select" ? multiSelect : undefined }
637
+ ref = { innerRef }
638
+ onBlur = { ( event ) => {
639
+ onComponentBlur ( event , innerRef . current , ( ) => {
640
+ onBlur &&
641
+ onBlur ( {
642
+ treeState : state ,
643
+ dispatch,
644
+ } ) ;
645
+ dispatch ( { type : treeTypes . blur } ) ;
646
+ } ) ;
647
+ } }
648
+ onKeyDown = { handleKeyDown ( {
649
+ data,
650
+ tabbableId : state . tabbableId ,
651
+ expandedIds : state . expandedIds ,
652
+ selectedIds : state . selectedIds ,
653
+ disabledIds : state . disabledIds ,
654
+ halfSelectedIds : state . halfSelectedIds ,
655
+ clickAction,
656
+ dispatch,
657
+ propagateCollapse,
658
+ propagateSelect,
659
+ multiSelect,
660
+ expandOnKeyboardSelect,
661
+ togglableSelect,
662
+ } ) }
663
+ { ...other }
664
+ >
665
+ { getTreeParent ( data ) . children . map ( ( x , index ) => (
666
+ < Node
667
+ key = { `${ x } -${ typeof x } ` }
668
+ data = { data }
669
+ element = { getTreeNode ( data , x ) as INode < M > }
670
+ setsize = { getTreeParent ( data ) . children . length }
671
+ posinset = { index + 1 }
672
+ level = { 1 }
673
+ { ...state }
674
+ state = { state }
675
+ dispatch = { dispatch }
676
+ nodeRefs = { nodeRefs }
677
+ leafRefs = { leafRefs }
678
+ baseClassNames = { baseClassNames }
679
+ nodeRenderer = { nodeRenderer }
680
+ propagateCollapse = { propagateCollapse }
681
+ propagateSelect = { propagateSelect }
682
+ propagateSelectUpwards = { propagateSelectUpwards }
683
+ multiSelect = { multiSelect }
684
+ togglableSelect = { togglableSelect }
685
+ clickAction = { clickAction }
686
+ nodeAction = { nodeAction }
687
+ />
688
+ ) ) }
689
+ </ ul >
690
+ ) ;
691
+ } ) ;
679
692
680
693
const handleKeyDown = ( {
681
694
data,
@@ -979,7 +992,6 @@ const handleKeyDown = ({
979
992
}
980
993
} ;
981
994
982
-
983
995
TreeView . propTypes = {
984
996
/** Tree data*/
985
997
data : PropTypes . array . isRequired ,
0 commit comments