@talend/react-bootstrap
Version:
Bootstrap 3 components built with React
146 lines (142 loc) • 4.3 kB
JavaScript
// TODO: The publicly exposed parts of this should be in lib/BootstrapUtils.
import invariant from 'invariant';
import PropTypes from 'prop-types';
import { SIZE_MAP } from './StyleConfig';
function curry(fn) {
return (...args) => {
let last = args[args.length - 1];
if (typeof last === 'function') {
return fn(...args);
}
return Component => fn(...args, Component);
};
}
export function prefix(props, variant) {
let bsClass = (props.bsClass || '').trim();
invariant(bsClass != null, 'A `bsClass` prop is required for this component');
return bsClass + (variant ? `-${variant}` : '');
}
export const bsClass = curry((defaultClass, Component) => {
let propTypes = Component.propTypes || (Component.propTypes = {});
let defaultProps = Component.defaultProps || (Component.defaultProps = {});
propTypes.bsClass = PropTypes.string;
defaultProps.bsClass = defaultClass;
return Component;
});
export const bsStyles = curry((styles, defaultStyle, Component) => {
if (typeof defaultStyle !== 'string') {
Component = defaultStyle;
defaultStyle = undefined;
}
let existing = Component.STYLES || [];
let propTypes = Component.propTypes || {};
styles.forEach(style => {
if (existing.indexOf(style) === -1) {
existing.push(style);
}
});
let propType = PropTypes.oneOf(existing);
// expose the values on the propType function for documentation
Component.STYLES = existing;
propType._values = existing;
Component.propTypes = {
...propTypes,
bsStyle: propType
};
if (defaultStyle !== undefined) {
let defaultProps = Component.defaultProps || (Component.defaultProps = {});
defaultProps.bsStyle = defaultStyle;
}
return Component;
});
export const bsSizes = curry((sizes, defaultSize, Component) => {
if (typeof defaultSize !== 'string') {
Component = defaultSize;
defaultSize = undefined;
}
let existing = Component.SIZES || [];
let propTypes = Component.propTypes || {};
sizes.forEach(size => {
if (existing.indexOf(size) === -1) {
existing.push(size);
}
});
const values = [];
existing.forEach(size => {
const mappedSize = SIZE_MAP[size];
if (mappedSize && mappedSize !== size) {
values.push(mappedSize);
}
values.push(size);
});
const propType = PropTypes.oneOf(values);
propType._values = values;
// expose the values on the propType function for documentation
Component.SIZES = existing;
Component.propTypes = {
...propTypes,
bsSize: propType
};
if (defaultSize !== undefined) {
if (!Component.defaultProps) {
Component.defaultProps = {};
}
Component.defaultProps.bsSize = defaultSize;
}
return Component;
});
export function getClassSet(props) {
const classes = {
[prefix(props)]: true
};
if (props.bsSize) {
const bsSize = SIZE_MAP[props.bsSize] || props.bsSize;
classes[prefix(props, bsSize)] = true;
}
if (props.bsStyle) {
classes[prefix(props, props.bsStyle)] = true;
}
return classes;
}
function getBsProps(props) {
return {
bsClass: props.bsClass,
bsSize: props.bsSize,
bsStyle: props.bsStyle,
bsRole: props.bsRole
};
}
function isBsProp(propName) {
return propName === 'bsClass' || propName === 'bsSize' || propName === 'bsStyle' || propName === 'bsRole';
}
export function splitBsProps(props) {
const elementProps = {};
Object.entries(props).forEach(([propName, propValue]) => {
if (!isBsProp(propName)) {
elementProps[propName] = propValue;
}
});
return [getBsProps(props), elementProps];
}
export function splitBsPropsAndOmit(props, omittedPropNames) {
const isOmittedProp = {};
omittedPropNames.forEach(propName => {
isOmittedProp[propName] = true;
});
const elementProps = {};
Object.entries(props).forEach(([propName, propValue]) => {
if (!isBsProp(propName) && !isOmittedProp[propName]) {
elementProps[propName] = propValue;
}
});
return [getBsProps(props), elementProps];
}
/**
* Add a style variant to a Component. Mutates the propTypes of the component
* in order to validate the new variant.
*/
export function addStyle(Component, ...styleVariant) {
bsStyles(styleVariant)(Component);
}
export const _curry = curry;
//# sourceMappingURL=bootstrapUtils.js.map