@@ -19,12 +19,11 @@ import {
1919 model ,
2020 signal ,
2121 WritableSignal ,
22- OnDestroy ,
2322} from '@angular/core' ;
2423import { RadioButtonPattern , RadioGroupPattern } from '../ui-patterns' ;
2524import { Directionality } from '@angular/cdk/bidi' ;
2625import { _IdGenerator } from '@angular/cdk/a11y' ;
27- import { CdkToolbar } from '.. /toolbar' ;
26+ import { CdkToolbarWidgetGroup } from '@angular/cdk-experimental /toolbar' ;
2827
2928// TODO: Move mapSignal to it's own file so it can be reused across components.
3029
@@ -91,23 +90,24 @@ export function mapSignal<T, V>(
9190 '(pointerdown)' : 'pattern.onPointerdown($event)' ,
9291 '(focusin)' : 'onFocus()' ,
9392 } ,
93+ hostDirectives : [ CdkToolbarWidgetGroup ] ,
9494} )
9595export class CdkRadioGroup < V > {
9696 /** A reference to the radio group element. */
9797 private readonly _elementRef = inject ( ElementRef ) ;
9898
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+
99105 /** The CdkRadioButtons nested inside of the CdkRadioGroup. */
100106 private readonly _cdkRadioButtons = contentChildren ( CdkRadioButton , { descendants : true } ) ;
101107
102108 /** A signal wrapper for directionality. */
103109 protected textDirection = inject ( Directionality ) . valueSignal ;
104110
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-
111111 /** The RadioButton UIPatterns of the child CdkRadioButtons. */
112112 protected items = computed ( ( ) => this . _cdkRadioButtons ( ) . map ( radio => radio . pattern ) ) ;
113113
@@ -136,16 +136,14 @@ export class CdkRadioGroup<V> {
136136 } ) ;
137137
138138 /** The RadioGroup UIPattern. */
139- pattern : RadioGroupPattern < V > = new RadioGroupPattern < V > ( {
139+ readonly pattern : RadioGroupPattern < V > = new RadioGroupPattern < V > ( {
140140 ...this ,
141141 items : this . items ,
142142 value : this . _value ,
143143 activeItem : signal ( undefined ) ,
144144 textDirection : this . textDirection ,
145- toolbar : this . _toolbarPattern ,
146145 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 ,
149147 } ) ;
150148
151149 /** Whether the radio group has received focus yet. */
@@ -162,35 +160,25 @@ export class CdkRadioGroup<V> {
162160 } ) ;
163161
164162 afterRenderEffect ( ( ) => {
165- if ( ! this . _hasFocused ( ) && ! this . toolbar ) {
163+ if ( ! this . _hasFocused ( ) && ! this . _hasToolbar ( ) ) {
166164 this . pattern . setDefaultState ( ) ;
167165 }
168166 } ) ;
169167
170- // TODO: Refactor to be handled within list behavior
171168 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 ( ) ) ;
181171 }
182172 } ) ;
173+
174+ if ( this . _hasToolbar ( ) ) {
175+ this . _cdkToolbarWidgetGroup . actions . set ( this . pattern . toolbarWidgetGroupActions ) ;
176+ }
183177 }
184178
185179 onFocus ( ) {
186180 this . _hasFocused . set ( true ) ;
187181 }
188-
189- toolbarButtonUnregister ( radio : CdkRadioButton < V > ) {
190- if ( this . toolbar ) {
191- this . toolbar . unregister ( radio ) ;
192- }
193- }
194182}
195183
196184/** A selectable radio button in a CdkRadioGroup. */
@@ -207,7 +195,7 @@ export class CdkRadioGroup<V> {
207195 '[id]' : 'pattern.id()' ,
208196 } ,
209197} )
210- export class CdkRadioButton < V > implements OnDestroy {
198+ export class CdkRadioButton < V > {
211199 /** A reference to the radio button element. */
212200 private readonly _elementRef = inject ( ElementRef ) ;
213201
@@ -218,13 +206,13 @@ export class CdkRadioButton<V> implements OnDestroy {
218206 private readonly _generatedId = inject ( _IdGenerator ) . getId ( 'cdk-radio-button-' ) ;
219207
220208 /** A unique identifier for the radio button. */
221- protected id = computed ( ( ) => this . _generatedId ) ;
209+ readonly id = computed ( ( ) => this . _generatedId ) ;
222210
223211 /** The value associated with the radio button. */
224212 readonly value = input . required < V > ( ) ;
225213
226214 /** The parent RadioGroup UIPattern. */
227- protected group = computed ( ( ) => this . _cdkRadioGroup . pattern ) ;
215+ readonly group = computed ( ( ) => this . _cdkRadioGroup . pattern ) ;
228216
229217 /** A reference to the radio button element to be focused on navigation. */
230218 element = computed ( ( ) => this . _elementRef . nativeElement ) ;
@@ -240,10 +228,4 @@ export class CdkRadioButton<V> implements OnDestroy {
240228 group : this . group ,
241229 element : this . element ,
242230 } ) ;
243-
244- ngOnDestroy ( ) {
245- if ( this . _cdkRadioGroup . toolbar ) {
246- this . _cdkRadioGroup . toolbarButtonUnregister ( this ) ;
247- }
248- }
249231}
0 commit comments