mirror of
https://github.com/youzan/vant.git
synced 2026-01-13 07:03:44 +08:00
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,
|
||||
// record the excess length for correcting the cursor position.
|
||||
// https://github.com/youzan/vant/issues/11289
|
||||
const limitDiffLen =
|
||||
getStringLength(originalValue) - getStringLength(value);
|
||||
const limitDiffLen = originalValue.length - value.length;
|
||||
|
||||
// https://github.com/youzan/vant/issues/13058
|
||||
if (props.type === 'number' || props.type === 'digit') {
|
||||
@@ -368,8 +367,7 @@ export default defineComponent({
|
||||
const bcoVal = cutString(originalValue, selectionEnd!);
|
||||
// Record the length change of `bcoVal` after formatting,
|
||||
// which is used to correct the cursor position.
|
||||
formatterDiffLen =
|
||||
getStringLength(formatter(bcoVal)) - getStringLength(bcoVal);
|
||||
formatterDiffLen = formatter(bcoVal).length - bcoVal.length;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -380,7 +378,7 @@ export default defineComponent({
|
||||
inputRef.value.value = value;
|
||||
|
||||
if (isDef(selectionStart) && isDef(selectionEnd)) {
|
||||
const valueLen = getStringLength(value);
|
||||
const valueLen = value.length;
|
||||
|
||||
if (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'),
|
||||
).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