Skip to content
This repository was archived by the owner on Jan 13, 2025. It is now read-only.

Commit afe5367

Browse files
authored
feat(chips): Add entry chips (#2414)
BREAKING CHANGE: Added a new chip variant (entry chips). Added new methods to MDCChipSet, MDCChipSetFoundation, and MDCChipSetAdapter.
1 parent 66f2464 commit afe5367

File tree

8 files changed

+115
-8
lines changed

8 files changed

+115
-8
lines changed

demos/chips.html

+26-4
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,15 @@
5555

5656
<section class="example">
5757
<h2>Entry Chips</h2>
58-
<div class="mdc-chip-set">
58+
<input id="entry-chip-set-input" placeholder="Chip text">
59+
<button id="entry-chip-set-button" class="mdc-button mdc-button--dense">
60+
Add Entry Chip
61+
</button>
62+
<div id="entry-chip-set" class="mdc-chip-set mdc-chip-set--entry">
5963
<div class="demo-chip mdc-chip" tabindex="0">
60-
<i class="material-icons mdc-chip__icon mdc-chip__icon--leading">face</i>
64+
<i id="entry-leading-icon" class="material-icons mdc-chip__icon mdc-chip__icon--leading">face</i>
6165
<div class="mdc-chip__text">Jane Smith</div>
62-
<i class="material-icons mdc-chip__icon mdc-chip__icon--trailing" tabindex="0" role="button" title="More options">more_vert</i>
66+
<i id="entry-trailing-icon" class="material-icons mdc-chip__icon mdc-chip__icon--trailing" tabindex="0" role="button" title="More options">more_vert</i>
6367
</div>
6468
<div class="demo-chip mdc-chip" tabindex="0">
6569
<i class="material-icons mdc-chip__icon mdc-chip__icon--leading">face</i>
@@ -231,10 +235,28 @@ <h2>Custom theme</h2>
231235
<script src="/assets/material-components-web.js" async></script>
232236
<script>
233237
demoReady(function() {
234-
var chipSets = document.querySelectorAll('.mdc-chip-set');
238+
var entryChipSet = document.getElementById('entry-chip-set');
239+
var chipSets = document.querySelectorAll('.mdc-chip-set:not(#entry-chip-set)');
240+
var entryInput = document.getElementById('entry-chip-set-input');
241+
var entryButton = document.getElementById('entry-chip-set-button');
242+
235243
[].forEach.call(chipSets, function(chipSet) {
236244
mdc.chips.MDCChipSet.attachTo(chipSet);
237245
});
246+
var entryChipSetComponent = mdc.chips.MDCChipSet.attachTo(entryChipSet);
247+
248+
function addChip(evt) {
249+
if ((evt.type === 'click' || evt.key === 'Enter' || evt.keyCode === 13) &&
250+
entryInput.value !== '') {
251+
var leadingIcon = document.getElementById('entry-leading-icon').cloneNode(true);
252+
var trailingIcon = document.getElementById('entry-trailing-icon').cloneNode(true);
253+
entryChipSetComponent.addChip(entryInput.value, leadingIcon, trailingIcon);
254+
entryInput.value = '';
255+
}
256+
};
257+
['click', 'keydown'].forEach(function(evtType) {
258+
entryButton.addEventListener(evtType, addChip);
259+
});
238260
});
239261
</script>
240262
</body>

demos/chips.scss

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
@import "./common";
1818
@import "../packages/mdc-chips/mdc-chips";
19+
@import "../packages/mdc-button/mdc-button";
1920

2021
.custom-chip-primary {
2122
@include mdc-chip-fill-color-accessible($mdc-theme-primary);

packages/mdc-chips/README.md

+9-2
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,10 @@ Property | Value Type | Description
190190

191191
#### `MDCChipSet`
192192

193+
Method Signature | Description
194+
--- | ---
195+
`addChip(text: string, leadingIcon: Element, trailingIcon: Element) => void` | Creates a new chip in the chip set with the given text, leading icon, and trailing icon
196+
193197
Property | Value Type | Description
194198
--- | --- | ---
195199
`chips` | Array<`MDCChip`> | An array of the `MDCChip` objects that represent chips in the set
@@ -220,8 +224,10 @@ Method Signature | Description
220224
Method Signature | Description
221225
--- | ---
222226
`hasClass(className: string) => boolean` | Returns whether the chip set element has the given class
223-
`registerInteractionHandler(evtType, handler) => void` | Registers an event handler on the root element for a given event
224-
`deregisterInteractionHandler(evtType, handler) => void` | Deregisters an event handler on the root element for a given event
227+
`registerInteractionHandler(evtType: string, handler: EventListener) => void` | Registers an event handler on the root element for a given event
228+
`deregisterInteractionHandler(evtType: string, handler: EventListener) => void` | Deregisters an event handler on the root element for a given event
229+
`createChipElement(text: string, leadingIcon: Element, trailingIcon: Element) => Element` | Returns a chip element with the given text, leading icon, and trailing icon
230+
`appendChild(el: Element) => void` | Appends the given element as a child of the root element
225231

226232
### Foundations: `MDCChipFoundation` and `MDCChipSetFoundation`
227233

@@ -236,5 +242,6 @@ Method Signature | Description
236242

237243
Method Signature | Description
238244
--- | ---
245+
`addChip(text: string, leadingIcon: Element, trailingIcon: Element) => Element` | Returns a new chip element with the given text, leading icon, and trailing icon, added to the root chip set element
239246
`select(chipFoundation: MDCChipFoundation) => void` | Selects the given chip
240247
`deselect(chipFoundation: MDCChipFoundation) => void` | Deselects the given chip

packages/mdc-chips/chip-set/adapter.js

+15
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,21 @@ class MDCChipSetAdapter {
4848
* @param {function(!Event): undefined} handler
4949
*/
5050
deregisterInteractionHandler(evtType, handler) {}
51+
52+
/**
53+
* Returns a chip element with the given text, leading icon, and trailing icon.
54+
* @param {string} text
55+
* @param {?Element} leadingIcon
56+
* @param {?Element} trailingIcon
57+
* @return {!Element}
58+
*/
59+
createChipElement(text, leadingIcon, trailingIcon) {}
60+
61+
/**
62+
* Appends the given element as a child of the root element.
63+
* @param {?Element} el
64+
*/
65+
appendChild(el) {}
5166
}
5267

5368
export default MDCChipSetAdapter;

packages/mdc-chips/chip-set/foundation.js

+14
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,20 @@ class MDCChipSetFoundation extends MDCFoundation {
7474
MDCChipFoundation.strings.INTERACTION_EVENT, this.chipInteractionHandler_);
7575
}
7676

77+
/**
78+
* Returns a new chip element with the given text, leading icon, and trailing icon,
79+
* added to the root chip set element.
80+
* @param {string} text
81+
* @param {?Element} leadingIcon
82+
* @param {?Element} trailingIcon
83+
* @return {!Element}
84+
*/
85+
addChip(text, leadingIcon, trailingIcon) {
86+
const chipEl = this.adapter_.createChipElement(text, leadingIcon, trailingIcon);
87+
this.adapter_.appendChild(chipEl);
88+
return chipEl;
89+
}
90+
7791
/**
7892
* Selects the given chip. Deselects all other chips if the chip set is of the choice variant.
7993
* @param {!MDCChipFoundation} chipFoundation

packages/mdc-chips/chip-set/index.js

+33-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import MDCComponent from '@material/base/component';
1919

2020
import MDCChipSetAdapter from './adapter';
2121
import MDCChipSetFoundation from './foundation';
22-
import {MDCChip} from '../chip/index';
22+
import {MDCChip, MDCChipFoundation} from '../chip/index';
2323

2424
/**
2525
* @extends {MDCComponent<!MDCChipSetFoundation>}
@@ -34,6 +34,8 @@ class MDCChipSet extends MDCComponent {
3434

3535
/** @type {!Array<!MDCChip>} */
3636
this.chips;
37+
/** @type {(function(!Element): !MDCChip)} */
38+
this.chipFactory_;
3739
}
3840

