Skip to content

Commit 449ec52

Browse files
authored
feat(chips): implement chips and chip-sets (#640, #632)
1 parent 9f7d96f commit 449ec52

23 files changed

+1159
-1
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Component | Documentation |
2424
button | [button docs & demo](https://blox.src.zone/material/directives/button) |
2525
card | [card docs & demo](https://blox.src.zone/material/directives/card) |
2626
checkbox | [checkbox docs & demo](https://blox.src.zone/material/directives/checkbox) |
27-
chips | in tracker |
27+
chips | [chips docs & demo](https://blox.src.zone/material/directives/chips) |
2828
dialog | [dialog docs & demo](https://blox.src.zone/material/directives/drawer) |
2929
drawer | [drawer docs & demo](https://blox.src.zone/material/directives/drawer) |
3030
elevation | [elevation docs & demo](https://blox.src.zone/material/directives/elevation) |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/** @docs-private */
2+
export interface MdcChipSetAdapter {
3+
hasClass: (className: string) => boolean,
4+
registerInteractionHandler: (evtType: string, handler: EventListener) => void,
5+
deregisterInteractionHandler: (evtType: string, handler: EventListener) => void,
6+
appendChip: (text: string, leadingIcon: Element, trailingIcon: Element) => Element,
7+
removeChip: (chip: any) => void
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/** @docs-private */
2+
export interface MdcChipAdapter {
3+
addClass: (className: string) => void,
4+
removeClass: (className: string) => void,
5+
hasClass: (className: string) => boolean,
6+
addClassToLeadingIcon: (className: string) => void,
7+
removeClassFromLeadingIcon: (className: string) => void,
8+
eventTargetHasClass: (target: EventTarget, className: string) => boolean,
9+
registerEventHandler: (evtType: string, handler: EventListener) => void,
10+
deregisterEventHandler: (evtType: string, handler: EventListener) => void,
11+
registerTrailingIconInteractionHandler: (evtType: string, handler: EventListener) => void,
12+
deregisterTrailingIconInteractionHandler: (evtType: string, handler: EventListener) => void,
13+
notifyInteraction: () => void,
14+
notifyTrailingIconInteraction: () => void,
15+
notifyRemoval: () => void,
16+
getComputedStyleValue: (propertyName: string) => string,
17+
setStyleProperty: (propertyName: string, value: string) => void
18+
}

bundle/src/components/chips/mdc.chip.directive.spec.ts

+425
Large diffs are not rendered by default.

bundle/src/components/chips/mdc.chip.directive.ts

+468
Large diffs are not rendered by default.

bundle/src/material.module.ts

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { MdcCardDirective,
1010
MdcCardPrimaryActionDirective } from './components/card/mdc.card.directive';
1111
import { MdcCheckboxDirective,
1212
MdcCheckboxInputDirective } from './components/checkbox/mdc.checkbox.directive';
13+
import { CHIP_DIRECTIVES } from './components/chips/mdc.chip.directive';
1314
import { DIALOG_DIRECTIVES } from './components/dialog/mdc.dialog.directive';
1415
import { MdcDrawerDirective,
1516
MdcDrawerContainerDirective,
@@ -84,6 +85,7 @@ export { MdcCardDirective,
8485
MdcCardPrimaryActionDirective } from './components/card/mdc.card.directive';
8586
export { MdcCheckboxDirective,
8687
MdcCheckboxInputDirective } from './components/checkbox/mdc.checkbox.directive';
88+
export * from './components/chips/mdc.chip.directive';
8789
export * from './components/dialog/mdc.dialog.directive';
8890
export { MdcDrawerDirective,
8991
MdcDrawerContainerDirective,
@@ -160,6 +162,7 @@ export { MdcEventRegistry } from './utils/mdc.event.registry';
160162
MdcCardDirective, MdcCardMediaDirective, MdcCardMediaContentDirective,
161163
MdcCardActionButtonsDirective, MdcCardActionIconsDirective, MdcCardActionsDirective, MdcCardPrimaryActionDirective,
162164
MdcCheckboxDirective, MdcCheckboxInputDirective,
165+
...CHIP_DIRECTIVES,
163166
...DIALOG_DIRECTIVES,
164167
MdcDrawerDirective, MdcDrawerContainerDirective, MdcDrawerToolbarSpacerDirective, MdcDrawerHeaderDirective, MdcDrawerHeaderContentDirective, MdcDrawerContentDirective,
165168
MdcElevationDirective,
@@ -191,6 +194,7 @@ export { MdcEventRegistry } from './utils/mdc.event.registry';
191194
MdcCardDirective, MdcCardMediaDirective, MdcCardMediaContentDirective,
192195
MdcCardActionButtonsDirective, MdcCardActionIconsDirective, MdcCardActionsDirective, MdcCardPrimaryActionDirective,
193196
MdcCheckboxDirective, MdcCheckboxInputDirective,
197+
...CHIP_DIRECTIVES,
194198
...DIALOG_DIRECTIVES,
195199
MdcDrawerDirective, MdcDrawerContainerDirective, MdcDrawerToolbarSpacerDirective, MdcDrawerHeaderDirective, MdcDrawerHeaderContentDirective, MdcDrawerContentDirective,
196200
MdcElevationDirective,

bundle/tools/ngbundler/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const globals = {
99
'@angular/router': 'ng.router',
1010
'@material/animation': 'mdc.animation',
1111
'@material/checkbox': 'mdc.checkbox',
12+
'@material/chips': 'mdc.chips',
1213
'@material/dialog': 'mdc.dialog',
1314
'@material/drawer': 'mdc.drawer',
1415
'@material/drawer/slidable': 'mdc.drawer',

site/src/app/app.module.ts

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
SnippetButtonComponent,
2525
SnippetCardComponent,
2626
SnippetCheckboxComponent,
27+
SnippetChipsComponent, SnippetChipsChoiceComponent, SnippetChipsFilterComponent, SnippetChipsInputComponent,
2728
SnippetDialogComponent,
2829
SnippetDrawerPermanentBelowComponent,
2930
SnippetDrawerPermanentComponent,
@@ -77,6 +78,7 @@ import { ThemeService } from './services';
7778
SnippetButtonComponent,
7879
SnippetCardComponent,
7980
SnippetCheckboxComponent,
81+
SnippetChipsComponent, SnippetChipsChoiceComponent, SnippetChipsFilterComponent, SnippetChipsInputComponent,
8082
SnippetDialogComponent,
8183
SnippetDrawerPermanentBelowComponent,
8284
SnippetDrawerPermanentComponent,

site/src/app/app.routes.ts

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
ButtonDirectivesComponent,
1313
CardDirectivesComponent,
1414
CheckboxDirectivesComponent,
15+
ChipsDirectivesComponent,
1516
DialogDirectivesComponent,
1617
DrawerDirectivesComponent,
1718
ElevationDirectivesComponent,
@@ -45,6 +46,7 @@ export const routes: Routes = [
4546
{path: ButtonDirectivesComponent.DOC_HREF, component: ButtonDirectivesComponent},
4647
{path: CardDirectivesComponent.DOC_HREF, component: CardDirectivesComponent},
4748
{path: CheckboxDirectivesComponent.DOC_HREF, component: CheckboxDirectivesComponent},
49+
{path: ChipsDirectivesComponent.DOC_HREF, component: ChipsDirectivesComponent},
4850
{path: DialogDirectivesComponent.DOC_HREF, component: DialogDirectivesComponent},
4951
{path: DrawerDirectivesComponent.DOC_HREF, component: DrawerDirectivesComponent},
5052
{path: ElevationDirectivesComponent.DOC_HREF, component: ElevationDirectivesComponent},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<h1>Chips</h1>
2+
<p>Chips are compact elements that allow users to enter information, select a choice, filter content, or trigger an action.
3+
</p>
4+
<blox-code-sample>
5+
<span bloxSampleTitle>Action Chips Demo</span>
6+
<blox-snippet-chips bloxSample></blox-snippet-chips>
7+
</blox-code-sample>
8+
<br/>
9+
<blox-code-sample>
10+
<span bloxSampleTitle>Choice Chips Demo</span>
11+
<blox-snippet-chips-choice bloxSample></blox-snippet-chips-choice>
12+
</blox-code-sample>
13+
<br/>
14+
<blox-code-sample>
15+
<span bloxSampleTitle>Filter Chips Demo</span>
16+
<blox-snippet-chips-filter bloxSample></blox-snippet-chips-filter>
17+
</blox-code-sample>
18+
<br/>
19+
<blox-code-sample>
20+
<span bloxSampleTitle>Input Chips Demo</span>
21+
<blox-snippet-chips-input bloxSample></blox-snippet-chips-input>
22+
</blox-code-sample>
23+
24+
<div class="blox-docs-api">${require('@blox/material/apidocs/chips.html')}</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { Component } from '@angular/core';
2+
3+
@Component({
4+
selector: 'blox-chips-directives',
5+
templateUrl: './chips.directives.component.html'
6+
})
7+
export class ChipsDirectivesComponent {
8+
static DOC_SVG = require('assets/img/mdc-icons/chip.svg');
9+
static DOC_TYPE = 'components';
10+
static DOC_HREF = 'chips';
11+
12+
constructor() {
13+
}
14+
}

site/src/app/components/directives.demo/index.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ButtonDirectivesComponent } from './button.directives.component';
22
import { CardDirectivesComponent } from './card.directives.component';
33
import { CheckboxDirectivesComponent } from './checkbox.directives.component';
4+
import { ChipsDirectivesComponent } from './chips.directives.component';
45
import { DialogDirectivesComponent } from './dialog.directives.component';
56
import { DrawerDirectivesComponent } from './drawer.directives.component';
67
import { ElevationDirectivesComponent } from './elevation.directives.component';
@@ -24,6 +25,7 @@ import { UtilityDirectivesComponent } from './utility.directives.component';
2425
export * from './button.directives.component';
2526
export * from './card.directives.component';
2627
export * from './checkbox.directives.component';
28+
export * from './chips.directives.component';
2729
export * from './dialog.directives.component';
2830
export * from './drawer.directives.component';
2931
export * from './elevation.directives.component';
@@ -48,6 +50,7 @@ export const MDC_DIRECTIVE_DOC_COMPONENTS = [
4850
ButtonDirectivesComponent,
4951
CardDirectivesComponent,
5052
CheckboxDirectivesComponent,
53+
ChipsDirectivesComponent,
5154
DialogDirectivesComponent,
5255
DrawerDirectivesComponent,
5356
ElevationDirectivesComponent,

site/src/app/components/snippets/directives/index.ts

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
export * from './snippet.button.component';
22
export * from './snippet.card.component';
33
export * from './snippet.checkbox.component';
4+
export * from './snippet.chips.component';
5+
export * from './snippet.chips.choice.component';
6+
export * from './snippet.chips.filter.component';
7+
export * from './snippet.chips.input.component';
48
export * from './snippet.dialog.component';
59
export * from './snippet.drawer.permanent.below.component';
610
export * from './snippet.drawer.permanent.component';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<fieldset class="blox-snippet snippet-skip-line">
2+
<div mdcChipSet="choice">
3+
<div mdcChip><div mdcChipText>Extra Small</div></div>
4+
<div mdcChip><div mdcChipText>Small</div></div>
5+
<div mdcChip><div mdcChipText>Medium</div></div>
6+
<div mdcChip><div mdcChipText>Large</div></div>
7+
<div mdcChip><div mdcChipText>Extra Large</div></div>
8+
</div>
9+
</fieldset><div class="snippet-skip-line"></div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Component } from '@angular/core';
2+
//snip:skip
3+
import { forwardRef } from '@angular/core';
4+
import { AbstractSnippetComponent } from '../abstract.snippet.component';
5+
//snip:endskip
6+
@Component({
7+
//snip:skip
8+
providers: [{provide: AbstractSnippetComponent, useExisting: forwardRef(() => SnippetChipsChoiceComponent)}],
9+
//snip:endskip
10+
selector: 'blox-snippet-chips-choice',
11+
templateUrl: './snippet.chips.choice.component.html'
12+
})
13+
export class SnippetChipsChoiceComponent/*snip:skip*/extends AbstractSnippetComponent/*snip:endskip*/ {
14+
//snip:skip
15+
constructor() {
16+
super({
17+
'html': require('!raw-loader!./snippet.chips.choice.component.html'),
18+
'typescript': require('!raw-loader!./snippet.chips.choice.component.ts')
19+
});
20+
}
21+
//snip:endskip
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<fieldset class="blox-snippet snippet-skip-line">
2+
<div mdcChipSet>
3+
<div mdcChip>
4+
<i mdcChipIcon class="material-icons">wb_sunny</i>
5+
<div mdcChipText>Turn lights on</div>
6+
</div>
7+
<div mdcChip>
8+
<i mdcChipIcon class="material-icons">bookmark</i>
9+
<div mdcChipText>Bookmark</div>
10+
</div>
11+
<div mdcChip>
12+
<i mdcChipIcon class="material-icons">alarm</i>
13+
<div mdcChipText>Set alarm</div>
14+
</div>
15+
<div mdcChip>
16+
<i mdcChipIcon class="material-icons">directions</i>
17+
<div mdcChipText>Get directions</div>
18+
</div>
19+
</div>
20+
</fieldset><div class="snippet-skip-line"></div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Component } from '@angular/core';
2+
//snip:skip
3+
import { forwardRef } from '@angular/core';
4+
import { AbstractSnippetComponent } from '../abstract.snippet.component';
5+
//snip:endskip
6+
@Component({
7+
//snip:skip
8+
providers: [{provide: AbstractSnippetComponent, useExisting: forwardRef(() => SnippetChipsComponent)}],
9+
//snip:endskip
10+
selector: 'blox-snippet-chips',
11+
templateUrl: './snippet.chips.component.html'
12+
})
13+
export class SnippetChipsComponent/*snip:skip*/extends AbstractSnippetComponent/*snip:endskip*/ {
14+
//snip:skip
15+
constructor() {
16+
super({
17+
'html': require('!raw-loader!./snippet.chips.component.html'),
18+
'typescript': require('!raw-loader!./snippet.chips.component.ts')
19+
});
20+
}
21+
//snip:endskip
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<fieldset class="blox-snippet snippet-skip-line">
2+
<div mdcChipSet="filter">
3+
<div mdcChip>
4+
<i mdcChipIcon class="material-icons">message</i>
5+
<div mdcChipText>Messages</div>
6+
</div>
7+
<div mdcChip>
8+
<i mdcChipIcon class="material-icons">notification_important</i>
9+
<div mdcChipText>Notifications</div>
10+
</div>
11+
<div mdcChip>
12+
<i mdcChipIcon class="material-icons">warning</i>
13+
<div mdcChipText>Warnings</div>
14+
</div>
15+
<div mdcChip>
16+
<i mdcChipIcon class="material-icons">error</i>
17+
<div mdcChipText>Errors</div>
18+
</div>
19+
</div>
20+
</fieldset><div class="snippet-skip-line"></div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Component } from '@angular/core';
2+
//snip:skip
3+
import { forwardRef } from '@angular/core';
4+
import { AbstractSnippetComponent } from '../abstract.snippet.component';
5+
//snip:endskip
6+
@Component({
7+
//snip:skip
8+
providers: [{provide: AbstractSnippetComponent, useExisting: forwardRef(() => SnippetChipsFilterComponent)}],
9+
//snip:endskip
10+
selector: 'blox-snippet-chips-filter',
11+
templateUrl: './snippet.chips.filter.component.html'
12+
})
13+
export class SnippetChipsFilterComponent/*snip:skip*/extends AbstractSnippetComponent/*snip:endskip*/ {
14+
//snip:skip
15+
constructor() {
16+
super({
17+
'html': require('!raw-loader!./snippet.chips.filter.component.html'),
18+
'typescript': require('!raw-loader!./snippet.chips.filter.component.ts')
19+
});
20+
}
21+
//snip:endskip
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<fieldset class="blox-snippet snippet-skip-line">
2+
<div mdcChipSet="input">
3+
<div *ngFor="let chip of chips; let i = index" mdcChip (remove)="removeChip(i)">
4+
<i mdcChipIcon class="material-icons">face</i>
5+
<div mdcChipText>{{chip}}</div>
6+
<i class="material-icons" mdcChipIcon>cancel</i>
7+
</div>
8+
</div>
9+
<form (submit)="addChip()">
10+
<div mdcTextField>
11+
<input mdcTextFieldInput type="text" name="chipInput" [(ngModel)]="newChip" autocomplete="off"/>
12+
<label mdcFloatingLabel>Add Chip</label>
13+
</div>
14+
<button type="submit" mdcButton [disabled]="!newChip">Add Chip</button>
15+
</form>
16+
</fieldset><div class="snippet-skip-line"></div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { Component } from '@angular/core';
2+
//snip:skip
3+
import { forwardRef } from '@angular/core';
4+
import { AbstractSnippetComponent } from '../abstract.snippet.component';
5+
//snip:endskip
6+
@Component({
7+
//snip:skip
8+
providers: [{provide: AbstractSnippetComponent, useExisting: forwardRef(() => SnippetChipsInputComponent)}],
9+
//snip:endskip
10+
selector: 'blox-snippet-chips-input',
11+
templateUrl: './snippet.chips.input.component.html'
12+
})
13+
export class SnippetChipsInputComponent/*snip:skip*/extends AbstractSnippetComponent/*snip:endskip*/ {
14+
chips = [ 'claire', 'pete', 'anne' ];
15+
newChip: string;
16+
17+
//snip:skip
18+
constructor() {
19+
super({
20+
'html': require('!raw-loader!./snippet.chips.input.component.html'),
21+
'typescript': require('!raw-loader!./snippet.chips.input.component.ts')
22+
});
23+
}
24+
//snip:endskip
25+
26+
addChip() {
27+
if (this.newChip) {
28+
let value = this.newChip.trim();
29+
if (value.length)
30+
this.chips.push(value);
31+
}
32+
this.newChip = null;
33+
}
34+
35+
removeChip(index: number) {
36+
this.chips.splice(index, 1);
37+
}
38+
}

site/src/app/messages.json

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
"components.checkbox.title": "Checkbox",
1212
"components.checkbox.description": "Multi selection controls",
1313
"components.checkbox.meta.description": "Checkbox (mdcCheckbox) component of ${default.meta.description}",
14+
"components.chips.title": "Chips",
15+
"components.chips.description": "Chips for actions, selection, and input",
16+
"components.chips.meta.description": "Chips (mdcChip, mdcChipSet) components of ${default.meta.description}",
1417
"components.dialog.title": "Dialog",
1518
"components.dialog.description": "Modal Dialogs",
1619
"components.dialog.meta.description": "Dialog (mdcDialog) component of ${default.meta.description}",

0 commit comments

Comments
 (0)