vuecssuiant-designantdreactantantd-vueenterprisefrontendui-designvue-antdvue-antd-uivue3vuecomponent
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
5.1 KiB
152 lines
5.1 KiB
import { computed, defineComponent, toRefs } from 'vue'; |
|
import classNames from '../_util/classNames'; |
|
import { isFunction } from '../_util/util'; |
|
import CloseOutlined from '@ant-design/icons-vue/CloseOutlined'; |
|
import { tourStepProps } from './interface'; |
|
import type { TourBtnProps } from './interface'; |
|
|
|
import LocaleReceiver from '../locale/LocaleReceiver'; |
|
import Button from '../button'; |
|
import type { ButtonProps } from '../button'; |
|
import defaultLocale from '../locale/en_US'; |
|
|
|
import type { VueNode } from '../_util/type'; |
|
|
|
const panelRender = defineComponent({ |
|
name: 'ATourPanel', |
|
inheritAttrs: false, |
|
props: tourStepProps(), |
|
setup(props, { attrs, slots }) { |
|
const { current, total } = toRefs(props); |
|
|
|
const isLastStep = computed(() => current.value === total.value - 1); |
|
|
|
const prevBtnClick = e => { |
|
const prevButtonProps = props.prevButtonProps as TourBtnProps; |
|
props.onPrev?.(e); |
|
if (typeof prevButtonProps?.onClick === 'function') { |
|
prevButtonProps?.onClick(); |
|
} |
|
}; |
|
|
|
const nextBtnClick = e => { |
|
const nextButtonProps = props.nextButtonProps as TourBtnProps; |
|
if (isLastStep.value) { |
|
props.onFinish?.(e); |
|
} else { |
|
props.onNext?.(e); |
|
} |
|
if (typeof nextButtonProps?.onClick === 'function') { |
|
nextButtonProps?.onClick(); |
|
} |
|
}; |
|
|
|
return () => { |
|
const { prefixCls, title, onClose, cover, description, type: stepType, arrow } = props; |
|
|
|
const prevButtonProps = props.prevButtonProps as TourBtnProps; |
|
const nextButtonProps = props.nextButtonProps as TourBtnProps; |
|
|
|
let headerNode: VueNode; |
|
if (title) { |
|
headerNode = ( |
|
<div class={`${prefixCls}-header`}> |
|
<div class={`${prefixCls}-title`}>{title}</div> |
|
</div> |
|
); |
|
} |
|
|
|
let descriptionNode: VueNode; |
|
if (description) { |
|
descriptionNode = <div class={`${prefixCls}-description`}>{description}</div>; |
|
} |
|
|
|
let coverNode: VueNode; |
|
if (cover) { |
|
coverNode = <div class={`${prefixCls}-cover`}>{cover}</div>; |
|
} |
|
|
|
let mergeIndicatorNode: VueNode; |
|
|
|
if (slots.indicatorsRender) { |
|
mergeIndicatorNode = slots.indicatorsRender({ current: current.value, total }); |
|
} else { |
|
mergeIndicatorNode = [...Array.from({ length: total.value }).keys()].map( |
|
(stepItem, index) => ( |
|
<span |
|
key={stepItem} |
|
class={classNames( |
|
index === current.value && `${prefixCls}-indicator-active`, |
|
`${prefixCls}-indicator`, |
|
)} |
|
/> |
|
), |
|
); |
|
} |
|
|
|
const mainBtnType = stepType === 'primary' ? 'default' : 'primary'; |
|
const secondaryBtnProps: ButtonProps = { |
|
type: 'default', |
|
ghost: stepType === 'primary', |
|
}; |
|
|
|
return ( |
|
<LocaleReceiver componentName="Tour" defaultLocale={defaultLocale.Tour}> |
|
{contextLocale => ( |
|
<div |
|
{...attrs} |
|
class={classNames( |
|
stepType === 'primary' ? `${prefixCls}-primary` : '', |
|
attrs.class, |
|
`${prefixCls}-content`, |
|
)} |
|
> |
|
{arrow && <div class={`${prefixCls}-arrow`} key="arrow" />} |
|
<div class={`${prefixCls}-inner`}> |
|
<CloseOutlined class={`${prefixCls}-close`} onClick={onClose} /> |
|
{coverNode} |
|
{headerNode} |
|
{descriptionNode} |
|
<div class={`${prefixCls}-footer`}> |
|
{total.value > 1 && ( |
|
<div class={`${prefixCls}-indicators`}>{mergeIndicatorNode}</div> |
|
)} |
|
<div class={`${prefixCls}-buttons`}> |
|
{current.value !== 0 ? ( |
|
<Button |
|
{...secondaryBtnProps} |
|
{...prevButtonProps} |
|
onClick={prevBtnClick} |
|
size="small" |
|
class={classNames(`${prefixCls}-prev-btn`, prevButtonProps?.className)} |
|
> |
|
{isFunction(prevButtonProps?.children) |
|
? prevButtonProps.children() |
|
: prevButtonProps?.children ?? contextLocale.Previous} |
|
</Button> |
|
) : null} |
|
<Button |
|
type={mainBtnType} |
|
{...nextButtonProps} |
|
onClick={nextBtnClick} |
|
size="small" |
|
class={classNames(`${prefixCls}-next-btn`, nextButtonProps?.className)} |
|
> |
|
{isFunction(nextButtonProps?.children) |
|
? nextButtonProps?.children() |
|
: isLastStep.value |
|
? contextLocale.Finish |
|
: contextLocale.Next} |
|
</Button> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
)} |
|
</LocaleReceiver> |
|
); |
|
}; |
|
}, |
|
}); |
|
|
|
export default panelRender;
|
|
|