import React, { cloneElement, Children, useMemo, ReactElement, isValidElement } from 'react'; import PropTypes from 'prop-types'; import cls from 'classnames'; import { stepsClasses as css } from '@douyinfe/semi-foundation/steps/constants'; import { Row, Col } from '../grid'; export type Status = 'wait' | 'process' | 'finish' | 'error' | 'warning'; export type Direction = 'horizontal' | 'vertical'; export interface FillStepsProps { prefixCls?: string; className?: string; current?: number; direction?: Direction; initial?: number; status?: Status; style?: React.CSSProperties; children?: React.ReactNode; onChange?: (current: number) => void; "aria-label"?: string; } const Steps = (props: FillStepsProps) => { const { current, status, children, prefixCls, initial, direction, className, style, onChange } = props; const inner = useMemo(() => { const filteredChildren = Children.toArray(children).filter(c => isValidElement(c)) as Array; const colStyle = direction === 'vertical' ? null : { width: `${100 / filteredChildren.length }%` }; const content = Children.map(filteredChildren, (child: ReactElement, index) => { if (!child) { return null; } const stepNumber = initial + index; const childProps = { stepNumber: `${stepNumber + 1}`, direction, ...child.props, }; if (status === 'error' && index === current - 1) { childProps.className = `${prefixCls}-next-error`; } if (!child.props.status) { if (stepNumber === current) { childProps.status = status; } else if (stepNumber < current) { childProps.status = 'finish'; } else { childProps.status = 'wait'; } } childProps.onChange = () => { if (index !== current) { onChange(index + initial); } }; return {cloneElement(child, { ...childProps })}; }); return content; }, [children, initial, prefixCls, direction, status, current, onChange]); const wrapperCls = cls(className, { [prefixCls]: true, [`${prefixCls}-${ direction}`]: true }); return (
{inner}
); }; Steps.propTypes = { prefixCls: PropTypes.string, className: PropTypes.string, style: PropTypes.object, current: PropTypes.number, initial: PropTypes.number, direction: PropTypes.oneOf(['horizontal', 'vertical']), status: PropTypes.oneOf(['wait', 'process', 'finish', 'error', 'warning']) }; Steps.defaultProps = { prefixCls: css.PREFIX, current: 0, direction: 'horizontal', initial: 0, status: 'process', }; export default Steps;