Skip to content

Commit

Permalink
fix(material-experimental/mdc-radio): avoid bundling styles from base…
Browse files Browse the repository at this point in the history
… radio button (#19032)

The MDC-based radio button currently extends the `MatRadioButton` directly which means that the styles and template from the base will be bundled together with the MDC one. These changes move all of the functionality into an undecorated base class which is then extended by the two button variants.

(cherry picked from commit 506b74a)
  • Loading branch information
crisbeto authored and jelbourn committed Apr 20, 2020
1 parent fd0217d commit 4557d58
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 47 deletions.
11 changes: 4 additions & 7 deletions src/material-experimental/mdc-radio/radio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
import {MDCRadioAdapter, MDCRadioFoundation} from '@material/radio';
import {
MAT_RADIO_DEFAULT_OPTIONS,
MatRadioButton as BaseMatRadioButton,
_MatRadioButtonBase,
MatRadioDefaultOptions,
MatRadioGroup as BaseMatRadioGroup,
} from '@angular/material/radio';
Expand Down Expand Up @@ -71,8 +71,8 @@ const RIPPLE_ANIMATION_CONFIG: RippleAnimationConfig = {
})
export class MatRadioGroup extends BaseMatRadioGroup {
/** Child radio buttons. */
@ContentChildren(forwardRef(() => MatRadioButton), { descendants: true })
_radios: QueryList<BaseMatRadioButton>;
@ContentChildren(forwardRef(() => MatRadioButton), {descendants: true})
_radios: QueryList<_MatRadioButtonBase>;
}

