import {customAttribute} from 'aurelia-framework'; /** * The au-class custom attribute is intended to simplify aurelia binding code in the standard html class attribute. * * This is an unofficial community proposal to add to Aurelia (aurelia.io) * * Before:
* After:
*/ @customAttribute('au-class') export class AuClass { classes = new Set(); static inject = [Element]; constructor(element: Element) { this.element = element; } valueChanged(newVal = {}) { let newClasses = new Set(AuClass._extractClasses(newVal)); let removedClasses = [...this.classes].filter(x => !newClasses.has(x)); let addedClasses = [...newClasses].filter(x => !this.classes.has(x)); this.removeClasses(removedClasses); this.addClasses(addedClasses); this.classes = newClasses; } addClasses(classes) { classes.forEach(c => this.element.classList.add(c)) } removeClasses(classes) { classes.forEach(c => this.element.classList.remove(c)) } static _extractClasses(args) { let classesFound; if (args && typeof args === 'string') { classesFound = [args]; } if (Array.isArray(args)) { classesFound = args.reduce((acc, arg) => acc.concat(AuClass._extractClasses(arg)), []); } else if (typeof args === 'object') { classesFound = Object.keys(args).filter(p => args[p]); } return classesFound; } }