mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
fix(components): [popper] fix arrow overflow issue (#20049)
* fix(components): [popper] fix arrow overflow issue Add popperArrowProp to popperContentProps to ensure usePopper correctly applies arrow options, preventing the arrow from overflowing the popper container edges. * fix(components): [popper] change arrowOffset to ref for reactivity * feat(components): [tooltip] add arrow-offset property - Allow users to control the padding of the tooltip arrow - Prevents the arrow from touching the popper's edge Reference: https://popper.js.org/docs/v2/modifiers/arrow/#padding * fix(components): [popper] add reactive watch for arrowOffset prop * feat(components): [popper] remove unused arrowOffset prop Removes unused arrowOffset prop and related logic - Removes arrowOffset from PopperContentInjectionContext - Removes arrowOffset prop watching and state management - Cleans up related test cases * docs(components): [tooltip] update version requirement update version requirement for arrow-offset prop * docs(components): [tooltip] update `arrow-offset` version * Update docs/en-US/component/tooltip.md Co-authored-by: kooriookami <38392315+kooriookami@users.noreply.github.com> --------- Co-authored-by: sea <45450994+warmthsea@users.noreply.github.com> Co-authored-by: kooriookami <38392315+kooriookami@users.noreply.github.com>
This commit is contained in:
@@ -173,6 +173,7 @@ tooltip/append-to
|
||||
| offset | offset of the Tooltip | ^[number] | 12 |
|
||||
| transition | animation name | ^[string] | — |
|
||||
| popper-options | [popper.js](https://popper.js.org/docs/v2/) parameters | ^[object]refer to [popper.js](https://popper.js.org/docs/v2/) doc | {} |
|
||||
| arrow-offset ^(2.9.10) | Controls the offset (padding) of the tooltip’s arrow relative to the popper. | ^[number] | 5 |
|
||||
| show-after | delay of appearance, in millisecond | ^[number] | 0 |
|
||||
| show-arrow | whether the tooltip content has an arrow | ^[boolean] | true |
|
||||
| hide-after | delay of disappear, in millisecond | ^[number] | 200 |
|
||||
|
||||
@@ -9,7 +9,6 @@ import type { PopperArrowInstance } from '../src/arrow'
|
||||
|
||||
const popperContentInjection = {
|
||||
arrowRef: ref(null),
|
||||
arrowOffset: ref(0),
|
||||
}
|
||||
|
||||
const mountArrow = () =>
|
||||
@@ -32,22 +31,10 @@ describe('<ElPopperArrow />', () => {
|
||||
afterEach(() => {
|
||||
wrapper?.unmount()
|
||||
popperContentInjection.arrowRef.value = null
|
||||
popperContentInjection.arrowOffset.value = 0
|
||||
})
|
||||
|
||||
it('should set the arrowRef after mounted', async () => {
|
||||
expect(popperContentInjection.arrowRef.value).toBe(wrapper.vm.arrowRef)
|
||||
expect(popperContentInjection.arrowOffset.value).toBe(0)
|
||||
})
|
||||
|
||||
it('should update the offset after props changed', async () => {
|
||||
expect(popperContentInjection.arrowOffset.value).toBe(0)
|
||||
|
||||
await wrapper.setProps({
|
||||
arrowOffset: 10,
|
||||
})
|
||||
|
||||
expect(popperContentInjection.arrowOffset.value).toBe(10)
|
||||
})
|
||||
|
||||
it('should unset arrowRef before unmount', async () => {
|
||||
|
||||
@@ -8,30 +8,21 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { inject, onBeforeUnmount, watch } from 'vue'
|
||||
import { inject, onBeforeUnmount } from 'vue'
|
||||
import { useNamespace } from '@element-plus/hooks'
|
||||
import { POPPER_CONTENT_INJECTION_KEY } from './constants'
|
||||
import { popperArrowProps } from './arrow'
|
||||
|
||||
defineOptions({
|
||||
name: 'ElPopperArrow',
|
||||
inheritAttrs: false,
|
||||
})
|
||||
|
||||
const props = defineProps(popperArrowProps)
|
||||
|
||||
const ns = useNamespace('popper')
|
||||
const { arrowOffset, arrowRef, arrowStyle } = inject(
|
||||
const { arrowRef, arrowStyle } = inject(
|
||||
POPPER_CONTENT_INJECTION_KEY,
|
||||
undefined
|
||||
)!
|
||||
|
||||
watch(
|
||||
() => props.arrowOffset,
|
||||
(val) => {
|
||||
arrowOffset.value = val
|
||||
}
|
||||
)
|
||||
onBeforeUnmount(() => {
|
||||
arrowRef.value = undefined
|
||||
})
|
||||
|
||||
@@ -17,7 +17,7 @@ export const usePopperContent = (props: PopperContentProps) => {
|
||||
)!
|
||||
|
||||
const arrowRef = ref<HTMLElement>()
|
||||
const arrowOffset = ref<number>()
|
||||
const arrowOffset = computed(() => props.arrowOffset)
|
||||
|
||||
const eventListenerModifier = computed(() => {
|
||||
return {
|
||||
|
||||
@@ -20,7 +20,6 @@ export type ElPopperInjectionContext = {
|
||||
|
||||
export type ElPopperContentInjectionContext = {
|
||||
arrowRef: Ref<HTMLElement | undefined>
|
||||
arrowOffset: Ref<number | undefined>
|
||||
arrowStyle: ComputedRef<CSSProperties>
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { placements } from '@popperjs/core'
|
||||
import { buildProps, definePropType } from '@element-plus/utils'
|
||||
import { useAriaProps } from '@element-plus/hooks'
|
||||
import { popperArrowProps } from './arrow'
|
||||
|
||||
import type { PopperEffect } from './popper'
|
||||
import type { ExtractPropTypes, StyleValue } from 'vue'
|
||||
@@ -66,6 +67,7 @@ export type PopperCoreConfigProps = ExtractPropTypes<
|
||||
|
||||
export const popperContentProps = buildProps({
|
||||
...popperCoreConfigProps,
|
||||
...popperArrowProps,
|
||||
id: String,
|
||||
style: {
|
||||
type: definePropType<StyleValue>([String, Array, Object]),
|
||||
|
||||
@@ -25,15 +25,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
inject,
|
||||
onBeforeUnmount,
|
||||
onMounted,
|
||||
provide,
|
||||
ref,
|
||||
unref,
|
||||
watch,
|
||||
} from 'vue'
|
||||
import { inject, onBeforeUnmount, onMounted, provide, unref, watch } from 'vue'
|
||||
import { isNil } from 'lodash-unified'
|
||||
import { NOOP, isElement } from '@element-plus/utils'
|
||||
import ElFocusTrap from '@element-plus/components/focus-trap'
|
||||
@@ -84,12 +76,10 @@ const {
|
||||
})
|
||||
|
||||
const formItemContext = inject(formItemContextKey, undefined)
|
||||
const arrowOffset = ref<number>()
|
||||
|
||||
provide(POPPER_CONTENT_INJECTION_KEY, {
|
||||
arrowStyle,
|
||||
arrowRef,
|
||||
arrowOffset,
|
||||
})
|
||||
|
||||
if (formItemContext) {
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
:offset="offset"
|
||||
:placement="placement"
|
||||
:popper-options="popperOptions"
|
||||
:arrow-offset="arrowOffset"
|
||||
:strategy="strategy"
|
||||
:effect="effect"
|
||||
:enterable="enterable"
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
:popper-style="popperStyle"
|
||||
:placement="placement"
|
||||
:popper-options="popperOptions"
|
||||
:arrow-offset="arrowOffset"
|
||||
:pure="pure"
|
||||
:raw-content="rawContent"
|
||||
:reference-el="referenceEl"
|
||||
@@ -42,7 +43,7 @@
|
||||
<span v-if="rawContent" v-html="content" />
|
||||
<span v-else>{{ content }}</span>
|
||||
</slot>
|
||||
<el-popper-arrow v-if="showArrow" :arrow-offset="arrowOffset" />
|
||||
<el-popper-arrow v-if="showArrow" />
|
||||
</el-tooltip-content>
|
||||
</el-popper>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user