Last active
January 20, 2023 12:14
-
-
Save sachin-hg/4e0f773adc304163625d5042d6a71727 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const cache = {} | |
const Obj = function (js, css, nonAtomic) { | |
this.__isAtomic = true | |
this.js = js | |
this.css = css | |
this.nonAtomic = nonAtomic | |
} | |
Obj.prototype.toString = function () { | |
return this.css + (this.nonAtomic.length ? ' ' + this.nonAtomic : '') | |
} | |
const getClassName = (js, css, nonAtomic = '') => { | |
const key = js + css + nonAtomic | |
// maintaining a cache because returning new references everytime might lead to useless react rerenders | |
let obj = cache[key] | |
if (!obj) { | |
obj = new Obj(js, css, nonAtomic) | |
cache[key] = obj | |
} | |
return obj | |
} | |
const cx = function () { | |
const presentClassNames = arguments | |
const length = presentClassNames.length | |
const atomicClasses = {} | |
let nonAtomic = '' | |
let atomicKey = '' | |
let atomicValue = '' | |
for (let i = length - 1; i >= 0; i--) { | |
let cls = presentClassNames[i] | |
if (cls) { | |
if (cls.__isAtomic) { | |
const keys = cls.js.split(' ') | |
const values = cls.css.split(' ') | |
if (cls.nonAtomic) { | |
nonAtomic += (nonAtomic.length ? ' ' : '') + cls.nonAtomic | |
} | |
const length = keys.length | |
for (let i = length - 1; i >= 0; i--) { | |
const keyHash = keys[i] | |
const value = values[i] | |
if (!atomicClasses[keyHash]) { | |
atomicClasses[keyHash] = value | |
atomicKey += (atomicKey.length ? ' ' : '') + keyHash | |
atomicValue += (atomicValue.length ? ' ' : '') + value | |
} | |
} | |
} else { | |
nonAtomic += (nonAtomic.length ? ' ' : '') + cls | |
} | |
} | |
} | |
return atomicValue.length ? getClassName(atomicKey, atomicValue, nonAtomic) : nonAtomic | |
} | |
// example usage | |
const style1 = getClassName('fs wt bg', 'a b c') // getClassName function call will be created by a babel-plugin or linaria | |
const style2 = getClassName('fs cl', 'd e') | |
const style3 = getClassName('fs bg', 'f g') | |
const style4 = getClassName('fs wt', 'h j') | |
cx(cx(style1, false && style2, style3, 'non-atomic', false && 'cta'), style4).toString() // in real world usage there wont be a need to manually call toString | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment