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

feat(autocomplete): adds autocomplete text-field #1418

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module.exports = function(config) {
// demos in the tests, and Karma doesn't support advanced
// globbing.
'src/components/*/*.js',
'src/components/tabs/js/*.js'
'src/components/*/js/*.js'
];

var COMPILED_SRC = [
Expand Down
11 changes: 0 additions & 11 deletions docs/app/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -83,17 +83,6 @@ code:not(.highlight) {
-webkit-font-smoothing: auto;
}

.visuallyhidden {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
text-transform: none;
width: 1px;
}
.md-sidenav-inner {
background: #fff;
}
Expand Down
2 changes: 1 addition & 1 deletion docs/app/partials/menu-link.tmpl.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<md-button ng-class="{'active' : isSelected()}"
ng-href="#{{section.url}}">
{{section | humanizeDoc}}
<span class="visuallyhidden"
<span class="visually-hidden"
ng-if="isSelected()">
current page
</span>
Expand Down
2 changes: 1 addition & 1 deletion docs/app/partials/menu-toggle.tmpl.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
{{section.name}}
<span aria-hidden="true" class="md-toggle-icon"
ng-class="{'toggled' : isOpen()}"></span>
<span class="visuallyhidden">
<span class="visually-hidden">
Toggle {{isOpen()? 'expanded' : 'collapsed'}}
</span>
</md-button>
Expand Down
20 changes: 20 additions & 0 deletions src/components/autocomplete/autocomplete-theme.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
md-autocomplete {
background: '{{background-50}}';
button {
background: '{{background-200}}';
}
ul {
background: '{{background-50}}';
li {
border-top: 1px solid '{{background-400}}';
color: '{{background-900}}';
.highlight {
color: '{{background-600}}';
}
&:hover,
&.selected {
background: '{{background-200}}';
}
}
}
}
11 changes: 11 additions & 0 deletions src/components/autocomplete/autocomplete.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
(function () {
'use strict';
/**
* @ngdoc module
* @name material.components.autocomplete
*/
/*
* @see js folder for autocomplete implementation
*/
angular.module('material.components.autocomplete', [ 'material.core' ]);
})();
145 changes: 145 additions & 0 deletions src/components/autocomplete/autocomplete.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
@keyframes md-autocomplete-list-out {
0% {
animation-timing-function: linear;
}
50% {
opacity: 0;
height: 40px;
animation-timing-function: ease-in;
}
100% {
height: 0;
opacity: 0;
}
}
@keyframes md-autocomplete-list-in {
0% {
opacity: 0;
height: 0;
animation-timing-function: ease-out;
}
50% {
opacity: 0;
height: 40px;
}
100% {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Sorry if it is obvious, but) what is the purpose of these keyframes having identical values for 50% and 100% ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, that was a bug - opacity was supposed to be 0 at 50%. Good catch!

opacity: 1;
height: 40px;
}
}
md-content {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be global?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed in latest commit

overflow: visible;
}
md-autocomplete {
box-shadow: 0 2px 5px rgba(black, 0.25);
border-radius: 2px;
display: block;
height: 40px;
position: relative;
overflow: visible;

md-autocomplete-wrap {
display: block;
position: relative;
overflow: visible;
height: 40px;

md-progress-linear {
position: absolute;
bottom: 0; left: 0; width: 100%;
height: 3px;
transition: none;

.md-container {
transition: none;
top: auto;
height: 3px;
}
&.ng-enter {
transition: opacity 0.15s linear;
&.ng-enter-active {
opacity: 1;
}
}
&.ng-leave {
transition: opacity 0.15s linear;
&.ng-leave-active {
opacity: 0;
}
}
}
}
input {
position: absolute;
left: 0;
top: 0;
width: 100%;
box-sizing: border-box;
border: none;
box-shadow: none;
padding: 0 15px;
font-size: 14px;
line-height: 40px;
height: 40px;
outline: none;
z-index: 2;
background: transparent;
}
button {
position: absolute;
top: 10px;
right: 10px;
line-height: 20px;
z-index: 2;
text-align: center;
width: 20px;
height: 20px;
cursor: pointer;
border: none;
border-radius: 50%;
padding: 0;
font-size: 12px;
&.ng-enter {
transform: scale(0);
transition: transform 0.15s ease-out;
&.ng-enter-active {
transform: scale(1);
}
}
&.ng-leave {
transition: transform 0.15s ease-out;
&.ng-leave-active {
transform: scale(0);
}
}
}
ul {
position: absolute;
top: 100%;
left: 0;
right: 0;
box-shadow: 0 2px 5px rgba(black, 0.25);
margin: 0;
list-style: none;
padding: 0;
overflow: auto;
max-height: 41px * 5.5;
li {
border-top: 1px solid #ddd;
padding: 0 15px;
line-height: 40px;
font-size: 14px;
overflow: hidden;
height: 40px;
transition: background 0.15s linear;
cursor: pointer;
margin: 0;
&.ng-enter {
animation: md-autocomplete-list-in 0.2s;
}
&.ng-leave {
animation: md-autocomplete-list-out 0.2s;
}
}
}
}
64 changes: 64 additions & 0 deletions src/components/autocomplete/autocomplete.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
describe('<md-autocomplete>', function() {

beforeEach(module('material.components.autocomplete'));

function compile (str, scope) {
var container;
inject(function ($compile) {
container = $compile(str)(scope);
scope.$apply();
});
return container;
}

function createScope () {
var scope;
var items = ['foo', 'bar', 'baz'].map(function (item) { return { display: item }; });
inject(function ($rootScope) {
scope = $rootScope.$new();
scope.match = function (term) {
return items.filter(function (item) {
return item.display.indexOf(term) === 0;
});
};
scope.searchText = '';
scope.selectedItem = null;
});
return scope;
}

describe('basic functionality', function () {
it('should fail', inject(function($timeout, $mdConstant) {
var scope = createScope();
var template = '\
<md-autocomplete\
md-selected-item="selectedItem"\
md-search-text="searchText"\
md-items="item in match(searchText)"\
md-item-text="display"\
placeholder="placeholder">\
<span md-highlight-text="searchText">{{item.display}}</span>\
</md-autocomplete>';
var element = compile(template, scope);
var ctrl = element.controller('mdAutocomplete');

expect(scope.searchText).toBe('');
expect(scope.selectedItem).toBe(null);

element.scope().searchText = 'fo';
ctrl.keydown({});
element.scope().$apply();
$timeout.flush();

expect(scope.searchText).toBe('fo');
expect(scope.match(scope.searchText).length).toBe(1);
expect(element.find('li').length).toBe(1);

ctrl.keydown({ keyCode: $mdConstant.KEY_CODE.DOWN_ARROW, preventDefault: angular.noop });
ctrl.keydown({ keyCode: $mdConstant.KEY_CODE.ENTER, preventDefault: angular.noop });
scope.$apply();
expect(scope.searchText).toBe('foo');
}));
});

});
18 changes: 18 additions & 0 deletions src/components/autocomplete/demoBasicUsage/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<div ng-app="inputBasicDemo" ng-controller="DemoCtrl as ctrl" layout="column">

