mirror of
https://github.com/fergalmoran/turnstone.git
synced 2025-12-25 11:17:59 +00:00
Add displayField as second onSelect argument
This commit is contained in:
@@ -5,6 +5,7 @@ import autocompleteStyles from './styles/autocomplete.module.css'
|
|||||||
import defaultListbox from '../_shared/defaultListbox'
|
import defaultListbox from '../_shared/defaultListbox'
|
||||||
import ItemContents from './components/itemContents/itemContents'
|
import ItemContents from './components/itemContents/itemContents'
|
||||||
import GroupName from './components/groupName/groupName'
|
import GroupName from './components/groupName/groupName'
|
||||||
|
import undef from '../../src/lib/utils/undef'
|
||||||
|
|
||||||
const maxItems = 10
|
const maxItems = 10
|
||||||
const placeholder = 'Enter a city or airport'
|
const placeholder = 'Enter a city or airport'
|
||||||
@@ -34,9 +35,14 @@ const listbox = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
const App = () => {
|
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(
|
const onEnter = useCallback(
|
||||||
(query, selectedResult) => {
|
(query, selectedResult) => {
|
||||||
@@ -78,11 +84,11 @@ const App = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
{selected && (
|
{!!selected.item && (
|
||||||
<div className={styles.selected}>
|
<div className={styles.selected}>
|
||||||
<strong>Selected Result</strong><br />
|
<strong>Selected Result</strong><br />
|
||||||
{selected.name}<br />
|
{selected.item[selected.displayField]}<br />
|
||||||
Coords: {selected.coords}
|
Coords: {selected.item.coords}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -63,18 +63,20 @@ export const useHighlight = (highlighted, hasFocus, queryInput, typeaheadInput)
|
|||||||
|
|
||||||
export const useSelected = (selected, queryInput, typeaheadInput, onSelect) => {
|
export const useSelected = (selected, queryInput, typeaheadInput, onSelect) => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let callbackValue
|
let value, displayField
|
||||||
|
|
||||||
if (isUndefined(selected)) {
|
if (isUndefined(selected)) {
|
||||||
callbackValue = undef
|
value = undef
|
||||||
|
displayField = undef
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
typeaheadInput.current.value = ''
|
typeaheadInput.current.value = ''
|
||||||
queryInput.current.blur()
|
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])
|
}, [selected, onSelect])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -132,7 +132,8 @@ describe('useSelected', () => {
|
|||||||
value: {
|
value: {
|
||||||
name: queryValue,
|
name: queryValue,
|
||||||
coords: '41.882304590139135, -87.62327214400634'
|
coords: '41.882304590139135, -87.62327214400634'
|
||||||
}
|
},
|
||||||
|
displayField: 'name'
|
||||||
}
|
}
|
||||||
|
|
||||||
test('Side effects of item selection occur correctly', () => {
|
test('Side effects of item selection occur correctly', () => {
|
||||||
@@ -143,7 +144,7 @@ describe('useSelected', () => {
|
|||||||
expect(queryRef.current.value).toBe(queryValue)
|
expect(queryRef.current.value).toBe(queryValue)
|
||||||
expect(queryRef.current.blur).toHaveBeenCalledTimes(1)
|
expect(queryRef.current.blur).toHaveBeenCalledTimes(1)
|
||||||
expect(typeaheadRef.current.value).toBe('')
|
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', () => {
|
test('Side effects do not occur if selected item is undefined', () => {
|
||||||
@@ -153,7 +154,7 @@ describe('useSelected', () => {
|
|||||||
renderHook(() => useSelected(undef, queryRef, typeaheadRef, onSelect))
|
renderHook(() => useSelected(undef, queryRef, typeaheadRef, onSelect))
|
||||||
expect(queryRef.current.blur).toHaveBeenCalledTimes(0)
|
expect(queryRef.current.blur).toHaveBeenCalledTimes(0)
|
||||||
expect(typeaheadRef.current.value).toBe(queryValue)
|
expect(typeaheadRef.current.value).toBe(queryValue)
|
||||||
expect(onSelect).toHaveBeenCalledWith(undef)
|
expect(onSelect).toHaveBeenCalledWith(undef, undef)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ export const fetcher = (query, listbox, defaultListbox, minQueryLength, maxItems
|
|||||||
groupId: listboxProp[groupIndex].id,
|
groupId: listboxProp[groupIndex].id,
|
||||||
groupName: listboxProp[groupIndex].name,
|
groupName: listboxProp[groupIndex].name,
|
||||||
searchType: listboxProp[groupIndex].searchType,
|
searchType: listboxProp[groupIndex].searchType,
|
||||||
|
displayField: listboxProp[groupIndex].displayField,
|
||||||
defaultListbox: isDefaultListbox
|
defaultListbox: isDefaultListbox
|
||||||
}))
|
}))
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ const server = setupServer(
|
|||||||
|
|
||||||
const apiListbox = [
|
const apiListbox = [
|
||||||
{
|
{
|
||||||
|
id: 'books',
|
||||||
name: 'Books',
|
name: 'Books',
|
||||||
ratio: 4,
|
ratio: 4,
|
||||||
displayField: 'title',
|
displayField: 'title',
|
||||||
@@ -61,25 +62,41 @@ describe('Fetching API data', () => {
|
|||||||
value: { title: 'Last Argument of Kings', author: 'Joe Abercrombie' },
|
value: { title: 'Last Argument of Kings', author: 'Joe Abercrombie' },
|
||||||
text: 'Last Argument of Kings',
|
text: 'Last Argument of Kings',
|
||||||
groupIndex: 0,
|
groupIndex: 0,
|
||||||
groupName: 'Books'
|
groupName: 'Books',
|
||||||
|
defaultListbox: undef,
|
||||||
|
displayField: 'title',
|
||||||
|
groupId: 'books',
|
||||||
|
searchType: undef
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: { title: 'Legend', author: 'Marie Lu' },
|
value: { title: 'Legend', author: 'Marie Lu' },
|
||||||
text: 'Legend',
|
text: 'Legend',
|
||||||
groupIndex: 0,
|
groupIndex: 0,
|
||||||
groupName: 'Books'
|
groupName: 'Books',
|
||||||
|
defaultListbox: undef,
|
||||||
|
displayField: 'title',
|
||||||
|
groupId: 'books',
|
||||||
|
searchType: undef
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: { title: 'Life After Life', author: 'Kate Atkinson' },
|
value: { title: 'Life After Life', author: 'Kate Atkinson' },
|
||||||
text: 'Life After Life',
|
text: 'Life After Life',
|
||||||
groupIndex: 0,
|
groupIndex: 0,
|
||||||
groupName: 'Books'
|
groupName: 'Books',
|
||||||
|
defaultListbox: undef,
|
||||||
|
displayField: 'title',
|
||||||
|
groupId: 'books',
|
||||||
|
searchType: undef
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: { title: 'Like Water for Chocolate', author: 'Laura Esquivel' },
|
value: { title: 'Like Water for Chocolate', author: 'Laura Esquivel' },
|
||||||
text: 'Like Water for Chocolate',
|
text: 'Like Water for Chocolate',
|
||||||
groupIndex: 0,
|
groupIndex: 0,
|
||||||
groupName: 'Books'
|
groupName: 'Books',
|
||||||
|
defaultListbox: undef,
|
||||||
|
displayField: 'title',
|
||||||
|
groupId: 'books',
|
||||||
|
searchType: undef
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 'Legume',
|
value: 'Legume',
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ const listboxRules = PropTypes.oneOfType([
|
|||||||
PropTypes.array
|
PropTypes.array
|
||||||
]).isRequired,
|
]).isRequired,
|
||||||
searchType: PropTypes.oneOf(searchTypes),
|
searchType: PropTypes.oneOf(searchTypes),
|
||||||
displayField: PropTypes.string,
|
displayField: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
||||||
id: PropTypes.string,
|
id: PropTypes.string,
|
||||||
name: PropTypes.string.isRequired,
|
name: PropTypes.string.isRequired,
|
||||||
ratio: PropTypes.number
|
ratio: PropTypes.number
|
||||||
@@ -59,7 +59,7 @@ const listboxRules = PropTypes.oneOfType([
|
|||||||
PropTypes.array
|
PropTypes.array
|
||||||
]).isRequired,
|
]).isRequired,
|
||||||
searchType: PropTypes.oneOf(searchTypes),
|
searchType: PropTypes.oneOf(searchTypes),
|
||||||
displayField: PropTypes.string
|
displayField: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
||||||
})
|
})
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -72,7 +72,6 @@ Turnstone.propTypes = {
|
|||||||
defaultListbox: listboxRules,
|
defaultListbox: listboxRules,
|
||||||
defaultListboxIsImmutable: PropTypes.bool,
|
defaultListboxIsImmutable: PropTypes.bool,
|
||||||
disabled: PropTypes.bool,
|
disabled: PropTypes.bool,
|
||||||
displayField: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
||||||
errorMessage: PropTypes.string,
|
errorMessage: PropTypes.string,
|
||||||
id: PropTypes.string,
|
id: PropTypes.string,
|
||||||
listbox: listboxRules.isRequired,
|
listbox: listboxRules.isRequired,
|
||||||
|
|||||||
Reference in New Issue
Block a user