Is there a better way of building multiple variations of buttons in Angular to be used in other components?

36 Views Asked by At

I am creating buttons of various colours and am wanting to import (put) these into other components like the NavBar and hero sections. I have chosen to do this by using a selector as a class (https://medium.com/@piyalidas.it/angular-component-loading-inside-another-component-in-different-ways-adfa157f4662) as I thought this would be easier but definitely open to other ways.

For the buttons, they each have their own TypeScript file and SCSS but they share a HTML as it is the same for all. I will put two examples of my buttons and the NavBar below, so far the buttons are not showing in the browser so I don't know if I have missed something.

(Additionally, I have made variations of buttons using STYLES in React to generate different classes but I wasn't sure how this translated to putting components inside others in Angular, can supply an example)

button-purple.component.ts

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';

@Component({
    selector: '.app-button-purple',
    templateUrl: './button.component.html',
    styleUrls: ['./button-purple.component.scss']
})
export class ButtonComponent {
  public buttonText = '';

    @Input()
    set text(name: string) {
        this.buttonText = name.toUpperCase();
    }
    get name(): string {
        return this.buttonText;
    }

    @Input() color: string = '0068B4';
    @Input() type: string = 'button';
    @Output() btnClick = new EventEmitter();
    @Input() isDisabled = false;

    constructor() {}

    onClick() {
        this.btnClick.emit();
    }
}

button-purple.component.scss

:root {
    --purple: #a61ed3;
    --green: #0df733;
    --orange: #f27a2a;
}

.btn {
    color: #fff;
    background-color: var(--purple);
    border-radius: 40px;
    border: 0;
    cursor: pointer;
    font-size: 1.8rem;
    font-weight: 600;
    margin: 1rem 0;
    outline: 0;
    padding: 2rem 4vw;
    text-align: center;
    white-space: nowrap;

    &:hover {
        color: var(--purple);
        background-color: #fff;
    }
}

button-green.components.ts

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';

@Component({
    selector: '.app-button-green',
    templateUrl: './button.component.html',
    styleUrls: ['./button-green.component.scss']
})
export class ButtonComponent {
  public buttonText = '';

    @Input()
    set text(name: string) {
        this.buttonText = name.toUpperCase();
    }
    get name(): string {
        return this.buttonText;
    }

    @Input() color: string = '0068B4';
    @Input() type: string = 'button';
    @Output() btnClick = new EventEmitter();
    @Input() isDisabled = false;

    constructor() {}

    onClick() {
        this.btnClick.emit();
    }
}

button-green.components.scss

:root {
    --purple: #a61ed3;
    --green: #0df733;
    --orange: #f27a2a;
}

.btn {
    color: #000;
    background-color: var(--green);
    border-radius: 40px;
    border: 0;
    cursor: pointer;
    font-size: 1.8rem;
    font-weight: 600;
    margin: 1rem 0;
    outline: 0;
    padding: 2rem 4vw;
    text-align: center;
    white-space: nowrap;

    &:hover {
        color: var(--green);
        background-color: #fff;
    }
}

button.component.html

<button [type]="type" (click)="onClick()" [disabled]="isDisabled" class="btn">
  <span>{{ buttonText }}</span>
</button>

nav-bar.components.ts

import { Component } from '@angular/core';
import { AccountService } from 'src/app/account/account.service';
import { BasketService } from 'src/app/basket/basket.service';
import { BasketItem } from 'src/app/shared/models/basket';

@Component({
  selector: 'app-nav-bar',
  templateUrl: './nav-bar.component.html',
  styleUrls: ['./nav-bar.component.scss']
})
export class NavBarComponent {

  constructor(public basketService: BasketService, public accountService: AccountService) {}

  getCount(items: BasketItem[]) {
    return items.reduce((sum, item) => sum + item.quantity, 0);
  }

}

nav-bar.components.html (adding classes to the Login and Sign Up buttons about halfway down this file)

<header
  class="d-flex flex-row align-items-center justify-content-between p-2 px-5 mb-3 bg-black border-bottom fixed-top shadow-sm"
>
  <img
    src="/assets/images/EAD Logo text white crop.png"
    alt="logo"
    class="logo"
    style="max-height: 60px"
    routerLink="/"
  />
  <nav class="my-2 fs-4">
    <a
      class="p-3"
      routerLink="/"
      routerLinkActive="active"
      [routerLinkActiveOptions]="{ exact: true }"
      >Home</a
    >
    <a class="p-3" routerLink="/shop" routerLinkActive="active">Shop</a>
    <a class="p-3" routerLink="/gallery" routerLinkActive="active">Gallery</a>
    <a class="p-3" routerLink="/test-error" routerLinkActive="active">Errors</a>
  </nav>
  <div class="d-flex align-items-center">
    <a routerLink="/basket" class="position-relative">
      <i class="fa fa-shopping-cart fa-2x me-5 text-white"></i>
      <div
        *ngIf="basketService.basketSource$ | async as basket"
        class="cart-no"
      >
        {{ getCount(basket.items) }}
      </div>
    </a>
    <ng-container *ngIf="(accountService.currentUser$ | async) === null">
      <a routerLink="/account/login" class="app-button-purple me-2">Login</a>
      <a routerLink="/account/register" class="app-button-green me-3"
        >Sign up</a
      >
    </ng-container>

    <ng-container *ngIf="accountService.currentUser$ | async as user">
      <div class="dropdown ms-3 me-5" style="cursor: pointer" dropdown>
        <a dropdownToggle class="dropdown-toggle">
          <strong>Welcome {{ user.displayName }}</strong>
        </a>
        <ul *dropdownMenu class="dropdown-menu dropdown-menu-right">
          <li class="py-1">
            <a routerLink="/basket" class="dropdown-item">
              <i class="fa fa-shopping-cart me-3"></i> View basket
            </a>
          </li>
          <li class="py-1">
            <a routerLink="/orders" class="dropdown-item">
              <i class="fa fa-history me-3"></i> View orders
            </a>
          </li>
          <div class="dropdown-divider"></div>
          <li class="py-1">
            <a (click)="accountService.logout()" class="dropdown-item">
              <i class="fa fa-sign-out me-3"></i> Logout
            </a>
          </li>
        </ul>
      </div>
    </ng-container>
  </div>
</header>

Trying to use a selector as a class and create different versions of a component to use in other components and expected this to work, however, it isn't displaying at all.

0

There are 0 best solutions below