fix(combobox): Fix search issues when modifying the middle of the input word (#2085)

This commit is contained in:
Gyulai Levente 2023-10-17 13:52:10 +02:00 committed by GitHub
parent 5e8e417ae9
commit dcf3a4b0bd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 51 additions and 22 deletions

View file

@ -0,0 +1,5 @@
---
'@lion/ui': patch
---
Fix search issues when modifying the middle of the input word in LionCombobox.

View file

@ -849,7 +849,9 @@ export class LionCombobox extends LocalizeMixin(OverlayMixin(LionListbox)) {
* @protected
*/
_handleAutocompletion() {
const hasSelection = this._inputNode.value.length !== this._inputNode.selectionStart;
const isSelectionEmpty = this._inputNode.selectionStart === this._inputNode.selectionEnd;
const hasSelection =
!isSelectionEmpty && this._inputNode.value.length !== this._inputNode.selectionStart;
const inputValue = this._inputNode.value;
const inputSelectionStart = this._inputNode.selectionStart;

View file

@ -63,39 +63,33 @@ export function mimicKeyPress(el, key) {
export async function mimicUserTypingAdvanced(el, values) {
const { _inputNode } = getComboboxMembers(el);
_inputNode.dispatchEvent(new Event('focusin', { bubbles: true }));
let cursorPosition = _inputNode.selectionStart || 0;
for (const key of values) {
// eslint-disable-next-line no-await-in-loop, no-loop-func
await new Promise(resolve => {
const hasSelection = _inputNode.selectionStart !== _inputNode.selectionEnd;
const selectionStart = _inputNode.selectionStart || 0;
const selectionEnd = _inputNode.selectionEnd || 0;
const hasSelection = selectionStart !== selectionEnd;
if (key === 'Backspace') {
if (hasSelection) {
_inputNode.value =
_inputNode.value.slice(
0,
_inputNode.selectionStart ? _inputNode.selectionStart : undefined,
) +
_inputNode.value.slice(
_inputNode.selectionEnd ? _inputNode.selectionEnd : undefined,
_inputNode.value.length,
);
} else {
_inputNode.value = _inputNode.value.slice(0, -1);
_inputNode.value.slice(0, selectionStart) + _inputNode.value.slice(selectionEnd);
cursorPosition = selectionStart;
} else if (cursorPosition > 0) {
_inputNode.value =
_inputNode.value.slice(0, cursorPosition - 1) + _inputNode.value.slice(cursorPosition);
cursorPosition -= 1;
}
} else if (hasSelection) {
_inputNode.value =
_inputNode.value.slice(
0,
_inputNode.selectionStart ? _inputNode.selectionStart : undefined,
) +
key +
_inputNode.value.slice(
_inputNode.selectionEnd ? _inputNode.selectionEnd : undefined,
_inputNode.value.length,
);
_inputNode.value.slice(0, selectionStart) + key + _inputNode.value.slice(selectionEnd);
cursorPosition = selectionStart + key.length;
} else {
_inputNode.value += key;
_inputNode.value =
_inputNode.value.slice(0, cursorPosition) + key + _inputNode.value.slice(cursorPosition);
cursorPosition += 1;
}
mimicKeyPress(_inputNode, key);

View file

@ -1610,6 +1610,34 @@ describe('lion-combobox', () => {
expect(el.checkedIndex).to.equal(0);
});
it('filters options correctly when changing the middle of the word', async () => {
const el = /** @type {LionCombobox} */ (
await fixture(html`
<lion-combobox name="foo" autocomplete="list" match-mode="all">
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
<lion-option .choiceValue="${'Chard'}">Chard</lion-option>
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
</lion-combobox>
`)
);
const { _inputNode } = getComboboxMembers(el);
mimicUserTyping(el, 'char');
expect(_inputNode.value).to.equal('char');
await el.updateComplete; // Char
expect(getFilteredOptionValues(el)).to.eql(['Chard']);
_inputNode.setSelectionRange(3, 3);
await mimicUserTypingAdvanced(el, ['Backspace', 'i', 'c', 'o']);
await el.updateComplete; // Chicor
expect(_inputNode.value).to.equal('chicor');
expect(getFilteredOptionValues(el)).to.eql(['Chicory']);
});
it('computation of "user intends autofill" works correctly afer autofill', async () => {
const el = /** @type {LionCombobox} */ (
await fixture(html`