Skip to content

Commit 1e280b5

Browse files
crisbetojelbourn
authored andcommitted
fix(material-experimental/mdc-radio): avoid hard references to base material components (#19403)
Currently the MDC radio button doesn't extend the Material one in order to avoid bringing in unecessary code. The problem is that the MDC button group still has a hard reference to the Material `MatRadioButton` which means that we'll likely end up importing it anyway. These changes move the button group code into a base class and remove the references to the Material button.
1 parent 50ab109 commit 1e280b5

File tree

3 files changed

+80
-52
lines changed

3 files changed

+80
-52
lines changed

src/material-experimental/mdc-radio/radio.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import {
2626
MAT_RADIO_DEFAULT_OPTIONS,
2727
_MatRadioButtonBase,
2828
MatRadioDefaultOptions,
29-
MatRadioGroup as BaseMatRadioGroup,
29+
_MatRadioGroupBase,
3030
} from '@angular/material/radio';
3131
import {FocusMonitor} from '@angular/cdk/a11y';
3232
import {UniqueSelectionDispatcher} from '@angular/cdk/collections';
@@ -66,13 +66,12 @@ const RIPPLE_ANIMATION_CONFIG: RippleAnimationConfig = {
6666
host: {
6767
'role': 'radiogroup',
6868
'class': 'mat-mdc-radio-group',
69-
'[class.mat-radio-group]': 'false',
7069
},
7170
})
72-
export class MatRadioGroup extends BaseMatRadioGroup {
71+
export class MatRadioGroup extends _MatRadioGroupBase<MatRadioButton> {
7372
/** Child radio buttons. */
7473
@ContentChildren(forwardRef(() => MatRadioButton), {descendants: true})
75-
_radios: QueryList<_MatRadioButtonBase>;
74+
_radios: QueryList<MatRadioButton>;
7675
}
7776

7877
@Component({

src/material/radio/radio.ts

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -78,32 +78,27 @@ export const MAT_RADIO_GROUP_CONTROL_VALUE_ACCESSOR: any = {
7878
export class MatRadioChange {
7979
constructor(
8080
/** The MatRadioButton that emits the change event. */
81-
public source: MatRadioButton,
81+
public source: _MatRadioButtonBase,
8282
/** The value of the MatRadioButton. */
8383
public value: any) {}
8484
}
8585

8686
/**
87-
* A group of radio buttons. May contain one or more `<mat-radio-button>` elements.
87+
* Base class with all of the `MatRadioGroup` functionality.
88+
* @docs-private
8889
*/
89-
@Directive({
90-
selector: 'mat-radio-group',
91-
exportAs: 'matRadioGroup',
92-
providers: [MAT_RADIO_GROUP_CONTROL_VALUE_ACCESSOR],
93-
host: {
94-
'role': 'radiogroup',
95-
'class': 'mat-radio-group',
96-
},
97-
})
98-
export class MatRadioGroup implements AfterContentInit, ControlValueAccessor {
90+
@Directive()
91+
// tslint:disable-next-line:class-name
92+
export abstract class _MatRadioGroupBase<T extends _MatRadioButtonBase> implements AfterContentInit,
93+
ControlValueAccessor {
9994
/** Selected value for the radio group. */
10095
private _value: any = null;
10196

10297
/** The HTML name attribute applied to radio buttons in this group. */
10398
private _name: string = `mat-radio-group-${nextUniqueId++}`;
10499

105100
/** The currently selected radio button. Should match value. */
106-
private _selected: MatRadioButton | null = null;
101+
private _selected: T | null = null;
107102

108103
/** Whether the `value` has been set to its initial value. */
109104
private _isInitialized: boolean = false;
@@ -134,8 +129,7 @@ export class MatRadioGroup implements AfterContentInit, ControlValueAccessor {
134129
@Output() readonly change: EventEmitter<MatRadioChange> = new EventEmitter<MatRadioChange>();
135130

136131
/** Child radio buttons. */
137-
@ContentChildren(forwardRef(() => MatRadioButton), { descendants: true })
138-
_radios: QueryList<MatRadioButton>;
132+
abstract _radios: QueryList<T>;
139133

140134
/** Theme color for all of the radio buttons in the group. */
141135
@Input() color: ThemePalette;
@@ -188,7 +182,7 @@ export class MatRadioGroup implements AfterContentInit, ControlValueAccessor {
188182
*/
189183
@Input()
190184
get selected() { return this._selected; }
191-
set selected(selected: MatRadioButton | null) {
185+
set selected(selected: T | null) {
192186
this._selected = selected;
193187
this.value = selected ? selected.value : null;
194188
this._checkSelectedRadioButton();
@@ -311,6 +305,23 @@ export class MatRadioGroup implements AfterContentInit, ControlValueAccessor {
311305
static ngAcceptInputType_required: BooleanInput;
312306
}
313307

308+
/**
309+
* A group of radio buttons. May contain one or more `<mat-radio-button>` elements.
310+
*/
311+
@Directive({
312+
selector: 'mat-radio-group',
313+
exportAs: 'matRadioGroup',
314+
providers: [MAT_RADIO_GROUP_CONTROL_VALUE_ACCESSOR],
315+
host: {
316+
'role': 'radiogroup',
317+
'class': 'mat-radio-group',
318+
},
319+
})
320+
export class MatRadioGroup extends _MatRadioGroupBase<MatRadioButton> {
321+
@ContentChildren(forwardRef(() => MatRadioButton), {descendants: true})
322+
_radios: QueryList<MatRadioButton>;
323+
}
324+
314325
// Boilerplate for applying mixins to MatRadioButton.
315326
/** @docs-private */
316327
class MatRadioButtonBase {
@@ -441,7 +452,7 @@ export abstract class _MatRadioButtonBase extends _MatRadioButtonMixinBase imple
441452
@Output() readonly change: EventEmitter<MatRadioChange> = new EventEmitter<MatRadioChange>();
442453

443454
/** The parent radio group. May or may not be present. */
444-
radioGroup: MatRadioGroup;
455+
radioGroup: _MatRadioGroupBase<_MatRadioButtonBase>;
445456

446457
/** ID of the native input element inside `<mat-radio-button>` */
447458
get inputId(): string { return `${this.id || this._uniqueId}-input`; }
@@ -464,7 +475,7 @@ export abstract class _MatRadioButtonBase extends _MatRadioButtonMixinBase imple
464475
/** The native `<input type=radio>` element */
465476
@ViewChild('input') _inputElement: ElementRef<HTMLInputElement>;
466477

467-
constructor(@Optional() radioGroup: MatRadioGroup,
478+
constructor(@Optional() radioGroup: _MatRadioGroupBase<_MatRadioButtonBase>,
468479
elementRef: ElementRef,
469480
protected _changeDetector: ChangeDetectorRef,
470481
private _focusMonitor: FocusMonitor,
@@ -615,4 +626,15 @@ export abstract class _MatRadioButtonBase extends _MatRadioButtonMixinBase imple
615626
changeDetection: ChangeDetectionStrategy.OnPush,
616627
})
617628
export class MatRadioButton extends _MatRadioButtonBase {
629+
constructor(@Optional() radioGroup: MatRadioGroup,
630+
elementRef: ElementRef,
631+
changeDetector: ChangeDetectorRef,
632+
focusMonitor: FocusMonitor,
633+
radioDispatcher: UniqueSelectionDispatcher,
634+
@Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode?: string,
635+
@Optional() @Inject(MAT_RADIO_DEFAULT_OPTIONS)
636+
providerOverride?: MatRadioDefaultOptions) {
637+
super(radioGroup, elementRef, changeDetector, focusMonitor, radioDispatcher,
638+
animationMode, providerOverride);
639+
}
618640
}

tools/public_api_guard/material/radio.d.ts

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ export declare abstract class _MatRadioButtonBase extends _MatRadioButtonMixinBa
1717
get labelPosition(): 'before' | 'after';
1818
set labelPosition(value: 'before' | 'after');
1919
name: string;
20-
radioGroup: MatRadioGroup;
20+
radioGroup: _MatRadioGroupBase<_MatRadioButtonBase>;
2121
get required(): boolean;
2222
set required(value: boolean);
2323
get value(): any;
2424
set value(value: any);
25-
constructor(radioGroup: MatRadioGroup, elementRef: ElementRef, _changeDetector: ChangeDetectorRef, _focusMonitor: FocusMonitor, _radioDispatcher: UniqueSelectionDispatcher, _animationMode?: string | undefined, _providerOverride?: MatRadioDefaultOptions | undefined);
25+
constructor(radioGroup: _MatRadioGroupBase<_MatRadioButtonBase>, elementRef: ElementRef, _changeDetector: ChangeDetectorRef, _focusMonitor: FocusMonitor, _radioDispatcher: UniqueSelectionDispatcher, _animationMode?: string | undefined, _providerOverride?: MatRadioDefaultOptions | undefined);
2626
_isRippleDisabled(): boolean;
2727
_markForCheck(): void;
2828
_onInputChange(event: Event): void;
@@ -40,32 +40,9 @@ export declare abstract class _MatRadioButtonBase extends _MatRadioButtonMixinBa
4040
static ɵfac: i0.ɵɵFactoryDef<_MatRadioButtonBase, [{ optional: true; }, null, null, null, null, { optional: true; }, { optional: true; }]>;
4141
}
4242

43-
export declare const MAT_RADIO_DEFAULT_OPTIONS: InjectionToken<MatRadioDefaultOptions>;
44-
45-
export declare function MAT_RADIO_DEFAULT_OPTIONS_FACTORY(): MatRadioDefaultOptions;
46-
47-
export declare const MAT_RADIO_GROUP_CONTROL_VALUE_ACCESSOR: any;
48-
49-
export declare class MatRadioButton extends _MatRadioButtonBase {
50-
static ɵcmp: i0.ɵɵComponentDefWithMeta<MatRadioButton, "mat-radio-button", ["matRadioButton"], { "disableRipple": "disableRipple"; "tabIndex": "tabIndex"; }, {}, never, ["*"]>;
51-
static ɵfac: i0.ɵɵFactoryDef<MatRadioButton, never>;
52-
}
53-
54-
export declare class MatRadioChange {
55-
source: MatRadioButton;
56-
value: any;
57-
constructor(
58-
source: MatRadioButton,
59-
value: any);
60-
}
61-
62-
export interface MatRadioDefaultOptions {
63-
color: ThemePalette;
64-
}
65-
66-
export declare class MatRadioGroup implements AfterContentInit, ControlValueAccessor {
43+
export declare abstract class _MatRadioGroupBase<T extends _MatRadioButtonBase> implements AfterContentInit, ControlValueAccessor {
6744
_controlValueAccessorChangeFn: (value: any) => void;
68-
_radios: QueryList<MatRadioButton>;
45+
abstract _radios: QueryList<T>;
6946
readonly change: EventEmitter<MatRadioChange>;
7047
color: ThemePalette;
7148
get disabled(): boolean;
@@ -77,8 +54,8 @@ export declare class MatRadioGroup implements AfterContentInit, ControlValueAcce
7754
onTouched: () => any;
7855
get required(): boolean;
7956
set required(value: boolean);
80-
get selected(): MatRadioButton | null;
81-
set selected(selected: MatRadioButton | null);
57+
get selected(): T | null;
58+
set selected(selected: T | null);
8259
get value(): any;
8360
set value(newValue: any);
8461
constructor(_changeDetector: ChangeDetectorRef);
@@ -93,7 +70,37 @@ export declare class MatRadioGroup implements AfterContentInit, ControlValueAcce
9370
writeValue(value: any): void;
9471
static ngAcceptInputType_disabled: BooleanInput;
9572
static ngAcceptInputType_required: BooleanInput;
96-
static ɵdir: i0.ɵɵDirectiveDefWithMeta<MatRadioGroup, "mat-radio-group", ["matRadioGroup"], { "color": "color"; "name": "name"; "labelPosition": "labelPosition"; "value": "value"; "selected": "selected"; "disabled": "disabled"; "required": "required"; }, { "change": "change"; }, ["_radios"]>;
73+
static ɵdir: i0.ɵɵDirectiveDefWithMeta<_MatRadioGroupBase<any>, never, never, { "color": "color"; "name": "name"; "labelPosition": "labelPosition"; "value": "value"; "selected": "selected"; "disabled": "disabled"; "required": "required"; }, { "change": "change"; }, never>;
74+
static ɵfac: i0.ɵɵFactoryDef<_MatRadioGroupBase<any>, never>;
75+
}
76+
77+
export declare const MAT_RADIO_DEFAULT_OPTIONS: InjectionToken<MatRadioDefaultOptions>;
78+
79+
export declare function MAT_RADIO_DEFAULT_OPTIONS_FACTORY(): MatRadioDefaultOptions;
80+
81+
export declare const MAT_RADIO_GROUP_CONTROL_VALUE_ACCESSOR: any;
82+
83+
export declare class MatRadioButton extends _MatRadioButtonBase {
84+
constructor(radioGroup: MatRadioGroup, elementRef: ElementRef, changeDetector: ChangeDetectorRef, focusMonitor: FocusMonitor, radioDispatcher: UniqueSelectionDispatcher, animationMode?: string, providerOverride?: MatRadioDefaultOptions);
85+
static ɵcmp: i0.ɵɵComponentDefWithMeta<MatRadioButton, "mat-radio-button", ["matRadioButton"], { "disableRipple": "disableRipple"; "tabIndex": "tabIndex"; }, {}, never, ["*"]>;
86+
static ɵfac: i0.ɵɵFactoryDef<MatRadioButton, [{ optional: true; }, null, null, null, null, { optional: true; }, { optional: true; }]>;
87+
}
88+
89+
export declare class MatRadioChange {
90+
source: _MatRadioButtonBase;
91+
value: any;
92+
constructor(
93+
source: _MatRadioButtonBase,
94+
value: any);
95+
}
96+
97+
export interface MatRadioDefaultOptions {
98+
color: ThemePalette;
99+
}
100+
101+
export declare class MatRadioGroup extends _MatRadioGroupBase<MatRadioButton> {
102+
_radios: QueryList<MatRadioButton>;
103+
static ɵdir: i0.ɵɵDirectiveDefWithMeta<MatRadioGroup, "mat-radio-group", ["matRadioGroup"], {}, {}, ["_radios"]>;
97104
static ɵfac: i0.ɵɵFactoryDef<MatRadioGroup, never>;
98105
}
99106

0 commit comments

Comments
 (0)