0

I am currently creating a components library. I am facing the problem how to apply multiple classes to it's host element based on several conditions.

Assuming I have the following component:

@Component({
    selector: 'abc-button',
    templateUrl: './abc-button.component.html',
    styleUrls: ['./abc-button.component.sass'],
})
export class AbcButtonComponent {

    @Input() title?: string
    @Input() type: 'primary' | 'secondary' | 'tertiary' = 'primary'
    @Input() state: 'stateA' | 'stateB' | 'stateC' = 'stateA'
    @Input() dropdown? : boolean = false
    @Input() size?: 'small' | 'medium' | 'large' = 'medium'
    @Input() disabled?: boolean = false

 ...
}

What would be best practice to assign a lot of classes to the host element based on it's input variables.

What I am currently doing is something like this:

@HostBinding('class.abc-button__type--primary')
get typeIsPrimary() { return this.type == 'primary' }

@HostBinding('class.abc-button__type--secondary')
get typeIsSecondary() { return this.type == 'secondary' }

...

@HostBinding('class.abc-button__state--stateA')
get typeIsStateA() { return this.state == 'stateA' }

@HostBinding('class.abc-button__state--stateB')
get typeIsStateB() { return this.state == 'stateB' }

...

For booleans this would be a good way:

@HostBinding("class.disabled") @Input() disabled: boolean;

But how about the others?

I have the feeling, that this is not best practice. On every user interaction every getter is called multiple times. Is there a better way to bind classes to the host element which can also be updated during runtime?

1 Answers1

0

You can assign classes dynamically like that:

@HostBinding('class')
get hostClasses(): string[] {
  return [
    this.type === 'primary' ? 'primary' : ' secondary',
    this.disabled === true ? 'disabled' : '',
    'other-class'
  ]
}

you can have Type defined as Enum:

enum Type {
 Primary = 'primary',
 Secondary = 'secondary',
}

then it's even easier:

@HostBinding('class')
get hostClasses(): string[] {
  return [
    this.type,
    this.disabled === true ? 'disabled' : '',
    'other-class'
  ]
}

And use OnPush to achieve better performance

Maciej Wojcik
  • 2,115
  • 2
  • 28
  • 47