Skip to content

Commit f2bc806

Browse files
committed
Sync and rebase & fix test
1 parent 17ea0a3 commit f2bc806

File tree

11 files changed

+127
-165
lines changed

11 files changed

+127
-165
lines changed

src/demo-app/chips/chips-demo.html

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,39 @@ <h4>Input Container</h4>
4545
<code>&lt;md-input-container&gt;</code>.
4646
</p>
4747

48-
<md-input-container [floatPlaceholder]="people.length > 0 ? 'always' : 'auto'">
49-
<md-chip-list mdPrefix #chipList>
48+
49+
<md-input-container>
50+
<md-chip-list mdPrefix #chipList1>
5051
<md-chip *ngFor="let person of people" [color]="color" [selectable]="selectable"
5152
[removable]="removable" (remove)="remove(person)">
5253
{{person.name}}
5354
<md-icon mdChipRemove>cancel</md-icon>
5455
</md-chip>
5556
</md-chip-list>
56-
<input mdInput mdChipInput placeholder="New Contributor..."
57-
[mdChipInputFor]="chipList"
57+
<input mdInput placeholder="New Contributor..."
58+
[mdChipInputFor]="chipList1"
59+
[mdChipInputSeparatorKeyCodes]="separatorKeysCodes"
60+
[mdChipInputAddOnBlur]="addOnBlur"
61+
(mdChipInputTokenEnd)="add($event)" />
62+
</md-input-container>
63+
64+
65+
66+
<p>
67+
You can also put <code>&lt;md-input-container&gt;</code> outside of an <code>md-chip-list</code>.
68+
With <code>mdChipInput</code> the input work with chip-list
69+
</p>
70+
71+
<md-chip-list #chipList2>
72+
<md-chip *ngFor="let person of people" [color]="color" [selectable]="selectable"
73+
[removable]="removable" (remove)="remove(person)">
74+
{{person.name}}
75+
<md-icon mdChipRemove>cancel</md-icon>
76+
</md-chip>
77+
</md-chip-list>
78+
<md-input-container>
79+
<input mdInput placeholder="New Contributor..."
80+
[mdChipInputFor]="chipList2"
5881
[mdChipInputSeparatorKeyCodes]="separatorKeysCodes"
5982
[mdChipInputAddOnBlur]="addOnBlur"
6083
(mdChipInputTokenEnd)="add($event)" />

src/lib/chips/chip-input.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {MdChipsModule} from './index';
33
import {Component, DebugElement} from '@angular/core';
44
import {MdChipInput, MdChipInputEvent} from './chip-input';
55
import {By} from '@angular/platform-browser';
6-
import {Dir} from '../core/rtl/dir';
6+
import {Directionality} from '../core';
77
import {createKeyboardEvent} from '../core/testing/event-objects';
88

