Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
componentDidUpdate(prevProps, prevState) {
if (!canUseDOM) return;
const { action, controlled, index, lifecycle, status } = this.state;
const { debug, run, stepIndex, steps } = this.props;
const { steps: prevSteps, stepIndex: prevStepIndex } = prevProps;
const { setSteps, reset, start, stop, update } = this.store;
const { changed: changedProps } = treeChanges(prevProps, this.props);
const { changed, changedFrom, changedTo } = treeChanges(prevState, this.state);
const step = getMergedStep(steps[index], this.props);
const stepsChanged = !isEqual(prevSteps, steps);
const stepIndexChanged = is.number(stepIndex) && changedProps('stepIndex');
if (stepsChanged) {
if (validateSteps(steps, debug)) {
setSteps(steps);
} else {
console.warn('Steps are not valid', steps); //eslint-disable-line no-console
}
}
/* istanbul ignore else */
if (changedProps('run')) {
if (run) {
start(stepIndex);
} else {
stop();
}
export function isEqual(left: any, right: any): boolean {
let type;
const hasReactElement = isValidElement(left) || isValidElement(right);
const hasUndefined = is.undefined(left) || is.undefined(right);
if (getObjectType(left) !== getObjectType(right) || hasReactElement || hasUndefined) {
return false;
}
if (is.domElement(left)) {
return left.isSameNode(right);
}
if (is.number(left)) {
return left === right;
}
if (is.function(left)) {
return left.toString() === right.toString();
}
for (const key in left) {
/* istanbul ignore else */
if (hasOwnProperty(left, key)) {
if (typeof left[key] === 'undefined' || typeof right[key] === 'undefined') {
return false;
}
type = getObjectType(left[key]);
initStore = () => {
const { debug, getHelpers, run, stepIndex } = this.props;
this.store = new Store({
...this.props,
controlled: run && is.number(stepIndex),
});
this.helpers = this.store.getHelpers();
const { addListener } = this.store;
log({
title: 'init',
data: [
{ key: 'props', value: this.props },
{ key: 'state', value: this.state },
],
debug,
});
// Sync the store to this component's state.
addListener(this.syncState);
constructor({ continuous = false, stepIndex, steps = [] }: Object = {}) {
this.setState(
{
action: ACTIONS.INIT,
controlled: is.number(stepIndex),
continuous,
index: is.number(stepIndex) ? stepIndex : 0,
lifecycle: LIFECYCLE.INIT,
status: steps.length ? STATUS.READY : STATUS.IDLE,
},
true,
);
this.setSteps(steps);
}
propFullName: string,
): any => {
const propValue = props[propName];
let Component = propValue;
if (!React.isValidElement(propValue) && isValidElementType(propValue)) {
const ownProps = {
ref: () => {},
step: {},
};
Component = ;
}
if (
is.string(propValue) ||
is.number(propValue) ||
!isValidElementType(propValue) ||
![Element, ForwardRef].includes(typeOf(Component))
) {
return new Error(
`Invalid ${location} \`${propFullName}\` supplied to \`${componentName}\`. Expected a React class or forwardRef.`,
);
}
return undefined;
},
);
constructor({ continuous = false, stepIndex, steps = [] }: Object = {}) {
this.setState(
{
action: ACTIONS.INIT,
controlled: is.number(stepIndex),
continuous,
index: is.number(stepIndex) ? stepIndex : 0,
lifecycle: LIFECYCLE.INIT,
status: steps.length ? STATUS.READY : STATUS.IDLE,
},
true,
);
this.setSteps(steps);
}
getNextState(state: Object, force: ?boolean = false): StoreState {
const { action, controlled, index, size, status } = this.getState();
const newIndex = is.number(state.index) ? state.index : index;
const nextIndex = controlled && !force ? index : Math.min(Math.max(newIndex, 0), size);
return {
action: state.action || action,
controlled,
index: nextIndex,
lifecycle: state.lifecycle || LIFECYCLE.INIT,
size: state.size || size,
status: nextIndex === size ? STATUS.FINISHED : state.status || status,
};
}
start = (nextIndex: number) => {
const { index, size } = this.getState();
this.setState({
...this.getNextState(
{
action: ACTIONS.START,
index: is.number(nextIndex) ? nextIndex : index,
},
true,
),
status: size ? STATUS.RUNNING : STATUS.WAITING,
});
};