lucid-ui
Version:
A UI component library from AppNexus.
62 lines (55 loc) • 2.12 kB
text/typescript
import _ from 'lodash';
import classNames from 'classnames';
const RANDOM_INTEGER = _.random(0, Number.MAX_SAFE_INTEGER);
/**
* bindClassNames
*
* Returns a version of the `classnames` functions where `&` is bound to a given
* value. The returned functions can be further bound to more specific values for
* `&` which allows your bound classnames to look closer to style selector.
*
* Examples:
* bindClassNames('lucid')('&-Button') === 'lucid-Button'
* bindClassNames('lucid').bind('&-Button')('&-active') === 'lucid-Button-active'
*/
export function bindClassNames(
value: string = '',
variable: RegExp | string = /&/g
) {
// We left `any` here because the classNames @types package doesn't export
// the right types for us to be able to use. It accepts a fairly wide range
// of input.
function cx(...args: any[]) {
return _.map(classNames(...args).split(' '), (className) =>
className.replace(variable, value)
).join(' ');
}
return _.assign(cx, {
bind(nextValue = value, ...args: any[]) {
return bindClassNames(nextValue.replace(variable, value), ...args);
},
});
}
// LUCID_CSS_NAMESPACE is a placeholder that webpack's DefinePlugin can
// overwrite at compile time. Paired with the `prefix` LESS variable, consumers
// are able to scope all class names to something custom. This is a really rare
// use-case. We needed it becuase we sometimes run two copies of the library on
// a single page and need the styles not to step on each other.
declare const LUCID_CSS_NAMESPACE: string;
export const NAMESPACE =
typeof LUCID_CSS_NAMESPACE !== 'undefined' ? LUCID_CSS_NAMESPACE : 'lucid'; // eslint-disable-line no-undef
/**
* Exports a lucid-bound version of classnames, which can be make more specific
* to a component.
*
* Example:
* const cx = lucidClassNames.bind('&-Button')
*
* cx('&',{
* '&-active': true
* }, ['custom-classname']) === 'lucid-Button lucid-Button-active custom-classname'
*/
export const lucidClassNames = bindClassNames(NAMESPACE);
export function uniqueName(prefix: string) {
return _.uniqueId(`${RANDOM_INTEGER}-${prefix}`);
}