-1

Using Angular 14

I have the following button component

button.component.html

<button class="btn btn-{{color}} my-4 mb-2"
        [class.btn-sm]="size === 'sm'"
        (click)="onClick.emit()">
  <ng-content select="[label]"></ng-content>
</button>

and button.component.ts

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

  @Input() color: 'primary'|'secondary'|'success' = 'primary';

  @Input() size: 'default'|'sm'|'lg' = 'default';

  @Output() onClick: EventEmitter<any> = new EventEmitter<any>();

  constructor() { }
}

Now I want to group the ButtonComponent to create button group as per the bootstrap 5, which should be like

<div class="btn-group" role="group">
  <button class="btn btn-primary">Button 1</button>
  <button class="btn btn-primary">Button 2</button>
</div>

But with the above html component, doing it like

<div class="btn-group" role="group">
  <app-button [color]="'primary'">
    <ng-container label>Button 1</ng-container>
  </app-button>
  <app-button [color]="'danger'">
    <ng-container label>Button 2</ng-container>
  </app-button>
</div>

which is generating dom like

<div class="btn-group" role="group">
  <app-button>
    <button class="btn btn-primary">Button 1</button>
  </app-button>
  <app-button>
    <button class="btn btn-primary">Button 2</button>
  </app-button>
</div>

This is resulting in breaking UI as the next child of btn-group should be button and not ng-button.

How can I remove extra <app-button> from the dom?

Anuj TBE
  • 9,198
  • 27
  • 136
  • 285

1 Answers1

0

Angular will always render the component in the dom (if it has a selector). What you want is a directive.

@Directive({
  selector: '[myButton]',
})
export class HelloDirective implements OnChanges {
  @Input() name: string;

  @Input() color: 'primary' | 'secondary' | 'success' = 'primary';
  @Input() size: 'default' | 'sm' | 'lg' = 'default';
  @Input() class: string = '';

  @HostBinding('class')
  customClass = `btn my-4 mb-2 btn-${this.color} btn-${this.size} ${this.class}`;

  ngAfterViewInit() {
    console.log(this);
  }

  ngOnChanges() {
    this.customClass = `btn my-4 mb-2 btn-${this.color} btn-${this.size} ${this.class}`;
  }
}

Usage :

<button myButton color="secondary" size="lg" class="btn btn-primary">
   Button
</button>

which renders :

<button  class="test btn btn-lg btn-secondary mb-2 my-4">
   Button
</button>
Matthieu Riegler
  • 31,918
  • 20
  • 95
  • 134