mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
fix(components): [mention] correct cursor position (#22070)
* fix(components): [mention] correct cursor position * test: add test * fix: use wrapper as a reference
This commit is contained in:
@@ -3,6 +3,7 @@ import { mount } from '@vue/test-utils'
|
||||
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'
|
||||
import Form from '@element-plus/components/form'
|
||||
import Mention from '../src/mention.vue'
|
||||
import * as helper from '../src/helper'
|
||||
|
||||
describe('Mention.vue', () => {
|
||||
beforeEach(() => {
|
||||
@@ -146,4 +147,73 @@ describe('Mention.vue', () => {
|
||||
expect(option.attributes('aria-disabled')).toBe('true')
|
||||
expect(option.classes()).toContain('is-disabled')
|
||||
})
|
||||
|
||||
test('should ensure the cursor position is correct', async () => {
|
||||
vi.spyOn(helper, 'getCursorPosition').mockReturnValue({
|
||||
top: 7,
|
||||
left: 14,
|
||||
height: 21,
|
||||
})
|
||||
|
||||
const wrapper = mount(Mention, {
|
||||
attachTo: document.body,
|
||||
props: { options, style: { marginTop: '100px', marginLeft: '100px' } },
|
||||
})
|
||||
|
||||
const elInputEl = wrapper.find('.el-input').element
|
||||
const inputEl = wrapper.find('input').element
|
||||
|
||||
const mockBoundingClientRect = (
|
||||
el: Element,
|
||||
rect: Partial<DOMRect> = {}
|
||||
) => {
|
||||
const defaultRect: DOMRect = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 100,
|
||||
height: 100,
|
||||
top: 0,
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
toJSON: () => {},
|
||||
}
|
||||
|
||||
return vi
|
||||
.spyOn(el, 'getBoundingClientRect')
|
||||
.mockReturnValue(Object.assign(defaultRect, rect))
|
||||
}
|
||||
|
||||
// Actual information obtained on the browser
|
||||
mockBoundingClientRect(elInputEl, {
|
||||
width: 320,
|
||||
height: 32,
|
||||
left: 100,
|
||||
x: 100,
|
||||
top: 100,
|
||||
y: 100,
|
||||
})
|
||||
mockBoundingClientRect(inputEl, {
|
||||
width: 298,
|
||||
height: 30,
|
||||
left: 111,
|
||||
x: 111,
|
||||
top: 101,
|
||||
y: 101,
|
||||
})
|
||||
|
||||
inputEl.focus()
|
||||
await wrapper.find('input').setValue('@')
|
||||
vi.advanceTimersByTime(150)
|
||||
await nextTick()
|
||||
|
||||
const cursorStyles = wrapper
|
||||
.find('.el-tooltip__trigger')
|
||||
.attributes('style')
|
||||
|
||||
expect(cursorStyles).toContain('left: 125px')
|
||||
expect(cursorStyles).toContain('top: 108px')
|
||||
|
||||
vi.restoreAllMocks()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -259,14 +259,14 @@ const syncCursor = () => {
|
||||
|
||||
const caretPosition = getCursorPosition(inputEl)
|
||||
const inputRect = inputEl.getBoundingClientRect()
|
||||
const elInputRect = elInputRef.value!.$el.getBoundingClientRect()
|
||||
const wrapperRect = wrapperRef.value!.getBoundingClientRect()
|
||||
|
||||
cursorStyle.value = {
|
||||
position: 'absolute',
|
||||
width: 0,
|
||||
height: `${caretPosition.height}px`,
|
||||
left: `${caretPosition.left + inputRect.left - elInputRect.left}px`,
|
||||
top: `${caretPosition.top + inputRect.top - elInputRect.top}px`,
|
||||
left: `${caretPosition.left + inputRect.left - wrapperRect.left}px`,
|
||||
top: `${caretPosition.top + inputRect.top - wrapperRect.top}px`,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user