-
Notifications
You must be signed in to change notification settings - Fork 516
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(core): provide information about stalled search to widgets #2569
Conversation
This commit adds a new step that can update the UI. In this change, the widgets are rendered when there are new results (previous behaviour) and when the search is found to be stalled. The information is propagated through a new option `searchMetadata` to the render method of the widgets. This is an object that contains the flag `isStalledSearch` that is set to `true` when there are still pending search after a delay (for now 200ms).
Deploy preview ready! Built with commit 737d28e https://deploy-preview-2569--algolia-instantsearch.netlify.com |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice 👍
I clearly prefer this implementation since it's not tightly coupled to the SearchBox widget 🎉
I like the implementation, as discussed earlier in a meeting, some questions still:
Can you provide an example of a widget rendering that would avoid re-rendering when the widget do not care about the isSearchStalled flag? Just curious here how to do it. Finally, for reference, can you provide a small concrete example of what's happening under the hood in a scenario where this is implemented? Something like:
Something like that. So that we all understand fully what's happening. |
This looks really nice, I think we should go this route. I guess we can add some componentShouldUpate hooks? |
That's a very speculative on my side here I guess. I can try to implement it on a widget / connector to see what happens.
Ok I'll do a schema.
I don't know if that's necessary but that can be done, indeed. |
I will move on with this solution and close the other. Thanks for the feedbacks :) |
…tsearch.js into poc/central-loading-state
Hello everyone, This is the final version. Here is the API: InstantSearch constructor / factory has a new option: stalledSearchDelay which configures the time before the stalled search kicks in. We have a new set of options for the loading indicator on the search box: {
/* ... other searchbox options */
loadingIndicator: true,
// or
loadingIndicator: {
template,
cssClasses: {root: ''}
}
} The connector provides a new information to the searchbox rendering: isSearchStalled, if the search is stalled. |
CI failed cause one commit message was too long (merge 1d0aa21) so you might need to rebase |
Thanks @Haroenv :D |
Merge commits are automatically generated and are already standardized by git, therefore there is no point in checking their length. Worst truncating them would make use loose information.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good job 👍
I just left two comments on documentation.
src/widgets/search-box/search-box.js
Outdated
/** | ||
* @typedef {Object} SearchBoxLoadingIndicatorOption | ||
* @property {function|string} template Template used for displaying the button. Can accept a function or a Hogan string. | ||
* @property {{root: string}} [cssClasses] CSS classes added to the reset buton. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be the loading indicator root element.
src/widgets/search-box/search-box.js
Outdated
@@ -173,8 +207,9 @@ searchBox({ | |||
* @property {string|HTMLElement} container CSS Selector or HTMLElement to insert the widget. | |||
* @property {string} [placeholder] Input's placeholder. | |||
* @property {boolean|SearchBoxPoweredByOption} [poweredBy=false] Define if a "powered by Algolia" link should be added near the input. | |||
* @property {boolean|SearchBoxResetOption} [reset=true] Define if a reset button should be added in the input when there is a query. | |||
* @property {boolean|SearchBoxResetOption} [reset=false] Define if a reset button should be added in the input when there is a query. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it an intended change? The default value is still true in the code.
@@ -35,6 +35,8 @@ Full documentation available at https://community.algolia.com/instantsearch.js/c | |||
* @property {function(string)} refine Sets a new query and searches. | |||
* @property {function()} clear Remove the query and perform search. | |||
* @property {Object} widgetParams All original `CustomSearchBoxWidgetOptions` forwarded to the `renderFn`. | |||
* @property {boolean} isSearchStalled `true` if the search results takes more than a certain time to come back |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we document "a certain time"? I would be curious as a dev to know more. This may be too vague
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indeed there is a default value. Will doc that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done (only happen a few lines after :))
src/widgets/search-box/search-box.js
Outdated
|
||
if (loadingIndicator) { | ||
if (isSearchStalled) { | ||
containerNode.firstChild.classList.add('stalled-search'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this CSS class name follow ais- conventions? And be documented somewhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yes sure. Also it doesn't work if you use an input as container :/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe document that part, but I won't be surprised as a dev for it not to be supported.
src/widgets/search-box/search-box.js
Outdated
@@ -173,8 +207,9 @@ searchBox({ | |||
* @property {string|HTMLElement} container CSS Selector or HTMLElement to insert the widget. | |||
* @property {string} [placeholder] Input's placeholder. | |||
* @property {boolean|SearchBoxPoweredByOption} [poweredBy=false] Define if a "powered by Algolia" link should be added near the input. | |||
* @property {boolean|SearchBoxResetOption} [reset=true] Define if a reset button should be added in the input when there is a query. | |||
* @property {boolean|SearchBoxResetOption} [reset=false] Define if a reset button should be added in the input when there is a query. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it false by default now to have a reset button?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will double check 👍
src/widgets/search-box/search-box.js
Outdated
* @property {boolean|SearchBoxMagnifierOption} [magnifier=true] Define if a magnifier should be added at beginning of the input to indicate a search input. | ||
* @property {boolean|SearchBoxLoadingIndicatorOption} [loadingIndicator=false] Define if a loading indicator should be added at beginning of the input to indicate that search is currently stalled. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we make it true by default, since it's a new feature and might bring good behaviour by default?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering. The idea behind false
by default is that we don't change any existing behavior / style, especially if the user doesn't use the provided stylesheets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep that's the safest, if we were to do a new breaking version we would make it true by default, cc @mthuret can we add that to the feedback/product loop?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Happy to break in v3 ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed, false for now, breaking to true
in v3 👍
The behavior and loading indicator have been validated by @sebnvzt :D |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love it, very nice work @bobylito 👍
This PR is an alternative implementation of #2509. This is currently a PoC.
At the core of this new implementation is a change when the render part of the lifecycle of the widget. With this implementation, the render can be called when the instantsearch detects that a search is stalled. This means that they will be called more often. However, this is not likely to have a big impact on the performance as it should be the responsability of the widgets to render only when necessary.
On the implementation of the connector and the widget, the work is trivial. It is merely a question of providing the
isSearchStalled
flag to the rendering. The logic is factored in instantsearch, which means that the usage in other widgets will be as easy.Having done this implementation, I think it's the way to go. WDYT? Happy to answer any questions.
PS: this new implementation has been inspired by what can be done in react-instantsearch and vue-instantsearch. If we were to implement them using this library, this means that we need to fit their logic.
PPS: this can be tested here: https://deploy-preview-2569--algolia-instantsearch.netlify.com/v2/dev-novel/?selectedStory=SearchBox.default