bootstrap-vue
Version:
With more than 85 components, over 45 available plugins, several directives, and 1000+ icons, BootstrapVue provides one of the most comprehensive implementations of the Bootstrap v4 component and grid system available for Vue.js v2.6, complete with extens
99 lines (87 loc) • 3.81 kB
JavaScript
import { PROP_TYPE_ANY } from '../constants/props'
import { cloneDeep } from './clone-deep'
import { getComponentConfig } from './config'
import { identity } from './identity'
import { isArray, isFunction, isObject, isUndefined } from './inspect'
import { clone, hasOwnProperty, keys } from './object'
import { lowerFirst, upperFirst } from './string'
// Prefix a property
export const prefixPropName = (prefix, value) => prefix + upperFirst(value)
// Remove a prefix from a property
export const unprefixPropName = (prefix, value) => lowerFirst(value.replace(prefix, ''))
// Suffix can be a falsey value so nothing is appended to string
// (helps when looping over props & some shouldn't change)
// Use data last parameters to allow for currying
export const suffixPropName = (suffix, value) => value + (suffix ? upperFirst(suffix) : '')
// Generates a prop object
export const makeProp = (
type = PROP_TYPE_ANY,
value = undefined,
requiredOrValidator = undefined,
validator = undefined
) => {
const required = requiredOrValidator === true
validator = required ? validator : requiredOrValidator
return {
...(type ? { type } : {}),
...(required
? { required }
: isUndefined(value)
? {}
: { default: isObject(value) ? () => value : value }),
...(isUndefined(validator) ? {} : { validator })
}
}
// Copies props from one array/object to a new array/object
// Prop values are also cloned as new references to prevent possible
// mutation of original prop object values
// Optionally accepts a function to transform the prop name
export const copyProps = (props, transformFn = identity) => {
if (isArray(props)) {
return props.map(transformFn)
}
const copied = {}
for (const prop in props) {
/* istanbul ignore else */
if (hasOwnProperty(props, prop)) {
// If the prop value is an object, do a shallow clone
// to prevent potential mutations to the original object
copied[transformFn(prop)] = isObject(props[prop]) ? clone(props[prop]) : props[prop]
}
}
return copied
}
// Given an array of properties or an object of property keys,
// plucks all the values off the target object, returning a new object
// that has props that reference the original prop values
export const pluckProps = (keysToPluck, objToPluck, transformFn = identity) =>
(isArray(keysToPluck) ? keysToPluck.slice() : keys(keysToPluck)).reduce((memo, prop) => {
memo[transformFn(prop)] = objToPluck[prop]
return memo
}, {})
// Make a prop object configurable by global configuration
// Replaces the current `default` key of each prop with a `getComponentConfig()`
// call that falls back to the current default value of the prop
export const makePropConfigurable = (prop, key, componentKey) => ({
...cloneDeep(prop),
default: function bvConfigurablePropDefault() {
const value = getComponentConfig(componentKey, key, prop.default)
return isFunction(value) ? value() : value
}
})
// Make a props object configurable by global configuration
// Replaces the current `default` key of each prop with a `getComponentConfig()`
// call that falls back to the current default value of the prop
export const makePropsConfigurable = (props, componentKey) =>
keys(props).reduce(
(result, key) => ({ ...result, [key]: makePropConfigurable(props[key], key, componentKey) }),
{}
)
// Get function name we use in `makePropConfigurable()`
// for the prop default value override to compare
// against in `hasPropFunction()`
const configurablePropDefaultFnName = makePropConfigurable({}, '', '').default.name
// Detect wether the given value is currently a function
// and isn't the props default function
export const hasPropFunction = fn =>
isFunction(fn) && fn.name && fn.name !== configurablePropDefaultFnName