diff --git a/src/demo-app/chips/chips-demo.html b/src/demo-app/chips/chips-demo.html
index 3ad365c44110..692d23e40da9 100644
--- a/src/demo-app/chips/chips-demo.html
+++ b/src/demo-app/chips/chips-demo.html
@@ -8,7 +8,7 @@
Simple
Chip 1
Chip 2
- Chip 3
+ Chip 3
Unstyled
@@ -31,6 +31,56 @@ Advanced
{{message}}
+
+ With avatar and icons
+
+
+
+
+ home
+ Home
+ cancel
+
+
+ P
+ Portel
+ cancel
+
+
+
+ M
+ Molly
+
+
+
+ Koby
+ cancel
+
+
+
+ Razzle
+
+
+
+
+ Mal
+
+
+
+
+ Husi
+ cancel
+
+
+
+ Good
+ star
+
+
+ Bad
+ star_border
+
+
diff --git a/src/lib/chips/_chips-theme.scss b/src/lib/chips/_chips-theme.scss
index fd5ff8f264e6..26110c83d688 100644
--- a/src/lib/chips/_chips-theme.scss
+++ b/src/lib/chips/_chips-theme.scss
@@ -37,11 +37,11 @@ $mat-chip-remove-font-size: 18px;
$unselected-foreground: mat-color($foreground, text);
- .mat-chip:not(.mat-basic-chip) {
+ .mat-chip.mat-standard-chip {
@include mat-chips-color($unselected-foreground, $unselected-background);
}
- .mat-chip.mat-chip-selected {
+ .mat-chip.mat-standard-chip.mat-chip-selected {
&.mat-primary {
@include mat-chips-theme-color($primary);
@@ -62,6 +62,7 @@ $mat-chip-remove-font-size: 18px;
font-size: $mat-chip-font-size;
line-height: $mat-chip-line-height;
+ .mat-chip-trailing-icon.mat-icon,
.mat-chip-remove.mat-icon {
font-size: $mat-chip-remove-font-size;
}
diff --git a/src/lib/chips/chip-list.ts b/src/lib/chips/chip-list.ts
index 643b4d6022aa..dc71b062c372 100644
--- a/src/lib/chips/chip-list.ts
+++ b/src/lib/chips/chip-list.ts
@@ -21,6 +21,7 @@ import {
DoCheck,
ElementRef,
EventEmitter,
+ Inject,
Input,
OnDestroy,
OnInit,
@@ -752,3 +753,4 @@ export class MatChipList extends _MatChipListMixinBase implements MatFormFieldCo
});
}
}
+
diff --git a/src/lib/chips/chip.ts b/src/lib/chips/chip.ts
index 7871ac4fcc96..bd60b052354b 100644
--- a/src/lib/chips/chip.ts
+++ b/src/lib/chips/chip.ts
@@ -10,9 +10,11 @@ import {FocusableOption} from '@angular/cdk/a11y';
import {coerceBooleanProperty} from '@angular/cdk/coercion';
import {BACKSPACE, DELETE, SPACE} from '@angular/cdk/keycodes';
import {
+ ContentChild,
Directive,
ElementRef,
EventEmitter,
+ forwardRef,
Input,
OnDestroy,
Output,
@@ -47,17 +49,27 @@ export class MatChipBase {
export const _MatChipMixinBase = mixinColor(mixinDisabled(MatChipBase), 'primary');
+const CHIP_ATTRIBUTE_NAMES = ['mat-basic-chip'];
/**
- * Dummy directive to add CSS class to basic chips.
+ * Dummy directive to add CSS class to chip avatar.
* @docs-private
*/
@Directive({
- selector: `mat-basic-chip, [mat-basic-chip]`,
- host: {'class': 'mat-basic-chip'},
+ selector: 'mat-chip-avatar, [matChipAvatar]',
+ host: {'class': 'mat-chip-avatar'}
})
-export class MatBasicChip {
-}
+export class MatChipAvatar {}
+
+/**
+ * Dummy directive to add CSS class to chip trailing icon.
+ * @docs-private
+ */
+@Directive({
+ selector: 'mat-chip-trailing-icon, [matChipTrailingIcon]',
+ host: {'class': 'mat-chip-trailing-icon'}
+})
+export class MatChipTrailingIcon {}
/**
* Material design styled Chip component. Used inside the MatChipList component.
@@ -71,6 +83,8 @@ export class MatBasicChip {
'[attr.tabindex]': 'disabled ? null : -1',
'role': 'option',
'[class.mat-chip-selected]': 'selected',
+ '[class.mat-chip-with-avatar]': 'avatar',
+ '[class.mat-chip-with-trailing-icon]': 'trailingIcon || removeIcon',
'[attr.disabled]': 'disabled || null',
'[attr.aria-disabled]': 'disabled.toString()',
'[attr.aria-selected]': 'ariaSelected',
@@ -95,6 +109,15 @@ export class MatChip extends _MatChipMixinBase implements FocusableOption, OnDes
/** Whether the chip has focus. */
_hasFocus: boolean = false;
+ /** The chip avatar */
+ @ContentChild(MatChipAvatar) avatar: MatChipAvatar;
+
+ /** The chip's trailing icon. */
+ @ContentChild(MatChipTrailingIcon) trailingIcon: MatChipTrailingIcon;
+
+ /** The chip's remove toggler. */
+ @ContentChild(forwardRef(() => MatChipRemove)) removeIcon: MatChipRemove;
+
/** Whether the chip is selected. */
@Input()
get selected(): boolean { return this._selected; }
@@ -170,6 +193,20 @@ export class MatChip extends _MatChipMixinBase implements FocusableOption, OnDes
constructor(public _elementRef: ElementRef) {
super(_elementRef);
+
+ this._addHostClassName();
+ }
+
+ _addHostClassName() {
+ // Add class for the different chips
+ for (const attr of CHIP_ATTRIBUTE_NAMES) {
+ if (this._elementRef.nativeElement.hasAttribute(attr) ||
+ this._elementRef.nativeElement.tagName.toLowerCase() === attr) {
+ (this._elementRef.nativeElement as HTMLElement).classList.add(attr);
+ return;
+ }
+ }
+ (this._elementRef.nativeElement as HTMLElement).classList.add('mat-standard-chip');
}
ngOnDestroy(): void {
@@ -300,7 +337,7 @@ export class MatChip extends _MatChipMixinBase implements FocusableOption, OnDes
@Directive({
selector: '[matChipRemove]',
host: {
- 'class': 'mat-chip-remove',
+ 'class': 'mat-chip-remove mat-chip-trailing-icon',
'(click)': '_handleClick()',
}
})
diff --git a/src/lib/chips/chips-module.ts b/src/lib/chips/chips-module.ts
index 3a8ca64e0f81..8c4cb7131cc9 100644
--- a/src/lib/chips/chips-module.ts
+++ b/src/lib/chips/chips-module.ts
@@ -9,14 +9,22 @@
import {NgModule} from '@angular/core';
import {ErrorStateMatcher} from '@angular/material/core';
import {MatChipList} from './chip-list';
-import {MatBasicChip, MatChip, MatChipRemove} from './chip';
+import {MatChip, MatChipRemove, MatChipAvatar, MatChipTrailingIcon} from './chip';
import {MatChipInput} from './chip-input';
+const CHIP_DECLARATIONS = [
+ MatChipList,
+ MatChip,
+ MatChipInput,
+ MatChipRemove,
+ MatChipAvatar,
+ MatChipTrailingIcon,
+];
@NgModule({
imports: [],
- exports: [MatChipList, MatChip, MatChipInput, MatChipRemove, MatChipRemove, MatBasicChip],
- declarations: [MatChipList, MatChip, MatChipInput, MatChipRemove, MatChipRemove, MatBasicChip],
+ exports: CHIP_DECLARATIONS,
+ declarations: CHIP_DECLARATIONS,
providers: [ErrorStateMatcher]
})
export class MatChipsModule {}
diff --git a/src/lib/chips/chips.scss b/src/lib/chips/chips.scss
index 541e9cc2bb13..de53e33fd911 100644
--- a/src/lib/chips/chips.scss
+++ b/src/lib/chips/chips.scss
@@ -3,22 +3,24 @@
$mat-chip-vertical-padding: 7px;
$mat-chip-horizontal-padding: 12px;
-$mat-chip-remove-margin-before: 6px;
-$mat-chip-remove-margin-after: -4px;
-$mat-chips-chip-margin: 8px;
+$mat-chip-remove-vertical-padding: 7px;
+$mat-chip-remove-before-margin: 7px;
+$mat-chip-remove-after-padding: 7px;
+
+$mat-chip-avatar-vertical-padding: 0;
+$mat-chip-avatar-before-padding: 0;
+$mat-chip-avatar-after-margin: 8px;
+
+$mat-chips-chip-margin: 4px;
$mat-chip-input-width: 150px;
$mat-chip-input-margin: 3px;
-.mat-chip-list-wrapper {
- display: flex;
- flex-direction: row;
- flex-wrap: wrap;
- align-items: baseline;
-}
+$mat-chip-avatar-size: 32px;
+$mat-chip-remove-size: 18px;
-.mat-chip:not(.mat-basic-chip) {
+.mat-standard-chip {
@include mat-elevation-transition;
display: inline-flex;
padding: $mat-chip-vertical-padding $mat-chip-horizontal-padding;
@@ -26,28 +28,13 @@ $mat-chip-input-margin: 3px;
align-items: center;
cursor: default;
- // Apply a margin to adjacent sibling chips.
- & + & {
- margin: 0 0 0 $mat-chips-chip-margin;
-
- [dir='rtl'] & {
- margin: 0 $mat-chips-chip-margin 0 0;
- }
- }
-
- .mat-form-field-prefix & {
- &:last-child {
- margin-right: $mat-chips-chip-margin;
- }
-
- [dir='rtl'] &:last-child {
- margin-left: $mat-chips-chip-margin;
- }
+ .mat-chip-list-wrapper & {
+ margin: $mat-chips-chip-margin;
}
.mat-chip-remove.mat-icon {
- width: 1em;
- height: 1em;
+ width: $mat-chip-remove-size;
+ height: $mat-chip-remove-size;
}
&:focus {
@@ -58,42 +45,100 @@ $mat-chip-input-margin: 3px;
@include cdk-high-contrast {
outline: solid 1px;
}
-}
-.mat-chip-list-stacked .mat-chip-list-wrapper {
- display: block;
+ &.mat-chip-with-trailing-icon.mat-chip-with-avatar,
+ &.mat-chip-with-avatar {
+ padding-top: $mat-chip-avatar-vertical-padding;
+ padding-bottom: $mat-chip-avatar-vertical-padding;
+ }
+
+ &.mat-chip-with-trailing-icon.mat-chip-with-avatar {
+ padding-right: $mat-chip-remove-after-padding;
+ padding-left: $mat-chip-avatar-before-padding;
+
+ [dir='rtl'] & {
+ padding-left: $mat-chip-remove-after-padding;
+ padding-right: $mat-chip-avatar-before-padding;
+ }
+ }
+
+ &.mat-chip-with-trailing-icon {
+ padding-top: $mat-chip-remove-vertical-padding;
+ padding-bottom: $mat-chip-remove-vertical-padding;
+ padding-right: $mat-chip-remove-after-padding;
+ padding-left: $mat-chip-horizontal-padding;
- .mat-chip:not(.mat-basic-chip) {
- display: block;
- margin: 0;
- margin-bottom: $mat-chips-chip-margin;
+ [dir='rtl'] & {
+ padding-left: $mat-chip-remove-after-padding;
+ padding-right: $mat-chip-horizontal-padding;
+ }
+ }
+
+ &.mat-chip-with-avatar {
+ padding-left: $mat-chip-avatar-before-padding;
+ padding-right: $mat-chip-horizontal-padding;
+
+ [dir='rtl'] & {
+ padding-right: $mat-chip-avatar-before-padding;
+ padding-left: $mat-chip-horizontal-padding;
+ }
+ }
+
+ .mat-chip-avatar {
+ width: $mat-chip-avatar-size;
+ height: $mat-chip-avatar-size;
+ margin-right: $mat-chip-avatar-after-margin;
+ margin-left: 0;
[dir='rtl'] & {
- margin: 0;
- margin-bottom: $mat-chips-chip-margin;
+ margin-left: $mat-chip-avatar-after-margin;
+ margin-right: 0;
}
+ }
+
+ .mat-chip-remove,
+ .mat-chip-trailing-icon {
+ width: $mat-chip-remove-size;
+ height: $mat-chip-remove-size;
+ cursor: pointer;
+ }
- &:last-child, [dir='rtl'] &:last-child {
- margin-bottom: 0;
+ .mat-chip-remove,
+ .mat-chip-trailing-icon {
+ margin-left: $mat-chip-remove-before-margin;
+ margin-right: 0;
+
+ [dir='rtl'] & {
+ margin-right: $mat-chip-remove-before-margin;
+ margin-left: 0;
}
}
}
-.mat-form-field-prefix .mat-chip-list-wrapper {
- margin-bottom: $mat-chips-chip-margin;
+.mat-chip-list-wrapper {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ align-items: center;
}
-.mat-chip-remove {
- margin-right: $mat-chip-remove-margin-after;
- margin-left: $mat-chip-remove-margin-before;
- cursor: pointer;
+.mat-chip-list-stacked .mat-chip-list-wrapper {
+ flex-direction: column;
+ align-items: flex-start;
- [dir='rtl'] & {
- margin-right: $mat-chip-remove-margin-before;
- margin-left: $mat-chip-remove-margin-after;
+ .mat-standard-chip {
+ width: 100%;
}
}
+.mat-chip-avatar {
+ border-radius: 50%;
+ justify-content: center;
+ align-items: center;
+ display: flex;
+ overflow: hidden;
+}
+
input.mat-chip-input {
width: $mat-chip-input-width;
margin: $mat-chip-input-margin;
diff --git a/src/lib/chips/public-api.ts b/src/lib/chips/public-api.ts
index a93755ac6646..940403e4c0be 100644
--- a/src/lib/chips/public-api.ts
+++ b/src/lib/chips/public-api.ts
@@ -10,4 +10,3 @@ export * from './chips-module';
export * from './chip-list';
export * from './chip';
export * from './chip-input';
-