Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(material-experimental/mdc-radio): add functionality and styling #18272

Merged
merged 5 commits into from
Feb 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/dev-app/mdc-radio/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ ng_module(
],
deps = [
"//src/material-experimental/mdc-radio",
"//src/material/button",
"//src/material/checkbox",
"@npm//@angular/forms",
"@npm//@angular/router",
],
)
Expand Down
8 changes: 8 additions & 0 deletions src/dev-app/mdc-radio/mdc-radio-demo-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,18 @@ import {NgModule} from '@angular/core';
import {MatRadioModule} from '@angular/material-experimental/mdc-radio';
import {RouterModule} from '@angular/router';
import {MdcRadioDemo} from './mdc-radio-demo';
import {FormsModule} from '@angular/forms';
import {MatButtonModule} from '@angular/material/button';
import {MatCheckboxModule} from '@angular/material/checkbox';
import {CommonModule} from '@angular/common';

@NgModule({
imports: [
CommonModule,
MatRadioModule,
FormsModule,
MatButtonModule,
MatCheckboxModule,
RouterModule.forChild([{path: '', component: MdcRadioDemo}]),
],
declarations: [MdcRadioDemo],
Expand Down
61 changes: 59 additions & 2 deletions src/dev-app/mdc-radio/mdc-radio-demo.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,63 @@
<h1>Basic Example</h1>
<section class="demo-section">
<mat-radio-button name="group1">Option 1</mat-radio-button>
<mat-radio-button name="group1" checked>Option 1</mat-radio-button>
<mat-radio-button name="group1">Option 2</mat-radio-button>
<mat-radio-button name="group1" disabled>Option 3 (Disabled)</mat-radio-button>
<mat-radio-button name="group1" disabled="true">Option 3 (disabled)</mat-radio-button>
</section>

<h1>Color Example</h1>
<section class="demo-section">
<mat-radio-button name="group2">Default (accent)</mat-radio-button>
<mat-radio-button name="group2" color="primary">Primary</mat-radio-button>
<mat-radio-button name="group2" color="accent">Accent</mat-radio-button>
<mat-radio-button name="group2" color="warn">Warn</mat-radio-button>
</section>

<h1>Group Color Example</h1>
<section class="demo-section">
<mat-radio-group color="warn">
<mat-radio-button name="group3" value="1">Option 1</mat-radio-button>
<mat-radio-button name="group3" value="2">Option 2</mat-radio-button>
<mat-radio-button name="group3" value="3">Option 3</mat-radio-button>
<mat-radio-button name="group3" value="4" color="primary">Option with color override</mat-radio-button>
</mat-radio-group>
</section>

<h1>Dynamic Example</h1>
<section class="demo-section">
<div>
<span>isDisabled: {{isDisabled}}</span>
<button mat-raised-button (click)="isDisabled=!isDisabled" class="demo-button">
Disable buttons
</button>
</div>
<div>
<span>isRequired: {{isRequired}}</span>
<button mat-raised-button (click)="isRequired=!isRequired" class="demo-button">
Require buttons
</button>
</div>
<div>
<span><mat-checkbox [(ngModel)]="isAlignEnd">Align end</mat-checkbox></span>
</div>
<mat-radio-group
name="my_options"
[disabled]="isDisabled"
[required]="isRequired"
[labelPosition]="isAlignEnd ? 'after' : 'before'">
<mat-radio-button value="option_1">Option 1</mat-radio-button>
<mat-radio-button value="option_2">Option 2</mat-radio-button>
<mat-radio-button value="option_3">Option 3</mat-radio-button>
</mat-radio-group>
</section>

<h1>Favorite Season Example</h1>
<h2>Dynamic Example with two-way data-binding</h2>
<section class="demo-section">
<mat-radio-group name="more_options" [(ngModel)]="favoriteSeason">
<mat-radio-button *ngFor="let season of seasonOptions" name="more_options" [value]="season">
{{season}}
</mat-radio-button>
</mat-radio-group>
<p>Your favorite season is: {{favoriteSeason}}</p>
</section>
14 changes: 13 additions & 1 deletion src/dev-app/mdc-radio/mdc-radio-demo.scss
Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
// TODO: copy in demo styles from existing mat-radio demo.
.demo-button {
margin: 8px;
text-transform: uppercase;
}

.demo-section {
margin: 8px;
padding: 16px;

.mat-radio-button {
margin: 8px;
}
}
10 changes: 10 additions & 0 deletions src/dev-app/mdc-radio/mdc-radio-demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,14 @@ import {Component} from '@angular/core';
styleUrls: ['mdc-radio-demo.css'],
})
export class MdcRadioDemo {
isAlignEnd: boolean = false;
isDisabled: boolean = false;
isRequired: boolean = false;
favoriteSeason: string = 'Autumn';
seasonOptions = [
'Winter',
'Spring',
'Summer',
'Autumn',
];
}
39 changes: 29 additions & 10 deletions src/material-experimental/mdc-radio/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package(default_visibility = ["//visibility:public"])

