Home > Software design >  How to build a toggle buttons group
How to build a toggle buttons group

Time:11-29

I'm building a group of buttons with Angular and Angular Material using the Button component and what I'm trying to achieve is the same behaviour of Button Toggle but with normal Button component, in order to use all the available styles.

In my angular component I have an array which is used to create the buttons:

buttonNames: string[] = ['1', '2', '3', '4'];

Then in the html file I use the ngFor directive:

<button mat-raised-button *ngFor="let num of buttonNames">{{ num }}</button>

Now my goal is to have a way to change the button's color on click event, and to reset the color of the previous selected one.
As an example:
this should be the initial state then when i press on another button (i.e. the second) this should happen changed state.

CodePudding user response:

You can use the CSS classes .mat-button-toggle and .mat-button-toggle-checked to style the different states.

With material theming you can extract whichever individual palettes you need from the theme and apply the background default-contrast color to the text color to achieve optimal contrast with light or dark colors.

mat-button-toggle-group example: Stackblitz angular-t1k1x6

Theming used:

@import '~@angular/material/theming';

@include mat-core();

$app-primary: mat-palette($mat-indigo);
$app-accent:  mat-palette($mat-pink, A200, A100, A400);

$app-theme: mat-light-theme($app-primary, $app-accent);

@mixin mix-app-theme($app-theme) {
  $primary: map-get($app-theme, primary);
  $accent: map-get($app-theme, accent);

  .mat-button-toggle {
    background-color: mat-color($primary);
    color: mat-color($primary, default-contrast);
  }

 .mat-button-toggle-checked {
    background-color: mat-color($accent);
    color: mat-color($accent, default-contrast);
  }
}

// Include the mixin
@include mix-app-theme($app-theme);

Documents: Theming your Angular Material app

CodePudding user response:

SOLVED

Basically I created 2 components a ContainerComponent and a ButtonComponent.
The first one is used to keep track of the last ButtonComponent that has been pressed, the second one has to tell that it was clicked.

button.component.ts

export class ButtonComponent {
 isSelected: boolean = false;

 constructor(private container: ContainerComponent) { }

 // change the state of the container
 toggle() { this.container.toggleButton(this); }

 toggleSelection() {this.isSelected = !this.isSelected; }
}

button.component.html

<button mat-raised-button (click)="toggle()" [class.selected]="isSelected">
 <ng-content></ng-content>
</button>

button.component.css

.selected {
    color: white;
    background-color: #3F51B5; 
}

Then there is the ContainerComponent container.component.ts

export class ContainerComponent {
 buttonNames: string[] = ['1', '2', '3', '4'];
 selectedButton: ButtonComponent | null = null;

   toggleButton(button: ButtonComponent) {
    if (this.selectedButton === null) {
      this.selectedButton = button;
      button.toggleSelection();
    } else {
      //turn off current selected button
      this.selectedButton.toggleSelection();
      this.selectedButton = button;
      // turn on new selected button
      this.selectedButton.toggleSelection();
    }
  }
}

container.component.html

    <app-button *ngFor="let num of buttonNames">
        <span>{{num}}</span>
    </app-button>
  • Related