@innovaccer/design-system
Version:
React components library project for Innovaccer Design System
154 lines (132 loc) • 4.66 kB
text/typescript
import * as React from 'react';
interface IValueHelper {
required?: boolean;
iterate?: boolean;
maxLen?: number;
}
const isMapper = (value: any) => typeof value === 'object' && !Array.isArray(value) && !React.isValidElement(value);
const filterRequired = (props: Record<string, any>) =>
Object.keys(props).reduce(
(out, curr) => {
if (props[curr].required) out.required[curr] = props[curr];
else {
out.optional[curr] = props[curr];
}
return out;
},
{ required: {}, optional: {} } as Record<string, any>
);
const iterateComb = (
requiredComb: Record<string, any>[],
optionalComb: Record<string, any>[],
testFunc?: (props: Record<string, any>) => void
): Record<string, any>[] => {
const combinations: Record<string, any>[] = [];
requiredComb.forEach((reqProps) => {
optionalComb.forEach((optProps) => {
const allProps = { ...reqProps, ...optProps };
if (!!testFunc) testFunc(allProps);
else combinations.push(allProps);
});
});
return combinations;
};
const getCombinations = (Props: Record<string, any>): Record<string, any>[] => {
const combinations: Record<string, any>[] = [];
const propNames = Object.keys(Props);
const iterateProps = (curr: Record<string, any> = {}, propIndex: number = 0): void => {
const iterateValues = (propValues: any[]) => {
for (const propValue of propValues) {
if (isMapper(propValue)) {
const propComb = iterateMapper(propValue);
for (const propVal of propComb as Record<string, any>[]) {
currProps[propName] = propVal;
iterateProps(currProps, propIndex + 1);
}
} else {
currProps[propName] = propValue;
iterateProps(currProps, propIndex + 1);
}
}
};
const currProps = { ...curr };
if (propIndex === propNames.length) {
combinations.push(currProps);
return;
}
const propName = propNames[propIndex];
const propValue = Props[propName].value;
if (Props[propName].iterate) {
iterateValues(propValue);
} else {
currProps[propName] = propValue;
iterateProps(currProps, propIndex + 1);
}
};
if (propNames.length) iterateProps(Props);
return combinations.length ? combinations : [{}];
};
const iterateMapper = (
Mapper: Record<string, any>,
testFunc?: (props: Record<string, any>) => void
): Record<string, any>[] | void => {
Mapper = filterRequired(Mapper);
const requiredComb = getCombinations(Mapper.required);
const optionalComb = getCombinations(Mapper.optional);
if (!testFunc) {
const allComb = iterateComb(requiredComb, optionalComb);
return allComb;
} else {
iterateComb(requiredComb, optionalComb, testFunc);
}
};
export const testHelper = (Mapper: Record<string, any>, testFunc: (props: Record<string, any>) => void): void => {
iterateMapper(Mapper, testFunc);
};
export const filterUndefined = (props: Record<string, any>) =>
Object.keys(props)
.filter((prop) => props[prop] !== undefined)
.reduce((out: Record<string, any>, curr) => {
out[curr] = props[curr];
return out;
}, {});
export const valueHelper = (props: any, options: IValueHelper = {}): Record<string, any> => {
const { required, iterate } = options;
if (!required) props = [undefined, ...props];
return { required, iterate, value: props };
};
export const arrayHelper = (props: any[], options: IValueHelper = {}) => {
const { maxLen = props.length } = options;
const generateComb = () => {
const combinations: any[] = [];
const iterate = (i: number, curr: any[] = []) => {
if (isMapper(props[i])) {
const propValues = iterateMapper(props[i]) as Record<string, any>[];
propValues.forEach((propValue) => {
const newCurr = [...curr, propValue];
combinations.push(newCurr);
if (i < maxLen - 1) iterate(i + 1, newCurr);
});
} else {
const newCurr = [...curr, props[i]];
combinations.push(newCurr);
if (i < maxLen - 1) iterate(i + 1, newCurr);
}
};
for (let i = 0; i < props.length; i++) {
iterate(i);
}
return combinations;
};
return valueHelper(generateComb(), { iterate: true });
};
export const testMessageHelper = (attr: Record<string, any>) => `
${Object.keys(attr)
.map((k) => `${k}: ${JSON.stringify(attr[k], JSONStringifyHelper)}`)
.join(', ')}
`;
export const JSONStringifyHelper = (_key: string, value: any) => {
if (typeof value === 'function') return '[Function]';
if (React.isValidElement(value)) return '[ReactNode]';
return value;
};