From afe6a4fcbbcde0df4af47abee432d06b7e87b383 Mon Sep 17 00:00:00 2001 From: Yuan Gao Date: Thu, 1 Jun 2017 16:32:27 -0700 Subject: [PATCH] Add chip list container --- src/demo-app/chips/chips-demo.html | 7 +-- src/lib/chips/chip-input.spec.ts | 4 +- src/lib/chips/chip-list.spec.ts | 37 +++++++--------- src/lib/chips/chip-list.ts | 17 +++++--- src/lib/chips/chip-remove.spec.ts | 8 ++-- src/lib/chips/chips.scss | 69 +++++++++++++----------------- src/lib/chips/index.ts | 10 ++--- 7 files changed, 67 insertions(+), 85 deletions(-) diff --git a/src/demo-app/chips/chips-demo.html b/src/demo-app/chips/chips-demo.html index 5b8d42c50fa1..a84fba98a81a 100644 --- a/src/demo-app/chips/chips-demo.html +++ b/src/demo-app/chips/chips-demo.html @@ -44,24 +44,19 @@

Input Container

<md-input-container>.

- + {{person.name}} cancel - - - - -

The example above has overridden the [separatorKeys] input to allow for ENTER, COMMA and SEMI COLON keys. diff --git a/src/lib/chips/chip-input.spec.ts b/src/lib/chips/chip-input.spec.ts index 401a7f025c45..28607f063592 100644 --- a/src/lib/chips/chip-input.spec.ts +++ b/src/lib/chips/chip-input.spec.ts @@ -102,9 +102,9 @@ describe('MdChipInput', () => { @Component({ template: ` - + ` }) class TestChipInput { diff --git a/src/lib/chips/chip-list.spec.ts b/src/lib/chips/chip-list.spec.ts index 399c183166e1..edbd1c29fcf7 100644 --- a/src/lib/chips/chip-list.spec.ts +++ b/src/lib/chips/chip-list.spec.ts @@ -44,7 +44,7 @@ describe('MdChipList', () => { setupStandardList(); })); - it('adds the `mat-chip-list` class', () => { + it('should add the `mat-chip-list` class', () => { expect(chipListNativeElement.classList).toContain('mat-chip-list'); }); }); @@ -58,7 +58,7 @@ describe('MdChipList', () => { manager = chipListInstance._keyManager; }); - it('focuses the first chip on focus', () => { + it('should focus the first chip on focus', () => { let FOCUS_EVENT = {} as Event; chipListInstance.focus(FOCUS_EVENT); @@ -67,7 +67,7 @@ describe('MdChipList', () => { expect(manager.activeItemIndex).toBe(0); }); - it('watches for chip focus', () => { + it('should watch for chip focus', () => { let array = chips.toArray(); let lastIndex = array.length - 1; let lastItem = array[lastIndex]; @@ -79,7 +79,7 @@ describe('MdChipList', () => { }); describe('on chip destroy', () => { - it('focuses the next item', () => { + it('should focus the next item', () => { let array = chips.toArray(); let midItem = array[2]; @@ -95,7 +95,7 @@ describe('MdChipList', () => { }); - it('focuses the previous item', () => { + it('should focus the previous item', () => { let array = chips.toArray(); let lastIndex = array.length - 1; let lastItem = array[lastIndex]; @@ -121,7 +121,7 @@ describe('MdChipList', () => { manager = chipListInstance._keyManager; })); - it('LEFT ARROW focuses previous item', () => { + it('should focus previous item when press LEFT ARROW', () => { let nativeChips = chipListNativeElement.querySelectorAll('md-chip'); let lastNativeChip = nativeChips[nativeChips.length - 1] as HTMLElement; @@ -142,7 +142,7 @@ describe('MdChipList', () => { expect(manager.activeItemIndex).toEqual(lastIndex - 1); }); - it('RIGHT ARROW focuses next item', () => { + it('should focus next item when press RIGHT ARROW', () => { let nativeChips = chipListNativeElement.querySelectorAll('md-chip'); let firstNativeChip = nativeChips[0] as HTMLElement; @@ -172,7 +172,7 @@ describe('MdChipList', () => { manager = chipListInstance._keyManager; })); - it('RIGHT ARROW focuses previous item', () => { + it('should focus previous item when press RIGHT ARROW', () => { let nativeChips = chipListNativeElement.querySelectorAll('md-chip'); let lastNativeChip = nativeChips[nativeChips.length - 1] as HTMLElement; @@ -194,7 +194,7 @@ describe('MdChipList', () => { expect(manager.activeItemIndex).toEqual(lastIndex - 1); }); - it('LEFT ARROW focuses next item', () => { + it('should focus next item when press LEFT ARROW', () => { let nativeChips = chipListNativeElement.querySelectorAll('md-chip'); let firstNativeChip = nativeChips[0] as HTMLElement; @@ -215,7 +215,7 @@ describe('MdChipList', () => { expect(manager.activeItemIndex).toEqual(1); }); - it('allow focus to escape when tabbing away', fakeAsync(() => { + it('should allow focus to escape when tabbing away', fakeAsync(() => { chipListInstance._keyManager.onKeydown(createKeyboardEvent('keydown', TAB)); expect(chipListInstance._tabIndex) @@ -240,15 +240,10 @@ describe('MdChipList', () => { manager = chipListInstance._keyManager; }); - it('SPACE ignores selection', () => { - let SPACE_EVENT = createKeyboardEvent('keydown', SPACE); - let firstChip: MdChip = chips.toArray()[0]; - }); - describe('when the input has focus', () => { - it('DELETE focuses the last chip', () => { - let nativeInput = chipListNativeElement.querySelector('input'); + it('should focus the last chip when press DELETE', () => { + let nativeInput = fixture.nativeElement.querySelector('input'); let DELETE_EVENT: KeyboardEvent = createKeyboardEvent('keydown', DELETE, nativeInput); @@ -264,8 +259,8 @@ describe('MdChipList', () => { expect(manager.activeItemIndex).toEqual(chips.length - 1); }); - it('BACKSPACE focuses the last chip', () => { - let nativeInput = chipListNativeElement.querySelector('input'); + it('should focus the last chip when press BACKSPACE', () => { + let nativeInput = fixture.nativeElement.querySelector('input'); let BACKSPACE_EVENT: KeyboardEvent = createKeyboardEvent('keydown', BACKSPACE, nativeInput); @@ -336,12 +331,12 @@ class StandardChipList { @Component({ template: ` - + Chip 1 Chip 1 Chip 1 - + ` }) diff --git a/src/lib/chips/chip-list.ts b/src/lib/chips/chip-list.ts index 9ff241197bed..c6a3004af93a 100644 --- a/src/lib/chips/chip-list.ts +++ b/src/lib/chips/chip-list.ts @@ -3,6 +3,7 @@ import { ChangeDetectionStrategy, Component, ContentChildren, + Directive, Input, QueryList, ViewEncapsulation, @@ -20,6 +21,14 @@ import { } from '../core/keyboard/keycodes'; import {Dir} from '../core/rtl/dir'; +@Directive({ + selector: '[mdChipListContainer], [matChipListContainer]', + host: { + '[class.mat-chip-list-container]': 'true' + } +}) +export class MdChipListContainer {} + /** * A material design chips component (named ChipList for it's similarity to the List component). * @@ -39,7 +48,7 @@ import {Dir} from '../core/rtl/dir'; '[attr.tabindex]': '_tabIndex', 'role': 'listbox', '[class.mat-chip-list]': 'true', - + // Actions '(focus)': 'focus($event)', '(keydown)': '_keydown($event)' }, @@ -118,17 +127,13 @@ export class MdChipList implements AfterContentInit, OnDestroy { } } - /** - * Associates an HTML input element with this chip list. - * - * @param inputElement The input to associate. - */ @Input() get selectable(): boolean { return this._selectable; } set selectable(value: boolean) { this._selectable = coerceBooleanProperty(value); } + /** Associates an HTML input element with this chip list. */ registerInput(inputElement: HTMLInputElement) { this._inputElement = inputElement; } diff --git a/src/lib/chips/chip-remove.spec.ts b/src/lib/chips/chip-remove.spec.ts index 276acb9c7f22..842f806aa66e 100644 --- a/src/lib/chips/chip-remove.spec.ts +++ b/src/lib/chips/chip-remove.spec.ts @@ -30,13 +30,13 @@ describe('Chip Remove', () => { })); describe('basic behavior', () => { - it('applies the `mat-chip-remove` CSS class', () => { + it('should applies the `mat-chip-remove` CSS class', () => { let hrefElement = chipNativeElement.querySelector('a'); expect(hrefElement.classList).toContain('mat-chip-remove'); }); - it('emits (remove) on click', () => { + it('should emits (remove) on click', () => { let hrefElement = chipNativeElement.querySelector('a'); testChip.removable = true; @@ -49,7 +49,7 @@ describe('Chip Remove', () => { expect(testChip.didRemove).toHaveBeenCalled(); }); - it(`monitors the parent chip's [removable] property`, () => { + it(`should monitors the parent chip's [removable] property`, () => { let hrefElement = chipNativeElement.querySelector('a'); testChip.removable = true; @@ -67,7 +67,7 @@ describe('Chip Remove', () => { @Component({ template: ` - + ` }) class TestChip { diff --git a/src/lib/chips/chips.scss b/src/lib/chips/chips.scss index 03fdd853b8b9..626d38aa2699 100644 --- a/src/lib/chips/chips.scss +++ b/src/lib/chips/chips.scss @@ -19,45 +19,33 @@ $mat-chip-remove-font-size: 18px; flex-wrap: wrap; align-items: flex-start; - /* - * Only apply the margins to chips - */ .mat-chip:not(.mat-basic-chip) { margin: $mat-chip-margin; // Do not apply the special margins inside an input container - :not(.mat-input-wrapper) & { - // Remove the margin from the first element (in both LTR and RTL) - &:first-child { - margin: { - left: 0; - right: $mat-chip-margin; - } - - [dir='rtl'] & { - margin: { - left: $mat-chip-margin; - right: 0; - } - } + // Remove the margin from the first element (in both LTR and RTL) + &:first-child { + margin-left: 0; + margin-right: $mat-chip-margin; + + [dir='rtl'] & { + margin-right: 0; + margin-left: $mat-chip-margin; } + } + + // Remove the margin from the last element (in both LTR and RTL) + &:last-child { + margin-right: 0; + margin-left: $mat-chip-margin; - // Remove the margin from the last element (in both LTR and RTL) - &:last-child { - margin: { - left: $mat-chip-margin; - right: 0; - } - - [dir='rtl'] & { - margin: { - left: 0; - right: $mat-chip-margin; - } - } + [dir='rtl'] & { + margin-left: 0; + margin-right: $mat-chip-margin; } } } + } .mat-input-prefix .mat-chip-list-wrapper { @@ -87,15 +75,6 @@ $mat-chip-remove-font-size: 18px; display: block; margin: 0; margin-bottom: $mat-chip-vertical-padding; - - [dir='rtl'] & { - margin: 0; - margin-bottom: $mat-chip-vertical-padding; - } - - &:last-child, [dir='rtl'] &:last-child { - margin-bottom: 0; - } } } @@ -115,6 +94,18 @@ $mat-chip-remove-font-size: 18px; display: none; } +.mat-chip-list-container .mat-input-placeholder-wrapper { + top: -4px; + + [dir='rtl'] & { + right: 8px; + } + + [dir='ltr'] & { + margin-left: 8px; + } +} + .mat-chip-input { [dir='rtl'] & { margin-right: 8px; diff --git a/src/lib/chips/index.ts b/src/lib/chips/index.ts index 99826ace423d..8240cabfbb5e 100644 --- a/src/lib/chips/index.ts +++ b/src/lib/chips/index.ts @@ -1,5 +1,5 @@ import {NgModule} from '@angular/core'; -import {MdChipList} from './chip-list'; +import {MdChipList, MdChipListContainer} from './chip-list'; import {MdChip} from './chip'; import {MdChipInput} from './chip-input'; import {MdChipRemove} from './chip-remove'; @@ -11,11 +11,7 @@ export * from './chip-remove'; @NgModule({ imports: [], - exports: [MdChipList, MdChip, MdChipInput, MdChipRemove], - declarations: [MdChipList, MdChip, MdChipInput, MdChipRemove] + exports: [MdChipList, MdChip, MdChipInput, MdChipRemove, MdChipListContainer], + declarations: [MdChipList, MdChip, MdChipInput, MdChipRemove, MdChipListContainer] }) export class MdChipsModule {} - - -export * from './chip-list'; -export * from './chip';