Skip to content

Commit

Permalink
feat(comp:tour): supports outline and mask container (#1868)
Browse files Browse the repository at this point in the history
  • Loading branch information
sallerli1 committed Mar 27, 2024
1 parent 0c6c54d commit 5c25eb3
Show file tree
Hide file tree
Showing 14 changed files with 335 additions and 132 deletions.
2 changes: 1 addition & 1 deletion packages/components/tour/demo/CustomMask.md
Expand Up @@ -7,7 +7,7 @@ title:

## zh

通过 `mask.color` 以及 `mask.class` 自定义遮罩。
通过 `mask.color`, `mask.container` 以及 `mask.class` 自定义遮罩。

## en

Expand Down
57 changes: 33 additions & 24 deletions packages/components/tour/demo/CustomMask.vue
Expand Up @@ -14,11 +14,7 @@
</div>
</IxSpace>
</div>
<IxTour
v-model:visible="tourVisible"
:steps="steps"
:mask="{ class: 'demo-tour-custom-mask-cls', color: 'rgba(40, 0, 255)' }"
></IxTour>
<IxTour v-model:visible="tourVisible" :steps="steps" :mask="mask"></IxTour>
</template>

<script setup lang="ts">
Expand All @@ -27,30 +23,43 @@ import type { TourStep } from '@idux/components/tour'
import { ref } from 'vue'
const tourVisible = ref(false)
const mask = ref({})
const steps = ref<TourStep[]>([])
const beginTour = () => (tourVisible.value = true)
let tmr: number
const beginTour = () => {
clearTimeout(tmr)
tmr = setTimeout(() => {
mask.value = {
container: { x: 10, y: 10, width: window.innerWidth - 20, height: window.innerHeight - 20 },
class: 'demo-tour-custom-mask-cls',
color: 'rgba(40, 0, 255)',
}
steps.value = [
{
title: 'Step1',
description: 'this is description...',
target: () => firstBtnRef.value,
},
{
title: 'Step2',
description: 'this is description...',
target: () => secondBtnRef.value,
},
{
title: 'Step3',
description: 'this is description...',
target: () => thirdBtnRef.value,
},
]
tourVisible.value = true
}, 500)
}
const firstBtnRef = ref<HTMLElement>()
const secondBtnRef = ref<HTMLElement>()
const thirdBtnRef = ref<HTMLElement>()
const steps: TourStep[] = [
{
title: 'Step1',
description: 'this is description...',
target: () => firstBtnRef.value,
},
{
title: 'Step2',
description: 'this is description...',
target: () => secondBtnRef.value,
},
{
title: 'Step3',
description: 'this is description...',
target: () => thirdBtnRef.value,
},
]
</script>

<style lang="less">
Expand Down
18 changes: 18 additions & 0 deletions packages/components/tour/demo/Outline.md
@@ -0,0 +1,18 @@
---
order: 31
title:
zh: 外边框
en: Outline
---

## zh

通过 `gap.outline``mask.outlineColor` 设置外边框。

外边框只能在有mask的时候显示

## en

Customize outline via `gap.outline` and `mask.outlineColor`.

Outline only works when mask is displayed.
57 changes: 57 additions & 0 deletions packages/components/tour/demo/Outline.vue
@@ -0,0 +1,57 @@
<template>
<div>
<IxButton @click="beginTour">Begin</IxButton>
<IxDivider />
<IxSpace>
<div ref="firstBtnRef">
<IxButton>Step1</IxButton>
</div>
<div ref="secondBtnRef">
<IxButton>Step2</IxButton>
</div>
<div ref="thirdBtnRef">
<IxButton>Step3</IxButton>
</div>
</IxSpace>
</div>
<IxTour v-model:visible="tourVisible" :steps="steps" :gap="{ outline: 2 }"></IxTour>
</template>

<script setup lang="ts">
import type { TourStep } from '@idux/components/tour'
import { ref } from 'vue'
const tourVisible = ref(false)
const steps = ref<TourStep[]>([
{
title: 'Step1',
description: 'this is description...',
target: () => firstBtnRef.value,
},
{
title: 'Step2',
description: 'this is description...',
target: () => secondBtnRef.value,
},
{
title: 'Step3',
description: 'this is description...',
target: () => thirdBtnRef.value,
},
])
const beginTour = () => {
tourVisible.value = true
}
const firstBtnRef = ref<HTMLElement>()
const secondBtnRef = ref<HTMLElement>()
const thirdBtnRef = ref<HTMLElement>()
</script>

<style lang="less">
.demo-tour-custom-mask-cls {
opacity: 0.4;
}
</style>
20 changes: 18 additions & 2 deletions packages/components/tour/src/Mask.tsx
Expand Up @@ -14,7 +14,16 @@ import { tourToken } from './token'
export default defineComponent({
setup() {
const { globalHashId, hashId } = useThemeToken('tour')
const { mergedPrefixCls, mergedProps, maskPath, maskAttrs, maskClass, maskStyle } = inject(tourToken)!
const {
mergedPrefixCls,
mergedProps,
maskPath,
maskOutlinePath,
maskAttrs,
maskClass,
maskStyle,
maskOutlineStyle,
} = inject(tourToken)!

const classes = computed(() => {
const prefixCls = `${mergedPrefixCls.value}-mask`
Expand All @@ -32,7 +41,14 @@ export default defineComponent({
return () => {
return (
<svg class={classes.value} style={maskStyle.value} {...maskAttrs.value}>
<path d={maskPath.value} />
<path class={`${mergedPrefixCls.value}-mask-target`} d={maskPath.value} />
{maskOutlinePath.value && (
<path
class={`${mergedPrefixCls.value}-mask-outline`}
style={maskOutlineStyle.value}
d={maskOutlinePath.value}
/>
)}
</svg>
)
}
Expand Down
14 changes: 5 additions & 9 deletions packages/components/tour/src/composables/useActiveStep.ts
Expand Up @@ -12,7 +12,7 @@ import type { TourLocale } from '@idux/components/locales'

import { type ComputedRef, watch } from 'vue'

import { isFunction, isNumber, isString } from 'lodash-es'
import { isFunction, isNumber, isString, merge } from 'lodash-es'

import { convertElement, useState } from '@idux/cdk/utils'

Expand Down Expand Up @@ -43,7 +43,7 @@ export function useActiveStep(
}

const gap = step.gap ?? props.gap
const mergedGap = isNumber(gap) ? { offset: gap } : gap
const mergedGap = merge({ ...props.gap }, isNumber(gap) ? { offset: gap } : gap)

const target = async () => {
if (!step.target) {
Expand Down Expand Up @@ -116,16 +116,12 @@ export function useActiveStep(
}

watch(
[activeIndex, () => mergedProps.value.steps],
([current, steps], [, preSteps]) => {
if (current === activeStep.value?.index && steps === preSteps) {
return
}

[activeIndex, () => mergedProps.value.steps, mergedProps],
([current]) => {
destroySteps()
pushCurrentUpdate(current)
},
{ immediate: true, flush: 'post' },
{ immediate: true, flush: 'post', deep: true },
)

return activeStep
Expand Down

0 comments on commit 5c25eb3

Please sign in to comment.