From 4a6a0f18bbd174be2ed809ce3c580956aad1fd57 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Mon, 8 Aug 2022 14:29:09 +0200 Subject: [PATCH] feat(material/radio): switch implementation to use MDC (#25409) Switches the `material/radio` implementation to use MDC by default. Old implementation is still available under `material/legacy-radio`. BREAKING CHANGE: - DOM and CSS classes for `mat-radio-group` and `mat-radio-button` have changes. - Typescript API is largely the same but may have minor differences. --- .github/CODEOWNERS | 5 +- .ng-dev/commit-message.mts | 2 +- .../harness-e2e-cli/e2e/radio-harness.spec.ts | 4 +- .../harness-e2e-cli/src/app/app.module.ts | 4 +- .../size-test/material/radio/BUILD.bazel | 2 +- .../size-test/material/radio/without-group.ts | 4 +- .../material/checkbox/BUILD.bazel | 2 +- .../material/checkbox/index.ts | 4 +- .../material/form-field/BUILD.bazel | 2 +- .../material/form-field/index.ts | 4 +- .../material/progress-bar/BUILD.bazel | 2 +- .../material/progress-bar/index.ts | 4 +- .../material/progress-spinner/BUILD.bazel | 2 +- .../material/progress-spinner/index.ts | 4 +- .../material/radio/BUILD.bazel | 8 +- .../material/radio/index.ts | 4 +- .../radio-harness-example.spec.ts | 17 +- .../material/sidenav/BUILD.bazel | 2 +- .../material/sidenav/index.ts | 4 +- .../material/slide-toggle/BUILD.bazel | 2 +- .../material/slide-toggle/index.ts | 4 +- .../material/stepper/BUILD.bazel | 2 +- .../material/stepper/index.ts | 4 +- src/dev-app/baseline/BUILD.bazel | 2 +- src/dev-app/baseline/baseline-demo.ts | 4 +- src/dev-app/connected-overlay/BUILD.bazel | 2 +- .../connected-overlay-demo.ts | 4 +- src/dev-app/expansion/BUILD.bazel | 2 +- src/dev-app/expansion/expansion-demo.ts | 4 +- src/dev-app/input-modality/BUILD.bazel | 2 +- .../input-modality-detector-demo.ts | 4 +- src/dev-app/mdc-radio/BUILD.bazel | 2 +- src/dev-app/mdc-radio/mdc-radio-demo.ts | 2 +- src/dev-app/radio/BUILD.bazel | 2 +- src/dev-app/radio/radio-demo.ts | 10 +- src/dev-app/youtube-player/BUILD.bazel | 2 +- .../youtube-player/youtube-player-demo.ts | 4 +- src/e2e-app/BUILD.bazel | 2 +- src/e2e-app/mdc-radio/mdc-radio-e2e-module.ts | 2 +- src/e2e-app/radio/radio-e2e-module.ts | 4 +- src/material-experimental/_index.scss | 2 - src/material-experimental/config.bzl | 2 - .../mdc-core/color/_all-color.import.scss | 4 - .../mdc-core/density/_all-density.import.scss | 4 - .../mdc-core/theming/BUILD.bazel | 1 - .../mdc-core/theming/_all-theme.import.scss | 5 - .../mdc-core/theming/_all-theme.scss | 3 +- .../typography/_all-typography.import.scss | 4 - src/material-experimental/mdc-radio/README.md | 73 ----- .../mdc-radio/_radio-theme.import.scss | 4 - .../mdc-radio/_radio-theme.scss | 109 ------- .../mdc-radio/public-api.ts | 12 - .../mdc-radio/radio.e2e.spec.ts | 22 -- .../mdc-radio/radio.html | 31 -- .../mdc-radio/radio.scss | 115 ------- .../mdc-radio/testing/radio-harness.spec.ts | 7 - src/material/_index.scss | 2 + src/material/_theming.scss | 2 +- src/material/config.bzl | 2 + .../core/density/private/_all-density.scss | 2 + src/material/core/theming/_all-theme.scss | 2 +- .../tests/test-css-variables-theme.scss | 2 - .../core/typography/_all-typography.scss | 2 +- .../legacy-core/theming/_all-theme.scss | 2 + .../typography/_all-typography.scss | 2 + .../legacy-radio}/BUILD.bazel | 44 +-- src/material/legacy-radio/README.md | 1 + .../legacy-radio/_radio-legacy-index.scss | 2 + .../legacy-radio/_radio-theme.import.scss | 8 + src/material/legacy-radio/_radio-theme.scss | 98 ++++++ .../legacy-radio}/index.ts | 0 src/material/legacy-radio/public-api.ts | 18 ++ .../{radio => legacy-radio}/radio-module.ts | 8 +- src/material/legacy-radio/radio.e2e.spec.ts | 38 +++ src/material/legacy-radio/radio.html | 40 +++ src/material/legacy-radio/radio.md | 62 ++++ src/material/legacy-radio/radio.scss | 223 ++++++++++++++ .../legacy-radio}/radio.spec.ts | 126 ++++---- .../legacy-radio}/radio.ts | 78 ++--- .../legacy-radio}/testing/BUILD.bazel | 12 +- .../legacy-radio}/testing/index.ts | 0 .../legacy-radio}/testing/public-api.ts | 0 .../testing/radio-harness.spec.ts | 11 + .../legacy-radio}/testing/radio-harness.ts | 48 ++- src/material/radio/BUILD.bazel | 44 +-- src/material/radio/README.md | 2 +- src/material/radio/_radio-legacy-index.scss | 2 - src/material/radio/_radio-theme.import.scss | 10 +- src/material/radio/_radio-theme.scss | 116 ++++--- .../mdc-radio => material/radio}/module.ts | 0 src/material/radio/public-api.ts | 2 +- src/material/radio/radio.e2e.spec.ts | 26 +- src/material/radio/radio.html | 67 ++-- src/material/radio/radio.scss | 291 ++++++------------ src/material/radio/radio.spec.ts | 68 ++-- src/material/radio/radio.ts | 135 ++++---- src/material/radio/testing/BUILD.bazel | 32 +- .../radio/testing/radio-harness.spec.ts | 2 +- src/material/radio/testing/radio-harness.ts | 36 ++- ...ame@dasherize__.component.spec.ts.template | 16 +- .../ng-generate/address-form/index.spec.ts | 6 +- .../ng-generate/address-form/index.ts | 28 +- .../kitchen-sink-mdc/kitchen-sink-mdc.ts | 2 +- .../kitchen-sink/kitchen-sink.ts | 4 +- .../material/legacy-radio-testing.md | 39 +++ .../public_api_guard/material/legacy-radio.md | 66 ++++ .../material/radio-testing.md | 4 +- tools/public_api_guard/material/radio.md | 8 +- 108 files changed, 1258 insertions(+), 1127 deletions(-) delete mode 100644 src/material-experimental/mdc-radio/README.md delete mode 100644 src/material-experimental/mdc-radio/_radio-theme.import.scss delete mode 100644 src/material-experimental/mdc-radio/_radio-theme.scss delete mode 100644 src/material-experimental/mdc-radio/public-api.ts delete mode 100644 src/material-experimental/mdc-radio/radio.e2e.spec.ts delete mode 100644 src/material-experimental/mdc-radio/radio.html delete mode 100644 src/material-experimental/mdc-radio/radio.scss delete mode 100644 src/material-experimental/mdc-radio/testing/radio-harness.spec.ts rename src/{material-experimental/mdc-radio => material/legacy-radio}/BUILD.bazel (69%) create mode 100644 src/material/legacy-radio/README.md create mode 100644 src/material/legacy-radio/_radio-legacy-index.scss create mode 100644 src/material/legacy-radio/_radio-theme.import.scss create mode 100644 src/material/legacy-radio/_radio-theme.scss rename src/{material-experimental/mdc-radio => material/legacy-radio}/index.ts (100%) create mode 100644 src/material/legacy-radio/public-api.ts rename src/material/{radio => legacy-radio}/radio-module.ts (61%) create mode 100644 src/material/legacy-radio/radio.e2e.spec.ts create mode 100644 src/material/legacy-radio/radio.html create mode 100644 src/material/legacy-radio/radio.md create mode 100644 src/material/legacy-radio/radio.scss rename src/{material-experimental/mdc-radio => material/legacy-radio}/radio.spec.ts (92%) rename src/{material-experimental/mdc-radio => material/legacy-radio}/radio.ts (65%) rename src/{material-experimental/mdc-radio => material/legacy-radio}/testing/BUILD.bazel (76%) rename src/{material-experimental/mdc-radio => material/legacy-radio}/testing/index.ts (100%) rename src/{material-experimental/mdc-radio => material/legacy-radio}/testing/public-api.ts (100%) create mode 100644 src/material/legacy-radio/testing/radio-harness.spec.ts rename src/{material-experimental/mdc-radio => material/legacy-radio}/testing/radio-harness.ts (57%) delete mode 100644 src/material/radio/_radio-legacy-index.scss rename src/{material-experimental/mdc-radio => material/radio}/module.ts (100%) create mode 100644 tools/public_api_guard/material/legacy-radio-testing.md create mode 100644 tools/public_api_guard/material/legacy-radio.md diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 264aa6fcbbd1..fb46bfaec67d 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -23,7 +23,7 @@ /src/material/legacy-prebuilt-themes/** @andrewseguin /src/material/legacy-progress-bar/** @andrewseguin @crisbeto /src/material/progress-spinner/** @andrewseguin @crisbeto -/src/material/radio/** @andrewseguin @devversion +/src/material/legacy-radio/** @andrewseguin @devversion /src/material/schematics/** @devversion @andrewseguin /src/material/legacy-select/** @crisbeto /src/material/select/** @crisbeto @@ -124,7 +124,7 @@ /src/material-experimental/mdc-paginator/** @crisbeto /src/material-experimental/mdc-progress-spinner/** @andrewseguin /src/material/progress-bar/** @andrewseguin -/src/material-experimental/mdc-radio/** @mmalerba +/src/material/radio/** @mmalerba /src/material-experimental/mdc-snack-bar/** @andrewseguin /src/material/slide-toggle/** @crisbeto /src/material-experimental/mdc-slider/** @devversion @@ -339,6 +339,7 @@ /tools/public_api_guard/material/legacy-progress-bar** @andrewseguin @crisbeto /tools/public_api_guard/material/progress-spinner**@andrewseguin @crisbeto /tools/public_api_guard/material/radio** @andrewseguin @devversion +/tools/public_api_guard/material/legacy-radio** @andrewseguin @devversion /tools/public_api_guard/material/legacy-select** @crisbeto /tools/public_api_guard/material/sidenav** @mmalerba /tools/public_api_guard/material/legacy-slide-toggle** @devversion diff --git a/.ng-dev/commit-message.mts b/.ng-dev/commit-message.mts index 57ae590dafa1..f106fafa0730 100644 --- a/.ng-dev/commit-message.mts +++ b/.ng-dev/commit-message.mts @@ -52,7 +52,6 @@ export const commitMessage: CommitMessageConfig = { 'material-experimental/mdc-paginator', 'material/progress-bar', 'material-experimental/mdc-progress-spinner', - 'material-experimental/mdc-radio', 'material/slide-toggle', 'material-experimental/mdc-slider', 'material-experimental/mdc-snack-bar', @@ -95,6 +94,7 @@ export const commitMessage: CommitMessageConfig = { 'material/legacy-progress-bar', 'material/progress-spinner', 'material/radio', + 'material/legacy-radio', 'material/schematics', 'material/select', 'material/legacy-select', diff --git a/integration/harness-e2e-cli/e2e/radio-harness.spec.ts b/integration/harness-e2e-cli/e2e/radio-harness.spec.ts index 24a9a2638ece..c298b03b8800 100644 --- a/integration/harness-e2e-cli/e2e/radio-harness.spec.ts +++ b/integration/harness-e2e-cli/e2e/radio-harness.spec.ts @@ -1,4 +1,4 @@ -import {MatRadioGroupHarness} from '@angular/material/radio/testing'; +import {MatLegacyRadioGroupHarness} from '@angular/material/legacy-radio/testing'; import {SeleniumWebDriverHarnessEnvironment} from '@angular/cdk/testing/selenium-webdriver'; import {HarnessLoader} from '@angular/cdk/testing'; import {configureDriver} from './driver.js'; @@ -18,7 +18,7 @@ describe('app test', () => { }); it('should work', async () => { - const group = await loader.getHarness(MatRadioGroupHarness); + const group = await loader.getHarness(MatLegacyRadioGroupHarness); expect(group).toBeDefined(); expect(await group.getCheckedValue()).toBe(null); diff --git a/integration/harness-e2e-cli/src/app/app.module.ts b/integration/harness-e2e-cli/src/app/app.module.ts index c7d7aa82584b..1ecb49ae75eb 100644 --- a/integration/harness-e2e-cli/src/app/app.module.ts +++ b/integration/harness-e2e-cli/src/app/app.module.ts @@ -3,11 +3,11 @@ import {BrowserModule} from '@angular/platform-browser'; import {NoopAnimationsModule} from '@angular/platform-browser/animations'; import {AppComponent} from './app.component'; -import {MatRadioModule} from '@angular/material/radio'; +import {MatLegacyRadioModule} from '@angular/material/legacy-radio'; @NgModule({ declarations: [AppComponent], - imports: [MatRadioModule, NoopAnimationsModule, BrowserModule], + imports: [MatLegacyRadioModule, NoopAnimationsModule, BrowserModule], bootstrap: [AppComponent], }) export class AppModule {} diff --git a/integration/size-test/material/radio/BUILD.bazel b/integration/size-test/material/radio/BUILD.bazel index 12e1478d275f..51d62ac94311 100644 --- a/integration/size-test/material/radio/BUILD.bazel +++ b/integration/size-test/material/radio/BUILD.bazel @@ -3,5 +3,5 @@ load("//integration/size-test:index.bzl", "size_test") size_test( name = "without-group", file = "without-group.ts", - deps = ["//src/material/radio"], + deps = ["//src/material/legacy-radio"], ) diff --git a/integration/size-test/material/radio/without-group.ts b/integration/size-test/material/radio/without-group.ts index 79a9a25e4ecb..f5bfce8f0058 100644 --- a/integration/size-test/material/radio/without-group.ts +++ b/integration/size-test/material/radio/without-group.ts @@ -1,5 +1,5 @@ import {Component, NgModule} from '@angular/core'; -import {MatRadioModule} from '@angular/material/radio'; +import {MatLegacyRadioModule} from '@angular/material/legacy-radio'; /** * Basic component using `MatRadioButton`. Doesn't use a `MatRadioGroup`, so the class @@ -13,7 +13,7 @@ import {MatRadioModule} from '@angular/material/radio'; export class TestComponent {} @NgModule({ - imports: [MatRadioModule], + imports: [MatLegacyRadioModule], declarations: [TestComponent], bootstrap: [TestComponent], }) diff --git a/src/components-examples/material/checkbox/BUILD.bazel b/src/components-examples/material/checkbox/BUILD.bazel index 7b518c887b90..cca9a4c9434f 100644 --- a/src/components-examples/material/checkbox/BUILD.bazel +++ b/src/components-examples/material/checkbox/BUILD.bazel @@ -18,7 +18,7 @@ ng_module( "//src/material/legacy-card", "//src/material/legacy-checkbox", "//src/material/legacy-checkbox/testing", - "//src/material/radio", + "//src/material/legacy-radio", "@npm//@angular/forms", "@npm//@angular/platform-browser", "@npm//@angular/platform-browser-dynamic", diff --git a/src/components-examples/material/checkbox/index.ts b/src/components-examples/material/checkbox/index.ts index b0792049d80b..273218ede44b 100644 --- a/src/components-examples/material/checkbox/index.ts +++ b/src/components-examples/material/checkbox/index.ts @@ -3,7 +3,7 @@ import {NgModule} from '@angular/core'; import {FormsModule, ReactiveFormsModule} from '@angular/forms'; import {MatLegacyCardModule} from '@angular/material/legacy-card'; import {MatLegacyCheckboxModule} from '@angular/material/legacy-checkbox'; -import {MatRadioModule} from '@angular/material/radio'; +import {MatLegacyRadioModule} from '@angular/material/legacy-radio'; import {CheckboxConfigurableExample} from './checkbox-configurable/checkbox-configurable-example'; import {CheckboxHarnessExample} from './checkbox-harness/checkbox-harness-example'; import {CheckboxOverviewExample} from './checkbox-overview/checkbox-overview-example'; @@ -28,7 +28,7 @@ const EXAMPLES = [ CommonModule, MatLegacyCardModule, MatLegacyCheckboxModule, - MatRadioModule, + MatLegacyRadioModule, FormsModule, ReactiveFormsModule, ], diff --git a/src/components-examples/material/form-field/BUILD.bazel b/src/components-examples/material/form-field/BUILD.bazel index 459a52482dd6..3e768c46ff21 100644 --- a/src/components-examples/material/form-field/BUILD.bazel +++ b/src/components-examples/material/form-field/BUILD.bazel @@ -22,7 +22,7 @@ ng_module( "//src/material/input", "//src/material/input/testing", "//src/material/legacy-checkbox", - "//src/material/radio", + "//src/material/legacy-radio", "//src/material/select", "@npm//@angular/forms", "@npm//@angular/platform-browser", diff --git a/src/components-examples/material/form-field/index.ts b/src/components-examples/material/form-field/index.ts index 0a498329803a..4f47fb0e35ce 100644 --- a/src/components-examples/material/form-field/index.ts +++ b/src/components-examples/material/form-field/index.ts @@ -6,7 +6,7 @@ import {MatLegacyCheckboxModule} from '@angular/material/legacy-checkbox'; import {MatFormFieldModule} from '@angular/material/form-field'; import {MatIconModule} from '@angular/material/icon'; import {MatInputModule} from '@angular/material/input'; -import {MatRadioModule} from '@angular/material/radio'; +import {MatLegacyRadioModule} from '@angular/material/legacy-radio'; import {MatSelectModule} from '@angular/material/select'; import {FormFieldAppearanceExample} from './form-field-appearance/form-field-appearance-example'; import { @@ -54,7 +54,7 @@ const EXAMPLES = [ MatFormFieldModule, MatIconModule, MatInputModule, - MatRadioModule, + MatLegacyRadioModule, MatSelectModule, ReactiveFormsModule, ], diff --git a/src/components-examples/material/progress-bar/BUILD.bazel b/src/components-examples/material/progress-bar/BUILD.bazel index fd1bbf17635b..eccecb427370 100644 --- a/src/components-examples/material/progress-bar/BUILD.bazel +++ b/src/components-examples/material/progress-bar/BUILD.bazel @@ -18,7 +18,7 @@ ng_module( "//src/material/legacy-card", "//src/material/legacy-progress-bar", "//src/material/legacy-progress-bar/testing", - "//src/material/radio", + "//src/material/legacy-radio", "//src/material/slider", "@npm//@angular/forms", "@npm//@angular/platform-browser", diff --git a/src/components-examples/material/progress-bar/index.ts b/src/components-examples/material/progress-bar/index.ts index 2343e307b68e..17283592cdad 100644 --- a/src/components-examples/material/progress-bar/index.ts +++ b/src/components-examples/material/progress-bar/index.ts @@ -3,7 +3,7 @@ import {NgModule} from '@angular/core'; import {FormsModule} from '@angular/forms'; import {MatLegacyCardModule} from '@angular/material/legacy-card'; import {MatLegacyProgressBarModule} from '@angular/material/legacy-progress-bar'; -import {MatRadioModule} from '@angular/material/radio'; +import {MatLegacyRadioModule} from '@angular/material/legacy-radio'; import {MatSliderModule} from '@angular/material/slider'; import {ProgressBarBufferExample} from './progress-bar-buffer/progress-bar-buffer-example'; import {ProgressBarConfigurableExample} from './progress-bar-configurable/progress-bar-configurable-example'; @@ -35,7 +35,7 @@ const EXAMPLES = [ CommonModule, MatLegacyCardModule, MatLegacyProgressBarModule, - MatRadioModule, + MatLegacyRadioModule, MatSliderModule, FormsModule, ], diff --git a/src/components-examples/material/progress-spinner/BUILD.bazel b/src/components-examples/material/progress-spinner/BUILD.bazel index 467dbebbc44f..0f8607e4f620 100644 --- a/src/components-examples/material/progress-spinner/BUILD.bazel +++ b/src/components-examples/material/progress-spinner/BUILD.bazel @@ -16,9 +16,9 @@ ng_module( "//src/cdk/testing", "//src/cdk/testing/testbed", "//src/material/legacy-card", + "//src/material/legacy-radio", "//src/material/progress-spinner", "//src/material/progress-spinner/testing", - "//src/material/radio", "//src/material/slider", "@npm//@angular/forms", "@npm//@angular/platform-browser", diff --git a/src/components-examples/material/progress-spinner/index.ts b/src/components-examples/material/progress-spinner/index.ts index 2ea85f342a65..36c5d780181d 100644 --- a/src/components-examples/material/progress-spinner/index.ts +++ b/src/components-examples/material/progress-spinner/index.ts @@ -3,7 +3,7 @@ import {NgModule} from '@angular/core'; import {FormsModule} from '@angular/forms'; import {MatLegacyCardModule} from '@angular/material/legacy-card'; import {MatProgressSpinnerModule} from '@angular/material/progress-spinner'; -import {MatRadioModule} from '@angular/material/radio'; +import {MatLegacyRadioModule} from '@angular/material/legacy-radio'; import {MatSliderModule} from '@angular/material/slider'; import {ProgressSpinnerConfigurableExample} from './progress-spinner-configurable/progress-spinner-configurable-example'; import {ProgressSpinnerOverviewExample} from './progress-spinner-overview/progress-spinner-overview-example'; @@ -26,7 +26,7 @@ const EXAMPLES = [ CommonModule, MatLegacyCardModule, MatProgressSpinnerModule, - MatRadioModule, + MatLegacyRadioModule, MatSliderModule, FormsModule, ], diff --git a/src/components-examples/material/radio/BUILD.bazel b/src/components-examples/material/radio/BUILD.bazel index 63b6858eb0a5..4385be6fda84 100644 --- a/src/components-examples/material/radio/BUILD.bazel +++ b/src/components-examples/material/radio/BUILD.bazel @@ -15,8 +15,8 @@ ng_module( deps = [ "//src/cdk/testing", "//src/cdk/testing/testbed", - "//src/material/radio", - "//src/material/radio/testing", + "//src/material/legacy-radio", + "//src/material/legacy-radio/testing", "@npm//@angular/forms", "@npm//@angular/platform-browser", "@npm//@angular/platform-browser-dynamic", @@ -40,8 +40,8 @@ ng_test_library( ":radio", "//src/cdk/testing", "//src/cdk/testing/testbed", - "//src/material/radio", - "//src/material/radio/testing", + "//src/material/legacy-radio", + "//src/material/legacy-radio/testing", "@npm//@angular/forms", "@npm//@angular/platform-browser-dynamic", ], diff --git a/src/components-examples/material/radio/index.ts b/src/components-examples/material/radio/index.ts index d9d31221373e..38885e3766a7 100644 --- a/src/components-examples/material/radio/index.ts +++ b/src/components-examples/material/radio/index.ts @@ -1,7 +1,7 @@ import {CommonModule} from '@angular/common'; import {NgModule} from '@angular/core'; import {FormsModule, ReactiveFormsModule} from '@angular/forms'; -import {MatRadioModule} from '@angular/material/radio'; +import {MatLegacyRadioModule} from '@angular/material/legacy-radio'; import {RadioNgModelExample} from './radio-ng-model/radio-ng-model-example'; import {RadioOverviewExample} from './radio-overview/radio-overview-example'; import {RadioHarnessExample} from './radio-harness/radio-harness-example'; @@ -11,7 +11,7 @@ export {RadioHarnessExample, RadioNgModelExample, RadioOverviewExample}; const EXAMPLES = [RadioHarnessExample, RadioNgModelExample, RadioOverviewExample]; @NgModule({ - imports: [ReactiveFormsModule, CommonModule, MatRadioModule, FormsModule], + imports: [ReactiveFormsModule, CommonModule, MatLegacyRadioModule, FormsModule], declarations: EXAMPLES, exports: EXAMPLES, }) diff --git a/src/components-examples/material/radio/radio-harness/radio-harness-example.spec.ts b/src/components-examples/material/radio/radio-harness/radio-harness-example.spec.ts index 7e80fea61cde..a3df5a7db7e0 100644 --- a/src/components-examples/material/radio/radio-harness/radio-harness-example.spec.ts +++ b/src/components-examples/material/radio/radio-harness/radio-harness-example.spec.ts @@ -1,8 +1,11 @@ import {ComponentFixture, TestBed} from '@angular/core/testing'; import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed'; -import {MatRadioButtonHarness, MatRadioGroupHarness} from '@angular/material/radio/testing'; +import { + MatLegacyRadioButtonHarness, + MatLegacyRadioGroupHarness, +} from '@angular/material/legacy-radio/testing'; import {HarnessLoader} from '@angular/cdk/testing'; -import {MatRadioModule} from '@angular/material/radio'; +import {MatLegacyRadioModule} from '@angular/material/legacy-radio'; import {RadioHarnessExample} from './radio-harness-example'; import {ReactiveFormsModule} from '@angular/forms'; @@ -12,7 +15,7 @@ describe('RadioHarnessExample', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [MatRadioModule, ReactiveFormsModule], + imports: [MatLegacyRadioModule, ReactiveFormsModule], declarations: [RadioHarnessExample], }).compileComponents(); fixture = TestBed.createComponent(RadioHarnessExample); @@ -21,18 +24,18 @@ describe('RadioHarnessExample', () => { }); it('should load all radio-group harnesses', async () => { - const groups = await loader.getAllHarnesses(MatRadioGroupHarness); + const groups = await loader.getAllHarnesses(MatLegacyRadioGroupHarness); expect(groups.length).toBe(1); }); it('should get name of radio-group', async () => { - const group = await loader.getHarness(MatRadioGroupHarness); + const group = await loader.getHarness(MatLegacyRadioGroupHarness); const name = await group.getName(); expect(name).toBe('flavors'); }); it('should check radio button', async () => { - const buttons = await loader.getAllHarnesses(MatRadioButtonHarness); + const buttons = await loader.getAllHarnesses(MatLegacyRadioButtonHarness); expect(await buttons[0].isChecked()).toBeTrue(); await buttons[1].check(); @@ -42,7 +45,7 @@ describe('RadioHarnessExample', () => { it('should get label text of buttons', async () => { const [firstRadio, secondRadio, thirdRadio] = await loader.getAllHarnesses( - MatRadioButtonHarness, + MatLegacyRadioButtonHarness, ); expect(await firstRadio.getLabelText()).toBe('Chocolate'); expect(await secondRadio.getLabelText()).toBe('Vanilla'); diff --git a/src/components-examples/material/sidenav/BUILD.bazel b/src/components-examples/material/sidenav/BUILD.bazel index 60ad9af9d22c..4057d76f6d45 100644 --- a/src/components-examples/material/sidenav/BUILD.bazel +++ b/src/components-examples/material/sidenav/BUILD.bazel @@ -19,9 +19,9 @@ ng_module( "//src/material/button", "//src/material/icon", "//src/material/legacy-checkbox", + "//src/material/legacy-radio", "//src/material/legacy-select", "//src/material/list", - "//src/material/radio", "//src/material/sidenav", "//src/material/toolbar", "@npm//@angular/forms", diff --git a/src/components-examples/material/sidenav/index.ts b/src/components-examples/material/sidenav/index.ts index 02e1fae7cc6e..0b38ebb7d244 100644 --- a/src/components-examples/material/sidenav/index.ts +++ b/src/components-examples/material/sidenav/index.ts @@ -5,7 +5,7 @@ import {MatButtonModule} from '@angular/material/button'; import {MatLegacyCheckboxModule} from '@angular/material/legacy-checkbox'; import {MatIconModule} from '@angular/material/icon'; import {MatListModule} from '@angular/material/list'; -import {MatRadioModule} from '@angular/material/radio'; +import {MatLegacyRadioModule} from '@angular/material/legacy-radio'; import {MatLegacySelectModule} from '@angular/material/legacy-select'; import {MatSidenavModule} from '@angular/material/sidenav'; import {MatToolbarModule} from '@angular/material/toolbar'; @@ -57,7 +57,7 @@ const EXAMPLES = [ MatLegacyCheckboxModule, MatIconModule, MatListModule, - MatRadioModule, + MatLegacyRadioModule, MatSidenavModule, MatLegacySelectModule, MatToolbarModule, diff --git a/src/components-examples/material/slide-toggle/BUILD.bazel b/src/components-examples/material/slide-toggle/BUILD.bazel index 8632f94df056..b28afd2bef43 100644 --- a/src/components-examples/material/slide-toggle/BUILD.bazel +++ b/src/components-examples/material/slide-toggle/BUILD.bazel @@ -18,9 +18,9 @@ ng_module( "//src/material/button", "//src/material/legacy-card", "//src/material/legacy-checkbox", + "//src/material/legacy-radio", "//src/material/legacy-slide-toggle", "//src/material/legacy-slide-toggle/testing", - "//src/material/radio", "@npm//@angular/forms", "@npm//@angular/platform-browser", "@npm//@angular/platform-browser-dynamic", diff --git a/src/components-examples/material/slide-toggle/index.ts b/src/components-examples/material/slide-toggle/index.ts index 9eadeb7f6802..0298751c7173 100644 --- a/src/components-examples/material/slide-toggle/index.ts +++ b/src/components-examples/material/slide-toggle/index.ts @@ -3,7 +3,7 @@ import {FormsModule, ReactiveFormsModule} from '@angular/forms'; import {MatButtonModule} from '@angular/material/button'; import {MatLegacyCardModule} from '@angular/material/legacy-card'; import {MatLegacyCheckboxModule} from '@angular/material/legacy-checkbox'; -import {MatRadioModule} from '@angular/material/radio'; +import {MatLegacyRadioModule} from '@angular/material/legacy-radio'; import {MatLegacySlideToggleModule} from '@angular/material/legacy-slide-toggle'; import {SlideToggleConfigurableExample} from './slide-toggle-configurable/slide-toggle-configurable-example'; import {SlideToggleFormsExample} from './slide-toggle-forms/slide-toggle-forms-example'; @@ -30,7 +30,7 @@ const EXAMPLES = [ MatButtonModule, MatLegacyCardModule, MatLegacyCheckboxModule, - MatRadioModule, + MatLegacyRadioModule, MatLegacySlideToggleModule, ReactiveFormsModule, ], diff --git a/src/components-examples/material/stepper/BUILD.bazel b/src/components-examples/material/stepper/BUILD.bazel index d0120b6d093b..807789ab4551 100644 --- a/src/components-examples/material/stepper/BUILD.bazel +++ b/src/components-examples/material/stepper/BUILD.bazel @@ -20,7 +20,7 @@ ng_module( "//src/material/button", "//src/material/icon", "//src/material/legacy-input", - "//src/material/radio", + "//src/material/legacy-radio", "//src/material/stepper", "//src/material/stepper/testing", "@npm//@angular/common", diff --git a/src/components-examples/material/stepper/index.ts b/src/components-examples/material/stepper/index.ts index 9b185fff4f62..4542b1b68fa0 100644 --- a/src/components-examples/material/stepper/index.ts +++ b/src/components-examples/material/stepper/index.ts @@ -4,7 +4,7 @@ import {CommonModule} from '@angular/common'; import {MatButtonModule} from '@angular/material/button'; import {MatIconModule} from '@angular/material/icon'; import {MatLegacyInputModule} from '@angular/material/legacy-input'; -import {MatRadioModule} from '@angular/material/radio'; +import {MatLegacyRadioModule} from '@angular/material/legacy-radio'; import {MatStepperModule} from '@angular/material/stepper'; import {StepperEditableExample} from './stepper-editable/stepper-editable-example'; import {StepperErrorsExample} from './stepper-errors/stepper-errors-example'; @@ -58,7 +58,7 @@ const EXAMPLES = [ MatButtonModule, MatIconModule, MatLegacyInputModule, - MatRadioModule, + MatLegacyRadioModule, MatStepperModule, ReactiveFormsModule, CommonModule, diff --git a/src/dev-app/baseline/BUILD.bazel b/src/dev-app/baseline/BUILD.bazel index 41cafac8b257..0ee026c6e507 100644 --- a/src/dev-app/baseline/BUILD.bazel +++ b/src/dev-app/baseline/BUILD.bazel @@ -14,8 +14,8 @@ ng_module( "//src/material/legacy-checkbox", "//src/material/legacy-form-field", "//src/material/legacy-input", + "//src/material/legacy-radio", "//src/material/legacy-select", - "//src/material/radio", "//src/material/toolbar", ], ) diff --git a/src/dev-app/baseline/baseline-demo.ts b/src/dev-app/baseline/baseline-demo.ts index 1d92925191db..6c5e75d4b2db 100644 --- a/src/dev-app/baseline/baseline-demo.ts +++ b/src/dev-app/baseline/baseline-demo.ts @@ -12,7 +12,7 @@ import {MatLegacyCardModule} from '@angular/material/legacy-card'; import {MatLegacyCheckboxModule} from '@angular/material/legacy-checkbox'; import {MatLegacyFormFieldModule} from '@angular/material/legacy-form-field'; import {MatLegacyInputModule} from '@angular/material/legacy-input'; -import {MatRadioModule} from '@angular/material/radio'; +import {MatLegacyRadioModule} from '@angular/material/legacy-radio'; import {MatLegacySelectModule} from '@angular/material/legacy-select'; import {MatToolbarModule} from '@angular/material/toolbar'; @@ -27,7 +27,7 @@ import {MatToolbarModule} from '@angular/material/toolbar'; MatLegacyCheckboxModule, MatLegacyFormFieldModule, MatLegacyInputModule, - MatRadioModule, + MatLegacyRadioModule, MatLegacySelectModule, MatToolbarModule, ], diff --git a/src/dev-app/connected-overlay/BUILD.bazel b/src/dev-app/connected-overlay/BUILD.bazel index 7d3913861b10..9a13b65e0ca8 100644 --- a/src/dev-app/connected-overlay/BUILD.bazel +++ b/src/dev-app/connected-overlay/BUILD.bazel @@ -16,7 +16,7 @@ ng_module( "//src/components-examples/cdk/overlay", "//src/material/button", "//src/material/legacy-checkbox", - "//src/material/radio", + "//src/material/legacy-radio", "@npm//@angular/forms", ], ) diff --git a/src/dev-app/connected-overlay/connected-overlay-demo.ts b/src/dev-app/connected-overlay/connected-overlay-demo.ts index 19a966a9ea5f..7e6e7a8f9e81 100644 --- a/src/dev-app/connected-overlay/connected-overlay-demo.ts +++ b/src/dev-app/connected-overlay/connected-overlay-demo.ts @@ -28,7 +28,7 @@ import { import {FormsModule} from '@angular/forms'; import {MatButtonModule} from '@angular/material/button'; import {MatLegacyCheckboxModule} from '@angular/material/legacy-checkbox'; -import {MatRadioModule} from '@angular/material/radio'; +import {MatLegacyRadioModule} from '@angular/material/legacy-radio'; @Component({ selector: 'overlay-demo', @@ -42,7 +42,7 @@ import {MatRadioModule} from '@angular/material/radio'; FormsModule, MatButtonModule, MatLegacyCheckboxModule, - MatRadioModule, + MatLegacyRadioModule, OverlayModule, ], }) diff --git a/src/dev-app/expansion/BUILD.bazel b/src/dev-app/expansion/BUILD.bazel index 64c31e0e74b6..ad498fb990aa 100644 --- a/src/dev-app/expansion/BUILD.bazel +++ b/src/dev-app/expansion/BUILD.bazel @@ -16,8 +16,8 @@ ng_module( "//src/material/legacy-checkbox", "//src/material/legacy-form-field", "//src/material/legacy-input", + "//src/material/legacy-radio", "//src/material/legacy-slide-toggle", - "//src/material/radio", "@npm//@angular/forms", ], ) diff --git a/src/dev-app/expansion/expansion-demo.ts b/src/dev-app/expansion/expansion-demo.ts index 8bb972fca8bf..1b8f393f6367 100644 --- a/src/dev-app/expansion/expansion-demo.ts +++ b/src/dev-app/expansion/expansion-demo.ts @@ -20,7 +20,7 @@ import { } from '@angular/material/expansion'; import {MatLegacyFormFieldModule} from '@angular/material/legacy-form-field'; import {MatLegacyInputModule} from '@angular/material/legacy-input'; -import {MatRadioModule} from '@angular/material/radio'; +import {MatLegacyRadioModule} from '@angular/material/legacy-radio'; import {MatLegacySlideToggleModule} from '@angular/material/legacy-slide-toggle'; @Component({ @@ -37,7 +37,7 @@ import {MatLegacySlideToggleModule} from '@angular/material/legacy-slide-toggle' MatExpansionModule, MatLegacyFormFieldModule, MatLegacyInputModule, - MatRadioModule, + MatLegacyRadioModule, MatLegacySlideToggleModule, ], }) diff --git a/src/dev-app/input-modality/BUILD.bazel b/src/dev-app/input-modality/BUILD.bazel index 9d53646f237d..3b887b07a6ee 100644 --- a/src/dev-app/input-modality/BUILD.bazel +++ b/src/dev-app/input-modality/BUILD.bazel @@ -11,7 +11,7 @@ ng_module( "//src/material/button", "//src/material/legacy-form-field", "//src/material/legacy-input", + "//src/material/legacy-radio", "//src/material/legacy-select", - "//src/material/radio", ], ) diff --git a/src/dev-app/input-modality/input-modality-detector-demo.ts b/src/dev-app/input-modality/input-modality-detector-demo.ts index b2c7ac59610d..4a33e800f674 100644 --- a/src/dev-app/input-modality/input-modality-detector-demo.ts +++ b/src/dev-app/input-modality/input-modality-detector-demo.ts @@ -15,7 +15,7 @@ import {CommonModule} from '@angular/common'; import {MatButtonModule} from '@angular/material/button'; import {MatLegacyFormFieldModule} from '@angular/material/legacy-form-field'; import {MatLegacyInputModule} from '@angular/material/legacy-input'; -import {MatRadioModule} from '@angular/material/radio'; +import {MatLegacyRadioModule} from '@angular/material/legacy-radio'; import {MatLegacySelectModule} from '@angular/material/legacy-select'; @Component({ @@ -28,7 +28,7 @@ import {MatLegacySelectModule} from '@angular/material/legacy-select'; MatButtonModule, MatLegacyFormFieldModule, MatLegacyInputModule, - MatRadioModule, + MatLegacyRadioModule, MatLegacySelectModule, ], }) diff --git a/src/dev-app/mdc-radio/BUILD.bazel b/src/dev-app/mdc-radio/BUILD.bazel index e8209bd1c987..0472c137783d 100644 --- a/src/dev-app/mdc-radio/BUILD.bazel +++ b/src/dev-app/mdc-radio/BUILD.bazel @@ -11,8 +11,8 @@ ng_module( ], deps = [ "//src/material-experimental/mdc-button", - "//src/material-experimental/mdc-radio", "//src/material/checkbox", + "//src/material/radio", "@npm//@angular/forms", ], ) diff --git a/src/dev-app/mdc-radio/mdc-radio-demo.ts b/src/dev-app/mdc-radio/mdc-radio-demo.ts index 8bc7e8ffdaff..25581ee91a47 100644 --- a/src/dev-app/mdc-radio/mdc-radio-demo.ts +++ b/src/dev-app/mdc-radio/mdc-radio-demo.ts @@ -7,7 +7,7 @@ */ import {Component} from '@angular/core'; -import {MatRadioModule} from '@angular/material-experimental/mdc-radio'; +import {MatRadioModule} from '@angular/material/radio'; import {FormsModule} from '@angular/forms'; import {MatButtonModule} from '@angular/material-experimental/mdc-button'; import {MatCheckboxModule} from '@angular/material/checkbox'; diff --git a/src/dev-app/radio/BUILD.bazel b/src/dev-app/radio/BUILD.bazel index 7d046b4d9100..3818dcb63979 100644 --- a/src/dev-app/radio/BUILD.bazel +++ b/src/dev-app/radio/BUILD.bazel @@ -12,7 +12,7 @@ ng_module( deps = [ "//src/material/button", "//src/material/legacy-checkbox", - "//src/material/radio", + "//src/material/legacy-radio", "@npm//@angular/forms", ], ) diff --git a/src/dev-app/radio/radio-demo.ts b/src/dev-app/radio/radio-demo.ts index 182d16d38183..ae10f58b87c5 100644 --- a/src/dev-app/radio/radio-demo.ts +++ b/src/dev-app/radio/radio-demo.ts @@ -11,14 +11,20 @@ import {CommonModule} from '@angular/common'; import {FormsModule} from '@angular/forms'; import {MatButtonModule} from '@angular/material/button'; import {MatLegacyCheckboxModule} from '@angular/material/legacy-checkbox'; -import {MatRadioModule} from '@angular/material/radio'; +import {MatLegacyRadioModule} from '@angular/material/legacy-radio'; @Component({ selector: 'radio-demo', templateUrl: 'radio-demo.html', styleUrls: ['radio-demo.css'], standalone: true, - imports: [CommonModule, FormsModule, MatButtonModule, MatLegacyCheckboxModule, MatRadioModule], + imports: [ + CommonModule, + FormsModule, + MatButtonModule, + MatLegacyCheckboxModule, + MatLegacyRadioModule, + ], }) export class RadioDemo { isAlignEnd: boolean = false; diff --git a/src/dev-app/youtube-player/BUILD.bazel b/src/dev-app/youtube-player/BUILD.bazel index 78764d6c017c..3478cdfe2808 100644 --- a/src/dev-app/youtube-player/BUILD.bazel +++ b/src/dev-app/youtube-player/BUILD.bazel @@ -10,7 +10,7 @@ ng_module( ":youtube_player_demo_scss", ], deps = [ - "//src/material/radio", + "//src/material/legacy-radio", "//src/youtube-player", "@npm//@angular/forms", ], diff --git a/src/dev-app/youtube-player/youtube-player-demo.ts b/src/dev-app/youtube-player/youtube-player-demo.ts index 81fe178e0b61..3d9fa3c1801f 100644 --- a/src/dev-app/youtube-player/youtube-player-demo.ts +++ b/src/dev-app/youtube-player/youtube-player-demo.ts @@ -16,7 +16,7 @@ import { } from '@angular/core'; import {CommonModule} from '@angular/common'; import {FormsModule} from '@angular/forms'; -import {MatRadioModule} from '@angular/material/radio'; +import {MatLegacyRadioModule} from '@angular/material/legacy-radio'; import {YouTubePlayerModule} from '@angular/youtube-player'; interface Video { @@ -44,7 +44,7 @@ const VIDEOS: Video[] = [ templateUrl: 'youtube-player-demo.html', styleUrls: ['youtube-player-demo.css'], standalone: true, - imports: [CommonModule, FormsModule, MatRadioModule, YouTubePlayerModule], + imports: [CommonModule, FormsModule, MatLegacyRadioModule, YouTubePlayerModule], }) export class YouTubePlayerDemo implements AfterViewInit, OnDestroy { @ViewChild('demoYouTubePlayer') demoYouTubePlayer: ElementRef; diff --git a/src/e2e-app/BUILD.bazel b/src/e2e-app/BUILD.bazel index 94b6f38e3f72..260d5467cced 100644 --- a/src/e2e-app/BUILD.bazel +++ b/src/e2e-app/BUILD.bazel @@ -45,7 +45,6 @@ ng_module( "//src/material-experimental/mdc-button", "//src/material-experimental/mdc-menu", "//src/material-experimental/mdc-progress-spinner", - "//src/material-experimental/mdc-radio", "//src/material-experimental/mdc-slider", "//src/material-experimental/mdc-table", "//src/material-experimental/mdc-tabs", @@ -63,6 +62,7 @@ ng_module( "//src/material/legacy-form-field", "//src/material/legacy-input", "//src/material/legacy-progress-bar", + "//src/material/legacy-radio", "//src/material/legacy-slide-toggle", "//src/material/list", "//src/material/menu", diff --git a/src/e2e-app/mdc-radio/mdc-radio-e2e-module.ts b/src/e2e-app/mdc-radio/mdc-radio-e2e-module.ts index 4baf556a7b7d..3327522e5a7b 100644 --- a/src/e2e-app/mdc-radio/mdc-radio-e2e-module.ts +++ b/src/e2e-app/mdc-radio/mdc-radio-e2e-module.ts @@ -7,7 +7,7 @@ */ import {NgModule} from '@angular/core'; -import {MatRadioModule} from '@angular/material-experimental/mdc-radio'; +import {MatRadioModule} from '@angular/material/radio'; import {MdcRadioE2e} from './mdc-radio-e2e'; @NgModule({ diff --git a/src/e2e-app/radio/radio-e2e-module.ts b/src/e2e-app/radio/radio-e2e-module.ts index 47fc9a1f4a63..726a1d299206 100644 --- a/src/e2e-app/radio/radio-e2e-module.ts +++ b/src/e2e-app/radio/radio-e2e-module.ts @@ -7,11 +7,11 @@ */ import {NgModule} from '@angular/core'; -import {MatRadioModule} from '@angular/material/radio'; +import {MatLegacyRadioModule} from '@angular/material/legacy-radio'; import {SimpleRadioButtons} from './radio-e2e'; @NgModule({ - imports: [MatRadioModule], + imports: [MatLegacyRadioModule], declarations: [SimpleRadioButtons], }) export class RadioE2eModule {} diff --git a/src/material-experimental/_index.scss b/src/material-experimental/_index.scss index 82d2a04bb6bf..7040effa97c1 100644 --- a/src/material-experimental/_index.scss +++ b/src/material-experimental/_index.scss @@ -32,8 +32,6 @@ @forward './mdc-progress-spinner/progress-spinner-theme' as mdc-progress-spinner-* show mdc-progress-spinner-color, mdc-progress-spinner-typography, mdc-progress-spinner-density, mdc-progress-spinner-theme; -@forward './mdc-radio/radio-theme' as mdc-radio-* show mdc-radio-color, mdc-radio-typography, - mdc-radio-density, mdc-radio-theme; @forward './mdc-slider/slider-theme' as mdc-slider-* show mdc-slider-color, mdc-slider-typography, mdc-slider-density, mdc-slider-theme; @forward './mdc-snack-bar/snack-bar-theme' as mdc-snack-bar-* show mdc-snack-bar-color, diff --git a/src/material-experimental/config.bzl b/src/material-experimental/config.bzl index c31213ea186b..5a31246403f3 100644 --- a/src/material-experimental/config.bzl +++ b/src/material-experimental/config.bzl @@ -11,8 +11,6 @@ entryPoints = [ "mdc-paginator/testing", "mdc-progress-spinner", "mdc-progress-spinner/testing", - "mdc-radio", - "mdc-radio/testing", "mdc-slider", "mdc-slider/testing", "mdc-snack-bar", diff --git a/src/material-experimental/mdc-core/color/_all-color.import.scss b/src/material-experimental/mdc-core/color/_all-color.import.scss index 85e7776804c1..29d8b8b4d4ee 100644 --- a/src/material-experimental/mdc-core/color/_all-color.import.scss +++ b/src/material-experimental/mdc-core/color/_all-color.import.scss @@ -7,10 +7,6 @@ mat-mdc-color, mat-mdc-density, mat-mdc-theme, mat-mdc-typography; $mat-mdc-button-mat-button-state-target; @forward '../../mdc-button/fab-theme' as mat-mdc-fab-*; @forward '../../mdc-button/icon-button-theme' as mat-mdc-icon-button-*; -@forward '../../mdc-radio/radio-theme' hide color, density, theme, typography; -@forward '../../mdc-radio/radio-theme' as mat-mdc-radio-* hide -$mat-mdc-radio-mdc-radio-baseline-theme-color, $mat-mdc-radio-mdc-radio-disabled-circle-color, -$mat-mdc-radio-mdc-radio-unchecked-color; @forward '../../mdc-snack-bar/snack-bar-theme' hide color, density, theme, typography; @forward '../../mdc-snack-bar/snack-bar-theme' as mat-mdc-snack-bar-* hide $mat-mdc-snack-bar-mdc-snackbar-dismiss-ink-color, $mat-mdc-snack-bar-mdc-snackbar-fill-color, diff --git a/src/material-experimental/mdc-core/density/_all-density.import.scss b/src/material-experimental/mdc-core/density/_all-density.import.scss index 432b7c18c573..9e7d177ca91f 100644 --- a/src/material-experimental/mdc-core/density/_all-density.import.scss +++ b/src/material-experimental/mdc-core/density/_all-density.import.scss @@ -7,10 +7,6 @@ mat-mdc-color, mat-mdc-density, mat-mdc-theme, mat-mdc-typography; $mat-mdc-button-mat-button-state-target; @forward '../../mdc-button/fab-theme' as mat-mdc-fab-*; @forward '../../mdc-button/icon-button-theme' as mat-mdc-icon-button-*; -@forward '../../mdc-radio/radio-theme' hide color, density, theme, typography; -@forward '../../mdc-radio/radio-theme' as mat-mdc-radio-* hide -$mat-mdc-radio-mdc-radio-baseline-theme-color, $mat-mdc-radio-mdc-radio-disabled-circle-color, -$mat-mdc-radio-mdc-radio-unchecked-color; @forward '../../mdc-snack-bar/snack-bar-theme' hide color, density, theme, typography; @forward '../../mdc-snack-bar/snack-bar-theme' as mat-mdc-snack-bar-* hide $mat-mdc-snack-bar-mdc-snackbar-dismiss-ink-color, $mat-mdc-snack-bar-mdc-snackbar-fill-color, diff --git a/src/material-experimental/mdc-core/theming/BUILD.bazel b/src/material-experimental/mdc-core/theming/BUILD.bazel index 51066e02bbb4..0ae7659f6ef0 100644 --- a/src/material-experimental/mdc-core/theming/BUILD.bazel +++ b/src/material-experimental/mdc-core/theming/BUILD.bazel @@ -26,7 +26,6 @@ sass_library( "//src/material-experimental/mdc-menu:mdc_menu_scss_lib", "//src/material-experimental/mdc-paginator:mdc_paginator_scss_lib", "//src/material-experimental/mdc-progress-spinner:mdc_progress_spinner_scss_lib", - "//src/material-experimental/mdc-radio:mdc_radio_scss_lib", "//src/material-experimental/mdc-slider:mdc_slider_scss_lib", "//src/material-experimental/mdc-snack-bar:mdc_snack_bar_scss_lib", "//src/material-experimental/mdc-table:mdc_table_scss_lib", diff --git a/src/material-experimental/mdc-core/theming/_all-theme.import.scss b/src/material-experimental/mdc-core/theming/_all-theme.import.scss index 5b2ab2bceed7..12a6ca1a866b 100644 --- a/src/material-experimental/mdc-core/theming/_all-theme.import.scss +++ b/src/material-experimental/mdc-core/theming/_all-theme.import.scss @@ -7,10 +7,6 @@ mat-mdc-color, mat-mdc-density, mat-mdc-theme, mat-mdc-typography; $mat-mdc-button-mat-button-state-target; @forward '../../mdc-button/fab-theme' as mat-mdc-fab-*; @forward '../../mdc-button/icon-button-theme' as mat-mdc-icon-button-*; -@forward '../../mdc-radio/radio-theme' hide color, density, theme, typography; -@forward '../../mdc-radio/radio-theme' as mat-mdc-radio-* hide -$mat-mdc-radio-mdc-radio-baseline-theme-color, $mat-mdc-radio-mdc-radio-disabled-circle-color, -$mat-mdc-radio-mdc-radio-unchecked-color; @forward '../../mdc-snack-bar/snack-bar-theme' hide color, density, theme, typography; @forward '../../mdc-snack-bar/snack-bar-theme' as mat-mdc-snack-bar-* hide $mat-mdc-snack-bar-mdc-snackbar-dismiss-ink-color, $mat-mdc-snack-bar-mdc-snackbar-fill-color, @@ -39,7 +35,6 @@ $mat-mdc-table-mdc-data-table-stroke-color, $mat-mdc-table-mdc-data-table-table- @import '../../mdc-button/button-theme'; @import '../../mdc-list/list-theme'; @import '../../mdc-menu/menu-theme'; -@import '../../mdc-radio/radio-theme'; @import '../../mdc-snack-bar/snack-bar-theme'; @import '../../mdc-tabs/tabs-theme'; @import '../../mdc-table/table-theme'; diff --git a/src/material-experimental/mdc-core/theming/_all-theme.scss b/src/material-experimental/mdc-core/theming/_all-theme.scss index b93793eadb75..e06169d71c35 100644 --- a/src/material-experimental/mdc-core/theming/_all-theme.scss +++ b/src/material-experimental/mdc-core/theming/_all-theme.scss @@ -6,7 +6,6 @@ @use '../../mdc-button/icon-button-theme'; @use '../../mdc-list/list-theme'; @use '../../mdc-menu/menu-theme'; -@use '../../mdc-radio/radio-theme'; @use '../../mdc-slider/slider-theme'; @use '../../mdc-snack-bar/snack-bar-theme'; @use '../../mdc-tabs/tabs-theme'; @@ -31,7 +30,7 @@ @include paginator-theme.theme($theme-or-color-config); @include mat.progress-bar-theme($theme-or-color-config); @include progress-spinner-theme.theme($theme-or-color-config); - @include radio-theme.theme($theme-or-color-config); + @include mat.radio-theme($theme-or-color-config); @include mat.select-theme($theme-or-color-config); @include mat.slide-toggle-theme($theme-or-color-config); @include slider-theme.theme($theme-or-color-config); diff --git a/src/material-experimental/mdc-core/typography/_all-typography.import.scss b/src/material-experimental/mdc-core/typography/_all-typography.import.scss index 90c2e4646090..b8d937286d16 100644 --- a/src/material-experimental/mdc-core/typography/_all-typography.import.scss +++ b/src/material-experimental/mdc-core/typography/_all-typography.import.scss @@ -7,10 +7,6 @@ mat-mdc-color, mat-mdc-density, mat-mdc-theme, mat-mdc-typography; $mat-mdc-button-mat-button-state-target; @forward '../../mdc-button/fab-theme' as mat-mdc-fab-*; @forward '../../mdc-button/icon-button-theme' as mat-mdc-icon-button-*; -@forward '../../mdc-radio/radio-theme' hide color, density, theme, typography; -@forward '../../mdc-radio/radio-theme' as mat-mdc-radio-* hide -$mat-mdc-radio-mdc-radio-baseline-theme-color, $mat-mdc-radio-mdc-radio-disabled-circle-color, -$mat-mdc-radio-mdc-radio-unchecked-color; @forward '../../mdc-snack-bar/snack-bar-theme' hide color, density, theme, typography; @forward '../../mdc-snack-bar/snack-bar-theme' as mat-mdc-snack-bar-* hide $mat-mdc-snack-bar-mdc-snackbar-dismiss-ink-color, $mat-mdc-snack-bar-mdc-snackbar-fill-color, diff --git a/src/material-experimental/mdc-radio/README.md b/src/material-experimental/mdc-radio/README.md deleted file mode 100644 index aba33b8850b1..000000000000 --- a/src/material-experimental/mdc-radio/README.md +++ /dev/null @@ -1,73 +0,0 @@ -This is a prototype of an alternate version of `MatRadio` built on top of -[MDC Web](https://github.com/material-components/material-components-web). This component is experimental and should not be used in production. - -## How to use -Assuming your application is already up and running using Angular Material, you can add this component by following these steps: - -1. Install `@angular/material-experimental` and MDC Web: - - ```bash - npm i material-components-web @angular/material-experimental - ``` - -2. In your `angular.json`, make sure `node_modules/` is listed as a Sass include path. This is - needed for the Sass compiler to be able to find the MDC Web Sass files. - - ```json - ... - "styles": [ - "src/styles.scss" - ], - "stylePreprocessorOptions": { - "includePaths": [ - "node_modules/" - ] - }, - ... - ``` - -3. Import the experimental `MatRadioModule` and add it to the module that declares your component: - - ```ts - import {MatRadioModule} from '@angular/material-experimental/mdc-radio'; - - @NgModule({ - declarations: [MyComponent], - imports: [MatRadioModule], - }) - export class MyModule {} - ``` - -4. Use the radio in your component's template: - - ```html - - Option 1 - Option 2 - Option 3 - - ``` - -5. Add the theme mixins to your Sass: - - ```scss - @use '@angular/material' as mat; - @use '@angular/material-experimental' as mat-experimental; - - $candy-app-primary: mat.define-palette(mat.$indigo-palette); - $candy-app-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400); - $candy-app-theme: mat.define-light-theme(( - color: ( - primary: $candy-app-primary, - accent: $candy-app-accent, - ) - )); - - - @include mat-experimental.mdc-radio-theme($candy-app-theme); - ``` - -## API differences - -The API of the radio matches the one from `@angular/material/radio`. Simply replace imports to -`@angular/material/radio` with imports to `@angular/material-experimental/mdc-radio`. diff --git a/src/material-experimental/mdc-radio/_radio-theme.import.scss b/src/material-experimental/mdc-radio/_radio-theme.import.scss deleted file mode 100644 index 07d8583a77d1..000000000000 --- a/src/material-experimental/mdc-radio/_radio-theme.import.scss +++ /dev/null @@ -1,4 +0,0 @@ -@forward 'radio-theme' hide color, density, theme, typography; -@forward 'radio-theme' as mat-mdc-radio-* hide $mat-mdc-radio-mdc-radio-baseline-theme-color, -$mat-mdc-radio-mdc-radio-disabled-circle-color, $mat-mdc-radio-mdc-radio-unchecked-color; - diff --git a/src/material-experimental/mdc-radio/_radio-theme.scss b/src/material-experimental/mdc-radio/_radio-theme.scss deleted file mode 100644 index 16683d61e5c7..000000000000 --- a/src/material-experimental/mdc-radio/_radio-theme.scss +++ /dev/null @@ -1,109 +0,0 @@ -@use 'sass:map'; -@use '@angular/material' as mat; -@use '@material/theme/theme-color' as mdc-theme-color; -@use '@material/radio/radio-theme' as mdc-radio-theme; -@use '@material/radio/radio' as mdc-radio; -@use '@material/form-field' as mdc-form-field; - -@mixin _color-palette($color-palette) { - @include mdc-radio-theme.theme(( - selected-focus-icon-color: $color-palette, - selected-hover-icon-color: $color-palette, - selected-icon-color: $color-palette, - selected-pressed-icon-color: $color-palette, - )); - - --mat-mdc-radio-checked-ripple-color: #{$color-palette}; -} - -@mixin color($config-or-theme) { - $config: mat.get-color-config($config-or-theme); - $primary: mat.get-color-from-palette(map.get($config, primary)); - $accent: mat.get-color-from-palette(map.get($config, accent)); - $warn: mat.get-color-from-palette(map.get($config, warn)); - $foreground: map.get($config, foreground); - - @include mat.private-using-mdc-theme($config) { - $on-surface: rgba(mdc-theme-color.$on-surface, 0.54); - $is-dark: map-get($config, is-dark); - $active-border-color: if( - $is-dark, - mat.get-color-from-palette(mat.$gray-palette, 200), - mat.get-color-from-palette(mat.$gray-palette, 900) - ); - - .mat-mdc-radio-button { - @include mdc-form-field.core-styles($query: mat.$private-mdc-theme-styles-query); - @include mdc-radio-theme.theme(( - // The disabled colors don't use the `rgba` version, because - // MDC applies a separate opacity to disabled buttons. - disabled-selected-icon-color: mdc-theme-color.$on-surface, - disabled-unselected-icon-color: mdc-theme-color.$on-surface, - unselected-focus-icon-color: $active-border-color, - unselected-hover-icon-color: $active-border-color, - unselected-icon-color: $on-surface, - unselected-pressed-icon-color: $on-surface, - )); - - --mat-mdc-radio-ripple-color: #{mdc-theme-color.prop-value(on-surface)}; - - // MDC should set the disabled color on the label, but doesn't, so we do it here instead. - .mdc-radio--disabled + label { - color: mat.get-color-from-palette($foreground, disabled-text); - } - - &.mat-primary { - @include _color-palette($primary); - } - - &.mat-accent { - @include _color-palette($accent); - } - - &.mat-warn { - @include _color-palette($warn); - } - } - } -} - -@mixin typography($config-or-theme) { - $config: mat.private-typography-to-2018-config( - mat.get-typography-config($config-or-theme)); - @include mat.private-using-mdc-typography($config) { - @include mdc-radio.without-ripple($query: mat.$private-mdc-typography-styles-query); - @include mdc-form-field.core-styles($query: mat.$private-mdc-typography-styles-query); - } -} - -@mixin density($config-or-theme) { - $density-scale: mat.get-density-config($config-or-theme); - .mat-mdc-radio-button .mdc-radio { - @include mdc-radio-theme.density($density-scale, $query: mat.$private-mdc-base-styles-query); - } - - @include mat.private-if-touch-targets-unsupported($density-scale) { - .mat-mdc-radio-touch-target { - display: none; - } - } -} - -@mixin theme($theme-or-color-config) { - $theme: mat.private-legacy-get-theme($theme-or-color-config); - @include mat.private-check-duplicate-theme-styles($theme, 'mat-mdc-radio') { - $color: mat.get-color-config($theme); - $density: mat.get-density-config($theme); - $typography: mat.get-typography-config($theme); - - @if $color != null { - @include color($color); - } - @if $density != null { - @include density($density); - } - @if $typography != null { - @include typography($typography); - } - } -} diff --git a/src/material-experimental/mdc-radio/public-api.ts b/src/material-experimental/mdc-radio/public-api.ts deleted file mode 100644 index 04d0903a8efb..000000000000 --- a/src/material-experimental/mdc-radio/public-api.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ - -export * from './radio'; -export * from './module'; - -export {MAT_RADIO_DEFAULT_OPTIONS_FACTORY, MatRadioDefaultOptions} from '@angular/material/radio'; diff --git a/src/material-experimental/mdc-radio/radio.e2e.spec.ts b/src/material-experimental/mdc-radio/radio.e2e.spec.ts deleted file mode 100644 index 9b53d10a41e6..000000000000 --- a/src/material-experimental/mdc-radio/radio.e2e.spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {browser, by, element} from 'protractor'; - -describe('radio', () => { - describe('disabling behavior', () => { - beforeEach(async () => await browser.get('/mdc-radio')); - - it('should be checked when clicked', async () => { - await element(by.id('water')).click(); - expect(await element(by.css('input:checked')).getAttribute('value')).toBe('water'); - - await element(by.id('leaf')).click(); - expect(await element(by.css('input:checked')).getAttribute('value')).toBe('leaf'); - }); - - it('should be disabled when disable the radio group', async () => { - await element(by.id('toggle-disable')).click(); - await element(by.id('water')).click(); - - expect(await element(by.css('input[id=water-input]')).getAttribute('disabled')).toBe('true'); - }); - }); -}); diff --git a/src/material-experimental/mdc-radio/radio.html b/src/material-experimental/mdc-radio/radio.html deleted file mode 100644 index 3ac71037faa5..000000000000 --- a/src/material-experimental/mdc-radio/radio.html +++ /dev/null @@ -1,31 +0,0 @@ -
-
- -
- -
-
-
-
-
-
-
-
- -
diff --git a/src/material-experimental/mdc-radio/radio.scss b/src/material-experimental/mdc-radio/radio.scss deleted file mode 100644 index 5bca6022dd63..000000000000 --- a/src/material-experimental/mdc-radio/radio.scss +++ /dev/null @@ -1,115 +0,0 @@ -@use 'sass:map'; -@use '@angular/material' as mat; -@use '@material/radio/radio' as mdc-radio; -@use '@material/radio/radio-theme' as mdc-radio-theme; -@use '@material/form-field' as mdc-form-field; -@use '@material/touch-target' as mdc-touch-target; -@use '@material/ripple' as mdc-ripple; - - -@include mat.private-disable-mdc-fallback-declarations { - @include mdc-radio.static-styles($query: mat.$private-mdc-base-styles-query); - @include mdc-form-field.core-styles($query: mat.$private-mdc-base-styles-query); -} - -.mat-mdc-radio-button { - .mdc-radio { - // MDC theme styles also include structural styles so we have to include the theme at least - // once here. The values will be overwritten by our own theme file afterwards. - @include mat.private-disable-mdc-fallback-declarations { - @include mdc-radio-theme.theme-styles(map.merge(mdc-radio-theme.$light-theme, ( - // Exclude the styles we don't need. - selected-focus-state-layer-color: null, - selected-focus-state-layer-opacity: null, - selected-hover-state-layer-color: null, - selected-hover-state-layer-opacity: null, - selected-pressed-state-layer-color: null, - selected-pressed-state-layer-opacity: null, - unselected-focus-icon-color: null, - unselected-focus-state-layer-color: null, - unselected-focus-state-layer-opacity: null, - unselected-hover-state-layer-color: null, - unselected-hover-state-layer-opacity: null, - unselected-pressed-state-layer-color: null, - unselected-pressed-state-layer-opacity: null, - ))); - - // TODO(crisbeto): this should be included by MDC's `theme-styles`, but it isn't currently. - @include mdc-radio-theme.focus-indicator-color( - var(--mat-mdc-radio-ripple-color, transparent)); - } - - // MDC's hover indication comes from their ripple which we don't use. - &:hover .mdc-radio__native-control:not([disabled]):not(:focus) { - & ~ .mdc-radio__background::before { - opacity: map.get(mdc-ripple.$dark-ink-opacities, hover); - transform: scale(1); - } - } - } - - &.mat-mdc-radio-checked { - // TODO(crisbeto): this should be included by MDC's `theme-styles`, but it isn't currently. - @include mdc-radio-theme.focus-indicator-color( - var(--mat-mdc-radio-checked-ripple-color, transparent)); - - .mat-ripple-element { - background-color: var(--mat-mdc-radio-checked-ripple-color, transparent); - } - } - - // 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-radio-ripple { - @include mat.private-fill; - pointer-events: none; - border-radius: 50%; - - .mat-ripple-element { - opacity: mdc-radio-theme.$ripple-opacity; - } - - &::before { - border-radius: 50%; - } - } - - &._mat-animation-noopable { - .mdc-radio__background::before, - .mdc-radio__outer-circle, - .mdc-radio__inner-circle { - // Needs to be `!important`, because MDC's selectors are really specific. - transition: none !important; - } - } - - // We don't inherit the border focus style from MDC since we don't use their ripple. - // Instead we need to replicate it here. - .mdc-radio .mdc-radio__native-control:focus:enabled:not(:checked) { - & ~ .mdc-radio__background .mdc-radio__outer-circle { - border-color: var(--mdc-radio-unselected-focus-icon-color, black); - } - } - - // For radios render the focus indicator when we know - // the hidden input is focused (slightly different for each control). - &.cdk-focused .mat-mdc-focus-indicator::before { - content: ''; - } -} - -// Element used to provide a larger tap target for users on touch devices. -.mat-mdc-radio-touch-target { - @include mat.private-disable-mdc-fallback-declarations { - @include mdc-touch-target.touch-target( - $set-width: true, - $query: mat.$private-mdc-base-styles-query); - } - - [dir='rtl'] & { - left: 0; - right: 50%; - transform: translate(50%, -50%); - } -} - diff --git a/src/material-experimental/mdc-radio/testing/radio-harness.spec.ts b/src/material-experimental/mdc-radio/testing/radio-harness.spec.ts deleted file mode 100644 index 5a1979039fdf..000000000000 --- a/src/material-experimental/mdc-radio/testing/radio-harness.spec.ts +++ /dev/null @@ -1,7 +0,0 @@ -import {MatRadioModule} from '@angular/material-experimental/mdc-radio'; -import {runHarnessTests} from '@angular/material/radio/testing/shared.spec'; -import {MatRadioButtonHarness, MatRadioGroupHarness} from './radio-harness'; - -describe('MDC-based radio harness', () => { - runHarnessTests(MatRadioModule, MatRadioGroupHarness as any, MatRadioButtonHarness as any); -}); diff --git a/src/material/_index.scss b/src/material/_index.scss index 9b8862f5fd85..03d9f9a7a389 100644 --- a/src/material/_index.scss +++ b/src/material/_index.scss @@ -128,6 +128,8 @@ @forward './progress-spinner/progress-spinner-theme' as progress-spinner-* show progress-spinner-theme, progress-spinner-color, progress-spinner-typography; @forward './radio/radio-theme' as radio-* show radio-theme, radio-color, radio-typography; +@forward './legacy-radio/radio-theme' as legacy-radio-* show legacy-radio-theme, legacy-radio-color, + legacy-radio-typography; @forward './select/select-theme' as select-* show select-theme, select-color, select-typography, select-density; @forward './legacy-select/select-theme' as legacy-select-* show legacy-select-theme, diff --git a/src/material/_theming.scss b/src/material/_theming.scss index 30090b074c07..5ea56d0b3f1b 100644 --- a/src/material/_theming.scss +++ b/src/material/_theming.scss @@ -28,7 +28,7 @@ @forward './paginator/paginator-legacy-index'; @forward './legacy-progress-bar/progress-bar-legacy-index'; @forward './progress-spinner/progress-spinner-legacy-index'; -@forward './radio/radio-legacy-index'; +@forward './legacy-radio/radio-legacy-index'; @forward './legacy-select/select-legacy-index'; @forward './sidenav/sidenav-legacy-index'; @forward './legacy-slide-toggle/slide-toggle-legacy-index'; diff --git a/src/material/config.bzl b/src/material/config.bzl index 060f0eba3422..ac5cfc59de77 100644 --- a/src/material/config.bzl +++ b/src/material/config.bzl @@ -64,6 +64,8 @@ entryPoints = [ "progress-spinner/testing", "radio", "radio/testing", + "legacy-radio", + "legacy-radio/testing", "select", "select/testing", "legacy-select", diff --git a/src/material/core/density/private/_all-density.scss b/src/material/core/density/private/_all-density.scss index 0edb9c071e63..cdc4fe57ff81 100644 --- a/src/material/core/density/private/_all-density.scss +++ b/src/material/core/density/private/_all-density.scss @@ -18,6 +18,7 @@ @use '../../../dialog/dialog-theme'; @use '../../../chips/chips-theme'; @use '../../../slide-toggle/slide-toggle-theme'; +@use '../../../radio/radio-theme'; @mixin private-all-unmigrated-component-densities($config) { @include expansion-theme.density($config); @@ -57,6 +58,7 @@ @include dialog-theme.density($config); @include chips-theme.density($config); @include slide-toggle-theme.density($config); + @include radio-theme.density($config); @include private-all-unmigrated-component-densities($config); } diff --git a/src/material/core/theming/_all-theme.scss b/src/material/core/theming/_all-theme.scss index f932fca9710e..281854ef7da8 100644 --- a/src/material/core/theming/_all-theme.scss +++ b/src/material/core/theming/_all-theme.scss @@ -52,7 +52,6 @@ @include menu-theme.theme($theme-or-color-config); @include paginator-theme.theme($theme-or-color-config); @include progress-spinner-theme.theme($theme-or-color-config); - @include radio-theme.theme($theme-or-color-config); @include sidenav-theme.theme($theme-or-color-config); @include slider-theme.theme($theme-or-color-config); @include stepper-theme.theme($theme-or-color-config); @@ -78,6 +77,7 @@ @include dialog-theme.theme($theme-or-color-config); @include chips-theme.theme($theme-or-color-config); @include slide-toggle-theme.theme($theme-or-color-config); + @include radio-theme.theme($theme-or-color-config); @include private-all-unmigrated-component-themes($theme-or-color-config); } } diff --git a/src/material/core/theming/tests/test-css-variables-theme.scss b/src/material/core/theming/tests/test-css-variables-theme.scss index d0ace45ae0f9..91e536d82bd5 100644 --- a/src/material/core/theming/tests/test-css-variables-theme.scss +++ b/src/material/core/theming/tests/test-css-variables-theme.scss @@ -17,7 +17,6 @@ @use '../../../menu/menu-theme'; @use '../../../paginator/paginator-theme'; @use '../../../progress-spinner/progress-spinner-theme'; -@use '../../../radio/radio-theme'; @use '../../../sidenav/sidenav-theme'; @use '../../../slider/slider-theme'; @use '../../../stepper/stepper-theme'; @@ -69,7 +68,6 @@ @include menu-theme.theme($css-var-theme); @include paginator-theme.theme($css-var-theme); @include progress-spinner-theme.theme($css-var-theme); - @include radio-theme.theme($css-var-theme); @include sidenav-theme.theme($css-var-theme); @include slider-theme.theme($css-var-theme); @include stepper-theme.theme($css-var-theme); diff --git a/src/material/core/typography/_all-typography.scss b/src/material/core/typography/_all-typography.scss index 2d641d78101e..e9830011b4d0 100644 --- a/src/material/core/typography/_all-typography.scss +++ b/src/material/core/typography/_all-typography.scss @@ -53,7 +53,6 @@ @include menu-theme.typography($config); @include paginator-theme.typography($config); @include progress-spinner-theme.typography($config); - @include radio-theme.typography($config); @include sidenav-theme.typography($config); @include slider-theme.typography($config); @include stepper-theme.typography($config); @@ -94,6 +93,7 @@ @include dialog-theme.typography($config); @include chips-theme.typography($config); @include slide-toggle-theme.typography($config); + @include radio-theme.typography($config); } // @deprecated Use `all-component-typographies`. diff --git a/src/material/legacy-core/theming/_all-theme.scss b/src/material/legacy-core/theming/_all-theme.scss index 37eb8391a7f2..0b447ed01ed8 100644 --- a/src/material/legacy-core/theming/_all-theme.scss +++ b/src/material/legacy-core/theming/_all-theme.scss @@ -12,6 +12,7 @@ @use '../../legacy-dialog/dialog-theme'; @use '../../legacy-chips/chips-theme'; @use '../../legacy-slide-toggle/slide-toggle-theme'; +@use '../../legacy-radio/radio-theme'; // Create a theme. @mixin all-legacy-component-themes($theme-or-color-config) { @@ -29,6 +30,7 @@ @include dialog-theme.theme($theme-or-color-config); @include chips-theme.theme($theme-or-color-config); @include slide-toggle-theme.theme($theme-or-color-config); + @include radio-theme.theme($theme-or-color-config); @include all-theme.private-all-unmigrated-component-themes($theme-or-color-config); } } diff --git a/src/material/legacy-core/typography/_all-typography.scss b/src/material/legacy-core/typography/_all-typography.scss index 975030ce529d..a8e2f367e123 100644 --- a/src/material/legacy-core/typography/_all-typography.scss +++ b/src/material/legacy-core/typography/_all-typography.scss @@ -14,6 +14,7 @@ @use '../../legacy-dialog/dialog-theme'; @use '../../legacy-chips/chips-theme'; @use '../../legacy-slide-toggle/slide-toggle-theme'; +@use '../../legacy-radio/radio-theme'; // Includes all of the typographic styles. @mixin all-legacy-component-typographies($config-or-theme: null) { @@ -45,6 +46,7 @@ @include dialog-theme.typography($config); @include chips-theme.typography($config); @include slide-toggle-theme.typography($config); + @include radio-theme.typography($config); } // @deprecated Use `all-legacy-component-typographies`. diff --git a/src/material-experimental/mdc-radio/BUILD.bazel b/src/material/legacy-radio/BUILD.bazel similarity index 69% rename from src/material-experimental/mdc-radio/BUILD.bazel rename to src/material/legacy-radio/BUILD.bazel index 902311035715..08ba22c2aab8 100644 --- a/src/material-experimental/mdc-radio/BUILD.bazel +++ b/src/material/legacy-radio/BUILD.bazel @@ -1,6 +1,7 @@ load("//src/e2e-app:test_suite.bzl", "e2e_test_suite") load( "//tools:defaults.bzl", + "markdown_to_html", "ng_e2e_test_library", "ng_module", "ng_test_library", @@ -12,67 +13,58 @@ load( package(default_visibility = ["//visibility:public"]) ng_module( - name = "mdc-radio", + name = "legacy-radio", srcs = glob( ["**/*.ts"], exclude = ["**/*.spec.ts"], ), - assets = [":radio_scss"] + glob(["**/*.html"]), + assets = [":radio.css"] + glob(["**/*.html"]), deps = [ "//src/cdk/a11y", "//src/cdk/coercion", "//src/cdk/collections", "//src/material/core", "//src/material/radio", + "@npm//@angular/animations", + "@npm//@angular/core", "@npm//@angular/forms", - "@npm//@material/radio", + "@npm//@angular/platform-browser", ], ) sass_library( - name = "mdc_radio_scss_lib", + name = "legacy_radio_scss_lib", srcs = glob(["**/_*.scss"]), - deps = [ - "//:mdc_sass_lib", - "//src/material:sass_lib", - "//src/material/core:core_scss_lib", - ], + deps = ["//src/material/core:core_scss_lib"], ) sass_binary( name = "radio_scss", src = "radio.scss", deps = [ - "//:mdc_sass_lib", - "//src/material:sass_lib", + "//src/cdk:sass_lib", "//src/material/core:core_scss_lib", ], ) -########### -# Testing -########### - ng_test_library( - name = "radio_tests_lib", + name = "unit_test_sources", srcs = glob( ["**/*.spec.ts"], exclude = ["**/*.e2e.spec.ts"], ), deps = [ - ":mdc-radio", + ":legacy-radio", "//src/cdk/testing/private", + "//src/material/radio", "@npm//@angular/forms", "@npm//@angular/platform-browser", - "@npm//@material/radio", ], ) ng_web_test_suite( name = "unit_tests", - deps = [ - ":radio_tests_lib", - ], + deps = [":unit_test_sources"], ) ng_e2e_test_library( @@ -90,3 +82,13 @@ e2e_test_suite( "//src/cdk/testing/private/e2e", ], ) + +markdown_to_html( + name = "overview", + srcs = [":radio.md"], +) + +filegroup( + name = "source-files", + srcs = glob(["**/*.ts"]), +) diff --git a/src/material/legacy-radio/README.md b/src/material/legacy-radio/README.md new file mode 100644 index 000000000000..9ad01c8968db --- /dev/null +++ b/src/material/legacy-radio/README.md @@ -0,0 +1 @@ +Please see the official documentation at https://material.angular.io/components/component/radio \ No newline at end of file diff --git a/src/material/legacy-radio/_radio-legacy-index.scss b/src/material/legacy-radio/_radio-legacy-index.scss new file mode 100644 index 000000000000..d4780da705bd --- /dev/null +++ b/src/material/legacy-radio/_radio-legacy-index.scss @@ -0,0 +1,2 @@ +@forward 'radio-theme' hide color, theme, typography; +@forward 'radio-theme' as mat-legacy-radio-* hide mat-legacy-radio-color, mat-legacy-radio-density; diff --git a/src/material/legacy-radio/_radio-theme.import.scss b/src/material/legacy-radio/_radio-theme.import.scss new file mode 100644 index 000000000000..c0d8eeefd4f2 --- /dev/null +++ b/src/material/legacy-radio/_radio-theme.import.scss @@ -0,0 +1,8 @@ +@forward '../core/theming/theming.import'; +@forward '../core/typography/typography-utils.import'; +@forward 'radio-theme' hide color, theme, typography; +@forward 'radio-theme' as mat-legacy-radio-* hide mat-legacy-radio-color, mat-legacy-radio-density; + +@import '../core/theming/palette'; +@import '../core/theming/theming'; +@import '../core/typography/typography-utils'; diff --git a/src/material/legacy-radio/_radio-theme.scss b/src/material/legacy-radio/_radio-theme.scss new file mode 100644 index 000000000000..0f32bcd69956 --- /dev/null +++ b/src/material/legacy-radio/_radio-theme.scss @@ -0,0 +1,98 @@ +@use 'sass:map'; +@use '../core/theming/theming'; +@use '../core/typography/typography'; +@use '../core/typography/typography-utils'; + +@mixin _color($palette) { + &.mat-radio-checked .mat-radio-outer-circle { + border-color: theming.get-color-from-palette($palette); + } + + .mat-radio-inner-circle, + .mat-radio-ripple .mat-ripple-element:not(.mat-radio-persistent-ripple), + &.mat-radio-checked .mat-radio-persistent-ripple, + &:active .mat-radio-persistent-ripple { + background-color: theming.get-color-from-palette($palette); + } +} + +@mixin color($config-or-theme) { + $config: theming.get-color-config($config-or-theme); + $primary: map.get($config, primary); + $accent: map.get($config, accent); + $warn: map.get($config, warn); + $background: map.get($config, background); + $foreground: map.get($config, foreground); + + .mat-radio-outer-circle { + border-color: theming.get-color-from-palette($foreground, secondary-text); + } + + .mat-radio-button { + &.mat-primary { + @include _color($primary); + } + + &.mat-accent { + @include _color($accent); + } + + &.mat-warn { + @include _color($warn); + } + + // This needs extra specificity, because the classes above are combined + // (e.g. `.mat-radio-button.mat-accent`) which increases their specificity a lot. + // TODO: consider making the selectors into descendants (`.mat-primary .mat-radio-button`). + &.mat-radio-disabled { + &.mat-radio-checked .mat-radio-outer-circle, + .mat-radio-outer-circle { + border-color: theming.get-color-from-palette($foreground, disabled); + } + + .mat-radio-ripple .mat-ripple-element, + .mat-radio-inner-circle { + background-color: theming.get-color-from-palette($foreground, disabled); + } + + .mat-radio-label-content { + color: theming.get-color-from-palette($foreground, disabled); + } + } + + // Switch this to a solid color since we're using `opacity` + // to control how opaque the ripple should be. + .mat-ripple-element { + background-color: map.get($foreground, base); + } + } +} + +@mixin typography($config-or-theme) { + $config: typography.private-typography-to-2014-config( + theming.get-typography-config($config-or-theme)); + .mat-radio-button { + font-family: typography-utils.font-family($config); + } +} + +@mixin _density($config-or-theme) {} + +@mixin theme($theme-or-color-config) { + $theme: theming.private-legacy-get-theme($theme-or-color-config); + @include theming.private-check-duplicate-theme-styles($theme, 'mat-legacy-radio') { + $color: theming.get-color-config($theme); + $density: theming.get-density-config($theme); + $typography: theming.get-typography-config($theme); + + @if $color != null { + @include color($color); + } + @if $density != null { + @include _density($density); + } + @if $typography != null { + @include typography($typography); + } + } +} diff --git a/src/material-experimental/mdc-radio/index.ts b/src/material/legacy-radio/index.ts similarity index 100% rename from src/material-experimental/mdc-radio/index.ts rename to src/material/legacy-radio/index.ts diff --git a/src/material/legacy-radio/public-api.ts b/src/material/legacy-radio/public-api.ts new file mode 100644 index 000000000000..524873a2ed4c --- /dev/null +++ b/src/material/legacy-radio/public-api.ts @@ -0,0 +1,18 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +export * from './radio-module'; +export * from './radio'; + +export { + MatRadioDefaultOptions as MatLegacyRadioDefaultOptions, + MatRadioChange as MatLegacyRadioChange, + MAT_RADIO_DEFAULT_OPTIONS_FACTORY, + MAT_RADIO_DEFAULT_OPTIONS, + MAT_RADIO_GROUP, +} from '@angular/material/radio'; diff --git a/src/material/radio/radio-module.ts b/src/material/legacy-radio/radio-module.ts similarity index 61% rename from src/material/radio/radio-module.ts rename to src/material/legacy-radio/radio-module.ts index 5ea871afa65f..134d1baa7e5c 100644 --- a/src/material/radio/radio-module.ts +++ b/src/material/legacy-radio/radio-module.ts @@ -8,11 +8,11 @@ import {NgModule} from '@angular/core'; import {MatCommonModule, MatRippleModule} from '@angular/material/core'; -import {MatRadioButton, MatRadioGroup} from './radio'; +import {MatLegacyRadioButton, MatLegacyRadioGroup} from './radio'; @NgModule({ imports: [MatRippleModule, MatCommonModule], - exports: [MatRadioGroup, MatRadioButton, MatCommonModule], - declarations: [MatRadioGroup, MatRadioButton], + exports: [MatLegacyRadioGroup, MatLegacyRadioButton, MatCommonModule], + declarations: [MatLegacyRadioGroup, MatLegacyRadioButton], }) -export class MatRadioModule {} +export class MatLegacyRadioModule {} diff --git a/src/material/legacy-radio/radio.e2e.spec.ts b/src/material/legacy-radio/radio.e2e.spec.ts new file mode 100644 index 000000000000..7eafd0339a5d --- /dev/null +++ b/src/material/legacy-radio/radio.e2e.spec.ts @@ -0,0 +1,38 @@ +import {browser, by, element, ExpectedConditions} from 'protractor'; + +describe('radio', () => { + describe('disabling behavior', () => { + beforeEach(async () => await browser.get('/radio')); + + it('should be checked when clicked', async () => { + await element(by.id('water')).click(); + + expect(await element(by.id('water')).getAttribute('class')).toContain('mat-radio-checked'); + + expect(await element(by.css('input[id=water-input]')).getAttribute('checked')).toBeTruthy(); + expect(await element(by.css('input[id=leaf-input]')).getAttribute('checked')).toBeFalsy(); + + await element(by.id('leaf')).click(); + expect(await element(by.id('leaf')).getAttribute('class')).toContain('mat-radio-checked'); + + expect(await element(by.css('input[id=leaf-input]')).getAttribute('checked')).toBeTruthy(); + expect(await element(by.css('input[id=water-input]')).getAttribute('checked')).toBeFalsy(); + }); + + it('should be disabled when disable the radio group', async () => { + await element(by.id('toggle-disable')).click(); + await element(by.id('water')).click(); + + expect(await element(by.id('water')).getAttribute('class')).toContain('mat-radio-disabled'); + + await browser.wait(ExpectedConditions.presenceOf(element(by.css('.mat-radio-disabled')))); + + expect(await element(by.css('input[id=water-input]')).getAttribute('disabled')).toBeTruthy(); + + await element(await by.id('leaf')).click(); + expect(await element(by.id('leaf')).getAttribute('class')).toContain('mat-radio-disabled'); + + expect(await element(by.css('input[id=leaf-input]')).getAttribute('disabled')).toBeTruthy(); + }); + }); +}); diff --git a/src/material/legacy-radio/radio.html b/src/material/legacy-radio/radio.html new file mode 100644 index 000000000000..15e839e9e12a --- /dev/null +++ b/src/material/legacy-radio/radio.html @@ -0,0 +1,40 @@ + + + diff --git a/src/material/legacy-radio/radio.md b/src/material/legacy-radio/radio.md new file mode 100644 index 000000000000..c63eb2ee3728 --- /dev/null +++ b/src/material/legacy-radio/radio.md @@ -0,0 +1,62 @@ +`` provides the same functionality as a native `` enhanced with +Material Design styling and animations. + + + +All radio-buttons with the same `name` comprise a set from which only one may be selected at a time. + +### Radio-button label +The radio-button label is provided as the content to the `` element. The label can +be positioned before or after the radio-button by setting the `labelPosition` property to `'before'` +or `'after'`. + +If you don't want the label to appear next to the radio-button, you can use +[`aria-label`](https://www.w3.org/TR/wai-aria/states_and_properties#aria-label) or +[`aria-labelledby`](https://www.w3.org/TR/wai-aria/states_and_properties#aria-labelledby) to +specify an appropriate label. + + +### Radio groups +Radio-buttons should typically be placed inside of an `` unless the DOM structure +would make that impossible (e.g., radio-buttons inside of table cells). The radio-group has a +`value` property that reflects the currently selected radio-button inside of the group. + +Individual radio-buttons inside of a radio-group will inherit the `name` of the group. + + +### Use with `@angular/forms` +`` is compatible with `@angular/forms` and supports both `FormsModule` +and `ReactiveFormsModule`. + +### Default Color Configuration +The default color for radio buttons can be configured globally using the `MAT_RADIO_DEFAULT_OPTIONS` provider + +``` +providers: [{ + provide: MAT_RADIO_DEFAULT_OPTIONS, + useValue: { color: 'accent' }, +}] +``` + +### Accessibility + +`MatRadioButton` uses an internal `` to provide an accessible experience. +This internal radio button receives focus and is automatically labelled by the text content of the +`` element. Avoid adding other interactive controls into the content of +``, as this degrades the experience for users of assistive technology. + +Always provide an accessible label via `aria-label` or `aria-labelledby` for radio buttons without +descriptive text content. For dynamic labels and descriptions, `MatRadioButton` provides input +properties for binding `aria-label`, `aria-labelledby`, and `aria-describedby`. This means that you +should not use the `attr.` prefix when binding these properties, as demonstrated below. + +```html + + +``` + +Prefer placing all radio buttons inside of a `` rather than creating standalone +radio buttons because groups are easier to use exclusively with a keyboard. + +You should provide an accessible label for all `` elements via `aria-label` or +`aria-labelledby`. diff --git a/src/material/legacy-radio/radio.scss b/src/material/legacy-radio/radio.scss new file mode 100644 index 000000000000..59b8414df1e5 --- /dev/null +++ b/src/material/legacy-radio/radio.scss @@ -0,0 +1,223 @@ +@use 'sass:math'; +@use '@angular/cdk'; + +@use '../core/style/variables'; +@use '../core/ripple/ripple'; +@use '../core/style/vendor-prefixes'; + + +$size: variables.$toggle-size !default; +$ripple-radius: 20px; + +// Top-level host container. +.mat-radio-button { + display: inline-block; + -webkit-tap-highlight-color: transparent; + outline: 0; +} + +// Inner label container, wrapping entire element. +// Enables focus by click. +.mat-radio-label { + // Disable text selection on the label itself, because having text selected + // will prevent focus from reaching the label. Below we'll re-enable it only + // for the label's content so that people can still select the text. + @include vendor-prefixes.user-select(none); + cursor: pointer; + display: inline-flex; + align-items: center; + white-space: nowrap; + vertical-align: middle; + + // Have the label span the rest of the radio button for maximum clickable area. + width: 100%; +} + +// Container for radio circles and ripple. +.mat-radio-container { + box-sizing: border-box; + display: inline-block; + position: relative; + width: $size; + height: $size; + // The radio container is inside of a inline-flex element and may shrink if the label + // is wide and text-wrapping is enabled. + flex-shrink: 0; +} + +// The outer circle for the radio, always present. +.mat-radio-outer-circle { + box-sizing: border-box; + display: block; + height: $size; + left: 0; + position: absolute; + top: 0; + transition: border-color ease 280ms; + width: $size; + border: { + width: 2px; + style: solid; + radius: 50%; + } + + ._mat-animation-noopable & { + transition: none; + } +} + +// The inner circle for the radio, shown when checked. +.mat-radio-inner-circle { + $transition-duration: 280ms; + $base-transition: transform ease $transition-duration, background-color ease $transition-duration; + border-radius: 50%; + box-sizing: border-box; + display: block; + height: $size; + left: 0; + position: absolute; + top: 0; + // On some zoom levels the `scale(0.001)` from below can cause the circle to be shown as a 1x1 + // dot (see #22036). Ensure that it's hidden using `opacity`. There's a slight transition with + // a long delay so that switching the opacity only applies after the `transform` is done. + opacity: 0; + transition: $base-transition, opacity linear 1ms $transition-duration; + width: $size; + + // Note: This starts from 0.001 instead of 0, because transitioning from 0 to 0.5 causes + // IE to flash the entire circle for a couple of frames, throwing off the entire animation. + transform: scale(0.001); + + // force browser to show background-color when using the print function + @include vendor-prefixes.color-adjust(exact); + + .mat-radio-checked & { + transform: scale(0.5); + opacity: 1; + transition: $base-transition; + + @include cdk.high-contrast(active, off) { + // Since we use a background color to render the circle, it won't be + // displayed in high contrast mode. Use a border as a fallback. + border: solid math.div($size, 2); + } + } + + ._mat-animation-noopable & { + transition: none; + } +} + +// Text label next to radio. +.mat-radio-label-content { + // Re-enable text selection for the button's content since + // we disabled it above in the `.mat-radio-label`. + @include vendor-prefixes.user-select(auto); + display: inline-block; + order: 0; + line-height: inherit; + padding-left: variables.$toggle-padding; + padding-right: 0; + + [dir='rtl'] & { + padding-right: variables.$toggle-padding; + padding-left: 0; + } +} + +// Alignment. +.mat-radio-label-content.mat-radio-label-before { + order: -1; + padding-left: 0; + padding-right: variables.$toggle-padding; + + [dir='rtl'] & { + padding-right: 0; + padding-left: variables.$toggle-padding; + } +} + +// Basic disabled state. +.mat-radio-disabled, +.mat-radio-disabled .mat-radio-label { + cursor: default; +} + +// Increase specificity because ripple styles are part of the `mat-core` mixin and can +// potentially overwrite the absolute position of the container. +.mat-radio-button .mat-radio-ripple { + position: absolute; + left: calc(50% - #{$ripple-radius}); + top: calc(50% - #{$ripple-radius}); + height: $ripple-radius * 2; + width: $ripple-radius * 2; + z-index: 1; + pointer-events: none; + + .mat-ripple-element:not(.mat-radio-persistent-ripple) { + opacity: 0.16; + } +} + +.mat-radio-persistent-ripple { + width: 100%; + height: 100%; + transform: none; + + // Needs an explicit top/left so it stays aligned no matter how the text is aligned (see #22389). + top: 0; + left: 0; + + .mat-radio-container:hover & { + opacity: 0.04; + } + + .mat-radio-button:not(.mat-radio-disabled).cdk-keyboard-focused &, + .mat-radio-button:not(.mat-radio-disabled).cdk-program-focused & { + opacity: 0.12; + } + + // We do this here, rather than having a `:not(.mat-radio-disabled)` + // above in the `:hover`, because the `:not` will bump the specificity + // a lot and will cause it to overide the focus styles. + &, .mat-radio-disabled .mat-radio-container:hover & { + opacity: 0; + } + + // Hover styles will be displayed after tapping on touch devices. + // Disable the hover styling if the user's device doesn't support hovering. + @media (hover: none) { + // Note that we only negate the `:hover` rather than setting it to always be `display: none`, + // in order to maintain the focus indication for hybrid touch + keyboard devices. + .mat-radio-container:hover & { + display: none; + } + } +} + +.mat-radio-input { + opacity: 0; + position: absolute; + top: 0; + left: 0; + margin: 0; + width: 100%; + height: 100%; + cursor: inherit; + + // Puts the input behind the circle while keeping it visible so that + // it allows `click` events to propagate up to the `label` wrapper. + z-index: -1; +} + +// Radio renders focus indicators when the +// associated visually-hidden input is focused. +.mat-radio-input:focus ~ .mat-focus-indicator::before { + content: ''; +} + +@include cdk.high-contrast(active, off) { + .mat-radio-disabled { + opacity: 0.5; + } +} diff --git a/src/material-experimental/mdc-radio/radio.spec.ts b/src/material/legacy-radio/radio.spec.ts similarity index 92% rename from src/material-experimental/mdc-radio/radio.spec.ts rename to src/material/legacy-radio/radio.spec.ts index 3be3839aa202..2cca2514c4b0 100644 --- a/src/material-experimental/mdc-radio/radio.spec.ts +++ b/src/material/legacy-radio/radio.spec.ts @@ -2,19 +2,15 @@ import {waitForAsync, ComponentFixture, fakeAsync, TestBed, tick} from '@angular import {FormControl, FormsModule, NgModel, ReactiveFormsModule} from '@angular/forms'; import {Component, DebugElement, ViewChild} from '@angular/core'; import {By} from '@angular/platform-browser'; -import {dispatchFakeEvent} from '../../cdk/testing/private'; -import { - MAT_RADIO_DEFAULT_OPTIONS, - MatRadioButton, - MatRadioChange, - MatRadioGroup, - MatRadioModule, -} from './index'; - -describe('MDC-based MatRadio', () => { +import {dispatchFakeEvent} from '@angular/cdk/testing/private'; + +import {MAT_RADIO_DEFAULT_OPTIONS, MatRadioChange} from '@angular/material/radio'; +import {MatLegacyRadioButton, MatLegacyRadioGroup, MatLegacyRadioModule} from './index'; + +describe('MatRadio', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - imports: [MatRadioModule, FormsModule, ReactiveFormsModule], + imports: [MatLegacyRadioModule, FormsModule, ReactiveFormsModule], declarations: [ DisableableRadioButton, FocusableRadioButton, @@ -40,9 +36,8 @@ describe('MDC-based MatRadio', () => { let radioNativeElements: HTMLElement[]; let radioLabelElements: HTMLLabelElement[]; let radioInputElements: HTMLInputElement[]; - let radioFormFieldElements: HTMLInputElement[]; - let groupInstance: MatRadioGroup; - let radioInstances: MatRadioButton[]; + let groupInstance: MatLegacyRadioGroup; + let radioInstances: MatLegacyRadioButton[]; let testComponent: RadiosInsideRadioGroup; beforeEach(waitForAsync(() => { @@ -51,10 +46,10 @@ describe('MDC-based MatRadio', () => { testComponent = fixture.debugElement.componentInstance; - groupDebugElement = fixture.debugElement.query(By.directive(MatRadioGroup))!; - groupInstance = groupDebugElement.injector.get(MatRadioGroup); + groupDebugElement = fixture.debugElement.query(By.directive(MatLegacyRadioGroup))!; + groupInstance = groupDebugElement.injector.get(MatLegacyRadioGroup); - radioDebugElements = fixture.debugElement.queryAll(By.directive(MatRadioButton)); + radioDebugElements = fixture.debugElement.queryAll(By.directive(MatLegacyRadioButton)); radioNativeElements = radioDebugElements.map(debugEl => debugEl.nativeElement); radioInstances = radioDebugElements.map(debugEl => debugEl.componentInstance); @@ -64,9 +59,6 @@ describe('MDC-based MatRadio', () => { radioInputElements = radioDebugElements.map( debugEl => debugEl.query(By.css('input'))!.nativeElement, ); - radioFormFieldElements = radioDebugElements.map( - debugEl => debugEl.query(By.css('.mdc-form-field'))!.nativeElement, - ); })); it('should set individual radio names based on the group name', () => { @@ -245,8 +237,8 @@ describe('MDC-based MatRadio', () => { testComponent.isFirstDisabled = true; fixture.detectChanges(); - dispatchFakeEvent(radioFormFieldElements[0], 'mousedown'); - dispatchFakeEvent(radioFormFieldElements[0], 'mouseup'); + dispatchFakeEvent(radioLabelElements[0], 'mousedown'); + dispatchFakeEvent(radioLabelElements[0], 'mouseup'); let rippleAmount = radioNativeElements[0].querySelectorAll( '.mat-ripple-element:not(.mat-radio-persistent-ripple)', @@ -259,8 +251,8 @@ describe('MDC-based MatRadio', () => { testComponent.isFirstDisabled = false; fixture.detectChanges(); - dispatchFakeEvent(radioFormFieldElements[0], 'mousedown'); - dispatchFakeEvent(radioFormFieldElements[0], 'mouseup'); + dispatchFakeEvent(radioLabelElements[0], 'mousedown'); + dispatchFakeEvent(radioLabelElements[0], 'mouseup'); rippleAmount = radioNativeElements[0].querySelectorAll( '.mat-ripple-element:not(.mat-radio-persistent-ripple)', @@ -273,9 +265,9 @@ describe('MDC-based MatRadio', () => { testComponent.disableRipple = true; fixture.detectChanges(); - for (const radioFormField of radioFormFieldElements) { - dispatchFakeEvent(radioFormField, 'mousedown'); - dispatchFakeEvent(radioFormField, 'mouseup'); + for (const radioLabel of radioLabelElements) { + dispatchFakeEvent(radioLabel, 'mousedown'); + dispatchFakeEvent(radioLabel, 'mouseup'); const rippleAmount = radioNativeElements[0].querySelectorAll( '.mat-ripple-element:not(.mat-radio-persistent-ripple)', @@ -287,9 +279,9 @@ describe('MDC-based MatRadio', () => { testComponent.disableRipple = false; fixture.detectChanges(); - for (const radioFormField of radioFormFieldElements) { - dispatchFakeEvent(radioFormField, 'mousedown'); - dispatchFakeEvent(radioFormField, 'mouseup'); + for (const radioLabel of radioLabelElements) { + dispatchFakeEvent(radioLabel, 'mousedown'); + dispatchFakeEvent(radioLabel, 'mouseup'); const rippleAmount = radioNativeElements[0].querySelectorAll( '.mat-ripple-element:not(.mat-radio-persistent-ripple)', @@ -428,7 +420,7 @@ describe('MDC-based MatRadio', () => { expect( radioRippleNativeElements.every(element => - element.classList.contains('mat-mdc-focus-indicator'), + element.classList.contains('mat-focus-indicator'), ), ).toBe(true); }); @@ -477,8 +469,8 @@ describe('MDC-based MatRadio', () => { let radioDebugElements: DebugElement[]; let innerRadios: DebugElement[]; let radioLabelElements: HTMLLabelElement[]; - let groupInstance: MatRadioGroup; - let radioInstances: MatRadioButton[]; + let groupInstance: MatLegacyRadioGroup; + let radioInstances: MatLegacyRadioButton[]; let testComponent: RadioGroupWithNgModel; let groupNgModel: NgModel; @@ -488,11 +480,11 @@ describe('MDC-based MatRadio', () => { testComponent = fixture.debugElement.componentInstance; - groupDebugElement = fixture.debugElement.query(By.directive(MatRadioGroup))!; - groupInstance = groupDebugElement.injector.get(MatRadioGroup); + groupDebugElement = fixture.debugElement.query(By.directive(MatLegacyRadioGroup))!; + groupInstance = groupDebugElement.injector.get(MatLegacyRadioGroup); groupNgModel = groupDebugElement.injector.get(NgModel); - radioDebugElements = fixture.debugElement.queryAll(By.directive(MatRadioButton)); + radioDebugElements = fixture.debugElement.queryAll(By.directive(MatLegacyRadioButton)); radioInstances = radioDebugElements.map(debugEl => debugEl.componentInstance); innerRadios = fixture.debugElement.queryAll(By.css('input[type="radio"]')); @@ -570,6 +562,7 @@ describe('MDC-based MatRadio', () => { // Blur the input element in order to verify that the ng-touched state has been set to true. // The touched state should be only set to true after the form control has been blurred. dispatchFakeEvent(innerRadios[2].nativeElement, 'blur'); + expect(groupNgModel.valid).toBe(true); expect(groupNgModel.pristine).toBe(false); expect(groupNgModel.touched).toBe(true); @@ -635,7 +628,7 @@ describe('MDC-based MatRadio', () => { describe('disableable', () => { let fixture: ComponentFixture; - let radioInstance: MatRadioButton; + let radioInstance: MatLegacyRadioButton; let radioNativeElement: HTMLInputElement; let testComponent: DisableableRadioButton; @@ -644,8 +637,8 @@ describe('MDC-based MatRadio', () => { fixture.detectChanges(); testComponent = fixture.debugElement.componentInstance; - const radioDebugElement = fixture.debugElement.query(By.directive(MatRadioButton))!; - radioInstance = radioDebugElement.injector.get(MatRadioButton); + const radioDebugElement = fixture.debugElement.query(By.directive(MatLegacyRadioButton))!; + radioInstance = radioDebugElement.injector.get(MatLegacyRadioButton); radioNativeElement = radioDebugElement.nativeElement.querySelector('input'); }); @@ -668,9 +661,9 @@ describe('MDC-based MatRadio', () => { describe('as standalone', () => { let fixture: ComponentFixture; let radioDebugElements: DebugElement[]; - let seasonRadioInstances: MatRadioButton[]; - let weatherRadioInstances: MatRadioButton[]; - let fruitRadioInstances: MatRadioButton[]; + let seasonRadioInstances: MatLegacyRadioButton[]; + let weatherRadioInstances: MatLegacyRadioButton[]; + let fruitRadioInstances: MatLegacyRadioButton[]; let fruitRadioNativeElements: HTMLElement[]; let fruitRadioNativeInputs: HTMLElement[]; let testComponent: StandaloneRadioButtons; @@ -681,7 +674,7 @@ describe('MDC-based MatRadio', () => { testComponent = fixture.debugElement.componentInstance; - radioDebugElements = fixture.debugElement.queryAll(By.directive(MatRadioButton)); + radioDebugElements = fixture.debugElement.queryAll(By.directive(MatLegacyRadioButton)); seasonRadioInstances = radioDebugElements .filter(debugEl => debugEl.componentInstance.name == 'season') .map(debugEl => debugEl.componentInstance); @@ -691,6 +684,7 @@ describe('MDC-based MatRadio', () => { fruitRadioInstances = radioDebugElements .filter(debugEl => debugEl.componentInstance.name == 'fruit') .map(debugEl => debugEl.componentInstance); + fruitRadioNativeElements = radioDebugElements .filter(debugEl => debugEl.componentInstance.name == 'fruit') .map(debugEl => debugEl.nativeElement); @@ -832,10 +826,8 @@ describe('MDC-based MatRadio', () => { }); it('should forward focus to native input', () => { - let radioButtonEl = fixture.debugElement.query( - By.css('.mat-mdc-radio-button'), - )!.nativeElement; - let inputEl = fixture.debugElement.query(By.css('.mdc-radio__native-control'))!.nativeElement; + const radioButtonEl = fixture.debugElement.query(By.css('.mat-radio-button'))!.nativeElement; + const inputEl = fixture.debugElement.query(By.css('.mat-radio-input'))!.nativeElement; radioButtonEl.focus(); // Focus events don't always fire in tests, so we need to fake it. @@ -846,7 +838,7 @@ describe('MDC-based MatRadio', () => { }); it('should allow specifying an explicit tabindex for a single radio-button', () => { - const radioButtonInput = fixture.debugElement.query(By.css('.mat-mdc-radio-button input'))! + const radioButtonInput = fixture.debugElement.query(By.css('.mat-radio-button input'))! .nativeElement as HTMLInputElement; expect(radioButtonInput.tabIndex) @@ -866,7 +858,7 @@ describe('MDC-based MatRadio', () => { predefinedFixture.detectChanges(); const radioButtonEl = predefinedFixture.debugElement.query( - By.css('.mat-mdc-radio-button'), + By.css('.mat-radio-button'), )!.nativeElement; expect(radioButtonEl.hasAttribute('tabindex')).toBe(false); @@ -877,7 +869,7 @@ describe('MDC-based MatRadio', () => { predefinedFixture.detectChanges(); const radioButtonInput = predefinedFixture.debugElement.query( - By.css('.mat-mdc-radio-button input'), + By.css('.mat-radio-button input'), )!.nativeElement as HTMLInputElement; expect(radioButtonInput.getAttribute('tabindex')).toBe('5'); @@ -888,38 +880,29 @@ describe('MDC-based MatRadio', () => { predefinedFixture.detectChanges(); const radioButtonEl = predefinedFixture.debugElement.query( - By.css('.mat-mdc-radio-button'), + By.css('.mat-radio-button'), )!.nativeElement; expect(radioButtonEl.hasAttribute('aria-label')).toBe(false); expect(radioButtonEl.hasAttribute('aria-describedby')).toBe(false); expect(radioButtonEl.hasAttribute('aria-labelledby')).toBe(false); }); - - it('should remove the tabindex from the host element when disabled', () => { - const radioButton = fixture.debugElement.query(By.css('.mat-mdc-radio-button')).nativeElement; - - fixture.componentInstance.disabled = true; - fixture.detectChanges(); - - expect(radioButton.hasAttribute('tabindex')).toBe(false); - }); }); describe('group interspersed with other tags', () => { let fixture: ComponentFixture; let groupDebugElement: DebugElement; - let groupInstance: MatRadioGroup; + let groupInstance: MatLegacyRadioGroup; let radioDebugElements: DebugElement[]; - let radioInstances: MatRadioButton[]; + let radioInstances: MatLegacyRadioButton[]; beforeEach(waitForAsync(() => { fixture = TestBed.createComponent(InterleavedRadioGroup); fixture.detectChanges(); - groupDebugElement = fixture.debugElement.query(By.directive(MatRadioGroup))!; - groupInstance = groupDebugElement.injector.get(MatRadioGroup); - radioDebugElements = fixture.debugElement.queryAll(By.directive(MatRadioButton)); + groupDebugElement = fixture.debugElement.query(By.directive(MatLegacyRadioGroup))!; + groupInstance = groupDebugElement.injector.get(MatLegacyRadioGroup); + radioDebugElements = fixture.debugElement.queryAll(By.directive(MatLegacyRadioButton)); radioInstances = radioDebugElements.map(debugEl => debugEl.componentInstance); })); @@ -933,7 +916,7 @@ describe('MatRadioDefaultOverrides', () => { describe('when MAT_RADIO_DEFAULT_OPTIONS overridden', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - imports: [MatRadioModule, FormsModule], + imports: [MatLegacyRadioModule, FormsModule], declarations: [DefaultRadioButton, RadioButtonWithColorBinding], providers: [ { @@ -950,7 +933,7 @@ describe('MatRadioDefaultOverrides', () => { TestBed.createComponent(DefaultRadioButton); fixture.detectChanges(); const radioDebugElement: DebugElement = fixture.debugElement.query( - By.directive(MatRadioButton), + By.directive(MatLegacyRadioButton), )!; expect(radioDebugElement.nativeElement.classList).toContain('mat-primary'); }); @@ -960,7 +943,7 @@ describe('MatRadioDefaultOverrides', () => { ); fixture.detectChanges(); const radioDebugElement: DebugElement = fixture.debugElement.query( - By.directive(MatRadioButton), + By.directive(MatLegacyRadioButton), )!; expect(radioDebugElement.nativeElement.classList).not.toContain('mat-primary'); expect(radioDebugElement.nativeElement.classList).toContain('mat-warn'); @@ -1061,7 +1044,7 @@ class RadioGroupWithNgModel { template: `One`, }) class DisableableRadioButton { - @ViewChild(MatRadioButton) matRadioButton: MatRadioButton; + @ViewChild(MatLegacyRadioButton) matRadioButton: MatLegacyRadioButton; set disabled(value: boolean) { this.matRadioButton.disabled = value; @@ -1077,16 +1060,15 @@ class DisableableRadioButton { `, }) class RadioGroupWithFormControl { - @ViewChild(MatRadioGroup) group: MatRadioGroup; + @ViewChild(MatLegacyRadioGroup) group: MatLegacyRadioGroup; formControl = new FormControl(''); } @Component({ - template: ``, + template: ``, }) class FocusableRadioButton { tabIndex: number; - disabled = false; } @Component({ diff --git a/src/material-experimental/mdc-radio/radio.ts b/src/material/legacy-radio/radio.ts similarity index 65% rename from src/material-experimental/mdc-radio/radio.ts rename to src/material/legacy-radio/radio.ts index 30233c31737d..199ad7fcf739 100644 --- a/src/material-experimental/mdc-radio/radio.ts +++ b/src/material/legacy-radio/radio.ts @@ -6,6 +6,8 @@ * found in the LICENSE file at https://angular.io/license */ +import {FocusMonitor} from '@angular/cdk/a11y'; +import {UniqueSelectionDispatcher} from '@angular/cdk/collections'; import { Attribute, ChangeDetectionStrategy, @@ -16,25 +18,19 @@ import { ElementRef, forwardRef, Inject, - InjectionToken, Optional, QueryList, ViewEncapsulation, } from '@angular/core'; +import {NG_VALUE_ACCESSOR} from '@angular/forms'; +import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations'; import { - MAT_RADIO_DEFAULT_OPTIONS, + MAT_RADIO_GROUP, + _MatRadioGroupBase, _MatRadioButtonBase, + MAT_RADIO_DEFAULT_OPTIONS, MatRadioDefaultOptions, - _MatRadioGroupBase, } from '@angular/material/radio'; -import {FocusMonitor} from '@angular/cdk/a11y'; -import {UniqueSelectionDispatcher} from '@angular/cdk/collections'; -import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations'; -import {NG_VALUE_ACCESSOR} from '@angular/forms'; - -// Re-export symbols used by the base Material radio component so that users do not need to depend -// on both packages. -export {MatRadioChange, MAT_RADIO_DEFAULT_OPTIONS} from '@angular/material/radio'; /** * Provider Expression that allows mat-radio-group to register as a ControlValueAccessor. This @@ -43,19 +39,10 @@ export {MatRadioChange, MAT_RADIO_DEFAULT_OPTIONS} from '@angular/material/radio */ export const MAT_RADIO_GROUP_CONTROL_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => MatRadioGroup), + useExisting: forwardRef(() => MatLegacyRadioGroup), multi: true, }; -/** - * Injection token that can be used to inject instances of `MatRadioGroup`. It serves as - * alternative token to the actual `MatRadioGroup` class which could cause unnecessary - * retention of the class and its component metadata. - */ -export const MAT_RADIO_GROUP = new InjectionToken<_MatRadioGroupBase<_MatRadioButtonBase>>( - 'MatRadioGroup', -); - /** * A group of radio buttons. May contain one or more `` elements. */ @@ -64,33 +51,39 @@ export const MAT_RADIO_GROUP = new InjectionToken<_MatRadioGroupBase<_MatRadioBu exportAs: 'matRadioGroup', providers: [ MAT_RADIO_GROUP_CONTROL_VALUE_ACCESSOR, - {provide: MAT_RADIO_GROUP, useExisting: MatRadioGroup}, + {provide: MAT_RADIO_GROUP, useExisting: MatLegacyRadioGroup}, ], host: { 'role': 'radiogroup', - 'class': 'mat-mdc-radio-group', + 'class': 'mat-radio-group', }, }) -export class MatRadioGroup extends _MatRadioGroupBase { - /** Child radio buttons. */ - @ContentChildren(forwardRef(() => MatRadioButton), {descendants: true}) - _radios: QueryList; +export class MatLegacyRadioGroup extends _MatRadioGroupBase { + @ContentChildren(forwardRef(() => MatLegacyRadioButton), {descendants: true}) + _radios: QueryList; } +/** + * A Material design radio-button. Typically placed inside of `` elements. + */ @Component({ selector: 'mat-radio-button', templateUrl: 'radio.html', styleUrls: ['radio.css'], + inputs: ['disableRipple', 'tabIndex'], + encapsulation: ViewEncapsulation.None, + exportAs: 'matRadioButton', host: { - 'class': 'mat-mdc-radio-button', - '[attr.id]': 'id', + 'class': 'mat-radio-button', + '[class.mat-radio-checked]': 'checked', + '[class.mat-radio-disabled]': 'disabled', + '[class._mat-animation-noopable]': '_noopAnimations', '[class.mat-primary]': 'color === "primary"', '[class.mat-accent]': 'color === "accent"', '[class.mat-warn]': 'color === "warn"', - '[class.mat-mdc-radio-checked]': 'checked', - '[class._mat-animation-noopable]': '_noopAnimations', // Needs to be removed since it causes some a11y issues (see #21266). '[attr.tabindex]': 'null', + '[attr.id]': 'id', '[attr.aria-label]': 'null', '[attr.aria-labelledby]': 'null', '[attr.aria-describedby]': 'null', @@ -99,32 +92,29 @@ export class MatRadioGroup extends _MatRadioGroupBase { // the focus to the native element. '(focus)': '_inputElement.nativeElement.focus()', }, - inputs: ['disableRipple', 'tabIndex'], - exportAs: 'matRadioButton', - encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, }) -export class MatRadioButton extends _MatRadioButtonBase { +export class MatLegacyRadioButton extends _MatRadioButtonBase { constructor( - @Optional() @Inject(MAT_RADIO_GROUP) radioGroup: MatRadioGroup, + @Optional() @Inject(MAT_RADIO_GROUP) radioGroup: MatLegacyRadioGroup, elementRef: ElementRef, - _changeDetector: ChangeDetectorRef, - _focusMonitor: FocusMonitor, - _radioDispatcher: UniqueSelectionDispatcher, + changeDetector: ChangeDetectorRef, + focusMonitor: FocusMonitor, + radioDispatcher: UniqueSelectionDispatcher, @Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode?: string, @Optional() @Inject(MAT_RADIO_DEFAULT_OPTIONS) - _providerOverride?: MatRadioDefaultOptions, + providerOverride?: MatRadioDefaultOptions, @Attribute('tabindex') tabIndex?: string, ) { super( radioGroup, elementRef, - _changeDetector, - _focusMonitor, - _radioDispatcher, + changeDetector, + focusMonitor, + radioDispatcher, animationMode, - _providerOverride, + providerOverride, tabIndex, ); } diff --git a/src/material-experimental/mdc-radio/testing/BUILD.bazel b/src/material/legacy-radio/testing/BUILD.bazel similarity index 76% rename from src/material-experimental/mdc-radio/testing/BUILD.bazel rename to src/material/legacy-radio/testing/BUILD.bazel index 4495a4427866..17fc5eec027b 100644 --- a/src/material-experimental/mdc-radio/testing/BUILD.bazel +++ b/src/material/legacy-radio/testing/BUILD.bazel @@ -9,24 +9,28 @@ ts_library( exclude = ["**/*.spec.ts"], ), deps = [ + "//src/cdk/coercion", "//src/cdk/testing", "//src/material/radio/testing", ], ) +filegroup( + name = "source-files", + srcs = glob(["**/*.ts"]), +) + ng_test_library( name = "unit_tests_lib", srcs = glob(["**/*.spec.ts"]), deps = [ ":testing", - "//src/material-experimental/mdc-radio", + "//src/material/legacy-radio", "//src/material/radio/testing:harness_tests_lib", ], ) ng_web_test_suite( name = "unit_tests", - deps = [ - ":unit_tests_lib", - ], + deps = [":unit_tests_lib"], ) diff --git a/src/material-experimental/mdc-radio/testing/index.ts b/src/material/legacy-radio/testing/index.ts similarity index 100% rename from src/material-experimental/mdc-radio/testing/index.ts rename to src/material/legacy-radio/testing/index.ts diff --git a/src/material-experimental/mdc-radio/testing/public-api.ts b/src/material/legacy-radio/testing/public-api.ts similarity index 100% rename from src/material-experimental/mdc-radio/testing/public-api.ts rename to src/material/legacy-radio/testing/public-api.ts diff --git a/src/material/legacy-radio/testing/radio-harness.spec.ts b/src/material/legacy-radio/testing/radio-harness.spec.ts new file mode 100644 index 000000000000..65c526ed83ab --- /dev/null +++ b/src/material/legacy-radio/testing/radio-harness.spec.ts @@ -0,0 +1,11 @@ +import {MatLegacyRadioModule} from '@angular/material/legacy-radio'; +import {runHarnessTests} from '@angular/material/radio/testing/shared.spec'; +import {MatLegacyRadioButtonHarness, MatLegacyRadioGroupHarness} from './radio-harness'; + +describe('Non-MDC-based', () => { + runHarnessTests( + MatLegacyRadioModule, + MatLegacyRadioGroupHarness as any, + MatLegacyRadioButtonHarness as any, + ); +}); diff --git a/src/material-experimental/mdc-radio/testing/radio-harness.ts b/src/material/legacy-radio/testing/radio-harness.ts similarity index 57% rename from src/material-experimental/mdc-radio/testing/radio-harness.ts rename to src/material/legacy-radio/testing/radio-harness.ts index 27829d012f58..2519276e10e4 100644 --- a/src/material-experimental/mdc-radio/testing/radio-harness.ts +++ b/src/material/legacy-radio/testing/radio-harness.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {ComponentHarnessConstructor, HarnessPredicate} from '@angular/cdk/testing'; +import {HarnessPredicate} from '@angular/cdk/testing'; import { RadioButtonHarnessFilters, RadioGroupHarnessFilters, @@ -14,50 +14,48 @@ import { _MatRadioButtonHarnessBase, } from '@angular/material/radio/testing'; -/** Harness for interacting with an MDC-based mat-radio-group in tests. */ -export class MatRadioGroupHarness extends _MatRadioGroupHarnessBase< - typeof MatRadioButtonHarness, - MatRadioButtonHarness, +/** Harness for interacting with a standard mat-radio-group in tests. */ +export class MatLegacyRadioGroupHarness extends _MatRadioGroupHarnessBase< + typeof MatLegacyRadioButtonHarness, + MatLegacyRadioButtonHarness, RadioButtonHarnessFilters > { /** The selector for the host element of a `MatRadioGroup` instance. */ - static hostSelector = '.mat-mdc-radio-group'; - protected _buttonClass = MatRadioButtonHarness; + static hostSelector = '.mat-radio-group'; + protected _buttonClass = MatLegacyRadioButtonHarness; /** - * Gets a `HarnessPredicate` that can be used to search for a radio group with specific - * attributes. + * Gets a `HarnessPredicate` that can be used to search for a `MatRadioGroupHarness` that meets + * certain criteria. * @param options Options for filtering which radio group instances are considered a match. * @return a `HarnessPredicate` configured with the given options. */ - static with( - this: ComponentHarnessConstructor, + static with( options: RadioGroupHarnessFilters = {}, - ): HarnessPredicate { - return new HarnessPredicate(this, options).addOption( + ): HarnessPredicate { + return new HarnessPredicate(MatLegacyRadioGroupHarness, options).addOption( 'name', options.name, - MatRadioGroupHarness._checkRadioGroupName, + this._checkRadioGroupName, ); } } -/** Harness for interacting with an MDC-based mat-radio-button in tests. */ -export class MatRadioButtonHarness extends _MatRadioButtonHarnessBase { +/** Harness for interacting with a standard mat-radio-button in tests. */ +export class MatLegacyRadioButtonHarness extends _MatRadioButtonHarnessBase { /** The selector for the host element of a `MatRadioButton` instance. */ - static hostSelector = '.mat-mdc-radio-button'; + static hostSelector = '.mat-radio-button'; /** - * Gets a `HarnessPredicate` that can be used to search for a radio button with specific - * attributes. + * Gets a `HarnessPredicate` that can be used to search for a `MatRadioButtonHarness` that meets + * certain criteria. * @param options Options for filtering which radio button instances are considered a match. * @return a `HarnessPredicate` configured with the given options. */ - static with( - this: ComponentHarnessConstructor, + static with( options: RadioButtonHarnessFilters = {}, - ): HarnessPredicate { - return new HarnessPredicate(this, options) + ): HarnessPredicate { + return new HarnessPredicate(MatLegacyRadioButtonHarness, options) .addOption('label', options.label, (harness, label) => HarnessPredicate.stringMatches(harness.getLabelText(), label), ) @@ -69,6 +67,6 @@ export class MatRadioButtonHarness extends _MatRadioButtonHarnessBase { ); } - protected _textLabel = this.locatorFor('label'); - protected _clickLabel = this._textLabel; + protected _textLabel = this.locatorFor('.mat-radio-label-content'); + protected _clickLabel = this.locatorFor('.mat-radio-label'); } diff --git a/src/material/radio/BUILD.bazel b/src/material/radio/BUILD.bazel index 2d6dbafb33e5..34840ca220f0 100644 --- a/src/material/radio/BUILD.bazel +++ b/src/material/radio/BUILD.bazel @@ -18,36 +18,51 @@ ng_module( ["**/*.ts"], exclude = ["**/*.spec.ts"], ), - assets = [":radio.css"] + glob(["**/*.html"]), + assets = [":radio_scss"] + glob(["**/*.html"]), deps = [ "//src/cdk/a11y", "//src/cdk/coercion", "//src/cdk/collections", "//src/material/core", - "@npm//@angular/animations", - "@npm//@angular/core", "@npm//@angular/forms", - "@npm//@angular/platform-browser", + "@npm//@material/radio", ], ) sass_library( name = "radio_scss_lib", srcs = glob(["**/_*.scss"]), - deps = ["//src/material/core:core_scss_lib"], + deps = [ + "//:mdc_sass_lib", + "//src/material/core:core_scss_lib", + ], ) sass_binary( name = "radio_scss", src = "radio.scss", deps = [ - "//src/cdk:sass_lib", + "//:mdc_sass_lib", "//src/material/core:core_scss_lib", ], ) +markdown_to_html( + name = "overview", + srcs = [":radio.md"], +) + +filegroup( + name = "source-files", + srcs = glob(["**/*.ts"]), +) + +########### +# Testing +########### + ng_test_library( - name = "unit_test_sources", + name = "radio_tests_lib", srcs = glob( ["**/*.spec.ts"], exclude = ["**/*.e2e.spec.ts"], @@ -57,12 +72,15 @@ ng_test_library( "//src/cdk/testing/private", "@npm//@angular/forms", "@npm//@angular/platform-browser", + "@npm//@material/radio", ], ) ng_web_test_suite( name = "unit_tests", - deps = [":unit_test_sources"], + deps = [ + ":radio_tests_lib", + ], ) ng_e2e_test_library( @@ -80,13 +98,3 @@ e2e_test_suite( "//src/cdk/testing/private/e2e", ], ) - -markdown_to_html( - name = "overview", - srcs = [":radio.md"], -) - -filegroup( - name = "source-files", - srcs = glob(["**/*.ts"]), -) diff --git a/src/material/radio/README.md b/src/material/radio/README.md index 9ad01c8968db..37cb69dd60d5 100644 --- a/src/material/radio/README.md +++ b/src/material/radio/README.md @@ -1 +1 @@ -Please see the official documentation at https://material.angular.io/components/component/radio \ No newline at end of file +Please see the official documentation at https://material.angular.io/components/component/radio diff --git a/src/material/radio/_radio-legacy-index.scss b/src/material/radio/_radio-legacy-index.scss deleted file mode 100644 index 2ea7eafb154b..000000000000 --- a/src/material/radio/_radio-legacy-index.scss +++ /dev/null @@ -1,2 +0,0 @@ -@forward 'radio-theme' hide color, theme, typography; -@forward 'radio-theme' as mat-radio-* hide mat-radio-color, mat-radio-density; diff --git a/src/material/radio/_radio-theme.import.scss b/src/material/radio/_radio-theme.import.scss index 4225856445dd..07d8583a77d1 100644 --- a/src/material/radio/_radio-theme.import.scss +++ b/src/material/radio/_radio-theme.import.scss @@ -1,8 +1,4 @@ -@forward '../core/theming/theming.import'; -@forward '../core/typography/typography-utils.import'; -@forward 'radio-theme' hide color, theme, typography; -@forward 'radio-theme' as mat-radio-* hide mat-radio-color, mat-radio-density; +@forward 'radio-theme' hide color, density, theme, typography; +@forward 'radio-theme' as mat-mdc-radio-* hide $mat-mdc-radio-mdc-radio-baseline-theme-color, +$mat-mdc-radio-mdc-radio-disabled-circle-color, $mat-mdc-radio-mdc-radio-unchecked-color; -@import '../core/theming/palette'; -@import '../core/theming/theming'; -@import '../core/typography/typography-utils'; diff --git a/src/material/radio/_radio-theme.scss b/src/material/radio/_radio-theme.scss index 668ca1d2ed5f..c7ffccd6f3c3 100644 --- a/src/material/radio/_radio-theme.scss +++ b/src/material/radio/_radio-theme.scss @@ -1,82 +1,96 @@ @use 'sass:map'; +@use '@material/theme/theme-color' as mdc-theme-color; +@use '@material/radio/radio-theme' as mdc-radio-theme; +@use '@material/radio/radio' as mdc-radio; +@use '@material/form-field' as mdc-form-field; @use '../core/theming/theming'; +@use '../core/mdc-helpers/mdc-helpers'; @use '../core/typography/typography'; -@use '../core/typography/typography-utils'; +@use '../core/theming/palette'; -@mixin _color($palette) { - &.mat-radio-checked .mat-radio-outer-circle { - border-color: theming.get-color-from-palette($palette); - } +@mixin _color-palette($color-palette) { + @include mdc-radio-theme.theme(( + selected-focus-icon-color: $color-palette, + selected-hover-icon-color: $color-palette, + selected-icon-color: $color-palette, + selected-pressed-icon-color: $color-palette, + )); - .mat-radio-inner-circle, - .mat-radio-ripple .mat-ripple-element:not(.mat-radio-persistent-ripple), - &.mat-radio-checked .mat-radio-persistent-ripple, - &:active .mat-radio-persistent-ripple { - background-color: theming.get-color-from-palette($palette); - } + --mat-mdc-radio-checked-ripple-color: #{$color-palette}; } @mixin color($config-or-theme) { $config: theming.get-color-config($config-or-theme); - $primary: map.get($config, primary); - $accent: map.get($config, accent); - $warn: map.get($config, warn); - $background: map.get($config, background); + $primary: theming.get-color-from-palette(map.get($config, primary)); + $accent: theming.get-color-from-palette(map.get($config, accent)); + $warn: theming.get-color-from-palette(map.get($config, warn)); $foreground: map.get($config, foreground); - .mat-radio-outer-circle { - border-color: theming.get-color-from-palette($foreground, secondary-text); - } + @include mdc-helpers.using-mdc-theme($config) { + $on-surface: rgba(mdc-theme-color.$on-surface, 0.54); + $is-dark: map-get($config, is-dark); + $active-border-color: if( + $is-dark, + theming.get-color-from-palette(palette.$gray-palette, 200), + theming.get-color-from-palette(palette.$gray-palette, 900) + ); - .mat-radio-button { - &.mat-primary { - @include _color($primary); - } + .mat-mdc-radio-button { + @include mdc-form-field.core-styles($query: mdc-helpers.$mdc-theme-styles-query); + @include mdc-radio-theme.theme(( + // The disabled colors don't use the `rgba` version, because + // MDC applies a separate opacity to disabled buttons. + disabled-selected-icon-color: mdc-theme-color.$on-surface, + disabled-unselected-icon-color: mdc-theme-color.$on-surface, + unselected-focus-icon-color: $active-border-color, + unselected-hover-icon-color: $active-border-color, + unselected-icon-color: $on-surface, + unselected-pressed-icon-color: $on-surface, + )); - &.mat-accent { - @include _color($accent); - } - - &.mat-warn { - @include _color($warn); - } + --mat-mdc-radio-ripple-color: #{mdc-theme-color.prop-value(on-surface)}; - // This needs extra specificity, because the classes above are combined - // (e.g. `.mat-radio-button.mat-accent`) which increases their specificity a lot. - // TODO: consider making the selectors into descendants (`.mat-primary .mat-radio-button`). - &.mat-radio-disabled { - &.mat-radio-checked .mat-radio-outer-circle, - .mat-radio-outer-circle { - border-color: theming.get-color-from-palette($foreground, disabled); + // MDC should set the disabled color on the label, but doesn't, so we do it here instead. + .mdc-radio--disabled + label { + color: theming.get-color-from-palette($foreground, disabled-text); } - .mat-radio-ripple .mat-ripple-element, - .mat-radio-inner-circle { - background-color: theming.get-color-from-palette($foreground, disabled); + &.mat-primary { + @include _color-palette($primary); } - .mat-radio-label-content { - color: theming.get-color-from-palette($foreground, disabled); + &.mat-accent { + @include _color-palette($accent); } - } - // Switch this to a solid color since we're using `opacity` - // to control how opaque the ripple should be. - .mat-ripple-element { - background-color: map.get($foreground, base); + &.mat-warn { + @include _color-palette($warn); + } } } } @mixin typography($config-or-theme) { - $config: typography.private-typography-to-2014-config( + $config: typography.private-typography-to-2018-config( theming.get-typography-config($config-or-theme)); - .mat-radio-button { - font-family: typography-utils.font-family($config); + @include mdc-helpers.using-mdc-typography($config) { + @include mdc-radio.without-ripple($query: mdc-helpers.$mdc-typography-styles-query); + @include mdc-form-field.core-styles($query: mdc-helpers.$mdc-typography-styles-query); } } -@mixin _density($config-or-theme) {} +@mixin density($config-or-theme) { + $density-scale: theming.get-density-config($config-or-theme); + .mat-mdc-radio-button .mdc-radio { + @include mdc-radio-theme.density($density-scale, $query: mdc-helpers.$mdc-base-styles-query); + } + + @include mdc-helpers.if-touch-targets-unsupported($density-scale) { + .mat-mdc-radio-touch-target { + display: none; + } + } +} @mixin theme($theme-or-color-config) { $theme: theming.private-legacy-get-theme($theme-or-color-config); @@ -89,7 +103,7 @@ @include color($color); } @if $density != null { - @include _density($density); + @include density($density); } @if $typography != null { @include typography($typography); diff --git a/src/material-experimental/mdc-radio/module.ts b/src/material/radio/module.ts similarity index 100% rename from src/material-experimental/mdc-radio/module.ts rename to src/material/radio/module.ts diff --git a/src/material/radio/public-api.ts b/src/material/radio/public-api.ts index de84533c48d8..86578200deaf 100644 --- a/src/material/radio/public-api.ts +++ b/src/material/radio/public-api.ts @@ -6,5 +6,5 @@ * found in the LICENSE file at https://angular.io/license */ -export * from './radio-module'; export * from './radio'; +export * from './module'; diff --git a/src/material/radio/radio.e2e.spec.ts b/src/material/radio/radio.e2e.spec.ts index 7eafd0339a5d..9b53d10a41e6 100644 --- a/src/material/radio/radio.e2e.spec.ts +++ b/src/material/radio/radio.e2e.spec.ts @@ -1,38 +1,22 @@ -import {browser, by, element, ExpectedConditions} from 'protractor'; +import {browser, by, element} from 'protractor'; describe('radio', () => { describe('disabling behavior', () => { - beforeEach(async () => await browser.get('/radio')); + beforeEach(async () => await browser.get('/mdc-radio')); it('should be checked when clicked', async () => { await element(by.id('water')).click(); - - expect(await element(by.id('water')).getAttribute('class')).toContain('mat-radio-checked'); - - expect(await element(by.css('input[id=water-input]')).getAttribute('checked')).toBeTruthy(); - expect(await element(by.css('input[id=leaf-input]')).getAttribute('checked')).toBeFalsy(); + expect(await element(by.css('input:checked')).getAttribute('value')).toBe('water'); await element(by.id('leaf')).click(); - expect(await element(by.id('leaf')).getAttribute('class')).toContain('mat-radio-checked'); - - expect(await element(by.css('input[id=leaf-input]')).getAttribute('checked')).toBeTruthy(); - expect(await element(by.css('input[id=water-input]')).getAttribute('checked')).toBeFalsy(); + expect(await element(by.css('input:checked')).getAttribute('value')).toBe('leaf'); }); it('should be disabled when disable the radio group', async () => { await element(by.id('toggle-disable')).click(); await element(by.id('water')).click(); - expect(await element(by.id('water')).getAttribute('class')).toContain('mat-radio-disabled'); - - await browser.wait(ExpectedConditions.presenceOf(element(by.css('.mat-radio-disabled')))); - - expect(await element(by.css('input[id=water-input]')).getAttribute('disabled')).toBeTruthy(); - - await element(await by.id('leaf')).click(); - expect(await element(by.id('leaf')).getAttribute('class')).toContain('mat-radio-disabled'); - - expect(await element(by.css('input[id=leaf-input]')).getAttribute('disabled')).toBeTruthy(); + expect(await element(by.css('input[id=water-input]')).getAttribute('disabled')).toBe('true'); }); }); }); diff --git a/src/material/radio/radio.html b/src/material/radio/radio.html index 15e839e9e12a..3ac71037faa5 100644 --- a/src/material/radio/radio.html +++ b/src/material/radio/radio.html @@ -1,40 +1,31 @@ - - - + + diff --git a/src/material/radio/radio.scss b/src/material/radio/radio.scss index 59b8414df1e5..e24b05f8a507 100644 --- a/src/material/radio/radio.scss +++ b/src/material/radio/radio.scss @@ -1,223 +1,116 @@ -@use 'sass:math'; -@use '@angular/cdk'; - -@use '../core/style/variables'; -@use '../core/ripple/ripple'; -@use '../core/style/vendor-prefixes'; - - -$size: variables.$toggle-size !default; -$ripple-radius: 20px; - -// Top-level host container. -.mat-radio-button { - display: inline-block; - -webkit-tap-highlight-color: transparent; - outline: 0; -} - -// Inner label container, wrapping entire element. -// Enables focus by click. -.mat-radio-label { - // Disable text selection on the label itself, because having text selected - // will prevent focus from reaching the label. Below we'll re-enable it only - // for the label's content so that people can still select the text. - @include vendor-prefixes.user-select(none); - cursor: pointer; - display: inline-flex; - align-items: center; - white-space: nowrap; - vertical-align: middle; - - // Have the label span the rest of the radio button for maximum clickable area. - width: 100%; +@use 'sass:map'; +@use '@material/radio/radio' as mdc-radio; +@use '@material/radio/radio-theme' as mdc-radio-theme; +@use '@material/form-field' as mdc-form-field; +@use '@material/touch-target' as mdc-touch-target; +@use '@material/ripple' as mdc-ripple; +@use '../core/mdc-helpers/mdc-helpers'; +@use '../core/style/layout-common'; + + +@include mdc-helpers.disable-mdc-fallback-declarations { + @include mdc-radio.static-styles($query: mdc-helpers.$mdc-base-styles-query); + @include mdc-form-field.core-styles($query: mdc-helpers.$mdc-base-styles-query); } -// Container for radio circles and ripple. -.mat-radio-container { - box-sizing: border-box; - display: inline-block; - position: relative; - width: $size; - height: $size; - // The radio container is inside of a inline-flex element and may shrink if the label - // is wide and text-wrapping is enabled. - flex-shrink: 0; -} +.mat-mdc-radio-button { + .mdc-radio { + // MDC theme styles also include structural styles so we have to include the theme at least + // once here. The values will be overwritten by our own theme file afterwards. + @include mdc-helpers.disable-mdc-fallback-declarations { + @include mdc-radio-theme.theme-styles(map.merge(mdc-radio-theme.$light-theme, ( + // Exclude the styles we don't need. + selected-focus-state-layer-color: null, + selected-focus-state-layer-opacity: null, + selected-hover-state-layer-color: null, + selected-hover-state-layer-opacity: null, + selected-pressed-state-layer-color: null, + selected-pressed-state-layer-opacity: null, + unselected-focus-icon-color: null, + unselected-focus-state-layer-color: null, + unselected-focus-state-layer-opacity: null, + unselected-hover-state-layer-color: null, + unselected-hover-state-layer-opacity: null, + unselected-pressed-state-layer-color: null, + unselected-pressed-state-layer-opacity: null, + ))); + + // TODO(crisbeto): this should be included by MDC's `theme-styles`, but it isn't currently. + @include mdc-radio-theme.focus-indicator-color( + var(--mat-mdc-radio-ripple-color, transparent)); + } -// The outer circle for the radio, always present. -.mat-radio-outer-circle { - box-sizing: border-box; - display: block; - height: $size; - left: 0; - position: absolute; - top: 0; - transition: border-color ease 280ms; - width: $size; - border: { - width: 2px; - style: solid; - radius: 50%; + // MDC's hover indication comes from their ripple which we don't use. + &:hover .mdc-radio__native-control:not([disabled]):not(:focus) { + & ~ .mdc-radio__background::before { + opacity: map.get(mdc-ripple.$dark-ink-opacities, hover); + transform: scale(1); + } + } } - ._mat-animation-noopable & { - transition: none; - } -} + &.mat-mdc-radio-checked { + // TODO(crisbeto): this should be included by MDC's `theme-styles`, but it isn't currently. + @include mdc-radio-theme.focus-indicator-color( + var(--mat-mdc-radio-checked-ripple-color, transparent)); -// The inner circle for the radio, shown when checked. -.mat-radio-inner-circle { - $transition-duration: 280ms; - $base-transition: transform ease $transition-duration, background-color ease $transition-duration; - border-radius: 50%; - box-sizing: border-box; - display: block; - height: $size; - left: 0; - position: absolute; - top: 0; - // On some zoom levels the `scale(0.001)` from below can cause the circle to be shown as a 1x1 - // dot (see #22036). Ensure that it's hidden using `opacity`. There's a slight transition with - // a long delay so that switching the opacity only applies after the `transform` is done. - opacity: 0; - transition: $base-transition, opacity linear 1ms $transition-duration; - width: $size; - - // Note: This starts from 0.001 instead of 0, because transitioning from 0 to 0.5 causes - // IE to flash the entire circle for a couple of frames, throwing off the entire animation. - transform: scale(0.001); - - // force browser to show background-color when using the print function - @include vendor-prefixes.color-adjust(exact); - - .mat-radio-checked & { - transform: scale(0.5); - opacity: 1; - transition: $base-transition; - - @include cdk.high-contrast(active, off) { - // Since we use a background color to render the circle, it won't be - // displayed in high contrast mode. Use a border as a fallback. - border: solid math.div($size, 2); + .mat-ripple-element { + background-color: var(--mat-mdc-radio-checked-ripple-color, transparent); } } - ._mat-animation-noopable & { - transition: none; - } -} + // 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-radio-ripple { + @include layout-common.fill; + pointer-events: none; + border-radius: 50%; -// Text label next to radio. -.mat-radio-label-content { - // Re-enable text selection for the button's content since - // we disabled it above in the `.mat-radio-label`. - @include vendor-prefixes.user-select(auto); - display: inline-block; - order: 0; - line-height: inherit; - padding-left: variables.$toggle-padding; - padding-right: 0; - - [dir='rtl'] & { - padding-right: variables.$toggle-padding; - padding-left: 0; - } -} - -// Alignment. -.mat-radio-label-content.mat-radio-label-before { - order: -1; - padding-left: 0; - padding-right: variables.$toggle-padding; + .mat-ripple-element { + opacity: mdc-radio-theme.$ripple-opacity; + } - [dir='rtl'] & { - padding-right: 0; - padding-left: variables.$toggle-padding; + &::before { + border-radius: 50%; + } } -} - -// Basic disabled state. -.mat-radio-disabled, -.mat-radio-disabled .mat-radio-label { - cursor: default; -} -// Increase specificity because ripple styles are part of the `mat-core` mixin and can -// potentially overwrite the absolute position of the container. -.mat-radio-button .mat-radio-ripple { - position: absolute; - left: calc(50% - #{$ripple-radius}); - top: calc(50% - #{$ripple-radius}); - height: $ripple-radius * 2; - width: $ripple-radius * 2; - z-index: 1; - pointer-events: none; - - .mat-ripple-element:not(.mat-radio-persistent-ripple) { - opacity: 0.16; + &._mat-animation-noopable { + .mdc-radio__background::before, + .mdc-radio__outer-circle, + .mdc-radio__inner-circle { + // Needs to be `!important`, because MDC's selectors are really specific. + transition: none !important; + } } -} - -.mat-radio-persistent-ripple { - width: 100%; - height: 100%; - transform: none; - // Needs an explicit top/left so it stays aligned no matter how the text is aligned (see #22389). - top: 0; - left: 0; - - .mat-radio-container:hover & { - opacity: 0.04; + // We don't inherit the border focus style from MDC since we don't use their ripple. + // Instead we need to replicate it here. + .mdc-radio .mdc-radio__native-control:focus:enabled:not(:checked) { + & ~ .mdc-radio__background .mdc-radio__outer-circle { + border-color: var(--mdc-radio-unselected-focus-icon-color, black); + } } - .mat-radio-button:not(.mat-radio-disabled).cdk-keyboard-focused &, - .mat-radio-button:not(.mat-radio-disabled).cdk-program-focused & { - opacity: 0.12; + // For radios render the focus indicator when we know + // the hidden input is focused (slightly different for each control). + &.cdk-focused .mat-mdc-focus-indicator::before { + content: ''; } +} - // We do this here, rather than having a `:not(.mat-radio-disabled)` - // above in the `:hover`, because the `:not` will bump the specificity - // a lot and will cause it to overide the focus styles. - &, .mat-radio-disabled .mat-radio-container:hover & { - opacity: 0; +// Element used to provide a larger tap target for users on touch devices. +.mat-mdc-radio-touch-target { + @include mdc-helpers.disable-mdc-fallback-declarations { + @include mdc-touch-target.touch-target( + $set-width: true, + $query: mdc-helpers.$mdc-base-styles-query); } - // Hover styles will be displayed after tapping on touch devices. - // Disable the hover styling if the user's device doesn't support hovering. - @media (hover: none) { - // Note that we only negate the `:hover` rather than setting it to always be `display: none`, - // in order to maintain the focus indication for hybrid touch + keyboard devices. - .mat-radio-container:hover & { - display: none; - } + [dir='rtl'] & { + left: 0; + right: 50%; + transform: translate(50%, -50%); } } -.mat-radio-input { - opacity: 0; - position: absolute; - top: 0; - left: 0; - margin: 0; - width: 100%; - height: 100%; - cursor: inherit; - - // Puts the input behind the circle while keeping it visible so that - // it allows `click` events to propagate up to the `label` wrapper. - z-index: -1; -} - -// Radio renders focus indicators when the -// associated visually-hidden input is focused. -.mat-radio-input:focus ~ .mat-focus-indicator::before { - content: ''; -} - -@include cdk.high-contrast(active, off) { - .mat-radio-disabled { - opacity: 0.5; - } -} diff --git a/src/material/radio/radio.spec.ts b/src/material/radio/radio.spec.ts index 91c031275a1c..3be3839aa202 100644 --- a/src/material/radio/radio.spec.ts +++ b/src/material/radio/radio.spec.ts @@ -3,11 +3,15 @@ import {FormControl, FormsModule, NgModel, ReactiveFormsModule} from '@angular/f import {Component, DebugElement, ViewChild} from '@angular/core'; import {By} from '@angular/platform-browser'; import {dispatchFakeEvent} from '../../cdk/testing/private'; - -import {MAT_RADIO_DEFAULT_OPTIONS} from './radio'; -import {MatRadioButton, MatRadioChange, MatRadioGroup, MatRadioModule} from './index'; - -describe('MatRadio', () => { +import { + MAT_RADIO_DEFAULT_OPTIONS, + MatRadioButton, + MatRadioChange, + MatRadioGroup, + MatRadioModule, +} from './index'; + +describe('MDC-based MatRadio', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ imports: [MatRadioModule, FormsModule, ReactiveFormsModule], @@ -36,6 +40,7 @@ describe('MatRadio', () => { let radioNativeElements: HTMLElement[]; let radioLabelElements: HTMLLabelElement[]; let radioInputElements: HTMLInputElement[]; + let radioFormFieldElements: HTMLInputElement[]; let groupInstance: MatRadioGroup; let radioInstances: MatRadioButton[]; let testComponent: RadiosInsideRadioGroup; @@ -59,6 +64,9 @@ describe('MatRadio', () => { radioInputElements = radioDebugElements.map( debugEl => debugEl.query(By.css('input'))!.nativeElement, ); + radioFormFieldElements = radioDebugElements.map( + debugEl => debugEl.query(By.css('.mdc-form-field'))!.nativeElement, + ); })); it('should set individual radio names based on the group name', () => { @@ -237,8 +245,8 @@ describe('MatRadio', () => { testComponent.isFirstDisabled = true; fixture.detectChanges(); - dispatchFakeEvent(radioLabelElements[0], 'mousedown'); - dispatchFakeEvent(radioLabelElements[0], 'mouseup'); + dispatchFakeEvent(radioFormFieldElements[0], 'mousedown'); + dispatchFakeEvent(radioFormFieldElements[0], 'mouseup'); let rippleAmount = radioNativeElements[0].querySelectorAll( '.mat-ripple-element:not(.mat-radio-persistent-ripple)', @@ -251,8 +259,8 @@ describe('MatRadio', () => { testComponent.isFirstDisabled = false; fixture.detectChanges(); - dispatchFakeEvent(radioLabelElements[0], 'mousedown'); - dispatchFakeEvent(radioLabelElements[0], 'mouseup'); + dispatchFakeEvent(radioFormFieldElements[0], 'mousedown'); + dispatchFakeEvent(radioFormFieldElements[0], 'mouseup'); rippleAmount = radioNativeElements[0].querySelectorAll( '.mat-ripple-element:not(.mat-radio-persistent-ripple)', @@ -265,9 +273,9 @@ describe('MatRadio', () => { testComponent.disableRipple = true; fixture.detectChanges(); - for (const radioLabel of radioLabelElements) { - dispatchFakeEvent(radioLabel, 'mousedown'); - dispatchFakeEvent(radioLabel, 'mouseup'); + for (const radioFormField of radioFormFieldElements) { + dispatchFakeEvent(radioFormField, 'mousedown'); + dispatchFakeEvent(radioFormField, 'mouseup'); const rippleAmount = radioNativeElements[0].querySelectorAll( '.mat-ripple-element:not(.mat-radio-persistent-ripple)', @@ -279,9 +287,9 @@ describe('MatRadio', () => { testComponent.disableRipple = false; fixture.detectChanges(); - for (const radioLabel of radioLabelElements) { - dispatchFakeEvent(radioLabel, 'mousedown'); - dispatchFakeEvent(radioLabel, 'mouseup'); + for (const radioFormField of radioFormFieldElements) { + dispatchFakeEvent(radioFormField, 'mousedown'); + dispatchFakeEvent(radioFormField, 'mouseup'); const rippleAmount = radioNativeElements[0].querySelectorAll( '.mat-ripple-element:not(.mat-radio-persistent-ripple)', @@ -420,7 +428,7 @@ describe('MatRadio', () => { expect( radioRippleNativeElements.every(element => - element.classList.contains('mat-focus-indicator'), + element.classList.contains('mat-mdc-focus-indicator'), ), ).toBe(true); }); @@ -562,7 +570,6 @@ describe('MatRadio', () => { // Blur the input element in order to verify that the ng-touched state has been set to true. // The touched state should be only set to true after the form control has been blurred. dispatchFakeEvent(innerRadios[2].nativeElement, 'blur'); - expect(groupNgModel.valid).toBe(true); expect(groupNgModel.pristine).toBe(false); expect(groupNgModel.touched).toBe(true); @@ -684,7 +691,6 @@ describe('MatRadio', () => { fruitRadioInstances = radioDebugElements .filter(debugEl => debugEl.componentInstance.name == 'fruit') .map(debugEl => debugEl.componentInstance); - fruitRadioNativeElements = radioDebugElements .filter(debugEl => debugEl.componentInstance.name == 'fruit') .map(debugEl => debugEl.nativeElement); @@ -826,8 +832,10 @@ describe('MatRadio', () => { }); it('should forward focus to native input', () => { - const radioButtonEl = fixture.debugElement.query(By.css('.mat-radio-button'))!.nativeElement; - const inputEl = fixture.debugElement.query(By.css('.mat-radio-input'))!.nativeElement; + let radioButtonEl = fixture.debugElement.query( + By.css('.mat-mdc-radio-button'), + )!.nativeElement; + let inputEl = fixture.debugElement.query(By.css('.mdc-radio__native-control'))!.nativeElement; radioButtonEl.focus(); // Focus events don't always fire in tests, so we need to fake it. @@ -838,7 +846,7 @@ describe('MatRadio', () => { }); it('should allow specifying an explicit tabindex for a single radio-button', () => { - const radioButtonInput = fixture.debugElement.query(By.css('.mat-radio-button input'))! + const radioButtonInput = fixture.debugElement.query(By.css('.mat-mdc-radio-button input'))! .nativeElement as HTMLInputElement; expect(radioButtonInput.tabIndex) @@ -858,7 +866,7 @@ describe('MatRadio', () => { predefinedFixture.detectChanges(); const radioButtonEl = predefinedFixture.debugElement.query( - By.css('.mat-radio-button'), + By.css('.mat-mdc-radio-button'), )!.nativeElement; expect(radioButtonEl.hasAttribute('tabindex')).toBe(false); @@ -869,7 +877,7 @@ describe('MatRadio', () => { predefinedFixture.detectChanges(); const radioButtonInput = predefinedFixture.debugElement.query( - By.css('.mat-radio-button input'), + By.css('.mat-mdc-radio-button input'), )!.nativeElement as HTMLInputElement; expect(radioButtonInput.getAttribute('tabindex')).toBe('5'); @@ -880,13 +888,22 @@ describe('MatRadio', () => { predefinedFixture.detectChanges(); const radioButtonEl = predefinedFixture.debugElement.query( - By.css('.mat-radio-button'), + By.css('.mat-mdc-radio-button'), )!.nativeElement; expect(radioButtonEl.hasAttribute('aria-label')).toBe(false); expect(radioButtonEl.hasAttribute('aria-describedby')).toBe(false); expect(radioButtonEl.hasAttribute('aria-labelledby')).toBe(false); }); + + it('should remove the tabindex from the host element when disabled', () => { + const radioButton = fixture.debugElement.query(By.css('.mat-mdc-radio-button')).nativeElement; + + fixture.componentInstance.disabled = true; + fixture.detectChanges(); + + expect(radioButton.hasAttribute('tabindex')).toBe(false); + }); }); describe('group interspersed with other tags', () => { @@ -1065,10 +1082,11 @@ class RadioGroupWithFormControl { } @Component({ - template: ``, + template: ``, }) class FocusableRadioButton { tabIndex: number; + disabled = false; } @Component({ diff --git a/src/material/radio/radio.ts b/src/material/radio/radio.ts index f720de7ef22a..cfe488b38fcf 100644 --- a/src/material/radio/radio.ts +++ b/src/material/radio/radio.ts @@ -6,9 +6,6 @@ * found in the LICENSE file at https://angular.io/license */ -import {FocusMonitor, FocusOrigin} from '@angular/cdk/a11y'; -import {BooleanInput, coerceBooleanProperty, coerceNumberProperty} from '@angular/cdk/coercion'; -import {UniqueSelectionDispatcher} from '@angular/cdk/collections'; import { AfterContentInit, AfterViewInit, @@ -33,7 +30,6 @@ import { ViewChild, ViewEncapsulation, } from '@angular/core'; -import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms'; import { CanDisableRipple, HasTabIndex, @@ -41,29 +37,25 @@ import { mixinTabIndex, ThemePalette, } from '@angular/material/core'; +import {FocusMonitor, FocusOrigin} from '@angular/cdk/a11y'; +import {BooleanInput, coerceBooleanProperty, coerceNumberProperty} from '@angular/cdk/coercion'; +import {UniqueSelectionDispatcher} from '@angular/cdk/collections'; import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations'; - -export interface MatRadioDefaultOptions { - color: ThemePalette; -} - -export const MAT_RADIO_DEFAULT_OPTIONS = new InjectionToken( - 'mat-radio-default-options', - { - providedIn: 'root', - factory: MAT_RADIO_DEFAULT_OPTIONS_FACTORY, - }, -); - -export function MAT_RADIO_DEFAULT_OPTIONS_FACTORY(): MatRadioDefaultOptions { - return { - color: 'accent', - }; -} +import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms'; // Increasing integer for generating unique ids for radio components. let nextUniqueId = 0; +/** Change event object emitted by radio button and radio group. */ +export class MatRadioChange { + constructor( + /** The radio button that emits the change event. */ + public source: _MatRadioButtonBase, + /** The value of the radio button. */ + public value: any, + ) {} +} + /** * Provider Expression that allows mat-radio-group to register as a ControlValueAccessor. This * allows it to support [(ngModel)] and ngControl. @@ -75,16 +67,6 @@ export const MAT_RADIO_GROUP_CONTROL_VALUE_ACCESSOR: any = { multi: true, }; -/** Change event object emitted by radio button and radio group. */ -export class MatRadioChange { - constructor( - /** The radio button that emits the change event. */ - public source: _MatRadioButtonBase, - /** The value of the radio button. */ - public value: any, - ) {} -} - /** * Injection token that can be used to inject instances of `MatRadioGroup`. It serves as * alternative token to the actual `MatRadioGroup` class which could cause unnecessary @@ -94,6 +76,24 @@ export const MAT_RADIO_GROUP = new InjectionToken<_MatRadioGroupBase<_MatRadioBu 'MatRadioGroup', ); +export interface MatRadioDefaultOptions { + color: ThemePalette; +} + +export const MAT_RADIO_DEFAULT_OPTIONS = new InjectionToken( + 'mat-radio-default-options', + { + providedIn: 'root', + factory: MAT_RADIO_DEFAULT_OPTIONS_FACTORY, + }, +); + +export function MAT_RADIO_DEFAULT_OPTIONS_FACTORY(): MatRadioDefaultOptions { + return { + color: 'accent', + }; +} + /** * Base class with all of the `MatRadioGroup` functionality. * @docs-private @@ -323,26 +323,6 @@ export abstract class _MatRadioGroupBase } } -/** - * A group of radio buttons. May contain one or more `` elements. - */ -@Directive({ - selector: 'mat-radio-group', - exportAs: 'matRadioGroup', - providers: [ - MAT_RADIO_GROUP_CONTROL_VALUE_ACCESSOR, - {provide: MAT_RADIO_GROUP, useExisting: MatRadioGroup}, - ], - host: { - 'role': 'radiogroup', - 'class': 'mat-radio-group', - }, -}) -export class MatRadioGroup extends _MatRadioGroupBase { - @ContentChildren(forwardRef(() => MatRadioButton), {descendants: true}) - _radios: QueryList; -} - // Boilerplate for applying mixins to MatRadioButton. /** @docs-private */ abstract class MatRadioButtonBase { @@ -668,26 +648,40 @@ export abstract class _MatRadioButtonBase } /** - * A Material design radio-button. Typically placed inside of `` elements. + * A group of radio buttons. May contain one or more `` elements. */ +@Directive({ + selector: 'mat-radio-group', + exportAs: 'matRadioGroup', + providers: [ + MAT_RADIO_GROUP_CONTROL_VALUE_ACCESSOR, + {provide: MAT_RADIO_GROUP, useExisting: MatRadioGroup}, + ], + host: { + 'role': 'radiogroup', + 'class': 'mat-mdc-radio-group', + }, +}) +export class MatRadioGroup extends _MatRadioGroupBase { + /** Child radio buttons. */ + @ContentChildren(forwardRef(() => MatRadioButton), {descendants: true}) + _radios: QueryList; +} + @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]': '_noopAnimations', + 'class': 'mat-mdc-radio-button', + '[attr.id]': 'id', '[class.mat-primary]': 'color === "primary"', '[class.mat-accent]': 'color === "accent"', '[class.mat-warn]': 'color === "warn"', + '[class.mat-mdc-radio-checked]': 'checked', + '[class._mat-animation-noopable]': '_noopAnimations', // Needs to be removed since it causes some a11y issues (see #21266). '[attr.tabindex]': 'null', - '[attr.id]': 'id', '[attr.aria-label]': 'null', '[attr.aria-labelledby]': 'null', '[attr.aria-describedby]': 'null', @@ -696,29 +690,32 @@ export abstract class _MatRadioButtonBase // the focus to the native element. '(focus)': '_inputElement.nativeElement.focus()', }, + inputs: ['disableRipple', 'tabIndex'], + exportAs: 'matRadioButton', + encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, }) export class MatRadioButton extends _MatRadioButtonBase { constructor( @Optional() @Inject(MAT_RADIO_GROUP) radioGroup: MatRadioGroup, elementRef: ElementRef, - changeDetector: ChangeDetectorRef, - focusMonitor: FocusMonitor, - radioDispatcher: UniqueSelectionDispatcher, + _changeDetector: ChangeDetectorRef, + _focusMonitor: FocusMonitor, + _radioDispatcher: UniqueSelectionDispatcher, @Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode?: string, @Optional() @Inject(MAT_RADIO_DEFAULT_OPTIONS) - providerOverride?: MatRadioDefaultOptions, + _providerOverride?: MatRadioDefaultOptions, @Attribute('tabindex') tabIndex?: string, ) { super( radioGroup, elementRef, - changeDetector, - focusMonitor, - radioDispatcher, + _changeDetector, + _focusMonitor, + _radioDispatcher, animationMode, - providerOverride, + _providerOverride, tabIndex, ); } diff --git a/src/material/radio/testing/BUILD.bazel b/src/material/radio/testing/BUILD.bazel index 2120378e3732..c5737a28054b 100644 --- a/src/material/radio/testing/BUILD.bazel +++ b/src/material/radio/testing/BUILD.bazel @@ -14,9 +14,17 @@ ts_library( ], ) -filegroup( - name = "source-files", - srcs = glob(["**/*.ts"]), +ng_test_library( + name = "unit_tests_lib", + srcs = glob( + ["**/*.spec.ts"], + exclude = ["shared.spec.ts"], + ), + deps = [ + ":harness_tests_lib", + ":testing", + "//src/material/radio", + ], ) ng_test_library( @@ -33,20 +41,14 @@ ng_test_library( ], ) -ng_test_library( - name = "unit_tests_lib", - srcs = glob( - ["**/*.spec.ts"], - exclude = ["shared.spec.ts"], - ), +ng_web_test_suite( + name = "unit_tests", deps = [ - ":harness_tests_lib", - ":testing", - "//src/material/radio", + ":unit_tests_lib", ], ) -ng_web_test_suite( - name = "unit_tests", - deps = [":unit_tests_lib"], +filegroup( + name = "source-files", + srcs = glob(["**/*.ts"]), ) diff --git a/src/material/radio/testing/radio-harness.spec.ts b/src/material/radio/testing/radio-harness.spec.ts index 667353473d27..363bda75b353 100644 --- a/src/material/radio/testing/radio-harness.spec.ts +++ b/src/material/radio/testing/radio-harness.spec.ts @@ -2,6 +2,6 @@ import {MatRadioModule} from '@angular/material/radio'; import {runHarnessTests} from '@angular/material/radio/testing/shared.spec'; import {MatRadioButtonHarness, MatRadioGroupHarness} from './radio-harness'; -describe('Non-MDC-based', () => { +describe('MDC-based radio harness', () => { runHarnessTests(MatRadioModule, MatRadioGroupHarness, MatRadioButtonHarness); }); diff --git a/src/material/radio/testing/radio-harness.ts b/src/material/radio/testing/radio-harness.ts index 44966b35684b..f86e9e091b4c 100644 --- a/src/material/radio/testing/radio-harness.ts +++ b/src/material/radio/testing/radio-harness.ts @@ -162,27 +162,30 @@ export abstract class _MatRadioGroupHarnessBase< } } -/** Harness for interacting with a standard mat-radio-group in tests. */ +/** Harness for interacting with an MDC-based mat-radio-group in tests. */ export class MatRadioGroupHarness extends _MatRadioGroupHarnessBase< typeof MatRadioButtonHarness, MatRadioButtonHarness, RadioButtonHarnessFilters > { /** The selector for the host element of a `MatRadioGroup` instance. */ - static hostSelector = '.mat-radio-group'; + static hostSelector = '.mat-mdc-radio-group'; protected _buttonClass = MatRadioButtonHarness; /** - * Gets a `HarnessPredicate` that can be used to search for a `MatRadioGroupHarness` that meets - * certain criteria. + * Gets a `HarnessPredicate` that can be used to search for a radio group with specific + * attributes. * @param options Options for filtering which radio group instances are considered a match. * @return a `HarnessPredicate` configured with the given options. */ - static with(options: RadioGroupHarnessFilters = {}): HarnessPredicate { - return new HarnessPredicate(MatRadioGroupHarness, options).addOption( + static with( + this: ComponentHarnessConstructor, + options: RadioGroupHarnessFilters = {}, + ): HarnessPredicate { + return new HarnessPredicate(this, options).addOption( 'name', options.name, - this._checkRadioGroupName, + MatRadioGroupHarness._checkRadioGroupName, ); } } @@ -261,19 +264,22 @@ export abstract class _MatRadioButtonHarnessBase extends ComponentHarness { } } -/** Harness for interacting with a standard mat-radio-button in tests. */ +/** Harness for interacting with an MDC-based mat-radio-button in tests. */ export class MatRadioButtonHarness extends _MatRadioButtonHarnessBase { /** The selector for the host element of a `MatRadioButton` instance. */ - static hostSelector = '.mat-radio-button'; + static hostSelector = '.mat-mdc-radio-button'; /** - * Gets a `HarnessPredicate` that can be used to search for a `MatRadioButtonHarness` that meets - * certain criteria. + * Gets a `HarnessPredicate` that can be used to search for a radio button with specific + * attributes. * @param options Options for filtering which radio button instances are considered a match. * @return a `HarnessPredicate` configured with the given options. */ - static with(options: RadioButtonHarnessFilters = {}): HarnessPredicate { - return new HarnessPredicate(MatRadioButtonHarness, options) + static with( + this: ComponentHarnessConstructor, + options: RadioButtonHarnessFilters = {}, + ): HarnessPredicate { + return new HarnessPredicate(this, options) .addOption('label', options.label, (harness, label) => HarnessPredicate.stringMatches(harness.getLabelText(), label), ) @@ -285,6 +291,6 @@ export class MatRadioButtonHarness extends _MatRadioButtonHarnessBase { ); } - protected _textLabel = this.locatorFor('.mat-radio-label-content'); - protected _clickLabel = this.locatorFor('.mat-radio-label'); + protected _textLabel = this.locatorFor('label'); + protected _clickLabel = this._textLabel; } diff --git a/src/material/schematics/ng-generate/address-form/files/__path__/__name@dasherize@if-flat__/__name@dasherize__.component.spec.ts.template b/src/material/schematics/ng-generate/address-form/files/__path__/__name@dasherize@if-flat__/__name@dasherize__.component.spec.ts.template index f0b71c0c23db..80ffafb8d68d 100644 --- a/src/material/schematics/ng-generate/address-form/files/__path__/__name@dasherize@if-flat__/__name@dasherize__.component.spec.ts.template +++ b/src/material/schematics/ng-generate/address-form/files/__path__/__name@dasherize@if-flat__/__name@dasherize__.component.spec.ts.template @@ -2,10 +2,10 @@ import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { MatButtonModule } from '@angular/material/button'; -import { MatCardModule } from '@angular/material/legacy-card'; -import { MatInputModule } from '@angular/material/legacy-input'; -import { MatRadioModule } from '@angular/material/radio'; -import { MatSelectModule } from '@angular/material/select'; +import { MatLegacyCardModule } from '@angular/material/legacy-card'; +import { MatLegacyInputModule } from '@angular/material/legacy-input'; +import { MatLegacyRadioModule } from '@angular/material/legacy-radio'; +import { MatLegacySelectModule } from '@angular/material/legacy-select'; import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; @@ -20,10 +20,10 @@ describe('<%= classify(name) %>Component', () => { NoopAnimationsModule, ReactiveFormsModule, MatButtonModule, - MatCardModule, - MatInputModule, - MatRadioModule, - MatSelectModule, + MatLegacyCardModule, + MatLegacyInputModule, + MatLegacyRadioModule, + MatLegacySelectModule, ] }).compileComponents(); })); diff --git a/src/material/schematics/ng-generate/address-form/index.spec.ts b/src/material/schematics/ng-generate/address-form/index.spec.ts index 1d15b3dea6e8..ac8781950d10 100644 --- a/src/material/schematics/ng-generate/address-form/index.spec.ts +++ b/src/material/schematics/ng-generate/address-form/index.spec.ts @@ -35,10 +35,10 @@ describe('Material address-form schematic', () => { const tree = await runner.runSchematicAsync('address-form', baseOptions, app).toPromise(); const moduleContent = getFileContent(tree, '/projects/material/src/app/app.module.ts'); - expect(moduleContent).toContain('MatInputModule'); + expect(moduleContent).toContain('MatLegacyInputModule'); expect(moduleContent).toContain('MatButtonModule'); - expect(moduleContent).toContain('MatSelectModule'); - expect(moduleContent).toContain('MatRadioModule'); + expect(moduleContent).toContain('MatLegacySelectModule'); + expect(moduleContent).toContain('MatLegacyRadioModule'); expect(moduleContent).toContain('ReactiveFormsModule'); }); diff --git a/src/material/schematics/ng-generate/address-form/index.ts b/src/material/schematics/ng-generate/address-form/index.ts index d202b4aa2dba..927600c80145 100644 --- a/src/material/schematics/ng-generate/address-form/index.ts +++ b/src/material/schematics/ng-generate/address-form/index.ts @@ -39,11 +39,31 @@ export default function (options: Schema): Rule { function addFormModulesToModule(options: Schema) { return async (host: Tree) => { const modulePath = (await findModuleFromOptions(host, options))!; - addModuleImportToModule(host, modulePath, 'MatInputModule', '@angular/material/legacy-input'); + addModuleImportToModule( + host, + modulePath, + 'MatLegacyInputModule', + '@angular/material/legacy-input', + ); addModuleImportToModule(host, modulePath, 'MatButtonModule', '@angular/material/button'); - addModuleImportToModule(host, modulePath, 'MatSelectModule', '@angular/material/select'); - addModuleImportToModule(host, modulePath, 'MatRadioModule', '@angular/material/radio'); - addModuleImportToModule(host, modulePath, 'MatCardModule', '@angular/material/legacy-card'); + addModuleImportToModule( + host, + modulePath, + 'MatLegacySelectModule', + '@angular/material/legacy-select', + ); + addModuleImportToModule( + host, + modulePath, + 'MatLegacyRadioModule', + '@angular/material/legacy-radio', + ); + addModuleImportToModule( + host, + modulePath, + 'MatLegacyCardModule', + '@angular/material/legacy-card', + ); addModuleImportToModule(host, modulePath, 'ReactiveFormsModule', '@angular/forms'); }; } diff --git a/src/universal-app/kitchen-sink-mdc/kitchen-sink-mdc.ts b/src/universal-app/kitchen-sink-mdc/kitchen-sink-mdc.ts index 80aabc85caca..c00c81b74d5a 100644 --- a/src/universal-app/kitchen-sink-mdc/kitchen-sink-mdc.ts +++ b/src/universal-app/kitchen-sink-mdc/kitchen-sink-mdc.ts @@ -9,7 +9,7 @@ import {MatListModule} from '@angular/material-experimental/mdc-list'; import {MatProgressBarModule} from '@angular/material/progress-bar'; import {MatChipsModule} from '@angular/material/chips'; import {MatMenuModule} from '@angular/material-experimental/mdc-menu'; -import {MatRadioModule} from '@angular/material-experimental/mdc-radio'; +import {MatRadioModule} from '@angular/material/radio'; import {MatSlideToggleModule} from '@angular/material/slide-toggle'; import {MatSliderModule} from '@angular/material-experimental/mdc-slider'; import {MatTabsModule} from '@angular/material-experimental/mdc-tabs'; diff --git a/src/universal-app/kitchen-sink/kitchen-sink.ts b/src/universal-app/kitchen-sink/kitchen-sink.ts index dc63bcc75fb2..502b9533d450 100644 --- a/src/universal-app/kitchen-sink/kitchen-sink.ts +++ b/src/universal-app/kitchen-sink/kitchen-sink.ts @@ -22,7 +22,7 @@ import {MatMenuModule} from '@angular/material/menu'; import {MatPaginatorModule} from '@angular/material/paginator'; import {MatLegacyProgressBarModule} from '@angular/material/legacy-progress-bar'; import {MatProgressSpinnerModule} from '@angular/material/progress-spinner'; -import {MatRadioModule} from '@angular/material/radio'; +import {MatLegacyRadioModule} from '@angular/material/legacy-radio'; import {MatLegacySelectModule} from '@angular/material/legacy-select'; import {MatSidenavModule} from '@angular/material/sidenav'; import {MatSliderModule} from '@angular/material/slider'; @@ -119,7 +119,7 @@ export class KitchenSink { MatPaginatorModule, MatLegacyProgressBarModule, MatProgressSpinnerModule, - MatRadioModule, + MatLegacyRadioModule, MatRippleModule, MatLegacySelectModule, MatSidenavModule, diff --git a/tools/public_api_guard/material/legacy-radio-testing.md b/tools/public_api_guard/material/legacy-radio-testing.md new file mode 100644 index 000000000000..98f9627cb513 --- /dev/null +++ b/tools/public_api_guard/material/legacy-radio-testing.md @@ -0,0 +1,39 @@ +## API Report File for "components-srcs" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { AsyncFactoryFn } from '@angular/cdk/testing'; +import { HarnessPredicate } from '@angular/cdk/testing'; +import { _MatRadioButtonHarnessBase } from '@angular/material/radio/testing'; +import { _MatRadioGroupHarnessBase } from '@angular/material/radio/testing'; +import { RadioButtonHarnessFilters } from '@angular/material/radio/testing'; +import { RadioGroupHarnessFilters } from '@angular/material/radio/testing'; +import { TestElement } from '@angular/cdk/testing'; + +// @public +export class MatLegacyRadioButtonHarness extends _MatRadioButtonHarnessBase { + // (undocumented) + protected _clickLabel: AsyncFactoryFn; + static hostSelector: string; + // (undocumented) + protected _textLabel: AsyncFactoryFn; + static with(options?: RadioButtonHarnessFilters): HarnessPredicate; +} + +// @public +export class MatLegacyRadioGroupHarness extends _MatRadioGroupHarnessBase { + // (undocumented) + protected _buttonClass: typeof MatLegacyRadioButtonHarness; + static hostSelector: string; + static with(options?: RadioGroupHarnessFilters): HarnessPredicate; +} + +export { RadioButtonHarnessFilters } + +export { RadioGroupHarnessFilters } + +// (No @packageDocumentation comment for this package) + +``` diff --git a/tools/public_api_guard/material/legacy-radio.md b/tools/public_api_guard/material/legacy-radio.md new file mode 100644 index 000000000000..6efe39fa6ec2 --- /dev/null +++ b/tools/public_api_guard/material/legacy-radio.md @@ -0,0 +1,66 @@ +## API Report File for "components-srcs" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { ChangeDetectorRef } from '@angular/core'; +import { ElementRef } from '@angular/core'; +import { FocusMonitor } from '@angular/cdk/a11y'; +import * as i0 from '@angular/core'; +import * as i2 from '@angular/material/core'; +import { MAT_RADIO_DEFAULT_OPTIONS } from '@angular/material/radio'; +import { MAT_RADIO_DEFAULT_OPTIONS_FACTORY } from '@angular/material/radio'; +import { MAT_RADIO_GROUP } from '@angular/material/radio'; +import { MatRadioChange as MatLegacyRadioChange } from '@angular/material/radio'; +import { MatRadioDefaultOptions as MatLegacyRadioDefaultOptions } from '@angular/material/radio'; +import { _MatRadioButtonBase } from '@angular/material/radio'; +import { _MatRadioGroupBase } from '@angular/material/radio'; +import { QueryList } from '@angular/core'; +import { UniqueSelectionDispatcher } from '@angular/cdk/collections'; + +export { MAT_RADIO_DEFAULT_OPTIONS } + +export { MAT_RADIO_DEFAULT_OPTIONS_FACTORY } + +export { MAT_RADIO_GROUP } + +// @public +export const MAT_RADIO_GROUP_CONTROL_VALUE_ACCESSOR: any; + +// @public +export class MatLegacyRadioButton extends _MatRadioButtonBase { + constructor(radioGroup: MatLegacyRadioGroup, elementRef: ElementRef, changeDetector: ChangeDetectorRef, focusMonitor: FocusMonitor, radioDispatcher: UniqueSelectionDispatcher, animationMode?: string, providerOverride?: MatLegacyRadioDefaultOptions, tabIndex?: string); + // (undocumented) + static ɵcmp: i0.ɵɵComponentDeclaration; + // (undocumented) + static ɵfac: i0.ɵɵFactoryDeclaration; +} + +export { MatLegacyRadioChange } + +export { MatLegacyRadioDefaultOptions } + +// @public +export class MatLegacyRadioGroup extends _MatRadioGroupBase { + // (undocumented) + _radios: QueryList; + // (undocumented) + static ɵdir: i0.ɵɵDirectiveDeclaration; + // (undocumented) + static ɵfac: i0.ɵɵFactoryDeclaration; +} + +// @public (undocumented) +export class MatLegacyRadioModule { + // (undocumented) + static ɵfac: i0.ɵɵFactoryDeclaration; + // (undocumented) + static ɵinj: i0.ɵɵInjectorDeclaration; + // (undocumented) + static ɵmod: i0.ɵɵNgModuleDeclaration; +} + +// (No @packageDocumentation comment for this package) + +``` diff --git a/tools/public_api_guard/material/radio-testing.md b/tools/public_api_guard/material/radio-testing.md index 8d02b6e50cab..cf6790d76a91 100644 --- a/tools/public_api_guard/material/radio-testing.md +++ b/tools/public_api_guard/material/radio-testing.md @@ -18,7 +18,7 @@ export class MatRadioButtonHarness extends _MatRadioButtonHarnessBase { static hostSelector: string; // (undocumented) protected _textLabel: AsyncFactoryFn; - static with(options?: RadioButtonHarnessFilters): HarnessPredicate; + static with(this: ComponentHarnessConstructor, options?: RadioButtonHarnessFilters): HarnessPredicate; } // @public (undocumented) @@ -45,7 +45,7 @@ export class MatRadioGroupHarness extends _MatRadioGroupHarnessBase; + static with(this: ComponentHarnessConstructor, options?: RadioGroupHarnessFilters): HarnessPredicate; } // @public (undocumented) diff --git a/tools/public_api_guard/material/radio.md b/tools/public_api_guard/material/radio.md index b8c69b8e170b..2493a90c4681 100644 --- a/tools/public_api_guard/material/radio.md +++ b/tools/public_api_guard/material/radio.md @@ -20,6 +20,7 @@ import { FocusOrigin } from '@angular/cdk/a11y'; import { HasTabIndex } from '@angular/material/core'; import * as i0 from '@angular/core'; import * as i2 from '@angular/material/core'; +import * as i3 from '@angular/common'; import { InjectionToken } from '@angular/core'; import { OnDestroy } from '@angular/core'; import { OnInit } from '@angular/core'; @@ -39,9 +40,9 @@ export const MAT_RADIO_GROUP: InjectionToken<_MatRadioGroupBase<_MatRadioButtonB // @public export const MAT_RADIO_GROUP_CONTROL_VALUE_ACCESSOR: any; -// @public +// @public (undocumented) export class MatRadioButton extends _MatRadioButtonBase { - constructor(radioGroup: MatRadioGroup, elementRef: ElementRef, changeDetector: ChangeDetectorRef, focusMonitor: FocusMonitor, radioDispatcher: UniqueSelectionDispatcher, animationMode?: string, providerOverride?: MatRadioDefaultOptions, tabIndex?: string); + constructor(radioGroup: MatRadioGroup, elementRef: ElementRef, _changeDetector: ChangeDetectorRef, _focusMonitor: FocusMonitor, _radioDispatcher: UniqueSelectionDispatcher, animationMode?: string, _providerOverride?: MatRadioDefaultOptions, tabIndex?: string); // (undocumented) static ɵcmp: i0.ɵɵComponentDeclaration; // (undocumented) @@ -114,7 +115,6 @@ export interface MatRadioDefaultOptions { // @public export class MatRadioGroup extends _MatRadioGroupBase { - // (undocumented) _radios: QueryList; // (undocumented) static ɵdir: i0.ɵɵDirectiveDeclaration; @@ -166,7 +166,7 @@ export class MatRadioModule { // (undocumented) static ɵinj: i0.ɵɵInjectorDeclaration; // (undocumented) - static ɵmod: i0.ɵɵNgModuleDeclaration; + static ɵmod: i0.ɵɵNgModuleDeclaration; } // (No @packageDocumentation comment for this package)