2023-02-15 06:08:45 +00:00
|
|
|
import type { App, ExtractPropTypes } from 'vue';
|
2021-09-25 08:51:32 +00:00
|
|
|
import { computed, defineComponent } from 'vue';
|
2020-03-30 16:02:28 +00:00
|
|
|
import CloseOutlined from '@ant-design/icons-vue/CloseOutlined';
|
|
|
|
import CheckOutlined from '@ant-design/icons-vue/CheckOutlined';
|
2023-04-05 05:39:40 +00:00
|
|
|
import type { VueNode } from '../_util/type';
|
2023-04-05 08:28:49 +00:00
|
|
|
import { anyType, booleanType, stringType, functionType, someType, arrayType } from '../_util/type';
|
2020-10-20 04:44:06 +00:00
|
|
|
import initDefaultProps from '../_util/props-util/initDefaultProps';
|
2021-11-10 02:06:59 +00:00
|
|
|
import VcSteps, { Step as VcStep } from '../vc-steps';
|
2023-01-27 08:00:17 +00:00
|
|
|
import useConfigInject from '../config-provider/hooks/useConfigInject';
|
2021-09-25 08:51:32 +00:00
|
|
|
import useBreakpoint from '../_util/hooks/useBreakpoint';
|
|
|
|
import classNames from '../_util/classNames';
|
|
|
|
import Progress from '../progress';
|
|
|
|
import omit from '../_util/omit';
|
2023-04-05 05:39:40 +00:00
|
|
|
import Tooltip from '../tooltip';
|
2021-11-26 13:48:35 +00:00
|
|
|
import { VcStepProps } from '../vc-steps/Step';
|
2023-04-05 08:28:49 +00:00
|
|
|
import type { Status, ProgressDotRender } from '../vc-steps/interface';
|
2022-03-12 01:56:32 +00:00
|
|
|
import type { MouseEventHandler } from '../_util/EventInterface';
|
2023-05-14 08:59:56 +00:00
|
|
|
import { useToken } from '../theme/internal';
|
2023-02-15 06:08:45 +00:00
|
|
|
|
|
|
|
// CSSINJS
|
|
|
|
import useStyle from './style';
|
2018-03-09 10:52:31 +00:00
|
|
|
|
2021-09-25 08:51:32 +00:00
|
|
|
export const stepsProps = () => ({
|
2022-03-12 01:56:32 +00:00
|
|
|
prefixCls: String,
|
|
|
|
iconPrefix: String,
|
|
|
|
current: Number,
|
|
|
|
initial: Number,
|
|
|
|
percent: Number,
|
2023-02-15 06:08:45 +00:00
|
|
|
responsive: booleanType(),
|
2023-04-05 05:39:40 +00:00
|
|
|
items: arrayType<StepProps[]>(),
|
2023-02-15 06:08:45 +00:00
|
|
|
labelPlacement: stringType<'horizontal' | 'vertical'>(),
|
2023-04-05 08:28:49 +00:00
|
|
|
status: stringType<Status>(),
|
2023-02-15 06:08:45 +00:00
|
|
|
size: stringType<'default' | 'small'>(),
|
|
|
|
direction: stringType<'horizontal' | 'vertical'>(),
|
2023-02-15 06:34:11 +00:00
|
|
|
progressDot: someType<boolean | ProgressDotRender>([Boolean, Function]),
|
|
|
|
type: stringType<'default' | 'navigation' | 'inline'>(),
|
2023-02-15 06:08:45 +00:00
|
|
|
onChange: functionType<(current: number) => void>(),
|
|
|
|
'onUpdate:current': functionType<(current: number) => void>(),
|
2021-09-25 08:51:32 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
export const stepProps = () => ({
|
2023-04-05 08:28:49 +00:00
|
|
|
description: anyType(),
|
|
|
|
icon: anyType(),
|
|
|
|
status: stringType<Status>(),
|
2023-02-15 06:08:45 +00:00
|
|
|
disabled: booleanType(),
|
2023-04-05 08:28:49 +00:00
|
|
|
title: anyType(),
|
|
|
|
subTitle: anyType(),
|
2023-02-15 06:08:45 +00:00
|
|
|
onClick: functionType<MouseEventHandler>(),
|
2021-09-25 08:51:32 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
export type StepsProps = Partial<ExtractPropTypes<ReturnType<typeof stepsProps>>>;
|
2018-03-09 10:52:31 +00:00
|
|
|
|
2021-09-25 08:51:32 +00:00
|
|
|
export type StepProps = Partial<ExtractPropTypes<ReturnType<typeof stepProps>>>;
|
2020-10-20 04:44:06 +00:00
|
|
|
|
|
|
|
const Steps = defineComponent({
|
2022-09-26 13:33:41 +00:00
|
|
|
compatConfig: { MODE: 3 },
|
2018-04-08 13:17:20 +00:00
|
|
|
name: 'ASteps',
|
2020-09-07 09:18:50 +00:00
|
|
|
inheritAttrs: false,
|
2021-09-25 08:51:32 +00:00
|
|
|
props: initDefaultProps(stepsProps(), {
|
2018-03-09 10:52:31 +00:00
|
|
|
current: 0,
|
2021-09-25 08:51:32 +00:00
|
|
|
responsive: true,
|
2022-03-12 01:56:32 +00:00
|
|
|
labelPlacement: 'horizontal',
|
2018-03-09 10:52:31 +00:00
|
|
|
}),
|
2021-09-25 08:51:32 +00:00
|
|
|
slots: ['progressDot'],
|
2022-03-26 14:52:54 +00:00
|
|
|
// emits: ['update:current', 'change'],
|
2021-09-25 08:51:32 +00:00
|
|
|
setup(props, { attrs, slots, emit }) {
|
|
|
|
const { prefixCls, direction: rtlDirection, configProvider } = useConfigInject('steps', props);
|
2023-02-15 06:08:45 +00:00
|
|
|
// style
|
|
|
|
const [wrapSSR, hashId] = useStyle(prefixCls);
|
2023-05-14 08:59:56 +00:00
|
|
|
const [, token] = useToken();
|
2023-02-15 06:08:45 +00:00
|
|
|
|
2021-09-25 08:51:32 +00:00
|
|
|
const screens = useBreakpoint();
|
|
|
|
const direction = computed(() =>
|
|
|
|
props.responsive && screens.value.xs ? 'vertical' : props.direction,
|
|
|
|
);
|
|
|
|
const iconPrefix = computed(() => configProvider.getPrefixCls('', props.iconPrefix));
|
|
|
|
const handleChange = (current: number) => {
|
|
|
|
emit('update:current', current);
|
|
|
|
emit('change', current);
|
2020-06-22 06:21:40 +00:00
|
|
|
};
|
2023-02-15 06:34:11 +00:00
|
|
|
const isInline = computed(() => props.type === 'inline');
|
|
|
|
const mergedPercent = computed(() => (isInline.value ? undefined : props.percent));
|
2021-09-25 08:51:32 +00:00
|
|
|
const stepIconRender = ({
|
|
|
|
node,
|
|
|
|
status,
|
|
|
|
}: {
|
|
|
|
node: any;
|
|
|
|
index: number;
|
|
|
|
status: string;
|
|
|
|
title: any;
|
|
|
|
description: any;
|
|
|
|
}) => {
|
|
|
|
if (status === 'process' && props.percent !== undefined) {
|
|
|
|
// currently it's hard-coded, since we can't easily read the actually width of icon
|
2023-05-14 08:59:56 +00:00
|
|
|
|
|
|
|
const progressWidth =
|
|
|
|
props.size === 'small' ? token.value.controlHeight : token.value.controlHeightLG;
|
|
|
|
|
2021-09-25 08:51:32 +00:00
|
|
|
const iconWithProgress = (
|
2023-02-15 06:08:45 +00:00
|
|
|
<div class={`${prefixCls.value}-progress-icon`}>
|
2021-09-25 08:51:32 +00:00
|
|
|
<Progress
|
|
|
|
type="circle"
|
2023-02-15 06:34:11 +00:00
|
|
|
percent={mergedPercent.value}
|
2023-04-08 12:57:46 +00:00
|
|
|
size={progressWidth}
|
2021-09-25 08:51:32 +00:00
|
|
|
strokeWidth={4}
|
|
|
|
format={() => null}
|
|
|
|
/>
|
|
|
|
{node}
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
return iconWithProgress;
|
|
|
|
}
|
|
|
|
return node;
|
2019-01-12 03:33:27 +00:00
|
|
|
};
|
2023-02-15 06:34:11 +00:00
|
|
|
const icons = computed(() => ({
|
|
|
|
finish: <CheckOutlined class={`${prefixCls.value}-finish-icon`} />,
|
|
|
|
error: <CloseOutlined class={`${prefixCls.value}-error-icon`} />,
|
|
|
|
}));
|
2021-09-25 08:51:32 +00:00
|
|
|
return () => {
|
|
|
|
const stepsClassName = classNames(
|
|
|
|
{
|
|
|
|
[`${prefixCls.value}-rtl`]: rtlDirection.value === 'rtl',
|
2023-02-15 06:34:11 +00:00
|
|
|
[`${prefixCls.value}-with-progress`]: mergedPercent.value !== undefined,
|
2021-09-25 08:51:32 +00:00
|
|
|
},
|
|
|
|
attrs.class,
|
2023-02-15 06:08:45 +00:00
|
|
|
hashId.value,
|
2021-09-25 08:51:32 +00:00
|
|
|
);
|
2023-04-05 05:39:40 +00:00
|
|
|
const itemRender = (item: StepProps, stepItem: VueNode) =>
|
|
|
|
item.description ? <Tooltip title={item.description}>{stepItem}</Tooltip> : stepItem;
|
2023-02-15 06:34:11 +00:00
|
|
|
|
2023-02-15 06:08:45 +00:00
|
|
|
return wrapSSR(
|
2021-09-25 08:51:32 +00:00
|
|
|
<VcSteps
|
2023-02-15 06:34:11 +00:00
|
|
|
icons={icons.value}
|
2023-02-15 06:08:45 +00:00
|
|
|
{...attrs}
|
2021-09-25 08:51:32 +00:00
|
|
|
{...omit(props, ['percent', 'responsive'])}
|
2023-04-05 08:28:49 +00:00
|
|
|
items={props.items}
|
2021-09-25 08:51:32 +00:00
|
|
|
direction={direction.value}
|
|
|
|
prefixCls={prefixCls.value}
|
|
|
|
iconPrefix={iconPrefix.value}
|
|
|
|
class={stepsClassName}
|
|
|
|
onChange={handleChange}
|
2023-04-05 05:39:40 +00:00
|
|
|
isInline={isInline.value}
|
|
|
|
itemRender={isInline.value ? itemRender : undefined}
|
|
|
|
v-slots={{ stepIcon: stepIconRender, ...slots }}
|
2023-02-15 06:08:45 +00:00
|
|
|
/>,
|
2021-09-25 08:51:32 +00:00
|
|
|
);
|
2019-01-12 03:33:27 +00:00
|
|
|
};
|
2018-03-09 10:52:31 +00:00
|
|
|
},
|
2020-10-20 04:44:06 +00:00
|
|
|
});
|
2018-03-19 02:16:27 +00:00
|
|
|
|
2018-09-19 05:21:57 +00:00
|
|
|
/* istanbul ignore next */
|
2021-11-26 14:34:27 +00:00
|
|
|
export const Step = defineComponent({
|
2022-09-26 13:33:41 +00:00
|
|
|
compatConfig: { MODE: 3 },
|
2023-04-08 12:57:46 +00:00
|
|
|
...(VcStep as any),
|
2021-11-26 14:34:27 +00:00
|
|
|
name: 'AStep',
|
|
|
|
props: VcStepProps(),
|
|
|
|
});
|
2021-11-10 02:06:59 +00:00
|
|
|
export default Object.assign(Steps, {
|
|
|
|
Step,
|
|
|
|
install: (app: App) => {
|
|
|
|
app.component(Steps.name, Steps);
|
|
|
|
app.component(Step.name, Step);
|
|
|
|
return app;
|
|
|
|
},
|
|
|
|
});
|