npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@mlakomy/class-binder

v14.0.2

Published

Set of tools to gracefully bind classes to Angular components

Downloads

3

Readme

ClassBinder

ClassBinder gracefully overcomes one of my oldest issues with Angular – styling host element.

This is something that bugged me since my very first days with Angular, after switching from Vue.js. This library is a result of years of struggle to come up with a lightweight, decent solution.

With something more robust than HostBinding() 😉

Table of Contents

Installation

NPM

  npm install @mlakomy/class-binder

Example

import { ClassBinder } from '@mlakomy/class-binder';

@Component({
  selector: 'app-root',
  template: '',
})
export class Component extends ClassBinder('root') {}

Extending ClassBinder class will result in adding class .root to app-root element.

Styling root component with ViewEncapsulation.Emulated

Styling host element with ViewEncapsulation.Enabled slightly differs from writing your usual SCSS. In order to target your element properly, you have to do it like so:

:host.root {
  display: flex;
  color: black;
}

Styling root component with ViewEncapsulation.None

When you don't use any kind of encapsulation, you can add your class to SCSS in very straightforward way:

.root {
  display: flex;
  color: black;
}

BindClass()

In order to make our life easier ClassBinder also comes with some magic 🧙 in form of custom decorator – BindClass(). Basically it is a neat way of assigning classes dynamically to your host element.

Note: I've written all examples below with usage of Input() decorator in mind, but of course it is not necessary. Also, visibility of your property doesn't matter too.

Static class name

import { ClassBinder, BindClass } from '@mlakomy/class-binder';

@Component()
export class Component extends ClassBinder('root') {
  @Input() @BindClass('root--disabled') public disabled: boolean = false;
}

Based on value of disabled property, ClassBinder will dynamically add or remove .root--disabled class from host element.

Type of your property doesn't have to be a boolean. It can be any type, BindClass() decides whether it should add or remove the class based on truthy / falsy values.

Factory class name

import { ClassBinder, BindClass } from '@mlakomy/class-binder';

const classFactory = (value: number): string | null => {
  if (value < 0) {
    return `root--negative`;
  } else if (value > 0) {
    return `root--positive`;
  }

  return null;
};

@Component()
export class Component extends ClassBinder('root') {
  @Input() @BindClass(classFactory) public value: number = 0;
}

Each time the value property change, BindClass() will evaluate class name all over again (and of course remove the old one). It is really powerful tool that gives you a way to organize your dynamic classes in a very clean and reusable way.

Property class name

import { ClassBinder, BindClass } from '@mlakomy/class-binder';

type Color = 'primary' | 'secondary' | 'error';

@Component()
export class Component extends ClassBinder('root') {
  @Input() @BindClass() public color: Color | null = 'primary';
}

The most simple approach to bind classes to the host element. BindClass() will use current value of the property. In this case it would give following results: .root .primary on your host element.

It is important to note, that value of this property must be either of type string | null | undefined. Each different type will result in runtime error.

Limitations

  • The most obvious limitation of this is that it requires extending ClassBinder class, and as we are all aware, currently in TypeScript you can only extend from one class.

    My ideal solution would be to make ClassBinder as a class decorator, but as I'm aware Angular won't treat your component as injectable, if you extend its constructor via decorator.

Future

  • At some point I would like to bring support for binding classes based on Observable value.