diff --git a/src/dev-app/checkbox/BUILD.bazel b/src/dev-app/checkbox/BUILD.bazel index 190471f72a4a..8535517d8cab 100644 --- a/src/dev-app/checkbox/BUILD.bazel +++ b/src/dev-app/checkbox/BUILD.bazel @@ -16,6 +16,7 @@ ng_module( "//src/material/form-field", "//src/material/input", "//src/material/select", + "//src/material/tooltip", "@npm//@angular/forms", ], ) diff --git a/src/dev-app/checkbox/checkbox-demo.html b/src/dev-app/checkbox/checkbox-demo.html index 8bd338ef7ae5..1c65e67460bc 100644 --- a/src/dev-app/checkbox/checkbox-demo.html +++ b/src/dev-app/checkbox/checkbox-demo.html @@ -26,19 +26,20 @@

mat-checkbox: Basic Example

(change)="isIndeterminate = false" [indeterminate]="isIndeterminate" [disabled]="isDisabled" - [labelPosition]="labelPosition"> + [disabledInteractive]="isDisabledInteractive" + [labelPosition]="labelPosition" + [matTooltip]="isDisabled ? 'Tooltip that only shows up when disabled' : null"> Do you want to foobar the bazquux? - {{printResult()}}
- + + +
diff --git a/src/dev-app/checkbox/checkbox-demo.ts b/src/dev-app/checkbox/checkbox-demo.ts index 6d26783d403d..873cb272093d 100644 --- a/src/dev-app/checkbox/checkbox-demo.ts +++ b/src/dev-app/checkbox/checkbox-demo.ts @@ -13,6 +13,7 @@ import {MAT_CHECKBOX_DEFAULT_OPTIONS, MatCheckboxModule} from '@angular/material import {MatPseudoCheckboxModule, ThemePalette} from '@angular/material/core'; import {MatInputModule} from '@angular/material/input'; import {MatSelectModule} from '@angular/material/select'; +import {MatTooltip} from '@angular/material/tooltip'; export interface Task { name: string; @@ -114,15 +115,17 @@ export class MatCheckboxDemoNestedChecklist { ClickActionNoop, ClickActionCheck, AnimationsNoop, + MatTooltip, ], changeDetection: ChangeDetectionStrategy.OnPush, }) export class CheckboxDemo { - isIndeterminate: boolean = false; - isChecked: boolean = false; - isDisabled: boolean = false; + isIndeterminate = false; + isChecked = false; + isDisabled = false; + isDisabledInteractive = false; labelPosition: 'before' | 'after' = 'after'; - useAlternativeColor: boolean = false; + useAlternativeColor = false; demoRequired = false; demoLabelAfter = false; diff --git a/src/material/checkbox/_checkbox-common.scss b/src/material/checkbox/_checkbox-common.scss index 0a713417a551..e17a06009638 100644 --- a/src/material/checkbox/_checkbox-common.scss +++ b/src/material/checkbox/_checkbox-common.scss @@ -138,6 +138,21 @@ $_fallback-size: 40px; @include token-utils.create-token-slot(border-color, selected-focus-icon-color); @include token-utils.create-token-slot(background-color, selected-focus-icon-color); } + + // Needs extra specificity to override the focus, hover, active states. + .mdc-checkbox--disabled.mat-mdc-checkbox-disabled-interactive { + .mdc-checkbox:hover .mdc-checkbox__native-control ~ .mdc-checkbox__background, + .mdc-checkbox .mdc-checkbox__native-control:focus ~ .mdc-checkbox__background, + .mdc-checkbox__background { + @include token-utils.create-token-slot(border-color, disabled-unselected-icon-color); + } + + .mdc-checkbox__native-control:checked ~ .mdc-checkbox__background, + .mdc-checkbox__native-control:indeterminate ~ .mdc-checkbox__background { + @include token-utils.create-token-slot(background-color, disabled-selected-icon-color); + border-color: transparent; + } + } } .mdc-checkbox__checkmark { @@ -158,8 +173,12 @@ $_fallback-size: 40px; } @include token-utils.use-tokens($prefix, $slots) { - .mdc-checkbox--disabled .mdc-checkbox__checkmark { - @include token-utils.create-token-slot(color, disabled-selected-checkmark-color); + .mdc-checkbox--disabled { + &, &.mat-mdc-checkbox-disabled-interactive { + .mdc-checkbox__checkmark { + @include token-utils.create-token-slot(color, disabled-selected-checkmark-color); + } + } } } @@ -193,8 +212,12 @@ $_fallback-size: 40px; } @include token-utils.use-tokens($prefix, $slots) { - .mdc-checkbox--disabled .mdc-checkbox__mixedmark { - @include token-utils.create-token-slot(border-color, disabled-selected-checkmark-color); + .mdc-checkbox--disabled { + &, &.mat-mdc-checkbox-disabled-interactive { + .mdc-checkbox__mixedmark { + @include token-utils.create-token-slot(border-color, disabled-selected-checkmark-color); + } + } } } @@ -520,4 +543,15 @@ $_fallback-size: 40px; ); } } + + // Needs extra specificity to override the focus, hover, active states. + .mdc-checkbox--disabled.mat-mdc-checkbox-disabled-interactive & { + .mdc-checkbox__native-control ~ .mat-mdc-checkbox-ripple .mat-ripple-element, + .mdc-checkbox__native-control ~ .mdc-checkbox__ripple { + @include token-utils.create-token-slot( + background-color, + unselected-hover-state-layer-color + ); + } + } } diff --git a/src/material/checkbox/checkbox-config.ts b/src/material/checkbox/checkbox-config.ts index bef49ab5856f..be9715448d52 100644 --- a/src/material/checkbox/checkbox-config.ts +++ b/src/material/checkbox/checkbox-config.ts @@ -18,8 +18,12 @@ export interface MatCheckboxDefaultOptions { * https://material.angular.io/guide/theming#using-component-color-variants */ color?: ThemePalette; + /** Default checkbox click action for checkboxes. */ clickAction?: MatCheckboxClickAction; + + /** Whether disabled checkboxes should be interactive. */ + disabledInteractive?: boolean; } /** Injection token to be used to override the default options for `mat-checkbox`. */ @@ -36,6 +40,7 @@ export function MAT_CHECKBOX_DEFAULT_OPTIONS_FACTORY(): MatCheckboxDefaultOption return { color: 'accent', clickAction: 'check-indeterminate', + disabledInteractive: false, }; } diff --git a/src/material/checkbox/checkbox.html b/src/material/checkbox/checkbox.html index 8378598df791..045ee998e872 100644 --- a/src/material/checkbox/checkbox.html +++ b/src/material/checkbox/checkbox.html @@ -10,14 +10,15 @@ [attr.aria-labelledby]="ariaLabelledby" [attr.aria-describedby]="ariaDescribedby" [attr.aria-checked]="indeterminate ? 'mixed' : null" + [attr.aria-disabled]="disabled && disabledInteractive ? true : null" [attr.name]="name" [attr.value]="value" [checked]="checked" [indeterminate]="indeterminate" - [disabled]="disabled" + [disabled]="disabled && !disabledInteractive" [id]="inputId" [required]="required" - [tabIndex]="disabled ? -1 : tabIndex" + [tabIndex]="disabled && !disabledInteractive ? -1 : tabIndex" (blur)="_onBlur()" (click)="_onInputClick()" (change)="_onInteractionEvent($event)"/> @@ -43,9 +44,7 @@ (#14385). Putting a click handler on the