Repository navigation
Expandable Search - #17629
Expandable Search#17629
Conversation
cfb4613 to
5e486fe
Compare
HansMuller
left a comment
There was a problem hiding this comment.
Still looking at this, here's some feedback before the next update
There was a problem hiding this comment.
To reduce the risk of importing this demo along with all of the others, it's best if this is the only public class in the file.
There was a problem hiding this comment.
NICE. You might want to add a comment that indicates that all of the gallery tests depend on this...
There was a problem hiding this comment.
It might be better to put something in this drawer that has to do with the demo. Search limits maybe?
There was a problem hiding this comment.
Let me think about this one...
There was a problem hiding this comment.
It would be OK to put this expression on the previous line
There was a problem hiding this comment.
AFAICT this delegate defines the search experience.
There was a problem hiding this comment.
It would be helpful to mention query and showResultsPage here
There was a problem hiding this comment.
It might be a bit more fluttery to define a ResultCard widget instead of this function
There was a problem hiding this comment.
"overlay" might be a little confusing vis the Overlay widget. The docs tend to refer to the result of showSearchOverlay as a page, show maybe showSearchPage etc.
There was a problem hiding this comment.
It would helpful to also mention [close] here
e0eb89b to
74f68fe
Compare
|
@HansMuller Addressed comments and added a way to pipe the search result back to the caller of |
HansMuller
left a comment
There was a problem hiding this comment.
I still haven't finished reviewing this, but here are some additional updates
There was a problem hiding this comment.
A slightly simpler way to create a vertical spacer is: const SizedBox(height: 64.0)
There was a problem hiding this comment.
Developers may want to reuse some of this buildSuggestions method, since showing a list of strings with the query highlighted is common. You could simplify lifting the reusable code by creating a _SuggestionList widget, like:
return new _SuggestionList(
query: query,
suggestions: suggestions.map((int i) => '$i'),
onSelected: (String suggestion) { // A ValueChanged<String> callback
query = suggestion;
showResultsPage(context);
},
);
If you passed the search delegate along then an onSelected callback wouldn't be needed.
There was a problem hiding this comment.
Maybe: Shows a full screen search experience in terms of a search page and a results page.
There was a problem hiding this comment.
"search experience" sounds pretty fancy; maybe just "search and results pages"
There was a problem hiding this comment.
to the search => to the search page
There was a problem hiding this comment.
in the underlying page while the search page fades in or out
There was a problem hiding this comment.
Do you really want to provide a default value here? Are developers supposed to specify null to get delegate.query?
There was a problem hiding this comment.
The reason I did it is that the SearchDelegate is potentially long-lived. If you do two searches back-to-back the expectation is that when the search page is brought up a second time the query field is empty again. That's what's enforced here. If developers want to diverge from the default behavior of resetting the query, they can do so here.
There was a problem hiding this comment.
The docs don't appear to cover the return value.
|
Addressed comments and restructured code: The search page is now just one PageRoute. |
HansMuller
left a comment
There was a problem hiding this comment.
This looks great, mostly just some doc wordsmithing.
Just needs some tests and it should be ready for its debut!
There was a problem hiding this comment.
Since I think we really intend for the suggestions to be based on the query string: The suggestions should be based on the [query] string ... And I think you should what the method is supposed to do if [query] is the empty string, since that's the default.
There was a problem hiding this comment.
content => current value of
There was a problem hiding this comment.
Typically an [IconButton] configured with a [BackButtonIcon] that exits the search with [close].
One can also use an [AnimatedIcon]...
There was a problem hiding this comment.
return by => returned by
There was a problem hiding this comment.
It's not really clear what this is for. In other words, if I'm building a SearchDelegate subclass what would I typically do with focusNode?
There was a problem hiding this comment.
Right. I'll make it private.
There was a problem hiding this comment.
Do SearchDelegate subclasses need to see this? If they really wanted to, they could remember if they'd most recently called showSuggestions or showResults
There was a problem hiding this comment.
I'll make it private as well.
There was a problem hiding this comment.
Same as earlier: do SearchDelegate subclassers need this?
|
@HansMuller Comments are addressed and tests have been added. PTAL. |
HansMuller
left a comment
There was a problem hiding this comment.
This looks great. Just one non-nit about Navigator.popping back to the showSearch caller's route
|
|
||
| /// The results shown after the user submits a search from the search page. | ||
| /// | ||
| /// The current value of [query] can be used to determine what the users |
| /// | ||
| /// Typically an [IconButton] configured with a [BackButtonIcon] that exits | ||
| /// the search with [close]. One can also use an [AnimatedIcon] driven by | ||
| /// [transitionAnimation], which animated from e.g. a hamburger menu to the |
| _textEditingController.text = value; | ||
| } | ||
|
|
||
| /// Transition to show search results. |
There was a problem hiding this comment.
It might be good to link this to buildResults more clearly. Like: Transition from the suggestions returned by [buildSuggestions] to the [query] results returned by [buildResults].
| _currentBody = _SearchBody.results; | ||
| } | ||
|
|
||
| /// Transition to show the search suggestions and places the input focus |
There was a problem hiding this comment.
Suggest complicating this this a little (as with showResults) to make the link to buildSuggestions clear.
| /// The current value of [query] can be used to determine what the users | ||
| /// searched for. | ||
| /// | ||
| /// Typically, this method returns a [ListView] with the search results. |
There was a problem hiding this comment.
It would be helpful to include a point about suggestion widget onTap handlers typically calling [close] to return the search result. Just like buildSuggestions mentions what a typical suggestion onTap handler does.
| ); | ||
| break; | ||
| } | ||
|
|
| ); | ||
| } | ||
|
|
||
| TextEditingController get _controller => widget.delegate._textEditingController; |
There was a problem hiding this comment.
It might be a little clearer if this was called queryTextController or something less generic.
| }, | ||
| decoration: new InputDecoration( | ||
| border: InputBorder.none, | ||
| hintText: MaterialLocalizations.of(context).searchFieldLabel |
|
|
||
| class TestHomePage extends StatelessWidget { | ||
| const TestHomePage( | ||
| {this.results, |
There was a problem hiding this comment.
{ goes on the previous line
| } | ||
|
|
||
| class TestHomePage extends StatelessWidget { | ||
| const TestHomePage( |
There was a problem hiding this comment.
We usually format this kind of thing like:
const TestHomePage({
this.foo,
this.delegate,
this.passInInitialQuery: false,
this.initialQuery,
});
| _currentBody = null; | ||
| _focusNode.unfocus(); | ||
| _result.complete(result); | ||
| Navigator.of(context) |
There was a problem hiding this comment.
I think it's possible for the original route to have been removed while the search dialog is up, which would probably trigger a strange failure mode. If developers start running into that, we could make this code more defensive. In a future PR.
|
We should update the stocks app to use this, probably. |
|
Thanks for adding this, @goderbauer. How do we use it? I don't see it anywhere. |
|
@ThinkDigitalRepair I cannot find it either. Maybe take a look at this demo. 🤷♂️ |
|
@NiklasPor, thank you. I ended up repurposing the demo and it works . |
#17119 (comment)
As spec'ed out in https://material.io/design/navigation/search.html#expandable-search.
The search can be triggered by tapping the search icon in the AppBar:
Doing so will bring up the search page where the user can type in a search query and see suggested queries:
Once the query is submitted, a results page is shown:
TODO:
Requires fix from #17624.