3941
/**
@@ -49,7 +51,8 @@ class MDCChipSet extends MDCComponent {
4951
* creates a new MDCChip.
5052
*/
5153
initialize(chipFactory = (el) => new MDCChip(el)) {
52-
this.chips = this.instantiateChips_(chipFactory);
54+
this.chipFactory_ = chipFactory;
55+
this.chips = this.instantiateChips_(this.chipFactory_);
5356
}
5457

5558
destroy() {
@@ -66,6 +69,17 @@ class MDCChipSet extends MDCComponent {
6669
});
6770
}
6871

72+
/**
73+
* Creates a new chip in the chip set with the given text, leading icon, and trailing icon.
74+
* @param {string} text
75+
* @param {?Element} leadingIcon
76+
* @param {?Element} trailingIcon
77+
*/
78+
addChip(text, leadingIcon, trailingIcon) {
79+
const chipEl = this.foundation_.addChip(text, leadingIcon, trailingIcon);
80+
this.chips.push(this.chipFactory_(chipEl));
81+
}
82+
6983
/**
7084
* @return {!MDCChipSetFoundation}
7185
*/
@@ -74,6 +88,23 @@ class MDCChipSet extends MDCComponent {
7488
hasClass: (className) => this.root_.classList.contains(className),
7589
registerInteractionHandler: (evtType, handler) => this.root_.addEventListener(evtType, handler),
7690
deregisterInteractionHandler: (evtType, handler) => this.root_.removeEventListener(evtType, handler),
91+
createChipElement: (text, leadingIcon, trailingIcon) => {
92+
const chipTextEl = document.createElement('div');
93+
chipTextEl.classList.add(MDCChipFoundation.cssClasses.TEXT);
94+
chipTextEl.appendChild(document.createTextNode(text));
95+
96+
const chipEl = document.createElement('div');
97+
chipEl.classList.add(MDCChipFoundation.cssClasses.CHIP);
98+
if (leadingIcon) {
99+
chipEl.appendChild(leadingIcon);
100+
}
101+
chipEl.appendChild(chipTextEl);
102+
if (trailingIcon) {
103+
chipEl.appendChild(trailingIcon);
104+
}
105+
return chipEl;
106+
},
107+
appendChild: (el) => this.root_.appendChild(el),
77108
})));
78109
}
79110

