From df64381144c65678e3e2319e3ac92d1d5204c428 Mon Sep 17 00:00:00 2001 From: Yi Zhan Date: Sat, 5 Sep 2026 01:42:22 +0000 Subject: [PATCH] fix(Combobox): keep filter after blur when input has search term Signed-off-by: Yi Zhan --- packages/react-widgets/src/Combobox.tsx | 5 ++- packages/react-widgets/test/Combobox-test.js | 42 ++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/packages/react-widgets/src/Combobox.tsx b/packages/react-widgets/src/Combobox.tsx index 8914bfb89..602afa27f 100644 --- a/packages/react-widgets/src/Combobox.tsx +++ b/packages/react-widgets/src/Combobox.tsx @@ -257,7 +257,10 @@ const ComboboxImpl: Combobox = React.forwardRef(function Combobox( { didHandle(focused) { if (!focused) { - shouldFilter.current = false + const term = inputRef.current?.value ?? accessors.text(currentValue) + if (!term.trim()) { + shouldFilter.current = false + } toggle.close() setSuggestion(null) list.focus(undefined) diff --git a/packages/react-widgets/test/Combobox-test.js b/packages/react-widgets/test/Combobox-test.js index 4da85fc93..77d74045a 100644 --- a/packages/react-widgets/test/Combobox-test.js +++ b/packages/react-widgets/test/Combobox-test.js @@ -181,4 +181,46 @@ describe('Combobox', function () { source: 'listbox', }) }) + + it('should keep the list filtered after blur when the input still has a search term', () => { + let blur = sinon.spy() + let inst = mount( + , + ) + + inst.find('div.rw-combobox').simulateWithTimers('focus') + + inst.find('input.rw-input').simulate('change', { + target: { value: 'asdf' }, + }) + inst.update() + + expect(inst.find('input.rw-input').getDOMNode().value).to.equal('asdf') + expect(inst.find('List').prop('data')).to.have.length(0) + expect(inst.find('.rw-list-empty').text()).to.equal( + 'The filter returned no results', + ) + + inst.find('div.rw-combobox').simulateWithTimers('blur') + inst.update() + + expect(blur.calledOnce).to.equal(true) + expect(inst.find('Popup').prop('open')).to.not.equal(true) + + inst.find('button').first().simulate('click') + inst.update() + + expect(inst.find('input.rw-input').getDOMNode().value).to.equal('asdf') + expect(inst.find('Popup').prop('open')).to.equal(true) + expect(inst.find('List').prop('data')).to.have.length(0) + expect(inst.find('[role="option"]').length).to.equal(0) + expect(inst.find('.rw-list-empty').text()).to.equal( + 'The filter returned no results', + ) + }) })