Confusing interactions around linked autocomplete items and client-side routing #629
Replies: 1 comment 2 replies
-
Thanks again for this piece of feedback. Having the keyboard navigator separated from click events is a design decision that we took to keep the click navigation accessible: opening the link on click, and respecting browser's events on modifier clicks (Ctrl, Cmd, Shift). I agree that this is easy to forget when implementing your templates though, so the developer experience suffers from this UX decision. Regarding your specific issue about using your app's router when clicking on a link, it depends on your framework solution. For instance, using Next, you would use their Router API in the Autocomplete's If we had taken a hard decision of handling links for you, you wouldn't have been able to flexibly use your custom router's implementation (except perhaps with alternative APIs to declare your link component of choice, which we might revisit later). A note about frameworks' specific link component depending on their contextIn frameworks like Next, the Therefore, you need to wrap your render call with your framework's Context: import ReactDOM from 'react-dom';
import { createElement, Fragment } from 'react';
import { RouterContext } from 'next/dist/next-server/lib/router-context';
import { autocomplete } from '@algolia/autocomplete-js';
export const createSearch = ({ router, ...props }) => {
return autocomplete({
...props,
renderer: { createElement, Fragment },
navigator: {
navigate({ itemUrl }) {
router.push(itemUrl);
},
},
render: ({ children }, root) => {
ReactDOM.render(
<RouterContext.Provider value={router}>
<>{children}</>
</RouterContext.Provider>,
root
);
},
});
}; I hope that clears things out for you. We're aware that this API is not optimal yet, and your suggestion about providing the |
Beta Was this translation helpful? Give feedback.
-
I have a relatively straightforward autocomplete where the items returned by one of my sources should be links that navigate the user to a whole different page when they're clicked (or selected w/ the keyboard). I'm using
getItemUrl
to activate keyboard navigation, which works great.Defining
getItemUrl
does not seem to automatically activate link-like treatment for selecting an item by clicking on it. This honestly surprised me, and I'm finding it hard to see when it'd make sense to have items behave like links when using the keyboard, but notonClick
. So I think it's worth considering having the presence ofgetItemUrl
define some click listeners too.Nevertheless, I tried to implement the behavior myself, and it seemed like the easiest (and, based on some past issues, perhaps suggested) way was to simply use an
<a>
tag, to leverage the browser's built-in logic for handling clicks. Going down that road led to a different issue, though: I have a single page app that useshistory.pushState
for navigation, and simply using an<a>
tag will trigger a hard page refresh that I don't want. So, I went down the road ofe.preventDefault(); ... history.pushState(...);
. At that point, though,Cmd/Ctrl + Click
andShift+Click
naturally stopped opening the item in a new tab/window, so I found myself faced with detecting the various modifier keys myself and re-implementing the various methods from the navigator API in myonClick
listener. To simplify this, it would've been nice to have access to the navigator instance in my templates. Although I still would've needed to detect the various modifier keys, so perhaps that goes back to my original suggestion that havinggetItemUrl
drive both keyboard + mouse navigation might be ideal.Beta Was this translation helpful? Give feedback.
All reactions