Last active
March 16, 2023 08:57
-
-
Save andyjessop/66c6f6d4481012c5dc6ac5c145a75b47 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
import { cx } from './cx'; | |
describe('classes', () => { | |
describe('cx', () => { | |
test('cx should combine class names', () => { | |
const result = cx('class1', { class2: true }, null, undefined, 'class3'); | |
expect(result).toBe('class1 class2 class3'); | |
}); | |
test('cx should return empty string if no arguments given', () => { | |
const result = cx(); | |
expect(result).toBe(''); | |
}); | |
test('cx should return empty string if null is provided', () => { | |
const result = cx(null); | |
expect(result).toBe(''); | |
}); | |
test('cx should return empty string if undefined is provided', () => { | |
const result = cx(undefined); | |
expect(result).toBe(''); | |
}); | |
test('cx should ignore falsy values in object', () => { | |
const result = cx({ class1: true, class2: false }); | |
expect(result).toBe('class1'); | |
}); | |
test('cx should handle incorrect argument types', () => { | |
// @ts-expect-error booleans are not a valid argument type | |
const result = cx('class1', false, 'class2'); | |
expect(result).toBe('class1 class2'); | |
}); | |
test('cx should handle multiple objects', () => { | |
const result = cx({ class1: true }, { class2: false }, { class3: true }); | |
expect(result).toBe('class1 class3'); | |
}); | |
test('cx should handle multiple falsy values', () => { | |
// @ts-expect-error booleans are not a valid argument type | |
const result = cx(false, null, undefined, 0, ''); | |
expect(result).toBe(''); | |
}); | |
}); | |
}); |
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
export { cx }; | |
type Arg = string | Record<string, boolean> | null | undefined; | |
/** | |
* Conditionally join classNames into a single string | |
*/ | |
function cx(...args: Arg[]): string { | |
let str = ''; | |
let i = 0; | |
let arg: unknown; | |
let val; | |
while (i < args.length) { | |
if ((arg = args[i++])) { | |
if (typeof arg === 'string') { | |
val = arg; | |
} else if (typeof arg === 'object') { | |
val = cxMap(arg as Record<string, boolean>); | |
} | |
if (val) { | |
if (str) { | |
str += ' '; | |
} | |
str += val; | |
} | |
} | |
} | |
return str; | |
} | |
function cxMap(map: Record<string, boolean>): string { | |
let str = ''; | |
for (const [key, value] of Object.entries(map)) { | |
if (value) { | |
if (str.length) { | |
str += ' '; | |
} | |
str += key; | |
} | |
} | |
return str; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment