mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
feat(components): [tour] target prop add more type (#15578)
* feat(components): [tour] target prop add more type * docs(components): [tour] target prop add description * docs(components): [tour] add example and version tag
This commit is contained in:
@@ -57,6 +57,16 @@ tour/indicator
|
||||
|
||||
:::
|
||||
|
||||
## Target
|
||||
|
||||
Various parameter passing types of target. The string and Function types are supported since ^(2.5.2).
|
||||
|
||||
:::demo
|
||||
|
||||
tour/target
|
||||
|
||||
:::
|
||||
|
||||
## Tour API
|
||||
|
||||
:::tip
|
||||
@@ -98,21 +108,21 @@ tour-step component configuration with the same name has higher priority
|
||||
|
||||
### 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` | - |
|
||||
| Property | Description | Type | Default |
|
||||
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- |
|
||||
| target | get the element the guide card points to. Empty makes it show in center of screen. the string and Function types are supported since ^(2.5.2). the string type is selectors of document.querySelector. | `HTMLElement` \| `string` \| ^[Function]`() => 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
|
||||
|
||||
|
||||
36
docs/examples/tour/target.vue
Normal file
36
docs/examples/tour/target.vue
Normal file
@@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<el-button type="primary" @click="open = true">Begin Tour</el-button>
|
||||
|
||||
<el-divider />
|
||||
|
||||
<el-space>
|
||||
<el-button id="btn1">upload</el-button>
|
||||
<el-button id="btn2" type="primary">save</el-button>
|
||||
<el-button ref="btnRef" :icon="MoreFilled" />
|
||||
</el-space>
|
||||
|
||||
<el-tour v-model="open">
|
||||
<el-tour-step
|
||||
target="#btn1"
|
||||
title="Upload File"
|
||||
description="Put you files here."
|
||||
/>
|
||||
<el-tour-step :target="el" title="Save" description="Save your changes" />
|
||||
<el-tour-step
|
||||
:target="btnRef?.$el"
|
||||
title="Other Actions"
|
||||
description="Click to see other"
|
||||
/>
|
||||
</el-tour>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { MoreFilled } from '@element-plus/icons-vue'
|
||||
import type { ButtonInstance } from 'element-plus'
|
||||
|
||||
const el = () => document.querySelector<HTMLElement>('#btn2')
|
||||
const btnRef = ref<ButtonInstance>()
|
||||
|
||||
const open = ref(false)
|
||||
</script>
|
||||
@@ -18,7 +18,14 @@ import {
|
||||
offset as offsetMiddelware,
|
||||
shift,
|
||||
} from '@floating-ui/dom'
|
||||
import { hasOwn, isArray, isClient, keysOf } from '@element-plus/utils'
|
||||
import {
|
||||
hasOwn,
|
||||
isArray,
|
||||
isClient,
|
||||
isFunction,
|
||||
isString,
|
||||
keysOf,
|
||||
} from '@element-plus/utils'
|
||||
|
||||
import type {
|
||||
CSSProperties,
|
||||
@@ -40,7 +47,9 @@ import type {
|
||||
} from '@floating-ui/dom'
|
||||
|
||||
export const useTarget = (
|
||||
target: Ref<HTMLElement | null | undefined>,
|
||||
target: Ref<
|
||||
string | HTMLElement | (() => HTMLElement | null) | null | undefined
|
||||
>,
|
||||
open: Ref<boolean>,
|
||||
gap: Ref<TourGap>,
|
||||
mergedMask: Ref<TourMask>,
|
||||
@@ -48,15 +57,28 @@ export const useTarget = (
|
||||
) => {
|
||||
const posInfo: Ref<PosInfo | null> = ref(null)
|
||||
|
||||
const getTargetEl = () => {
|
||||
let targetEl: HTMLElement | null | undefined
|
||||
if (isString(target.value)) {
|
||||
targetEl = document.querySelector<HTMLElement>(target.value)
|
||||
} else if (isFunction(target.value)) {
|
||||
targetEl = target.value()
|
||||
} else {
|
||||
targetEl = target.value
|
||||
}
|
||||
return targetEl
|
||||
}
|
||||
|
||||
const updatePosInfo = () => {
|
||||
if (!target.value || !open.value) {
|
||||
const targetEl = getTargetEl()
|
||||
if (!targetEl || !open.value) {
|
||||
posInfo.value = null
|
||||
return
|
||||
}
|
||||
if (!isInViewPort(target.value) && open.value) {
|
||||
target.value.scrollIntoView(scrollIntoViewOptions.value)
|
||||
if (!isInViewPort(targetEl) && open.value) {
|
||||
targetEl.scrollIntoView(scrollIntoViewOptions.value)
|
||||
}
|
||||
const { left, top, width, height } = target.value.getBoundingClientRect()
|
||||
const { left, top, width, height } = targetEl.getBoundingClientRect()
|
||||
posInfo.value = {
|
||||
left,
|
||||
top,
|
||||
@@ -104,8 +126,9 @@ export const useTarget = (
|
||||
})
|
||||
|
||||
const triggerTarget = computed(() => {
|
||||
if (!mergedMask.value || !target.value || !window.DOMRect) {
|
||||
return target.value || undefined
|
||||
const targetEl = getTargetEl()
|
||||
if (!mergedMask.value || !targetEl || !window.DOMRect) {
|
||||
return targetEl || undefined
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -8,7 +8,9 @@ export const tourStepProps = buildProps({
|
||||
* @description get the element the guide card points to. empty makes it show in center of screen
|
||||
*/
|
||||
target: {
|
||||
type: definePropType<HTMLElement | null>(Object),
|
||||
type: definePropType<
|
||||
string | HTMLElement | (() => HTMLElement | null) | null
|
||||
>([String, Object, Function]),
|
||||
},
|
||||
/**
|
||||
* @description the title of the tour content
|
||||
|
||||
@@ -29,7 +29,7 @@ export interface PosInfo {
|
||||
}
|
||||
|
||||
export interface UsedTourStepProps {
|
||||
target?: HTMLElement | null
|
||||
target?: string | HTMLElement | (() => HTMLElement | null) | null
|
||||
showArrow?: boolean
|
||||
placement?: Placement
|
||||
contentStyle?: CSSProperties
|
||||
|
||||
Reference in New Issue
Block a user