From c762a77c7691bf893e50bc4de03805e0d3268d5e Mon Sep 17 00:00:00 2001 From: Tom Southall Date: Tue, 15 Mar 2022 13:20:15 +0000 Subject: [PATCH] Ensure a no-items message is displayed if a query is entered but no items have ever been loaded --- CHANGELOG.md | 1 + src/lib/components/container.jsx | 2 +- src/lib/context/state.jsx | 2 +- src/lib/reducers/reducer.js | 11 ++++++----- src/lib/reducers/reducer.test.js | 22 ++++++++++++---------- 5 files changed, 21 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1bf0081..686de2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### 1.1.2 (15 Mar 2022) +- Ensure a no-items message is displayed if a query is entered but no items have ever been loaded - Do not do any text matching in default listbox - Pass the highlighted state to custom Item component - Only show a transparent background on input box if there is no typeahead diff --git a/src/lib/components/container.jsx b/src/lib/components/container.jsx index 307ed49..57e18d2 100644 --- a/src/lib/components/container.jsx +++ b/src/lib/components/container.jsx @@ -81,7 +81,7 @@ export default function Container(props) { const hasTypeahead = typeahead && state.items.length > 1 const hasClearButton = clearButton && !!state.query const hasCancelButton = cancelButton && hasFocus - const isExpanded = hasFocus && state.itemsLoaded + const isExpanded = hasFocus && state.canShowListbox const isErrorExpanded = !!props.errorMessage && state.itemsError const containerClassname = hasFocus ? 'containerFocus' : 'container' const containerStyles = customStyles[containerClassname] || customStyles.container diff --git a/src/lib/context/state.jsx b/src/lib/context/state.jsx index 7b3ac23..71ee72a 100644 --- a/src/lib/context/state.jsx +++ b/src/lib/context/state.jsx @@ -12,7 +12,7 @@ const StateContextProvider = (props) => { query: text, items, itemsError: false, - itemsLoaded: false, + canShowListbox: false, highlighted: undef, selected: undef, customStyles: styles, diff --git a/src/lib/reducers/reducer.js b/src/lib/reducers/reducer.js index 63712ee..c67652b 100644 --- a/src/lib/reducers/reducer.js +++ b/src/lib/reducers/reducer.js @@ -14,6 +14,7 @@ const reducer = (state, action) => { switch (action.type) { case types.SET_QUERY: newState = { + canShowListbox: !!action.query.length, itemsError: false, query: action.query, selected: undef @@ -21,11 +22,11 @@ const reducer = (state, action) => { // Disallow listbox until user has entered a long enough query if(action.query.length < state.props.minQueryLength) - newState.itemsLoaded = false + newState.canShowListbox = false // Allow listbox if there is no query and we have default items to show if(action.query.length === 0 && state.props.defaultListbox) - newState.itemsLoaded = true + newState.canShowListbox = true return newState case types.SET_ITEMS: @@ -36,7 +37,7 @@ const reducer = (state, action) => { ? highlightedItem(0, action.items) : undef } - if(action.items.length) newState.itemsLoaded = true + if(action.items.length) newState.canShowListbox = true return newState case types.CLEAR: @@ -44,7 +45,7 @@ const reducer = (state, action) => { query: '', items: [], itemsError: false, - itemsLoaded: false, + canShowListbox: false, highlighted: undef, selected: undef } @@ -52,7 +53,7 @@ const reducer = (state, action) => { return { items: [], itemsError: true, - itemsLoaded: false + canShowListbox: false } case types.SET_HIGHLIGHTED: return { highlighted: highlightedItem(action.index, state.items) } diff --git a/src/lib/reducers/reducer.test.js b/src/lib/reducers/reducer.test.js index f8e1d06..ad65e63 100644 --- a/src/lib/reducers/reducer.test.js +++ b/src/lib/reducers/reducer.test.js @@ -7,6 +7,7 @@ import { defaultListbox } from '../../../examples/_shared/defaultListbox' describe('SET_QUERY action', () => { test('produces expected new state', () => { const state = { + canShowListbox: false, itemsError: true, query: 'foo', selected: {index: 0, text: 'Foobar'}, @@ -18,6 +19,7 @@ describe('SET_QUERY action', () => { const action = actions.setQuery('bar') expect(reducer(state, action)).toEqual({ + canShowListbox: true, itemsError: false, query: 'bar', selected: undef, @@ -42,7 +44,7 @@ describe('SET_QUERY action', () => { itemsError: false, query: '', selected: undef, - itemsLoaded: false, + canShowListbox: false, props: { minQueryLength: 1 } @@ -62,7 +64,7 @@ describe('SET_QUERY action', () => { itemsError: false, query: 'f', selected: undef, - itemsLoaded: false, + canShowListbox: false, props: { minQueryLength: 3 } @@ -83,7 +85,7 @@ describe('SET_QUERY action', () => { query: '', selected: undef, itemsError: false, - itemsLoaded: true, + canShowListbox: true, props: { minQueryLength: 1, defaultListbox @@ -97,7 +99,7 @@ describe('SET_ITEMS action', () => { const state = { query: 'foo', itemsError: true, - itemsLoaded: false + canShowListbox: false } const items = [ @@ -112,7 +114,7 @@ describe('SET_ITEMS action', () => { query: 'foo', items, itemsError: false, - itemsLoaded: true, + canShowListbox: true, highlighted: { index: 0, text: 'foo' } }) }) @@ -168,7 +170,7 @@ describe('SET_ITEMS action', () => { query: '', items, itemsError: false, - itemsLoaded: true, + canShowListbox: true, highlighted: undef }) }) @@ -184,7 +186,7 @@ describe('SET_ITEMS_ERROR action', () => { {text: 'foofoo'} ], itemsError: false, - itemsLoaded: true + canShowListbox: true } action = actions.setItemsError() @@ -192,7 +194,7 @@ describe('SET_ITEMS_ERROR action', () => { expect(reducer(state, action)).toEqual({ items: [], itemsError: true, - itemsLoaded: false + canShowListbox: false }) }) }) @@ -208,7 +210,7 @@ describe('CLEAR action', () => { {text: 'foofoo'} ], itemsError: true, - itemsLoaded: true, + canShowListbox: true, highlighted: { index: 0, text: 'foo' }, selected: {text: 'foo'} } @@ -219,7 +221,7 @@ describe('CLEAR action', () => { query: '', items: [], itemsError: false, - itemsLoaded: false, + canShowListbox: false, highlighted: undef, selected: undef })