packages/mdc-chips/chip/constants.js

+2
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@ const strings = {
2727
/** @enum {string} */
2828
const cssClasses = {
2929
CHECKMARK: 'mdc-chip__checkmark',
30+
CHIP: 'mdc-chip',
3031
HIDDEN_LEADING_ICON: 'mdc-chip__icon--leading-hidden',
3132
LEADING_ICON: 'mdc-chip__icon--leading',
3233
SELECTED: 'mdc-chip--selected',
34+
TEXT: 'mdc-chip__text',
3335
};
3436

3537
export {strings, cssClasses};

test/unit/mdc-chips/mdc-chip-set.test.js

+15
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,18 @@ test('#adapter.deregisterInteractionHandler removes a handler from the root elem
114114
domEvents.emit(root, 'click');
115115
td.verify(handler(td.matchers.anything()), {times: 0});
116116
});
117+
118+
test('#adapter.createChipElement returns a new chip element', () => {
119+
const {component} = setupTest();
120+
const chipEl = component.getDefaultFoundation().adapter_.createChipElement('hello world');
121+
assert.isTrue(chipEl.classList.contains('mdc-chip'));
122+
assert.isTrue(chipEl.childNodes[0].classList.contains('mdc-chip__text'));
123+
assert.equal(chipEl.childNodes[0].textContent, 'hello world');
124+
});
125+
126+
test('#adapter.appendChild adds a child to the chip set element', () => {
127+
const {root, component} = setupTest();
128+
const chipEl = bel`<div class="mdc-chip"><div class="mdc-chip__text">hello world</div></div>`;
129+
component.getDefaultFoundation().adapter_.appendChild(chipEl);
130+
assert.equal(root.childNodes[3], chipEl);
131+
});

0 commit comments

Comments
 (0)