fix(Field): improve cursor position handling for emoji input and formatting (#13711)
This commit is contained in:
@@ -329,8 +329,7 @@ export default defineComponent({
|
|||||||
// When the value length exceeds maxlength,
|
// When the value length exceeds maxlength,
|
||||||
// record the excess length for correcting the cursor position.
|
// record the excess length for correcting the cursor position.
|
||||||
// https://github.com/youzan/vant/issues/11289
|
// https://github.com/youzan/vant/issues/11289
|
||||||
const limitDiffLen =
|
const limitDiffLen = originalValue.length - value.length;
|
||||||
getStringLength(originalValue) - getStringLength(value);
|
|
||||||
|
|
||||||
// https://github.com/youzan/vant/issues/13058
|
// https://github.com/youzan/vant/issues/13058
|
||||||
if (props.type === 'number' || props.type === 'digit') {
|
if (props.type === 'number' || props.type === 'digit') {
|
||||||
@@ -368,8 +367,7 @@ export default defineComponent({
|
|||||||
const bcoVal = cutString(originalValue, selectionEnd!);
|
const bcoVal = cutString(originalValue, selectionEnd!);
|
||||||
// Record the length change of `bcoVal` after formatting,
|
// Record the length change of `bcoVal` after formatting,
|
||||||
// which is used to correct the cursor position.
|
// which is used to correct the cursor position.
|
||||||
formatterDiffLen =
|
formatterDiffLen = formatter(bcoVal).length - bcoVal.length;
|
||||||
getStringLength(formatter(bcoVal)) - getStringLength(bcoVal);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,7 +378,7 @@ export default defineComponent({
|
|||||||
inputRef.value.value = value;
|
inputRef.value.value = value;
|
||||||
|
|
||||||
if (isDef(selectionStart) && isDef(selectionEnd)) {
|
if (isDef(selectionStart) && isDef(selectionEnd)) {
|
||||||
const valueLen = getStringLength(value);
|
const valueLen = value.length;
|
||||||
|
|
||||||
if (limitDiffLen) {
|
if (limitDiffLen) {
|
||||||
selectionStart -= limitDiffLen;
|
selectionStart -= limitDiffLen;
|
||||||
|
|||||||
@@ -608,3 +608,39 @@ test("should not be set label's for attribute when using input slot", async () =
|
|||||||
wrapper.find('.van-field__label label').attributes('for'),
|
wrapper.find('.van-field__label label').attributes('for'),
|
||||||
).toBeUndefined();
|
).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should update selection range correctly when inputting text into string with emoji', async () => {
|
||||||
|
const wrapper = mount(Field, {
|
||||||
|
props: {
|
||||||
|
maxlength: 2,
|
||||||
|
modelValue: '😀😀',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const input = wrapper.find('input');
|
||||||
|
await input.trigger('focus');
|
||||||
|
|
||||||
|
input.element.value = '😀😀😀';
|
||||||
|
input.element.selectionEnd = 6;
|
||||||
|
input.trigger('input');
|
||||||
|
|
||||||
|
expect(input.element.selectionEnd).toEqual(4);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should update selection range correctly when using formatter with emoji', async () => {
|
||||||
|
const wrapper = mount(Field, {
|
||||||
|
props: {
|
||||||
|
modelValue: '',
|
||||||
|
formatter: (val) => val.replace('1', '😀😀'),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const input = wrapper.find('input');
|
||||||
|
await input.trigger('focus');
|
||||||
|
|
||||||
|
input.element.value = '1';
|
||||||
|
input.element.selectionEnd = 1;
|
||||||
|
input.trigger('input');
|
||||||
|
|
||||||
|
expect(input.element.selectionEnd).toEqual(4);
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user