<md-content class="md-padding" layout="column">

<md-autocomplete
md-selected-item="ctrl.selectedItem"
md-search-text="ctrl.searchText"
md-items="item in ctrl.getItems(ctrl.searchText)"
md-item-text="display"
placeholder="select a state...">
<span md-highlight-text="ctrl.searchText">{{item.display}}</span>
</md-autocomplete>

<p>Current search term: "{{ctrl.searchText}}"</p>

</md-content>

</div>
26 changes: 26 additions & 0 deletions src/components/autocomplete/demoBasicUsage/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
angular
.module('autocompleteDemo', ['ngMaterial'])
.controller('DemoCtrl', DemoCtrl);

function DemoCtrl ($timeout, $q) {
var self = this;
this.selectedItem = null;
this.searchText = null;
this.states = 'Alabama, Alaska, Arizona, Arkansas, California, Colorado, Connecticut, Deleware,\
Florida, Georgia, Hawaii, Idaho, Illanois, Indiana, Iowa, Kansas, Kentucky, Louisiana,\
Maine, Maryland, Massachusetts, Michigan, Minnesota, Mississippi, Missouri, Montana,\
Nebraska, Nevada, New Hampshire, New Jersey, New Mexico, New York, North Carolina,\
North Dakota, Ohio, Oklahoma, Oregon, Pennsylvania, Rhode Island, South Carolina,\
South Dakota, Tennessee, Texas, Utah, Vermont, Virginia, Washington, West Virginia,\
Wisconsin, Wyoming'.split(/, +/g).map(function (state) { return { value: state.toLowerCase(), display: state }; });
this.getItems = getItems;

function getItems (query) {
if (!query) return [];
var deferred = $q.defer();
var lowercaseQuery = angular.lowercase(query);
var results = self.states.filter(function (state) { return state.value.indexOf(lowercaseQuery) === 0; });
$timeout(function () { deferred.resolve(results); }, Math.random() * 1000, false);
return deferred.promise;
}
}
3 changes: 3 additions & 0 deletions src/components/autocomplete/demoBasicUsage/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
md-content {
min-height: 500px;
}
Loading