import { computed , defineComponent , mergeProps , PropType , ref } from 'vue' ; import { Direction , DIRECTIONS } from '../_utils/constant' ; import { getPrefixCls } from '../_utils/global-config' ; import { getChildrenComponents } from '../_utils/vue-utils' ; import { StepStatus , StepsType } from './interface' ; export default defineComponent ( { name : 'Steps' , props : { zh en values type : { type : String as PropType < StepsType > , default : 'default' } , zh en values direction : { type : String as PropType < Direction > , default : 'horizontal' } , zh en values labelPlacement : { type : String as PropType < Direction > , default : 'horizontal' } , zh en vModel current : { type : Number , default : undefined } , zh en defaultCurrent : { type : Number , default : 1 } , zh en values status : { type : String as PropType < StepStatus > , default : 'process' } , zh en lineLess : { type : Boolean , default : false } , zh en small : { type : Boolean , default : false } , zh en changeable : { type : Boolean , default : false } } , emits : [ 'update:current' , 'change' , ] , setup ( props , { emit , slots } ) { const prefixCls = getPrefixCls ( 'steps' ) ; const _current = ref ( props . defaultCurrent ) ; const computedCurrent = computed ( ( ) => props . current ?? _current . value ) ; const direction = computed ( ( ) => [ 'navigation' , 'arrow' ] . includes ( props . type ) ? 'horizontal' : props . direction ) ; const labelPlacement = computed ( ( ) => { if ( props . type === 'dot' ) { return direction . value === 'vertical' ? 'horizontal' : 'vertical' ; } if ( props . type === 'navigation' ) { return 'horizontal' ; } return props . labelPlacement ; } ) ; const handleClick = ( step , e ) => { if ( props . changeable ) { _current . value = step ; emit ( 'update:current' , step ) ; emit ( 'change' , step , e ) ; } } ; const getStatus = ( step , current ) : StepStatus => { if ( step < current ) { return 'finish' ; } if ( step > current ) { return 'wait' ; } return props . status ; } ; const cls = computed ( ( ) => [ prefixCls , `${ prefixCls }-${ direction . value }` , `${ prefixCls }-label-${ labelPlacement . value }` , `${ prefixCls }-mode-${ props . type }` , { [ `${ prefixCls }-changeable` ] : props . changeable , [ `${ prefixCls }-size-small` ] : props . small && props . type !== 'dot' , [ `${ prefixCls }-line-less` ] : props . lineLess } , ] ) ; return ( ) => { const children = getChildrenComponents ( slots . default ?. ( ) ?? [ ] , 'Step' , ( vn , index ) => { const step = index + 1 ; const status = getStatus ( step , computedCurrent . value ) ; return { step , current : computedCurrent . value , status : vn . props ?. status ?? status , direction : direction . value , labelPlacement : labelPlacement . value , lineLess : props . lineLess , type : props . type , onClick : handleClick } ; } ) ; children . forEach ( ( vn , index ) => { const next = children [ index + 1 ] ; if ( next && next . props ?. status === 'error' ) { vn . props = mergeProps ( vn . props ?? { } , { nextStepError : true } ) ; } } ) ; return < div class = { cls . value } > { children } < /div>; } ; } } ) ;