-
Notifications
You must be signed in to change notification settings - Fork 401
feat(navbar): Add basic search bar component to site. #134
base: main
Are you sure you want to change the base?
Conversation
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.
Can you also add some tests? :D
} | ||
|
||
public toggleIsExpanded() { | ||
this._isExpanded = !this._isExpanded; |
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.
The autocomplete trigger has a panelOpen
property. Have you tried using that instead of toggling it here? You should be able to do a ViewChild query for 'auto'
to get a reference to the trigger.
host: {
'[class.expanded]': '_autocompleteTrigger?.panelOpen'
}
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 believe this will cause the input to expand only when the user starts typing and suggesting show up. We want the input to enlarge right when the user focuses it so I'm using the _isExpanded
here instead
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.
The autocomplete panel should appear whenever the input is focused. If that's not happening, seems like an autocomplete bug.
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 think I may be. It seems that the first time the field is focused it does not show the panel, and the second time the field is focused it does show it.
}) | ||
|
||
export class SearchBar { | ||
@HostBinding('class.expanded') _isExpanded = false; |
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.
Move this to the host object in the Component metadata? Generally prefer that instead of using the decorator.
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 added it as a decorator as the docs on angular.io suggest it's better to prefer the decorator over the metadata: https://angular.io/docs/ts/latest/guide/style-guide.html#!#06-03
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.
In Material, we actually do the opposite because @HostBinding causes issues with Angular Universal (which it seems the docs authors weren't aware of)
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.
Ahh, I see. Alrighty, I'll switch it up 👍
type="text" | ||
(focus)="toggleIsExpanded(true)" | ||
(blur)="toggleIsExpanded(false)" | ||
(keyup.enter)="navigate($event.target.value.toLowerCase())" |
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.
Does this also navigate when you click on the option? Also have you considered switching to the optionSelections
observable on the trigger rather than this event? It emits any option object that is selected (via the keyboard or the mouse).
</div> | ||
|
||
<md-autocomplete #auto="mdAutocomplete"> | ||
<md-option *ngFor="let item of filteredSuggestions | async" [value]="item.name"> |
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.
Another idea would be to bind the entire item as the option value, and use the displayWith
property on md-autocomplete
to map that object to its display value (the name). That way, you don't have to go through the list in navigate()
to find the ID that matches the search string. You can just get the object itself on selection and pass through its ID to the route.
import {Router} from '@angular/router'; | ||
import {FormControl} from '@angular/forms'; | ||
import {MdSnackBar} from '@angular/material'; | ||
import {Observable} from 'rxjs'; |
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.
Can you restrict the import a bit? From 'rxjs/Observable'
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.
To elaborate: when you import from just rxjs
, it brings in a lot of than just what you're using and increases the payload size.
box-sizing: border-box; | ||
} | ||
|
||
&.expanded .search-input-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.
All of the css should start with a docs-
prefix
(mainly so that people looking at the docs site in dev tools can differentiate between docs-site-specific css and the underlying library css)
&::-webkit-input-placeholder { @include color-placeholder(); } /* Chrome/Opera/Safari */ | ||
&::-moz-placeholder { @include color-placeholder(); } /* Firefox 19+ */ | ||
&:-moz-placeholder { @include color-placeholder(); } /* Firefox 18- */ | ||
&:ms-input-placeholder { @include color-placeholder(); } /* IE 10+ */ |
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.
autoprefixer is supposed to be built into the angular-cli, but I'm not sure if there's some specific configuration needed to turn it on
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 did see that it was auto-prefixing some styles, but the input placeholder one unfortunately wasn't being done for some reason.
import {Router} from '@angular/router'; | ||
import {FormControl} from '@angular/forms'; | ||
import {MdSnackBar} from '@angular/material'; | ||
import {Observable} from 'rxjs'; |
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.
To elaborate: when you import from just rxjs
, it brings in a lot of than just what you're using and increases the payload size.
<svg fill="#FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"> | ||
<path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/> | ||
<path d="M0 0h24v24H0z" fill="none"/> | ||
</svg> |
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 there a font icon for search that would serve for this instead of using an svg?
91044c5
to
f0507bf
Compare
f0507bf
to
fe77301
Compare
87a943c
to
a49b4ce
Compare
c1c7f81
to
f688a90
Compare
@jelbourn This should be ready for another look over again |
placeholder="Search" | ||
type="text" | ||
(focus)="toggleIsExpanded(true)" | ||
(blur)="toggleIsExpanded(false)" |
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.
This method doesn't take an argument
@@ -0,0 +1,60 @@ | |||
$input-bg: #85D9E2; |
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.
All of the colors should be part of the theme
(keyup.enter)="handlePlainSearch($event.target.value.toLowerCase())" | ||
[mdAutocomplete]="auto" | ||
[formControl]="searchControl"> | ||
<i class="material-icons">search</i> |
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.
This should probably be <md-icon>
} | ||
} | ||
|
||
input { |
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.
Can this be done with a css class instead? E.g. .docs-search-input
} | ||
|
||
public handlePlainSearch(searchTerm) { | ||
const item = this.allDocItems.find(item => item.name.toLowerCase() === searchTerm); |
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.
Partial matches should also jump to the first result. E.g., typing "Date" and hitting enter should jump to the datepicker.
|
||
public handlePlainSearch(searchTerm) { | ||
const item = this.allDocItems.find(item => item.name.toLowerCase() === searchTerm); | ||
item ? this.navigate(item.id) : this._showError(); |
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.
We should clear the input on a successful search
@ViewChild(MdAutocompleteTrigger) | ||
private _autocompleteTrigger: MdAutocompleteTrigger; | ||
|
||
public allDocItems: DocItem[]; |
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.
Don't need to explicitly say public
since that's the default
public allDocItems: DocItem[]; | ||
public filteredSuggestions: Observable<DocItem[]>; | ||
public searchControl: FormControl = new FormControl(''); | ||
public sub; |
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.
sub
should have a more specific name and probably a type
@jelbourn Updated this with the recent requested changes |
@jelbourn Set the panel to open and close in sync with the expanding animation |
0c6c522
to
7ffa889
Compare
@riavalon looks like clicking on the autocomplete items doesn't navigate any more |
7ffa889
to
a3166ea
Compare
@jelbourn Blur event was being called when trying to click on an option. I rewrote the focus/blur logic to ignore clicks on |
a3166ea
to
2fcf039
Compare
2fcf039
to
dfcf761
Compare
Up, this would be a nice feature on the docs site |
note:
karma.conf.js
file has errors in it preventing tests from running. The issue is fixed in this pr: #138