Skip to content

Commit

Permalink
feat(components): tour component (element-plus#14952)
Browse files Browse the repository at this point in the history
  • Loading branch information
Fuphoenixes authored Dec 27, 2023
1 parent 3fdab26 commit 2fd7ba8
Show file tree
Hide file tree
Showing 46 changed files with 1,998 additions and 0 deletions.
5 changes: 5 additions & 0 deletions docs/.vitepress/crowdin/en-US/pages/component.json
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,11 @@
"link": "/timeline",
"text": "Timeline"
},
{
"link": "/tour",
"text": "Tour",
"promotion": "2.5.0"
},
{
"link": "/tree",
"text": "Tree"
Expand Down
129 changes: 129 additions & 0 deletions docs/en-US/component/tour.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
---
title: Tour
lang: en-US
---

# Tour

A popup component for guiding users through a product. Use when you want to guide users through a product.

## Basic usage

The most basic usage

:::demo

tour/basic

:::

## Non modal

Use `:mask="false"` to make Tour non-modal. At the meantime it is recommended to use with `type="primary"` to emphasize the guide itself.

:::demo

tour/non-modal

:::

## Placement

Change the placement of the guide relative to the target, there are 12 placements available. When `target` is empty the guide will show in the center.

:::demo

tour/placement

:::

## Custom mask style

Custom mask style.

:::demo

tour/mask

:::

## Custom indicator

Custom indicator.

:::demo

tour/indicator

:::


## Tour API

:::tip
tour-step component configuration with the same name has higher priority
:::

### Tour Attributes

| Property | Description | Type | Default |
| --- | --- | --- | --- |
| show-arrow | whether to show the arrow | `boolean` | true |
| placement | position of the guide card relative to the target element | ^[enum]`'top' \| 'top-start' \| 'top-end' \| 'bottom' \| 'bottom-start' \| 'bottom-end' \| 'left' \| 'left-start' \| 'left-end' \| 'right' \| 'right-start' \| 'right-end'` | `bottom` |
| content-style | custom style for content | `CSSProperties` | - |
| mask | whether to enable masking, change mask style and fill color by pass custom props | `boolean` \| ^[Object]`{ style?: CSSProperties; color?: string; }` | `true` |
| type | type, affects the background color and text color | `default` \| `primary` | `default` |
| model-value / v-model | open tour | `boolean` | - |
| current / v-model:current | what is the current step | `number` | - |
| scroll-into-view-options | support pass custom scrollIntoView options | `boolean` \| `ScrollIntoViewOptions` | ^[Object]`{ block: 'center' }` |
| z-index | Tour's zIndex | `number` | `2001` |
| show-close | whether to show a close button | `boolean` | `true` |
| close-icon | custom close icon, default is Close | `string` \| `Component` | - |
| close-on-press-escape | whether the Dialog can be closed by pressing ESC | `boolean` | `true` |
| target-area-clickable | whether the target element can be clickable, when using mask | `boolean` | `true` |

### Tour slots

| Name | Description |
| ------------------- | -------------------------- |
| default | tourStep component list |
| indicators | custom indicator, The scope parameter is `{ current, total }` |

### Tour events

| Name | Description | Type |
| --- | --- | --- |
| close | callback function on shutdown | ^[Function]`(current: number) => void` |
| finish | callback function on finished | ^[Function]`() => void` |
| change | callback when the step changes | ^[Function]`(current: number) => void` |

### TourStep Attributes

| Property | Description | Type | Default |
| --- | --- | --- | --- |
| target | get the element the guide card points to. Empty makes it show in center of screen | `HTMLElement` | - |
| show-arrow | whether to show the arrow | `boolean` | `true` |
| title | title | `string` | - |
| description | description | `string` | - |
| placement | position of the guide card relative to the target element | ^[enum]`'top' \| 'top-start' \| 'top-end' \| 'bottom' \| 'bottom-start' \| 'bottom-end' \| 'left' \| 'left-start' \| 'left-end' \| 'right' \| 'right-start' \| 'right-end'` | `bottom` |
| content-style | custom style for content | `CSSProperties` | - |
| mask | whether to enable masking, change mask style and fill color by pass custom props | `boolean` \| ^[Object]`{ style?: CSSProperties; color?: string; }` | `true` |
| type | type, affects the background color and text color | `default` \| `primary` | `default` |
| next-button-props | properties of the Next button | ^[Object]`{ children: VueNode \| string; onClick: Function }` | - |
| prev-button-props | properties of the previous button | ^[Object]`{ children: VueNode \| string; onClick: Function }` | - |
| scroll-into-view-options | support pass custom scrollIntoView options, the default follows the `scrollIntoViewOptions` property of Tour | `boolean` \| `ScrollIntoViewOptions` | - |
| show-close | whether to show a close button | `boolean` | `true` |
| close-icon | custom close icon, default is Close | `string` \| `Component` | - |

### TourStep slots

| Name | Description |
| ------------------- | ---------------------------- |
| default | description |
| title | title |

### TourStep events

| Name | Description | Arguments |
| ----------- | ----------------------------- | ---------- |
| close | callback function on shutdown | ^[Function]`() => void` |
43 changes: 43 additions & 0 deletions docs/examples/tour/basic.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<template>
<el-button type="primary" @click="open = true">Begin Tour</el-button>

<el-divider />

<el-space>
<el-button ref="ref1">upload</el-button>
<el-button ref="ref2" type="primary">save</el-button>
<el-button ref="ref3" :icon="MoreFilled" />
</el-space>

<el-tour v-model="open">
<el-tour-step :target="ref1?.$el" title="Upload File">
<img
src="https://element-plus.org/images/element-plus-logo.svg"
alt="tour.png"
/>
<div>Put you files here.</div>
</el-tour-step>
<el-tour-step
:target="ref2?.$el"
title="Save"
description="Save your changes"
/>
<el-tour-step
:target="ref3?.$el"
title="Other Actions"
description="Click to see other"
/>
</el-tour>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { type ElButton } from 'element-plus'
import { MoreFilled } from '@element-plus/icons-vue'
const ref1 = ref<InstanceType<typeof ElButton> | null>(null)
const ref2 = ref<InstanceType<typeof ElButton> | null>(null)
const ref3 = ref<InstanceType<typeof ElButton> | null>(null)
const open = ref(false)
</script>
44 changes: 44 additions & 0 deletions docs/examples/tour/indicator.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<template>
<el-button type="primary" @click="open = true">Begin Tour</el-button>

<el-divider />

<el-space>
<el-button ref="ref1">upload</el-button>
<el-button ref="ref2" type="primary">save</el-button>
<el-button ref="ref3" :icon="MoreFilled" />
</el-space>

<el-tour v-model="open">
<el-tour-step
:target="ref1?.$el"
title="Upload File"
description="Put you files here."
/>
<el-tour-step
:target="ref2?.$el"
title="Save"
description="Save your changes"
/>
<el-tour-step
:target="ref3?.$el"
title="Other Actions"
description="Click to see other"
/>
<template #indicators="{ current, total }">
<span>{{ current + 1 }} / {{ total }}</span>
</template>
</el-tour>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { type ElButton } from 'element-plus'
import { MoreFilled } from '@element-plus/icons-vue'
const ref1 = ref<InstanceType<typeof ElButton> | null>(null)
const ref2 = ref<InstanceType<typeof ElButton> | null>(null)
const ref3 = ref<InstanceType<typeof ElButton> | null>(null)
const open = ref(false)
</script>
58 changes: 58 additions & 0 deletions docs/examples/tour/mask.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<template>
<el-button type="primary" @click="open = true">Begin Tour</el-button>

<el-divider />

<el-space>
<el-button ref="ref1">upload</el-button>
<el-button ref="ref2" type="primary">save</el-button>
<el-button ref="ref3" :icon="MoreFilled" />
</el-space>

<el-tour
v-model="open"
:mask="{
style: {
boxShadow: 'inset 0 0 15px #333',
},
color: 'rgba(80, 255, 255, .4)',
}"
>
<el-tour-step :target="ref1?.$el" title="Upload File">
<img
src="https://element-plus.org/images/element-plus-logo.svg"
alt="tour.png"
/>
<div>Put you files here.</div>
</el-tour-step>
<el-tour-step
:target="ref2?.$el"
title="Save"
description="Save your changes"
:mask="{
style: {
boxShadow: 'inset 0 0 15px #fff',
},
color: 'rgba(40, 0, 255, .4)',
}"
/>
<el-tour-step
:target="ref3?.$el"
title="Other Actions"
description="Click to see other"
:mask="false"
/>
</el-tour>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { type ElButton } from 'element-plus'
import { MoreFilled } from '@element-plus/icons-vue'
const ref1 = ref<InstanceType<typeof ElButton> | null>(null)
const ref2 = ref<InstanceType<typeof ElButton> | null>(null)
const ref3 = ref<InstanceType<typeof ElButton> | null>(null)
const open = ref(false)
</script>
41 changes: 41 additions & 0 deletions docs/examples/tour/non-modal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<template>
<el-button type="primary" @click="open = true">Begin Tour</el-button>

<el-divider />

<el-space>
<el-button ref="ref1">upload</el-button>
<el-button ref="ref2" type="primary">save</el-button>
<el-button ref="ref3" :icon="MoreFilled" />
</el-space>

<el-tour v-model="open" type="primary" :mask="false">
<el-tour-step
:target="ref1?.$el"
title="Upload File"
description="Put you files here."
/>
<el-tour-step
:target="ref2?.$el"
title="Save"
description="Save your changes"
/>
<el-tour-step
:target="ref3?.$el"
title="Other Actions"
description="Click to see other"
/>
</el-tour>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { type ElButton } from 'element-plus'
import { MoreFilled } from '@element-plus/icons-vue'
const ref1 = ref<InstanceType<typeof ElButton> | null>(null)
const ref2 = ref<InstanceType<typeof ElButton> | null>(null)
const ref3 = ref<InstanceType<typeof ElButton> | null>(null)
const open = ref(false)
</script>
33 changes: 33 additions & 0 deletions docs/examples/tour/placement.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<template>
<el-button ref="btnRef" type="primary" @click="open = true">
Begin Tour
</el-button>

<el-tour v-model="open">
<el-tour-step
title="Center"
description="Displayed in the center of screen."
/>
<el-tour-step
title="Right"
description="On the right of target."
placement="right"
:target="btnRef?.$el"
/>
<el-tour-step
title="Top"
description="On the top of target."
placement="top"
:target="btnRef?.$el"
/>
</el-tour>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { type ElButton } from 'element-plus'
const btnRef = ref<InstanceType<typeof ElButton> | null>(null)
const open = ref(false)
</script>
1 change: 1 addition & 0 deletions packages/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export * from './tree-v2'
export * from './upload'
export * from './virtual-list'
export * from './watermark'
export * from './tour'

// plugins
export * from './infinite-scroll'
Expand Down
Empty file.
Empty file.
Loading

0 comments on commit 2fd7ba8

Please sign in to comment.