export default class ClassBuilder { constructor(block, defaultIgnoreList) { this.block = `mdc-${block}` this.defaultIgnoreList = defaultIgnoreList //will be ignored when building custom classes } /* handles both blocks and elementss (BEM MD Notation) params = {elementName: string, props: {modifiers{}, customs:{}, extras: []}} All are optional */ build(params) { if (!params) return this.block //return block if nothing passed const { props, elementName } = params let base = elementName ? `${this.block}__${elementName}` : this.block if (!props) return base return this._handleProps(base, props) } //Easily grab a simple element class elem(elementName) { return this.build({ elementName }) } //use if a different base is needed than whats defined by this.block debase(base, elementProps) { if (!elementProps) return base return this._handleProps(base, elementProps) } //proxies bindProps and checks for which elementProps exist before binding _handleProps(base, elementProps) { let cls = base const { modifiers, customs, extras } = elementProps if (modifiers) cls += this._bindProps(modifiers, base) if (customs) cls += this._bindProps(customs, base, true) if (extras) cls += ` ${extras.join(" ")}` return cls.trim() } /* Handles both modifiers and customs. Use property, value or both depending on whether it is passsed props for custom or modifiers if custom uses the following convention for scss mixins: bbmd-{this.block}--{property}-{value} bbmd-mdc-button--size-large */ _bindProps(elementProps, base, isCustom = false) { return Object.entries(elementProps) .map(([property, value]) => { //disregard falsy and values set by defaultIgnoreList constructor param if ( !!value && (!this.defaultIgnoreList || !this.defaultIgnoreList.includes(value)) ) { let classBase = isCustom ? `bbmd-${base}` : `${base}` let valueType = typeof value if (valueType == "string" || valueType == "number") { return isCustom ? ` ${classBase}--${this._convertCamel(property)}-${value}` : ` ${classBase}--${value}` } else if (valueType == "boolean") { return ` ${classBase}--${this._convertCamel(property)}` } } }) .join("") } _convertCamel(str) { return str.replace(/[A-Z]/g, match => `-${match.toLowerCase()}`) } }