Skip to content
This repository has been archived by the owner on Dec 18, 2024. It is now read-only.

feat(navbar): Add basic search bar component to site. #134

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

riavalon
Copy link
Contributor

@riavalon riavalon commented Mar 17, 2017

note: karma.conf.js file has errors in it preventing tests from running. The issue is fixed in this pr: #138

Copy link
Contributor

@kara kara left a 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;
Copy link
Contributor

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'
}

Copy link
Contributor Author

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

Copy link
Contributor

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.

Copy link
Contributor Author

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;
Copy link
Contributor

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.

Copy link
Contributor Author

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

Copy link
Contributor

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)

Copy link
Contributor Author

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())"
Copy link
Contributor

@kara kara Mar 20, 2017

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">
Copy link
Contributor

@kara kara Mar 20, 2017

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';
Copy link
Contributor

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'

Copy link
Member

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.

@kara kara assigned riavalon and unassigned jelbourn and kara Mar 20, 2017
box-sizing: border-box;
}

&.expanded .search-input-container {
Copy link
Member

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+ */
Copy link
Member

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

Copy link
Contributor Author

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';
Copy link
Member

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>
Copy link
Member

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?

@riavalon riavalon force-pushed the feat-search-bar branch 4 times, most recently from 87a943c to a49b4ce Compare April 13, 2017 17:23
@riavalon riavalon force-pushed the feat-search-bar branch 5 times, most recently from c1c7f81 to f688a90 Compare April 27, 2017 18:22
@riavalon
Copy link
Contributor Author

riavalon commented Jun 5, 2017

@jelbourn This should be ready for another look over again

placeholder="Search"
type="text"
(focus)="toggleIsExpanded(true)"
(blur)="toggleIsExpanded(false)"
Copy link
Member

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;
Copy link
Member

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>
Copy link
Member

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 {
Copy link
Member

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);
Copy link
Member

@jelbourn jelbourn Jun 6, 2017

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();
Copy link
Member

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[];
Copy link
Member

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;
Copy link
Member

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

@riavalon
Copy link
Contributor Author

riavalon commented Jun 7, 2017

@jelbourn Updated this with the recent requested changes

@jelbourn
Copy link
Member

jelbourn commented Jun 7, 2017

Looks good except for one last thing I noticed:
image

When the input is first focused, the autocomplete uses the original width before the input finishes expanding. In reality this is probably a while new feature we need in autocomplete, but for now I think we can work around it by immediately closing the autocomplete on focus and then opening it manually when the input's expansion animation completes.

@riavalon
Copy link
Contributor Author

riavalon commented Jun 9, 2017

@jelbourn Set the panel to open and close in sync with the expanding animation

@jelbourn
Copy link
Member

@riavalon looks like clicking on the autocomplete items doesn't navigate any more

@riavalon
Copy link
Contributor Author

@jelbourn Blur event was being called when trying to click on an option. I rewrote the focus/blur logic to ignore clicks on md-options.

@jotatoledo
Copy link

Up, this would be a nice feature on the docs site

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants