Skip to content

Commit

Permalink
fix(combobox): Fix search issues when modifying the middle of the inp…
Browse files Browse the repository at this point in the history
…ut word (#2085)
  • Loading branch information
gyulus3 authored Oct 17, 2023
1 parent 5e8e417 commit dcf3a4b
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 22 deletions.
5 changes: 5 additions & 0 deletions .changeset/nine-icons-end.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@lion/ui': patch
---

Fix search issues when modifying the middle of the input word in LionCombobox.
4 changes: 3 additions & 1 deletion packages/ui/components/combobox/src/LionCombobox.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
36 changes: 15 additions & 21 deletions packages/ui/components/combobox/test-helpers/combobox-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
28 changes: 28 additions & 0 deletions packages/ui/components/combobox/test/lion-combobox.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down

0 comments on commit dcf3a4b

Please sign in to comment.