@use 'sass:map'; @use 'sass:meta'; @use '@angular/cdk'; @use '../style/layout-common'; @use '../theming/theming'; // Private sass variables that will be used as reference throughout component stylesheets. $default-border-width: 3px; $default-border-style: solid; $default-border-color: transparent; $default-border-radius: 4px; // Mixin that renders the focus indicator structural styles. @mixin structural-styling($prefix) { .#{$prefix}-focus-indicator { position: relative; &::before { @include layout-common.fill(); box-sizing: border-box; pointer-events: none; display: var(--#{$prefix}-focus-indicator-display, none); // Hide the indicator by default. border: var( --#{$prefix}-focus-indicator-border-width, #{$default-border-width} ) var( --#{$prefix}-focus-indicator-border-style, #{$default-border-style} ) var( --#{$prefix}-focus-indicator-border-color, #{$default-border-color} ); border-radius: var( --#{$prefix}-focus-indicator-border-radius, #{$default-border-radius} ); } // By default, render the focus indicator when the focus indicator host element takes focus. // Defining a pseudo element's content will cause it to render. &:focus::before { content: ''; } } // Enable the indicator in high contrast mode. @include cdk.high-contrast(active, off) { @include customize-focus-indicators((display: block), $prefix); } } // Generates CSS variable declarations from a map. @mixin _output-variables($map) { @each $key, $value in $map { @if ($value) { --#{$key}: #{$value}; } } } // Mixin that dedups CSS variables for the strong-focus-indicators mixin. @mixin customize-focus-indicators($config, $prefix) { $border-style: map.get($config, border-style); $border-width: map.get($config, border-width); $border-radius: map.get($config, border-radius); $border-color: map.get($config, border-color); $display: map.get($config, display); $map: ( '#{$prefix}-focus-indicator-border-style': $border-style, '#{$prefix}-focus-indicator-border-width': $border-width, '#{$prefix}-focus-indicator-border-radius': $border-radius, '#{$prefix}-focus-indicator-border-color': $border-color, '#{$prefix}-focus-indicator-display': $display, ); @if (&) { @include _output-variables($map); } @else { // We use `html` here instead of `:root`, because the // latter causes some issues with internal tooling. html { @include _output-variables($map); } } } @mixin strong-focus-indicators($config: ()) { // Default focus indicator config. $default-config: ( border-color: black, display: block, ); // Merge default config with user config. $config: map.merge($default-config, $config); @include customize-focus-indicators($config, 'mat'); } @mixin mdc-strong-focus-indicators($config: ()) { // Default focus indicator config. $default-config: ( border-color: black, display: block, ); // Merge default config with user config. $config: map.merge($default-config, $config); @include customize-focus-indicators($config, 'mat-mdc'); } @mixin strong-focus-indicators-color($config-or-theme-or-color) { @if meta.type-of($config-or-theme-or-color) == 'color' { @include customize-focus-indicators(( border-color: $config-or-theme-or-color ), 'mat'); } @else { $config: theming.get-color-config($config-or-theme-or-color); $border-color: theming.get-color-from-palette(map.get($config, primary)); @include customize-focus-indicators(( border-color: $border-color ), 'mat'); } } @mixin strong-focus-indicators-theme($theme-or-color-config-or-color) { @if meta.type-of($theme-or-color-config-or-color) == 'color' { @include customize-focus-indicators(( border-color: $theme-or-color-config-or-color ), 'mat'); } @else { $theme: theming.private-legacy-get-theme($theme-or-color-config-or-color); @include theming.private-check-duplicate-theme-styles($theme, 'mat-focus-indicators') { $color: theming.get-color-config($theme); @if $color != null { @include strong-focus-indicators-color($color); } } } } @mixin mdc-strong-focus-indicators-color($config-or-theme-or-color) { @if meta.type-of($config-or-theme-or-color) == 'color' { @include customize-focus-indicators(( border-color: $config-or-theme-or-color ), 'mat-mdc'); } @else { $config: theming.get-color-config($config-or-theme-or-color); $border-color: theming.get-color-from-palette(map.get($config, primary)); @include customize-focus-indicators(( border-color: $border-color ), 'mat-mdc'); } } @mixin mdc-strong-focus-indicators-theme($theme-or-color-config-or-color) { @if meta.type-of($theme-or-color-config-or-color) == 'color' { @include customize-focus-indicators(( border-color: $theme-or-color-config-or-color ), 'mat-mdc'); } @else { $theme: theming.private-legacy-get-theme($theme-or-color-config-or-color); @include theming.private-check-duplicate-theme-styles($theme, 'mat-mdc-focus-indicators') { $color: theming.get-color-config($theme); @if $color != null { @include mdc-strong-focus-indicators-color($color); } } } }