@Component({
Expand All @@ -81,9 +81,6 @@ export class MatRadioGroup extends BaseMatRadioGroup {
styleUrls: ['radio.css'],
host: {
'class': 'mat-mdc-radio-button',
// Ivy will inherit the mat-radio-button class from the parent class, but we do not want
// this to be applied in the MDC component. Set this explicitly to false so it is not applied.
'[class.mat-radio-button]': 'false',
'[attr.id]': 'id',
'[class.mat-primary]': 'color === "primary"',
'[class.mat-accent]': 'color === "accent"',
Expand All @@ -102,7 +99,7 @@ export class MatRadioGroup extends BaseMatRadioGroup {
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MatRadioButton extends BaseMatRadioButton implements AfterViewInit, OnDestroy {
export class MatRadioButton extends _MatRadioButtonBase implements AfterViewInit, OnDestroy {

private _radioAdapter: MDCRadioAdapter = {
addClass: (className: string) => this._setClass(className, true),
Expand Down
72 changes: 41 additions & 31 deletions src/material/radio/radio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -328,38 +328,13 @@ const _MatRadioButtonMixinBase:
mixinDisableRipple(mixinTabIndex(MatRadioButtonBase));

/**
* A Material design radio-button. Typically placed inside of `<mat-radio-group>` elements.
* Base class with all of the `MatRadioButton` functionality.
* @docs-private
*/
@Component({
selector: 'mat-radio-button',
templateUrl: 'radio.html',
styleUrls: ['radio.css'],
inputs: ['disableRipple', 'tabIndex'],
encapsulation: ViewEncapsulation.None,
exportAs: 'matRadioButton',
host: {
'class': 'mat-radio-button',
'[class.mat-radio-checked]': 'checked',
'[class.mat-radio-disabled]': 'disabled',
'[class._mat-animation-noopable]': '_animationMode === "NoopAnimations"',
'[class.mat-primary]': 'color === "primary"',
'[class.mat-accent]': 'color === "accent"',
'[class.mat-warn]': 'color === "warn"',
// Needs to be -1 so the `focus` event still fires.
'[attr.tabindex]': '-1',
'[attr.id]': 'id',
'[attr.aria-label]': 'null',
'[attr.aria-labelledby]': 'null',
'[attr.aria-describedby]': 'null',
// Note: under normal conditions focus shouldn't land on this element, however it may be
// programmatically set, for example inside of a focus trap, in this case we want to forward
// the focus to the native element.
'(focus)': '_inputElement.nativeElement.focus()',
},
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MatRadioButton extends _MatRadioButtonMixinBase
implements OnInit, AfterViewInit, OnDestroy, CanDisableRipple, HasTabIndex {
@Directive()
// tslint:disable-next-line:class-name
export abstract class _MatRadioButtonBase extends _MatRadioButtonMixinBase implements OnInit,
AfterViewInit, OnDestroy, CanDisableRipple, HasTabIndex {

private _uniqueId: string = `mat-radio-${++nextUniqueId}`;

Expand Down Expand Up @@ -606,3 +581,38 @@ export class MatRadioButton extends _MatRadioButtonMixinBase
static ngAcceptInputType_required: BooleanInput;
static ngAcceptInputType_disableRipple: BooleanInput;
}


/**
* A Material design radio-button. Typically placed inside of `<mat-radio-group>` elements.
*/
@Component({
selector: 'mat-radio-button',
templateUrl: 'radio.html',
styleUrls: ['radio.css'],
inputs: ['disableRipple', 'tabIndex'],
encapsulation: ViewEncapsulation.None,
exportAs: 'matRadioButton',
host: {
'class': 'mat-radio-button',
'[class.mat-radio-checked]': 'checked',
'[class.mat-radio-disabled]': 'disabled',
'[class._mat-animation-noopable]': '_animationMode === "NoopAnimations"',
'[class.mat-primary]': 'color === "primary"',
'[class.mat-accent]': 'color === "accent"',
'[class.mat-warn]': 'color === "warn"',
// Needs to be -1 so the `focus` event still fires.
'[attr.tabindex]': '-1',
'[attr.id]': 'id',
'[attr.aria-label]': 'null',
'[attr.aria-labelledby]': 'null',
'[attr.aria-describedby]': 'null',
// Note: under normal conditions focus shouldn't land on this element, however it may be
// programmatically set, for example inside of a focus trap, in this case we want to forward
// the focus to the native element.
'(focus)': '_inputElement.nativeElement.focus()',
},
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MatRadioButton extends _MatRadioButtonBase {
}
23 changes: 14 additions & 9 deletions tools/public_api_guard/material/radio.d.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
export declare const MAT_RADIO_DEFAULT_OPTIONS: InjectionToken<MatRadioDefaultOptions>;

export declare function MAT_RADIO_DEFAULT_OPTIONS_FACTORY(): MatRadioDefaultOptions;

export declare const MAT_RADIO_GROUP_CONTROL_VALUE_ACCESSOR: any;

export declare class MatRadioButton extends _MatRadioButtonMixinBase implements OnInit, AfterViewInit, OnDestroy, CanDisableRipple, HasTabIndex {
export declare abstract class _MatRadioButtonBase extends _MatRadioButtonMixinBase implements OnInit, AfterViewInit, OnDestroy, CanDisableRipple, HasTabIndex {
_animationMode?: string | undefined;
protected _changeDetector: ChangeDetectorRef;
_inputElement: ElementRef<HTMLInputElement>;
Expand Down Expand Up @@ -42,8 +36,19 @@ export declare class MatRadioButton extends _MatRadioButtonMixinBase implements
static ngAcceptInputType_disableRipple: BooleanInput;
static ngAcceptInputType_disabled: BooleanInput;
static ngAcceptInputType_required: BooleanInput;
static ɵcmp: i0.ɵɵComponentDefWithMeta<MatRadioButton, "mat-radio-button", ["matRadioButton"], { "disableRipple": "disableRipple"; "tabIndex": "tabIndex"; "id": "id"; "name": "name"; "ariaLabel": "aria-label"; "ariaLabelledby": "aria-labelledby"; "ariaDescribedby": "aria-describedby"; "checked": "checked"; "value": "value"; "labelPosition": "labelPosition"; "disabled": "disabled"; "required": "required"; "color": "color"; }, { "change": "change"; }, never, ["*"]>;
static ɵfac: i0.ɵɵFactoryDef<MatRadioButton, [{ optional: true; }, null, null, null, null, { optional: true; }, { optional: true; }]>;
static ɵdir: i0.ɵɵDirectiveDefWithMeta<_MatRadioButtonBase, never, never, { "id": "id"; "name": "name"; "ariaLabel": "aria-label"; "ariaLabelledby": "aria-labelledby"; "ariaDescribedby": "aria-describedby"; "checked": "checked"; "value": "value"; "labelPosition": "labelPosition"; "disabled": "disabled"; "required": "required"; "color": "color"; }, { "change": "change"; }, never>;
static ɵfac: i0.ɵɵFactoryDef<_MatRadioButtonBase, [{ optional: true; }, null, null, null, null, { optional: true; }, { optional: true; }]>;
}

export declare const MAT_RADIO_DEFAULT_OPTIONS: InjectionToken<MatRadioDefaultOptions>;

export declare function MAT_RADIO_DEFAULT_OPTIONS_FACTORY(): MatRadioDefaultOptions;

export declare const MAT_RADIO_GROUP_CONTROL_VALUE_ACCESSOR: any;

export declare class MatRadioButton extends _MatRadioButtonBase {
static ɵcmp: i0.ɵɵComponentDefWithMeta<MatRadioButton, "mat-radio-button", ["matRadioButton"], { "disableRipple": "disableRipple"; "tabIndex": "tabIndex"; }, {}, never, ["*"]>;
static ɵfac: i0.ɵɵFactoryDef<MatRadioButton, never>;
}

export declare class MatRadioChange {
Expand Down

0 comments on commit 4557d58

Please sign in to comment.