mirror of
https://github.com/element-plus/element-plus.git
synced 2024-12-21 02:50:11 +08:00
9b23b1c9ec
Co-authored-by: 三咲智子 <sxzz@sxzz.moe>
67 lines
1.7 KiB
TypeScript
67 lines
1.7 KiB
TypeScript
import { ref } from 'vue'
|
|
|
|
import type { ShallowRef } from 'vue'
|
|
|
|
// Keep input cursor in the correct position when we use formatter.
|
|
export function useCursor(
|
|
input: ShallowRef<HTMLInputElement | undefined>
|
|
): [() => void, () => void] {
|
|
const selectionRef = ref<{
|
|
selectionStart?: number
|
|
selectionEnd?: number
|
|
value?: string
|
|
beforeTxt?: string
|
|
afterTxt?: string
|
|
}>()
|
|
|
|
function recordCursor() {
|
|
if (input.value == undefined) return
|
|
|
|
const { selectionStart, selectionEnd, value } = input.value
|
|
|
|
if (selectionStart == null || selectionEnd == null) return
|
|
|
|
const beforeTxt = value.slice(0, Math.max(0, selectionStart))
|
|
const afterTxt = value.slice(Math.max(0, selectionEnd))
|
|
|
|
selectionRef.value = {
|
|
selectionStart,
|
|
selectionEnd,
|
|
value,
|
|
beforeTxt,
|
|
afterTxt,
|
|
}
|
|
}
|
|
function setCursor() {
|
|
if (input.value == undefined || selectionRef.value == undefined) return
|
|
|
|
const { value } = input.value
|
|
const { beforeTxt, afterTxt, selectionStart } = selectionRef.value
|
|
|
|
if (
|
|
beforeTxt == undefined ||
|
|
afterTxt == undefined ||
|
|
selectionStart == undefined
|
|
)
|
|
return
|
|
|
|
let startPos = value.length
|
|
|
|
if (value.endsWith(afterTxt)) {
|
|
startPos = value.length - afterTxt.length
|
|
} else if (value.startsWith(beforeTxt)) {
|
|
startPos = beforeTxt.length
|
|
} else {
|
|
const beforeLastChar = beforeTxt[selectionStart - 1]
|
|
const newIndex = value.indexOf(beforeLastChar, selectionStart - 1)
|
|
if (newIndex !== -1) {
|
|
startPos = newIndex + 1
|
|
}
|
|
}
|
|
|
|
input.value.setSelectionRange(startPos, startPos)
|
|
}
|
|
|
|
return [recordCursor, setCursor]
|
|
}
|