99
import {ENTER, COMMA} from '../core/keyboard/keycodes';
@@ -22,7 +22,7 @@ describe('MdChipInput', () => {
2222
imports: [MdChipsModule],
2323
declarations: [TestChipInput],
2424
providers: [{
25-
provide: Dir, useFactory: () => {
25+
provide: Directionality, useFactory: () => {
2626
return {value: dir.toLowerCase()};
2727
}
2828
}]
@@ -101,18 +101,18 @@ describe('MdChipInput', () => {
101101

102102
@Component({
103103
template: `
104-
<md-chip-list>
105-
<input mdInput mdChipInputFor
104+
<md-chip-list #chipList>
105+
</md-chip-list>
106+
<input mdInput [mdChipInputFor]="chipList"
106107
[mdChipInputAddOnBlur]="addOnBlur"
107108
[mdChipInputSeparatorKeyCodes]="separatorKeys"
108109
(mdChipInputTokenEnd)="add($event)" />
109-
</md-chip-list>
110110
`
111111
})
112112
class TestChipInput {
113113
addOnBlur: boolean = false;
114114
separatorKeys: number[] = [ENTER];
115115

116-
add(event: MdChipInputEvent) {
116+
add(_: MdChipInputEvent) {
117117
}
118118
}

src/lib/chips/chip-input.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
19
import {Directive, Output, EventEmitter, ElementRef, Input} from '@angular/core';
2-
import {coerceBooleanProperty} from '../core/coercion/boolean-property';
3-
import {ENTER, BACKSPACE} from '../core/keyboard/keycodes';
10+
import {coerceBooleanProperty} from '@angular/cdk';
11+
import {ENTER} from '../core/keyboard/keycodes';
412
import {MdChipList} from './chip-list';
513

614
export interface MdChipInputEvent {
@@ -9,7 +17,7 @@ export interface MdChipInputEvent {
917
}
1018

1119
@Directive({
12-
selector: 'input[mdChipInput], input[matChipInput]',
20+
selector: 'input[mdChipInputFor], input[matChipInputFor]',
1321
host: {
1422
'class': 'mat-chip-input',
1523
'(keydown)': '_keydown($event)',
@@ -81,8 +89,8 @@ export class MdChipInput {
8189

8290
/** Checks to see if the (chipEnd) event needs to be emitted. */
8391
_emitChipEnd(event?: KeyboardEvent) {
84-
if (!this._inputElement.value && !!event && event.keyCode == BACKSPACE) {
85-
this._chipList.chips.last.focus();
92+
if (!this._inputElement.value && !!event) {
93+
this._chipList._keydown(event);
8694
}
8795
if (!event || this.separatorKeyCodes.indexOf(event.keyCode) > -1) {
8896
this.chipEnd.emit({ input: this._inputElement, value: this._inputElement.value });

src/lib/chips/chip-list.spec.ts

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {createKeyboardEvent} from '../core/testing/event-objects';
88

99
import {MdInputModule} from '../input/index';
1010
import {LEFT_ARROW, RIGHT_ARROW, BACKSPACE, DELETE, SPACE, TAB} from '../core/keyboard/keycodes';
11-
import {Dir} from '../core/rtl/dir';
11+
import {Directionality} from '../core';
1212

1313
describe('MdChipList', () => {
1414
let fixture: ComponentFixture<any>;
@@ -28,7 +28,7 @@ describe('MdChipList', () => {
2828
StandardChipList, InputContainerChipList
2929
],
3030
providers: [{
31-
provide: Dir, useFactory: () => {
31+
provide: Directionality, useFactory: () => {
3232
return {value: dir.toLowerCase()};
3333
}
3434
}]
@@ -82,20 +82,6 @@ describe('MdChipList', () => {
8282
expect(manager.activeItemIndex).toBe(lastIndex);
8383
});
8484

85-
86-
it('should focus the previous item', () => {
87-
// Focus the last item by fake updating the _hasFocus state for unit tests.
88-
lastItem._hasFocus = true;
89-
90-
// Destroy the last item
91-
testComponent.remove = lastIndex;
92-
93-
lastItem.focus();
94-
fixture.detectChanges();
95-
96-
expect(manager.activeItemIndex).toBe(lastIndex);
97-
});
98-
9985
describe('on chip destroy', () => {
10086
it('should focus the next item', () => {
10187
let array = chips.toArray();
@@ -267,7 +253,7 @@ describe('MdChipList', () => {
267253

268254
// Focus the input
269255
nativeInput.focus();
270-
expect(manager.activeItemIndex).toBeFalsy();
256+
expect(manager.activeItemIndex).toBe(-1);
271257

272258
// Press the DELETE key
273259
chipListInstance._keydown(DELETE_EVENT);
@@ -284,7 +270,7 @@ describe('MdChipList', () => {
284270

285271
// Focus the input
286272
nativeInput.focus();
287-
expect(manager.activeItemIndex).toBeFalsy();
273+
expect(manager.activeItemIndex).toBe(-1);
288274

289275
// Press the BACKSPACE key
290276
chipListInstance._keydown(BACKSPACE_EVENT);
@@ -350,8 +336,8 @@ class StandardChipList {
350336
<md-chip>Chip 1</md-chip>
351337
<md-chip>Chip 1</md-chip>
352338
<md-chip>Chip 1</md-chip>
353-
<input mdInput name="test" [mdChipInputFor]="chipList"/>
354339
</md-chip-list>
340+
<input mdInput name="test" [mdChipInputFor]="chipList"/>
355341
</md-input-container>
356342
`
357343
})

src/lib/chips/chip-list.ts

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,23 @@ import {
1111
ChangeDetectionStrategy,
1212
Component,
1313
ContentChildren,
14-
Directive,
1514
Input,
1615
QueryList,
1716
ViewEncapsulation,
1817
OnDestroy,
18+
Optional,
1919
ElementRef,
2020
Renderer2,
2121
} from '@angular/core';
2222

2323
import {MdChip} from './chip';
2424
import {FocusKeyManager} from '../core/a11y/focus-key-manager';
25-
import {SPACE, LEFT_ARROW, RIGHT_ARROW, TAB} from '../core/keyboard/keycodes';
2625
import {coerceBooleanProperty} from '@angular/cdk';
2726
import {Subscription} from 'rxjs/Subscription';
2827
import {
29-
LEFT_ARROW, RIGHT_ARROW, SPACE, BACKSPACE, DELETE, UP_ARROW, DOWN_ARROW
28+
LEFT_ARROW, RIGHT_ARROW, BACKSPACE, DELETE, UP_ARROW, DOWN_ARROW
3029
} from '../core/keyboard/keycodes';
31-
import {Dir} from '../core/rtl/dir';
30+
import {Directionality} from '../core';
3231

3332
/** Utility to check if an input element has no value. */
3433
function _isInputEmpty(element: HTMLElement): boolean {
@@ -60,7 +59,7 @@ function _isInputEmpty(element: HTMLElement): boolean {
6059
'role': 'listbox',
6160
'class': 'mat-chip-list',
6261

63-
'(focus)': 'focus($event)',
62+
'(focus)': 'focus()',
6463
'(keydown)': '_keydown($event)'
6564
},
6665
queries: {
@@ -73,7 +72,7 @@ function _isInputEmpty(element: HTMLElement): boolean {
7372
export class MdChipList implements AfterContentInit, OnDestroy {
7473

7574
/** When a chip is destroyed, we track the index so we can focus the appropriate next chip. */
76-
protected _lastDestroyedIndex: number = null;
75+
protected _lastDestroyedIndex: number|null = null;
7776

7877
/** Track which chips we're listening to for focus/destruction. */
7978
protected _chipSet: WeakMap<MdChip, boolean> = new WeakMap();
@@ -96,7 +95,7 @@ export class MdChipList implements AfterContentInit, OnDestroy {
9695
chips: QueryList<MdChip>;
9796

9897
constructor(protected _renderer: Renderer2, protected _elementRef: ElementRef,
99-
protected _dir: Dir) {
98+
@Optional() private _dir: Directionality) {
10099
}
101100

102101
ngAfterContentInit(): void {
@@ -157,7 +156,7 @@ export class MdChipList implements AfterContentInit, OnDestroy {
157156
* Focuses the the first non-disabled chip in this chip list, or the associated input when there
158157
* are no eligible chips.
159158
*/
160-
focus(event?: Event) {
159+
focus() {
161160
// TODO: ARIA says this should focus the first `selected` chip if any are selected.
162161
if (this.chips.length > 0) {
163162
this._keyManager.setFirstItemActive();
@@ -180,7 +179,7 @@ export class MdChipList implements AfterContentInit, OnDestroy {
180179
let code = event.keyCode;
181180
let target = event.target as HTMLElement;
182181
let isInputEmpty = _isInputEmpty(target);
183-
let isRtl = this._dir.value == 'rtl';
182+
let isRtl = this._dir && this._dir.value == 'rtl';
184183

185184
let isPrevKey = (code == (isRtl ? RIGHT_ARROW : LEFT_ARROW));
186185
let isNextKey = (code == (isRtl ? LEFT_ARROW : RIGHT_ARROW));
@@ -258,15 +257,19 @@ export class MdChipList implements AfterContentInit, OnDestroy {
258257
// On destroy, remove the item from our list, and setup our destroyed focus check
259258
chip.destroy.subscribe(() => {
260259
let chipIndex: number = this.chips.toArray().indexOf(chip);
261-
262-
if (this._isValidIndex(chipIndex) && chip._hasFocus) {
263-
// Check whether the chip is the last item
264-
if (chipIndex < this.chips.length - 1) {
265-
this._keyManager.setActiveItem(chipIndex);
266-
} else if (chipIndex - 1 >= 0) {
267-
this._keyManager.setActiveItem(chipIndex - 1);
260+
if (this._isValidIndex(chipIndex)) {
261+
if (chip._hasFocus) {
262+
// Check whether the chip is the last item
263+
if (chipIndex < this.chips.length - 1) {
264+
this._keyManager.setActiveItem(chipIndex);
265+
} else if (chipIndex - 1 >= 0) {
266+
this._keyManager.setActiveItem(chipIndex - 1);
267+
}
268268
}
269-
this._lastDestroyedIndex = chipIndex;
269+
if (this._keyManager.activeItemIndex == chipIndex) {
270+
this._lastDestroyedIndex = chipIndex;
271+
}
272+
270273
}
271274

272275
this._chipSet.delete(chip);
@@ -282,12 +285,12 @@ export class MdChipList implements AfterContentInit, OnDestroy {
282285
*/
283286
protected _updateFocusForDestroyedChips() {
284287
let chipsArray = this.chips;
285-
let focusChip: MdChip;
286288

287289
if (this._lastDestroyedIndex != null && chipsArray.length > 0) {
288290
// Check whether the destroyed chip was the last item
289291
const newFocusIndex = Math.min(this._lastDestroyedIndex, chipsArray.length - 1);
290292
this._keyManager.setActiveItem(newFocusIndex);
293+
let focusChip = this._keyManager.activeItem;
291294

292295
// Focus the chip
293296
if (focusChip) {

src/lib/chips/chip-remove.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ describe('Chip Remove', () => {
3131

3232
describe('basic behavior', () => {
3333
it('should applies the `mat-chip-remove` CSS class', () => {
34-
let hrefElement = chipNativeElement.querySelector('a');
34+
let hrefElement = chipNativeElement.querySelector('a')!;
3535

3636
expect(hrefElement.classList).toContain('mat-chip-remove');
3737
});
3838

3939
it('should emits (remove) on click', () => {
40-
let hrefElement = chipNativeElement.querySelector('a');
40+
let hrefElement = chipNativeElement.querySelector('a')!;
4141

4242
testChip.removable = true;
4343
fixture.detectChanges();
@@ -50,7 +50,7 @@ describe('Chip Remove', () => {
5050
});
5151

5252
it(`should monitors the parent chip's [removable] property`, () => {
53-
let hrefElement = chipNativeElement.querySelector('a');
53+
let hrefElement = chipNativeElement.querySelector('a')!;
5454

5555
testChip.removable = true;
5656
fixture.detectChanges();

src/lib/chips/chip.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {By} from '@angular/platform-browser';
44
import {MdChipList, MdChip, MdChipEvent, MdChipsModule} from './index';
55
import {SPACE, DELETE, BACKSPACE} from '../core/keyboard/keycodes';
66
import {createKeyboardEvent} from '../core/testing/event-objects';
7-
import {Dir} from '../core/rtl/dir';
7+
import {Directionality} from '../core';
88

99
describe('Chips', () => {
1010
let fixture: ComponentFixture<any>;
@@ -22,7 +22,7 @@ describe('Chips', () => {
2222
BasicChip, SingleChip
2323
],
2424
providers: [{
25-
provide: Dir, useFactory: () => {
25+
provide: Directionality, useFactory: () => {
2626
return {value: dir};
2727
}
2828
}]
@@ -64,7 +64,7 @@ describe('Chips', () => {
6464
chipDebugElement = fixture.debugElement.query(By.directive(MdChip));
6565
chipListNativeElement = fixture.debugElement.query(By.directive(MdChipList)).nativeElement;
6666
chipNativeElement = chipDebugElement.nativeElement;
67-
chipInstance = chipDebugElement.componentInstance;
67+
chipInstance = chipDebugElement.injector.get(MdChip);
6868
testComponent = fixture.debugElement.componentInstance;
6969

7070
document.body.appendChild(chipNativeElement);

0 commit comments

Comments
 (0)