77 */
88
99import {
10- Directive ,
11- ElementRef ,
10+ afterNextRender ,
1211 afterRenderEffect ,
1312 booleanAttribute ,
1413 computed ,
14+ Directive ,
15+ ElementRef ,
1516 inject ,
1617 input ,
1718 model ,
19+ OnDestroy ,
1820 signal ,
1921 Signal ,
2022 untracked ,
@@ -23,10 +25,10 @@ import {_IdGenerator} from '@angular/cdk/a11y';
2325import { Directionality } from '@angular/cdk/bidi' ;
2426import {
2527 ComboboxTreePattern ,
28+ SortedCollection ,
29+ tabIndexTransform ,
2630 TreeItemPattern ,
2731 TreePattern ,
28- sortDirectives ,
29- tabIndexTransform ,
3032} from '../private' ;
3133import { ComboboxPopup } from '../combobox' ;
3234import type { TreeItem } from './tree-item' ;
@@ -84,7 +86,7 @@ import type {TreeItem} from './tree-item';
8486 } ,
8587 hostDirectives : [ ComboboxPopup ] ,
8688} )
87- export class Tree < V > {
89+ export class Tree < V > implements OnDestroy {
8890 /** A reference to the host element. */
8991 private readonly _elementRef = inject ( ElementRef ) ;
9092
@@ -96,8 +98,8 @@ export class Tree<V> {
9698 optional : true ,
9799 } ) ;
98100
99- /** All TreeItem instances within this tree. */
100- private readonly _unorderedItems = signal ( new Set < TreeItem < V > > ( ) ) ;
101+ /** The collection of tree items . */
102+ readonly _collection = new SortedCollection < TreeItem < V > > ( ) ;
101103
102104 /** A unique identifier for the tree. */
103105 readonly id = input ( inject ( _IdGenerator ) . getId ( 'ng-tree-' , true ) ) ;
@@ -170,9 +172,7 @@ export class Tree<V> {
170172 const inputs = {
171173 ...this ,
172174 id : this . id ,
173- items : computed ( ( ) =>
174- [ ...this . _unorderedItems ( ) ] . sort ( sortDirectives ) . map ( item => item . _pattern ) ,
175- ) ,
175+ items : computed ( ( ) => this . _collection . orderedItems ( ) . map ( item => item . _pattern ) ) ,
176176 activeItem : signal < TreeItemPattern < V > | undefined > ( undefined ) ,
177177 combobox : ( ) => this . _popup ?. combobox ?. _pattern ,
178178 element : ( ) => this . element ,
@@ -184,11 +184,15 @@ export class Tree<V> {
184184
185185 this . activeDescendant = computed ( ( ) => this . _pattern . activeDescendant ( ) ) ;
186186
187+ afterNextRender ( ( ) => {
188+ this . _collection . startObserving ( this . element ) ;
189+ } ) ;
190+
187191 if ( this . _popup ?. combobox ) {
188192 this . _popup ?. _controls ?. set ( this . _pattern as ComboboxTreePattern < V > ) ;
189193 }
190194
191- // Check for any violationns after the DOM has been updated.
195+ // Check for any violations after the DOM has been updated.
192196 afterRenderEffect ( {
193197 read : ( ) => {
194198 if ( typeof ngDevMode === 'undefined' || ngDevMode ) {
@@ -228,14 +232,8 @@ export class Tree<V> {
228232 } ) ;
229233 }
230234
231- _register ( child : TreeItem < V > ) {
232- this . _unorderedItems ( ) . add ( child ) ;
233- this . _unorderedItems . set ( new Set ( this . _unorderedItems ( ) ) ) ;
234- }
235-
236- _unregister ( child : TreeItem < V > ) {
237- this . _unorderedItems ( ) . delete ( child ) ;
238- this . _unorderedItems . set ( new Set ( this . _unorderedItems ( ) ) ) ;
235+ ngOnDestroy ( ) {
236+ this . _collection . stopObserving ( ) ;
239237 }
240238
241239 scrollActiveItemIntoView ( options : ScrollIntoViewOptions = { block : 'nearest' } ) {
0 commit comments