@@ -19,12 +19,11 @@ import {
19
19
model ,
20
20
signal ,
21
21
WritableSignal ,
22
- OnDestroy ,
23
22
} from '@angular/core' ;
24
23
import { RadioButtonPattern , RadioGroupPattern } from '../ui-patterns' ;
25
24
import { Directionality } from '@angular/cdk/bidi' ;
26
25
import { _IdGenerator } from '@angular/cdk/a11y' ;
27
- import { CdkToolbar } from '.. /toolbar' ;
26
+ import { CdkToolbarWidgetGroup } from '@angular/cdk-experimental /toolbar' ;
28
27
29
28
// TODO: Move mapSignal to it's own file so it can be reused across components.
30
29
@@ -91,23 +90,24 @@ export function mapSignal<T, V>(
91
90
'(pointerdown)' : 'pattern.onPointerdown($event)' ,
92
91
'(focusin)' : 'onFocus()' ,
93
92
} ,
93
+ hostDirectives : [ CdkToolbarWidgetGroup ] ,
94
94
} )
95
95
export class CdkRadioGroup < V > {
96
96
/** A reference to the radio group element. */
97
97
private readonly _elementRef = inject ( ElementRef ) ;
98
98
99
+ /** A reference to the CdkToolbarWidgetGroup, if the radio group is in a toolbar. */
100
+ private readonly _cdkToolbarWidgetGroup = inject ( CdkToolbarWidgetGroup ) ;
101
+
102
+ /** Whether the radio group is inside of a CdkToolbar. */
103
+ private readonly _hasToolbar = computed ( ( ) => ! ! this . _cdkToolbarWidgetGroup . toolbar ( ) ) ;
104
+
99
105
/** The CdkRadioButtons nested inside of the CdkRadioGroup. */
100
106
private readonly _cdkRadioButtons = contentChildren ( CdkRadioButton , { descendants : true } ) ;
101
107
102
108
/** A signal wrapper for directionality. */
103
109
protected textDirection = inject ( Directionality ) . valueSignal ;
104
110
105
- /** A signal wrapper for toolbar. */
106
- toolbar = inject ( CdkToolbar , { optional : true } ) ;
107
-
108
- /** Toolbar pattern if applicable */
109
- private readonly _toolbarPattern = computed ( ( ) => this . toolbar ?. pattern ) ;
110
-
111
111
/** The RadioButton UIPatterns of the child CdkRadioButtons. */
112
112
protected items = computed ( ( ) => this . _cdkRadioButtons ( ) . map ( radio => radio . pattern ) ) ;
113
113
@@ -136,16 +136,14 @@ export class CdkRadioGroup<V> {
136
136
} ) ;
137
137
138
138
/** The RadioGroup UIPattern. */
139
- pattern : RadioGroupPattern < V > = new RadioGroupPattern < V > ( {
139
+ readonly pattern : RadioGroupPattern < V > = new RadioGroupPattern < V > ( {
140
140
...this ,
141
141
items : this . items ,
142
142
value : this . _value ,
143
143
activeItem : signal ( undefined ) ,
144
144
textDirection : this . textDirection ,
145
- toolbar : this . _toolbarPattern ,
146
145
element : ( ) => this . _elementRef . nativeElement ,
147
- focusMode : this . _toolbarPattern ( ) ?. inputs . focusMode ?? this . focusMode ,
148
- skipDisabled : this . _toolbarPattern ( ) ?. inputs . skipDisabled ?? this . skipDisabled ,
146
+ toolbar : this . _cdkToolbarWidgetGroup . toolbar ,
149
147
} ) ;
150
148
151
149
/** Whether the radio group has received focus yet. */
@@ -162,35 +160,25 @@ export class CdkRadioGroup<V> {
162
160
} ) ;
163
161
164
162
afterRenderEffect ( ( ) => {
165
- if ( ! this . _hasFocused ( ) && ! this . toolbar ) {
163
+ if ( ! this . _hasFocused ( ) && ! this . _hasToolbar ( ) ) {
166
164
this . pattern . setDefaultState ( ) ;
167
165
}
168
166
} ) ;
169
167
170
- // TODO: Refactor to be handled within list behavior
171
168
afterRenderEffect ( ( ) => {
172
- if ( this . toolbar ) {
173
- const radioButtons = this . _cdkRadioButtons ( ) ;
174
- // If the group is disabled and the toolbar is set to skip disabled items,
175
- // the radio buttons should not be part of the toolbar's navigation.
176
- if ( this . disabled ( ) && this . toolbar . skipDisabled ( ) ) {
177
- radioButtons . forEach ( radio => this . toolbar ! . unregister ( radio ) ) ;
178
- } else {
179
- radioButtons . forEach ( radio => this . toolbar ! . register ( radio ) ) ;
180
- }
169
+ if ( this . _hasToolbar ( ) ) {
170
+ this . _cdkToolbarWidgetGroup . disabled . set ( this . disabled ( ) ) ;
181
171
}
182
172
} ) ;
173
+
174
+ if ( this . _hasToolbar ( ) ) {
175
+ this . _cdkToolbarWidgetGroup . actions . set ( this . pattern . toolbarWidgetGroupActions ) ;
176
+ }
183
177
}
184
178
185
179
onFocus ( ) {
186
180
this . _hasFocused . set ( true ) ;
187
181
}
188
-
189
- toolbarButtonUnregister ( radio : CdkRadioButton < V > ) {
190
- if ( this . toolbar ) {
191
- this . toolbar . unregister ( radio ) ;
192
- }
193
- }
194
182
}
195
183
196
184
/** A selectable radio button in a CdkRadioGroup. */
@@ -207,7 +195,7 @@ export class CdkRadioGroup<V> {
207
195
'[id]' : 'pattern.id()' ,
208
196
} ,
209
197
} )
210
- export class CdkRadioButton < V > implements OnDestroy {
198
+ export class CdkRadioButton < V > {
211
199
/** A reference to the radio button element. */
212
200
private readonly _elementRef = inject ( ElementRef ) ;
213
201
@@ -218,13 +206,13 @@ export class CdkRadioButton<V> implements OnDestroy {
218
206
private readonly _generatedId = inject ( _IdGenerator ) . getId ( 'cdk-radio-button-' ) ;
219
207
220
208
/** A unique identifier for the radio button. */
221
- protected id = computed ( ( ) => this . _generatedId ) ;
209
+ readonly id = computed ( ( ) => this . _generatedId ) ;
222
210
223
211
/** The value associated with the radio button. */
224
212
readonly value = input . required < V > ( ) ;
225
213
226
214
/** The parent RadioGroup UIPattern. */
227
- protected group = computed ( ( ) => this . _cdkRadioGroup . pattern ) ;
215
+ readonly group = computed ( ( ) => this . _cdkRadioGroup . pattern ) ;
228
216
229
217
/** A reference to the radio button element to be focused on navigation. */
230
218
element = computed ( ( ) => this . _elementRef . nativeElement ) ;
@@ -240,10 +228,4 @@ export class CdkRadioButton<V> implements OnDestroy {
240
228
group : this . group ,
241
229
element : this . element ,
242
230
} ) ;
243
-
244
- ngOnDestroy ( ) {
245
- if ( this . _cdkRadioGroup . toolbar ) {
246
- this . _cdkRadioGroup . toolbarButtonUnregister ( this ) ;
247
- }
248
- }
249
231
}
0 commit comments