68 lines
1.6 KiB
JavaScript
68 lines
1.6 KiB
JavaScript
|
import {
|
||
|
isString,
|
||
|
isBoolean,
|
||
|
isNumber,
|
||
|
isArray,
|
||
|
isUndefined
|
||
|
} from "lodash/fp";
|
||
|
|
||
|
import { assign } from "lodash";
|
||
|
|
||
|
export const createDefaultProps = (propsDefinition, derivedFromProps) => {
|
||
|
|
||
|
const props = {};
|
||
|
const errors = [];
|
||
|
|
||
|
for(let propDef in propsDefinition) {
|
||
|
const parsedPropDef = parsePropDef(propsDefinition[propDef]);
|
||
|
if(parsedPropDef.error)
|
||
|
errors.push({propName:propDef, error:parsedPropDef.error});
|
||
|
else
|
||
|
props[propDef] = parsedPropDef;
|
||
|
}
|
||
|
|
||
|
if(derivedFromProps) {
|
||
|
assign(props, ...derivedFromProps);
|
||
|
}
|
||
|
|
||
|
return ({
|
||
|
props, errors
|
||
|
});
|
||
|
}
|
||
|
|
||
|
const parsePropDef = propDef => {
|
||
|
const error = message => ({error:message});
|
||
|
|
||
|
if(isString(propDef)) {
|
||
|
if(!types[propDef])
|
||
|
return error(`Do not recognise type ${propDef}`);
|
||
|
|
||
|
return types[propDef].default();
|
||
|
}
|
||
|
|
||
|
if(!propDef.type)
|
||
|
return error("Property Definition must declare a type");
|
||
|
|
||
|
const type = types[propDef.type];
|
||
|
if(!type)
|
||
|
return error(`Do not recognise type ${propDef.type}`);
|
||
|
|
||
|
if(isUndefined(propDef.default))
|
||
|
return type.default(propDef);
|
||
|
|
||
|
if(!type.isOfType(propDef.default))
|
||
|
return error(`${propDef.default} is not of type ${type}`);
|
||
|
|
||
|
return propDef.default;
|
||
|
}
|
||
|
|
||
|
const propType = (defaultValue, isOfType) => ({
|
||
|
isOfType, default:defaultValue
|
||
|
});
|
||
|
|
||
|
const types = {
|
||
|
string: propType(() => "", isString),
|
||
|
bool: propType(() => false, isBoolean),
|
||
|
number: propType(() => 0, isNumber),
|
||
|
array: propType(() => [], isArray)
|
||
|
}
|