diff --git a/examples/geo/App.jsx b/examples/geo/App.jsx index 5d808a3..7486afa 100644 --- a/examples/geo/App.jsx +++ b/examples/geo/App.jsx @@ -5,6 +5,7 @@ import autocompleteStyles from './styles/autocomplete.module.css' import defaultListbox from '../_shared/defaultListbox' import ItemContents from './components/itemContents/itemContents' import GroupName from './components/groupName/groupName' +import undef from '../../src/lib/utils/undef' const maxItems = 10 const placeholder = 'Enter a city or airport' @@ -34,9 +35,14 @@ const listbox = [ ] const App = () => { - const [selected, setSelected] = useState() + const [selected, setSelected] = useState({item: undef, displayField: undef}) - const onSelect = sel => setSelected(sel) + const onSelect = useCallback( + (item, displayField) => { + console.log({item, displayField}) + setSelected({item, displayField}) + }, [] + ) const onEnter = useCallback( (query, selectedResult) => { @@ -78,11 +84,11 @@ const App = () => { /> - {selected && ( + {!!selected.item && (
Selected Result
- {selected.name}
- Coords: {selected.coords} + {selected.item[selected.displayField]}
+ Coords: {selected.item.coords}
)} diff --git a/src/lib/components/hooks/containerEffects.js b/src/lib/components/hooks/containerEffects.js index bea01b5..ed7c672 100644 --- a/src/lib/components/hooks/containerEffects.js +++ b/src/lib/components/hooks/containerEffects.js @@ -63,18 +63,20 @@ export const useHighlight = (highlighted, hasFocus, queryInput, typeaheadInput) export const useSelected = (selected, queryInput, typeaheadInput, onSelect) => { useEffect(() => { - let callbackValue + let value, displayField if (isUndefined(selected)) { - callbackValue = undef + value = undef + displayField = undef } else { typeaheadInput.current.value = '' queryInput.current.blur() - callbackValue = selected.value + value = selected.value + displayField = selected.displayField } - if (typeof onSelect === 'function') onSelect(callbackValue) + if (typeof onSelect === 'function') onSelect(value, displayField) }, [selected, onSelect]) } diff --git a/src/lib/components/hooks/containerEffects.test.js b/src/lib/components/hooks/containerEffects.test.js index 31b120c..e36c561 100644 --- a/src/lib/components/hooks/containerEffects.test.js +++ b/src/lib/components/hooks/containerEffects.test.js @@ -132,7 +132,8 @@ describe('useSelected', () => { value: { name: queryValue, coords: '41.882304590139135, -87.62327214400634' - } + }, + displayField: 'name' } test('Side effects of item selection occur correctly', () => { @@ -143,7 +144,7 @@ describe('useSelected', () => { expect(queryRef.current.value).toBe(queryValue) expect(queryRef.current.blur).toHaveBeenCalledTimes(1) expect(typeaheadRef.current.value).toBe('') - expect(onSelect).toHaveBeenCalledWith(selected.value) + expect(onSelect).toHaveBeenCalledWith(selected.value, selected.displayField) }) test('Side effects do not occur if selected item is undefined', () => { @@ -153,7 +154,7 @@ describe('useSelected', () => { renderHook(() => useSelected(undef, queryRef, typeaheadRef, onSelect)) expect(queryRef.current.blur).toHaveBeenCalledTimes(0) expect(typeaheadRef.current.value).toBe(queryValue) - expect(onSelect).toHaveBeenCalledWith(undef) + expect(onSelect).toHaveBeenCalledWith(undef, undef) }) }) diff --git a/src/lib/components/hooks/useData.js b/src/lib/components/hooks/useData.js index dc0b3b3..91153e2 100644 --- a/src/lib/components/hooks/useData.js +++ b/src/lib/components/hooks/useData.js @@ -103,6 +103,7 @@ export const fetcher = (query, listbox, defaultListbox, minQueryLength, maxItems groupId: listboxProp[groupIndex].id, groupName: listboxProp[groupIndex].name, searchType: listboxProp[groupIndex].searchType, + displayField: listboxProp[groupIndex].displayField, defaultListbox: isDefaultListbox })) ] diff --git a/src/lib/components/hooks/useData.test.js b/src/lib/components/hooks/useData.test.js index 6030d02..089235e 100644 --- a/src/lib/components/hooks/useData.test.js +++ b/src/lib/components/hooks/useData.test.js @@ -29,6 +29,7 @@ const server = setupServer( const apiListbox = [ { + id: 'books', name: 'Books', ratio: 4, displayField: 'title', @@ -61,25 +62,41 @@ describe('Fetching API data', () => { value: { title: 'Last Argument of Kings', author: 'Joe Abercrombie' }, text: 'Last Argument of Kings', groupIndex: 0, - groupName: 'Books' + groupName: 'Books', + defaultListbox: undef, + displayField: 'title', + groupId: 'books', + searchType: undef }, { value: { title: 'Legend', author: 'Marie Lu' }, text: 'Legend', groupIndex: 0, - groupName: 'Books' + groupName: 'Books', + defaultListbox: undef, + displayField: 'title', + groupId: 'books', + searchType: undef }, { value: { title: 'Life After Life', author: 'Kate Atkinson' }, text: 'Life After Life', groupIndex: 0, - groupName: 'Books' + groupName: 'Books', + defaultListbox: undef, + displayField: 'title', + groupId: 'books', + searchType: undef }, { value: { title: 'Like Water for Chocolate', author: 'Laura Esquivel' }, text: 'Like Water for Chocolate', groupIndex: 0, - groupName: 'Books' + groupName: 'Books', + defaultListbox: undef, + displayField: 'title', + groupId: 'books', + searchType: undef }, { value: 'Legume', diff --git a/src/lib/index.jsx b/src/lib/index.jsx index 5e050c5..2fa23ac 100644 --- a/src/lib/index.jsx +++ b/src/lib/index.jsx @@ -48,7 +48,7 @@ const listboxRules = PropTypes.oneOfType([ PropTypes.array ]).isRequired, searchType: PropTypes.oneOf(searchTypes), - displayField: PropTypes.string, + displayField: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), id: PropTypes.string, name: PropTypes.string.isRequired, ratio: PropTypes.number @@ -59,7 +59,7 @@ const listboxRules = PropTypes.oneOfType([ PropTypes.array ]).isRequired, searchType: PropTypes.oneOf(searchTypes), - displayField: PropTypes.string + displayField: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), }) ]) @@ -72,7 +72,6 @@ Turnstone.propTypes = { defaultListbox: listboxRules, defaultListboxIsImmutable: PropTypes.bool, disabled: PropTypes.bool, - displayField: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), errorMessage: PropTypes.string, id: PropTypes.string, listbox: listboxRules.isRequired,