@@ -79,9 +79,6 @@ export class CdkTree<V> {
79
79
/** All CdkTreeItem instances within this tree. */
80
80
private readonly _unorderedItems = signal ( new Set < CdkTreeItem < V > > ( ) ) ;
81
81
82
- /** All CdkGroup instances within this tree. */
83
- readonly unorderedGroups = signal ( new Set < CdkTreeItemGroup < V > > ( ) ) ;
84
-
85
82
/** Orientation of the tree. */
86
83
readonly orientation = input < 'vertical' | 'horizontal' > ( 'vertical' ) ;
87
84
@@ -144,28 +141,14 @@ export class CdkTree<V> {
144
141
this . _hasFocused . set ( true ) ;
145
142
}
146
143
147
- register ( child : CdkTreeItemGroup < V > | CdkTreeItem < V > ) {
148
- if ( child instanceof CdkTreeItemGroup ) {
149
- this . unorderedGroups ( ) . add ( child ) ;
150
- this . unorderedGroups . set ( new Set ( this . unorderedGroups ( ) ) ) ;
151
- }
152
-
153
- if ( child instanceof CdkTreeItem ) {
154
- this . _unorderedItems ( ) . add ( child ) ;
155
- this . _unorderedItems . set ( new Set ( this . _unorderedItems ( ) ) ) ;
156
- }
144
+ register ( child : CdkTreeItem < V > ) {
145
+ this . _unorderedItems ( ) . add ( child ) ;
146
+ this . _unorderedItems . set ( new Set ( this . _unorderedItems ( ) ) ) ;
157
147
}
158
148
159
- deregister ( child : CdkTreeItemGroup < V > | CdkTreeItem < V > ) {
160
- if ( child instanceof CdkTreeItemGroup ) {
161
- this . unorderedGroups ( ) . delete ( child ) ;
162
- this . unorderedGroups . set ( new Set ( this . unorderedGroups ( ) ) ) ;
163
- }
164
-
165
- if ( child instanceof CdkTreeItem ) {
166
- this . _unorderedItems ( ) . delete ( child ) ;
167
- this . _unorderedItems . set ( new Set ( this . _unorderedItems ( ) ) ) ;
168
- }
149
+ unregister ( child : CdkTreeItem < V > ) {
150
+ this . _unorderedItems ( ) . delete ( child ) ;
151
+ this . _unorderedItems . set ( new Set ( this . _unorderedItems ( ) ) ) ;
169
152
}
170
153
}
171
154
@@ -185,7 +168,7 @@ export class CdkTree<V> {
185
168
'[attr.aria-current]' : 'pattern.current()' ,
186
169
'[attr.aria-disabled]' : 'pattern.disabled()' ,
187
170
'[attr.aria-level]' : 'pattern.level()' ,
188
- '[attr.aria-owns]' : 'group()?.id ' ,
171
+ '[attr.aria-owns]' : 'ownsId() ' ,
189
172
'[attr.aria-setsize]' : 'pattern.setsize()' ,
190
173
'[attr.aria-posinset]' : 'pattern.posinset()' ,
191
174
'[attr.tabindex]' : 'pattern.tabindex()' ,
@@ -199,29 +182,21 @@ export class CdkTreeItem<V> implements OnInit, OnDestroy, HasElement {
199
182
/** A unique identifier for the tree item. */
200
183
private readonly _id = inject ( _IdGenerator ) . getId ( 'cdk-tree-item-' ) ;
201
184
202
- /** The top level CdkTree. */
203
- private readonly _tree = inject ( CdkTree < V > ) ;
204
-
205
- /** The parent CdkTreeItem. */
206
- private readonly _treeItem = inject ( CdkTreeItem < V > , { optional : true , skipSelf : true } ) ;
207
-
208
- /** The parent CdkGroup, if any. */
209
- private readonly _parentGroup = inject ( CdkTreeItemGroup < V > , { optional : true } ) ;
185
+ /** The owned tree item group. */
186
+ private readonly _group = signal < CdkTreeItemGroup < V > | undefined > ( undefined ) ;
210
187
211
- /** The top level TreePattern. */
212
- private readonly _treePattern = computed ( ( ) => this . _tree . pattern ) ;
213
-
214
- /** The parent TreeItemPattern. */
215
- private readonly _parentPattern : Signal < TreeItemPattern < V > | TreePattern < V > > = computed (
216
- ( ) => this . _treeItem ?. pattern ?? this . _treePattern ( ) ,
217
- ) ;
188
+ /** The id of the owned group. */
189
+ readonly ownsId = computed ( ( ) => this . _group ( ) ?. id ) ;
218
190
219
191
/** The host native element. */
220
192
readonly element = computed ( ( ) => this . _elementRef . nativeElement ) ;
221
193
222
194
/** The value of the tree item. */
223
195
readonly value = input . required < V > ( ) ;
224
196
197
+ /** The parent tree root or tree item group. */
198
+ readonly parent = input . required < CdkTree < V > | CdkTreeItemGroup < V > > ( ) ;
199
+
225
200
/** Whether the tree item is disabled. */
226
201
readonly disabled = input ( false , { transform : booleanAttribute } ) ;
227
202
@@ -231,46 +206,61 @@ export class CdkTreeItem<V> implements OnInit, OnDestroy, HasElement {
231
206
/** Search term for typeahead. */
232
207
readonly searchTerm = computed ( ( ) => this . label ( ) ?? this . element ( ) . textContent ) ;
233
208
234
- /** Manual group assignment. */
235
- readonly group = signal < CdkTreeItemGroup < V > | undefined > ( undefined ) ;
209
+ /** The tree root. */
210
+ readonly tree : Signal < CdkTree < V > > = computed ( ( ) => {
211
+ if ( this . parent ( ) instanceof CdkTree ) {
212
+ return this . parent ( ) as CdkTree < V > ;
213
+ }
214
+ return ( this . parent ( ) as CdkTreeItemGroup < V > ) . ownedBy ( ) . tree ( ) ;
215
+ } ) ;
236
216
237
217
/** The UI pattern for this item. */
238
- readonly pattern : TreeItemPattern < V > = new TreeItemPattern < V > ( {
239
- ...this ,
240
- id : ( ) => this . _id ,
241
- tree : this . _treePattern ,
242
- parent : this . _parentPattern ,
243
- children : computed (
244
- ( ) =>
245
- this . group ( )
246
- ?. children ( )
247
- . map ( item => ( item as CdkTreeItem < V > ) . pattern ) ?? [ ] ,
248
- ) ,
249
- hasChildren : computed ( ( ) => ! ! this . group ( ) ) ,
250
- } ) ;
218
+ pattern : TreeItemPattern < V > ;
251
219
252
220
constructor ( ) {
253
- afterRenderEffect ( ( ) => {
254
- const group = [ ...this . _tree . unorderedGroups ( ) ] . find ( group => group . value ( ) === this . value ( ) ) ;
255
- if ( group ) {
256
- this . group . set ( group ) ;
257
- }
258
- } ) ;
259
-
260
221
// Updates the visibility of the owned group.
261
222
afterRenderEffect ( ( ) => {
262
- this . group ( ) ?. visible . set ( this . pattern . expanded ( ) ) ;
223
+ this . _group ( ) ?. visible . set ( this . pattern . expanded ( ) ) ;
263
224
} ) ;
264
225
}
265
226
266
227
ngOnInit ( ) {
267
- this . _tree . register ( this ) ;
268
- this . _parentGroup ?. register ( this ) ;
228
+ this . parent ( ) . register ( this ) ;
229
+ this . tree ( ) . register ( this ) ;
230
+
231
+ const treePattern = computed ( ( ) => this . tree ( ) . pattern ) ;
232
+ const parentPattern = computed ( ( ) => {
233
+ if ( this . parent ( ) instanceof CdkTree ) {
234
+ return treePattern ( ) ;
235
+ }
236
+ return ( this . parent ( ) as CdkTreeItemGroup < V > ) . ownedBy ( ) . pattern ;
237
+ } ) ;
238
+ this . pattern = new TreeItemPattern < V > ( {
239
+ ...this ,
240
+ id : ( ) => this . _id ,
241
+ tree : treePattern ,
242
+ parent : parentPattern ,
243
+ children : computed (
244
+ ( ) =>
245
+ this . _group ( )
246
+ ?. children ( )
247
+ . map ( item => ( item as CdkTreeItem < V > ) . pattern ) ?? [ ] ,
248
+ ) ,
249
+ hasChildren : computed ( ( ) => ! ! this . _group ( ) ) ,
250
+ } ) ;
269
251
}
270
252
271
253
ngOnDestroy ( ) {
272
- this . _tree . deregister ( this ) ;
273
- this . _parentGroup ?. deregister ( this ) ;
254
+ this . parent ( ) . unregister ( this ) ;
255
+ this . tree ( ) . unregister ( this ) ;
256
+ }
257
+
258
+ register ( group : CdkTreeItemGroup < V > ) {
259
+ this . _group . set ( group ) ;
260
+ }
261
+
262
+ unregister ( ) {
263
+ this . _group . set ( undefined ) ;
274
264
}
275
265
}
276
266
@@ -300,9 +290,6 @@ export class CdkTreeItemGroup<V> implements OnInit, OnDestroy, HasElement {
300
290
/** The DeferredContentAware host directive. */
301
291
private readonly _deferredContentAware = inject ( DeferredContentAware ) ;
302
292
303
- /** The top level CdkTree. */
304
- private readonly _tree = inject ( CdkTree < V > ) ;
305
-
306
293
/** All groupable items that are descendants of the group. */
307
294
private readonly _unorderedItems = signal ( new Set < CdkTreeItem < V > > ( ) ) ;
308
295
@@ -318,8 +305,8 @@ export class CdkTreeItemGroup<V> implements OnInit, OnDestroy, HasElement {
318
305
/** Child items within this group. */
319
306
readonly children = computed ( ( ) => [ ...this . _unorderedItems ( ) ] . sort ( sortDirectives ) ) ;
320
307
321
- /** Identifier for matching the group owner . */
322
- readonly value = input . required < V > ( ) ;
308
+ /** Tree item that owns the group. */
309
+ readonly ownedBy = input . required < CdkTreeItem < V > > ( ) ;
323
310
324
311
constructor ( ) {
325
312
// Connect the group's hidden state to the DeferredContentAware's visibility.
@@ -329,19 +316,19 @@ export class CdkTreeItemGroup<V> implements OnInit, OnDestroy, HasElement {
329
316
}
330
317
331
318
ngOnInit ( ) {
332
- this . _tree . register ( this ) ;
319
+ this . ownedBy ( ) . register ( this ) ;
333
320
}
334
321
335
322
ngOnDestroy ( ) {
336
- this . _tree . deregister ( this ) ;
323
+ this . ownedBy ( ) . unregister ( ) ;
337
324
}
338
325
339
326
register ( child : CdkTreeItem < V > ) {
340
327
this . _unorderedItems ( ) . add ( child ) ;
341
328
this . _unorderedItems . set ( new Set ( this . _unorderedItems ( ) ) ) ;
342
329
}
343
330
344
- deregister ( child : CdkTreeItem < V > ) {
331
+ unregister ( child : CdkTreeItem < V > ) {
345
332
this . _unorderedItems ( ) . delete ( child ) ;
346
333
this . _unorderedItems . set ( new Set ( this . _unorderedItems ( ) ) ) ;
347
334
}
0 commit comments