load("//src/e2e-app:test_suite.bzl", "e2e_test_suite")
load(
"//tools:defaults.bzl",
"ng_e2e_test_library",
"ng_module",
"ng_test_library",
"ng_web_test_suite",
"sass_binary",
"sass_library",
)
Expand All @@ -18,7 +18,12 @@ ng_module(
assets = [":radio_scss"] + glob(["**/*.html"]),
module_name = "@angular/material-experimental/mdc-radio",
deps = [
"//src/cdk/a11y",
"//src/cdk/coercion",
"//src/cdk/collections",
"//src/material/core",
"//src/material/radio",
"@npm//@angular/forms",
"@npm//@material/radio",
],
)
Expand All @@ -44,18 +49,32 @@ sass_binary(
],
)

ng_e2e_test_library(
name = "e2e_test_sources",
srcs = glob(["**/*.e2e.spec.ts"]),
###########
# Testing
###########

ng_test_library(
name = "radio_tests_lib",
srcs = glob(
["**/*.spec.ts"],
exclude = ["**/*.e2e.spec.ts"],
),
deps = [
"//src/cdk/testing/private/e2e",
":mdc-radio",
"//src/cdk/testing/private",
"@npm//@angular/forms",
"@npm//@angular/platform-browser",
"@npm//@material/radio",
],
)

e2e_test_suite(
name = "e2e_tests",
ng_web_test_suite(
name = "unit_tests",
static_files = [
"@npm//:node_modules/@material/radio/dist/mdc.radio.js",
],
deps = [
":e2e_test_sources",
"//src/cdk/testing/private/e2e",
":radio_tests_lib",
"//src/material-experimental:mdc_require_config.js",
],
)
29 changes: 27 additions & 2 deletions src/material-experimental/mdc-radio/_mdc-radio.scss
Original file line number Diff line number Diff line change
@@ -1,13 +1,38 @@
@import '../mdc-helpers/mdc-helpers';
@import '@material/radio/mixins';
@import '@material/radio/variables';

@mixin mat-radio-theme-mdc($theme) {
// Save original values of MDC global variables. We need to save these so we can restore the
// variables to their original values and prevent unintended side effects from using this mixin.
$orig-mdc-radio-baseline-theme-color: $mdc-radio-baseline-theme-color;

@include mat-using-mdc-theme($theme) {
// TODO: MDC theme styles here.
$mdc-radio-baseline-theme-color: primary !global;

.mat-mdc-radio-button {
&.mat-primary {
@include mdc-radio-without-ripple($query: $mat-theme-styles-query);
}

&.mat-accent {
$mdc-radio-baseline-theme-color: secondary !global;
@include mdc-radio-without-ripple($query: $mat-theme-styles-query);
}

&.mat-warn {
$mdc-radio-baseline-theme-color: error !global;
@include mdc-radio-without-ripple($query: $mat-theme-styles-query);
}
}
}

// Restore original values of MDC global variables.
$mdc-radio-baseline-theme-color: $orig-mdc-radio-baseline-theme-color !global;
}

@mixin mat-radio-typography-mdc($config) {
@include mat-using-mdc-typography($config) {
// TODO: MDC typography styles here.
@include mdc-radio-without-ripple($query: $mat-typography-styles-query);
}
}
10 changes: 5 additions & 5 deletions src/material-experimental/mdc-radio/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@

import {CommonModule} from '@angular/common';
import {NgModule} from '@angular/core';
import {MatCommonModule} from '@angular/material/core';
import {MatRadioButton} from './radio';
import {MatCommonModule, MatRippleModule} from '@angular/material/core';
import {MatRadioButton, MatRadioGroup} from './radio';

@NgModule({
imports: [MatCommonModule, CommonModule],
exports: [MatRadioButton, MatCommonModule],
declarations: [MatRadioButton],
imports: [MatCommonModule, CommonModule, MatRippleModule],
exports: [MatRadioGroup, MatRadioButton],
declarations: [MatRadioGroup, MatRadioButton],
})
export class MatRadioModule {
}
28 changes: 25 additions & 3 deletions src/material-experimental/mdc-radio/radio.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,34 @@
<div class="mdc-form-field">
<div class="mdc-form-field" #formField
[class.mdc-form-field--align-end]="labelPosition == 'before'">
<div class="mdc-radio" [ngClass]="_classes">
<input class="mdc-radio__native-control" type="radio" [id]="inputId" [disabled]="disabled">
<input #input class="mdc-radio__native-control" type="radio"
[id]="inputId"
[checked]="checked"
[disabled]="disabled"
[tabIndex]="tabIndex"
[attr.name]="name"
[attr.value]="value"
[required]="required"
[attr.aria-label]="ariaLabel"
[attr.aria-labelledby]="ariaLabelledby"
[attr.aria-describedby]="ariaDescribedby"
(change)="_onInputChange($event)"
(click)="_onInputClick($event)">
<div class="mdc-radio__background">
<div class="mdc-radio__outer-circle"></div>
<div class="mdc-radio__inner-circle"></div>
</div>
<div class="mdc-radio__ripple"></div>
<div mat-ripple class="mat-radio-ripple"
[matRippleTrigger]="formField"
[matRippleDisabled]="_isRippleDisabled()"
[matRippleCentered]="true"
[matRippleRadius]="20"
[matRippleAnimation]="{enterDuration: 150}">
<div class="mat-ripple-element mat-radio-persistent-ripple"></div>
</div>
</div>
<label [for]="inputId" #label>
<label [for]="inputId">
<ng-content></ng-content>
</label>
</div>
18 changes: 17 additions & 1 deletion src/material-experimental/mdc-radio/radio.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
@import '@material/radio/mixins.import';
@import '@material/radio/variables.import';
@import '@material/form-field/mixins.import';
@import '../mdc-helpers/mdc-helpers';


@include mdc-radio-without-ripple($query: $mat-base-styles-query);
@include mdc-form-field-core-styles($query: $mat-base-styles-query);

// This is necessary because we do not depend on MDC's ripple, but have our own that should be
// positioned correctly. This can be removed once we start using MDC's ripple implementation.
.mat-mdc-radio-button .mat-radio-ripple {
position: absolute;
left: calc(50% - #{$mdc-radio-icon-size});
top: calc(50% - #{$mdc-radio-icon-size});
height: $mdc-radio-icon-size * 2;
width: $mdc-radio-icon-size * 2;
z-index: 1;
pointer-events: none;

.mat-ripple-element:not(.mat-radio-persistent-ripple) {
opacity: $mdc-radio-ripple-opacity;
}
}
Loading