Skip to content

Instantly share code, notes, and snippets.

@peisenmann
Created February 24, 2016 12:05
Show Gist options
  • Save peisenmann/0d9bc4755e29f1fc12c8 to your computer and use it in GitHub Desktop.
Save peisenmann/0d9bc4755e29f1fc12c8 to your computer and use it in GitHub Desktop.
Au-Class custom attribute for simplifying bound CSS declarations
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:
<div class="base-class ${foo} ${someVMProp < 10 ? 'red' : ''} ${!otherVMProp ? 'blue' : ''}"></div>
* After:
<div au-class.bind="['base-class', foo, {red: someVMProp < 10, blue: !otherVMProp}]"></div>
*/
@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;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment