web-dev-qa-db-fra.com

comment désactiver ou écraser cdk-focalisé dans angular 5

Je travaille sur le groupe mat-button-toggle-group pour lequel j'ai modifié les CSS existants en écrasant la classe mat-button-toggle-vérifiée comme ci-dessous. Maintenant, quand je bascule entre les boutons, le css ne fonctionne pas jusqu'à ce que je sois focalisé, c'est parce que 2 classes de cdk 'cdk-driven' et 'cdk-program-focalisé' sont ajoutées lorsque le bouton cliqué est au point. Existe-t-il un moyen de rendre ces classes désactivées, de ne pas les appliquer ou de les écraser avec le même css de mat-button-toggle-vérifié?

<mat-button-toggle-group #group="matButtonToggleGroup" value="line">
    <mat-button-toggle (click)="showLine()" value="line">Line</mat-button-toggle>
    <mat-button-toggle (click)="showChart()" value="chart">Chart</mat-button-toggle>
</mat-button-toggle-group>

et css

mat-button-toggle-group {
    border: solid 1px #d1d8de;
    width:260px;
    height:41px;
    text-align: center;
    .mat-button-toggle-checked{
      background-color: #ffffff;
      font-weight: bold;
    }
    .mat-button-toggle{
      width:50%;
      font-size: 15px;
    }
  }
5
user3154990

Vous pouvez utiliser Angular CDK'sFocusMonitor service pour désactiver les classes .cdk-focused et .cdk-program-focused en appelant la méthode stopMonitoring() du service.

La documentation relative à cela et à l'API peut être trouvée dans les liens suivants:
1) Documentation FocusMonitor &
2) API FocusMonitor

Le problème que j'ai eu:

Ma sidenav avait 4 boutons créés avec * ngFor. Chacun de ces boutons était également une routerLink. Seul le bouton dont le lien de routeur était actif doit avoir la couleur de fond primaire. 

Maintenant, cela devenait confus si, par exemple, le routerLink associé à mon 4ème bouton était actif car le 4ème bouton aurait le primary background color et le 1er bouton aurait focused styling en raison des classes .cdk-focused et .cdk-program-focused appliquées par le FocusMonitor sur le bouton.

La solution:

import { Component, AfterViewInit } from '@angular/core';
import { FocusMonitor } from '@angular/cdk/a11y';

@Component({
    selector   : 'test-component',
    templateUrl: 'test-component.template.html',
})

export class TestComponent implements AfterViewInit {
    constructor(private _focusMonitor: FocusMonitor) {}

    ngAfterViewInit() {
        this._focusMonitor.stopMonitoring(document.getElementById('navButton_1'));
    }
}

Vous pouvez consulter les documentations pour l'adapter à vos besoins.

5
James Antony

Je faisais face au même problème en utilisant une composante de navigation latérale.

Après avoir lu la solution fournie par Aravind, voici Comment utiliser EventEmitter (onClose) du serveur Sidenav j’ai décidé d’appeler la méthode suivante:

onSideNavOpened() {
    let buttonsList = document.getElementsByClassName('mat-button');

    for(let currentButton of buttonsList) {
      currentButton.classList.remove("cdk-focused");
      currentButton.classList.remove("cdk-program-focused");
    }
  }

Peut-être que vous pouvez faire plus ou moins la même chose dans votre méthode ngOnInit () par exemple?

(Pour mémoire, ma balise d'ouverture de navigation latérale ressemble à ceci: <mat-sidenav #snav class="menu-sidenav" mode="over" position="end" opened="false" (open)="onSideNavOpened()">)

2
Romano

Faites défiler la liste jusqu'au texte en gras pour obtenir des réponses.

Une bonne pratique consiste à ne pas référencer par élément mais par classe lorsque vous modifiez le style d'un élément. Par exemple, au lieu d'utiliser:

mat-button-toggle-group {
    border: solid 1px #d1d8de;
}

tu écrirais 

.mat-button-toggle-group {
    border: solid 1px #d1d8de;
}

Encore une fois, c'est juste une bonne pratique.

Une autre chose importante (sans jeu de mots) est de souligner que vous devez vous abstenir d'utiliser !important. En règle générale, cela devrait être réservé aux cas spéciaux Edge (comme l'impression). En effet, il peut être difficile de conserver des feuilles de style. Un bon exemple de problème serait de vouloir changer la frontière:

.mat-button-toggle-group {
    border: solid 1px #d1d8de !important;
}

car le seul moyen de remplacer un !important est d'utiliser un autre !important

Solutions possibles à votre réponse

Créez un fichier material-theme-overrides.scss qui remplace fondamentalement le style des classes. Cette méthode est idéale lorsque vous souhaitez que toutes les classes se comportent de cette manière par défaut. Comme si vous voulez que tous vos boutons .mat aient un rayon. Le matériel fournit un bon guide pour le faire: https://material.angular.io/guide/theming

Une autre option Utilisez ::ng-deep, ce qui vous permet de forcer un style aux composants enfants. En savoir plus à ce sujet ici: 

Comment et où utiliser :: ng-deep?

1
DonDaniel

Aviez-vous essayé d'ajouter !important aux attributs de votre sélecteur:

mat-button-toggle-group {
    border: solid 1px #d1d8de !important;
    width:260px !important;
    height:41px !important;
    text-align: center !important;
    .mat-button-toggle-checked{
      background-color: #ffffff !important;
      font-weight: bold !important;
    }
    .mat-button-toggle{
      width:50% !important;
      font-size: 15px !important;
    }
  }

De cette façon, vous écraserez les classes cdk-focused et cdk-program-focused.

0
jcmordan