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 * @protected
*/ */
_handleAutocompletion() { _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 inputValue = this._inputNode.value;
const inputSelectionStart = this._inputNode.selectionStart; const inputSelectionStart = this._inputNode.selectionStart;

View file

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

View file

@ -1610,6 +1610,34 @@ describe('lion-combobox', () => {
expect(el.checkedIndex).to.equal(0); 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 () => { it('computation of "user intends autofill" works correctly afer autofill', async () => {
const el = /** @type {LionCombobox} */ ( const el = /** @type {LionCombobox} */ (
await fixture(html` await fixture(html`