react-native-rue-wizard-stepper
Version:
126 lines (125 loc) • 4.96 kB
JavaScript
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import React, { isValidElement, useEffect, useState, useMemo, Children, cloneElement, } from "react";
import { SafeAreaView, StyleSheet, useWindowDimensions, View, } from "react-native";
import { useStepper } from "../hooks";
import StepIcon from "./StepIcon";
const StepperFlow = (_a) => {
var _b, _c, _d, _e;
var { children, onChangeStep, showLabelAboveSteps = true, completedBarColor, incompletedBarColor } = _a, props = __rest(_a, ["children", "onChangeStep", "showLabelAboveSteps", "completedBarColor", "incompletedBarColor"]);
const { width } = useWindowDimensions();
const [stepIconWidthOffSet, setStepIconWidthOffSet] = useState([]);
const { activeStep, totalSteps } = useStepper();
useEffect(() => {
if (onChangeStep) {
onChangeStep();
}
}, [activeStep]);
const renderChildren = useMemo(() => {
const tmp = Children.map(children, (ele) => {
var _a;
if (ele && isValidElement(ele) && !((_a = ele === null || ele === void 0 ? void 0 : ele.props) === null || _a === void 0 ? void 0 : _a.hide)) {
return cloneElement(ele);
}
});
return tmp;
}, [children]);
const renderStepIcons = () => {
var _a, _b, _c;
let step = [];
let i = 0;
while (i !== totalSteps) {
const isCompletedStep = i < activeStep;
const isActiveStep = i === activeStep;
step.push(<View key={i} style={{ flex: 1 }} onLayout={({ nativeEvent: offSet }) => {
setStepIconWidthOffSet((s) => {
return [...s, offSet].slice(-totalSteps).sort((a, b) => {
return a.layout.x - b.layout.x;
});
});
}}>
<StepIcon {...Object.assign(Object.assign({}, props), { showLabelAboveSteps })} stepNumber={i + 1} isCompletedStep={isCompletedStep} isActiveStep={isActiveStep} label={(_c = (_b = (_a = renderChildren[i]) === null || _a === void 0 ? void 0 : _a.props) === null || _b === void 0 ? void 0 : _b.label) !== null && _c !== void 0 ? _c : ""}/>
</View>);
i++;
}
return step;
};
const calculateIndicatorTop = (widthParam) => {
const threshold = (widthParam * 10) / 100;
const isThresholdMet = threshold >= 50;
if (showLabelAboveSteps) {
return isThresholdMet ? 77 : (width * 27) / 200;
}
else {
return isThresholdMet ? 30 : threshold / 2;
}
};
const indicatorTop = useMemo(() => calculateIndicatorTop(width), [width, showLabelAboveSteps]);
return (<SafeAreaView style={styles.container}>
<View style={{
maxHeight: 115,
backgroundColor: "transparent",
}}>
<View style={[
styles.stepIcons,
{
maxHeight: 115,
height: (width * 20) / 100,
width: width,
},
]}>
{renderStepIcons()}
<View style={[
styles.stepIndicatorOuter,
{
backgroundColor: incompletedBarColor,
top: indicatorTop,
width: (_c = (_b = stepIconWidthOffSet[totalSteps - 1]) === null || _b === void 0 ? void 0 : _b.layout) === null || _c === void 0 ? void 0 : _c.x,
},
]}>
<View style={{
borderColor: completedBarColor,
width: (_e = (_d = stepIconWidthOffSet[activeStep]) === null || _d === void 0 ? void 0 : _d.layout) === null || _e === void 0 ? void 0 : _e.x,
borderWidth: 1.5,
}}/>
</View>
</View>
</View>
{<View style={styles.bodyContainer}>
{isValidElement(renderChildren[activeStep]) &&
cloneElement(renderChildren[activeStep])}
</View>}
</SafeAreaView>);
};
export default StepperFlow;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "transparent",
},
stepIndicatorOuter: {
zIndex: -1,
position: "absolute",
alignSelf: "center",
},
bodyContainer: {
flex: 1,
backgroundColor: "transparent",
},
stepIcons: {
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
alignSelf: "center",
backgroundColor: "transparent",
},
});