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

Commit

Permalink
feat(chips): Add entry chips (#2414)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Added a new chip variant (entry chips). Added new methods to MDCChipSet, MDCChipSetFoundation, and MDCChipSetAdapter.
  • Loading branch information
bonniezhou authored Apr 6, 2018
1 parent 66f2464 commit afe5367
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 8 deletions.
30 changes: 26 additions & 4 deletions demos/chips.html
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,15 @@

<section class="example">
<h2>Entry Chips</h2>
<div class="mdc-chip-set">
<input id="entry-chip-set-input" placeholder="Chip text">
<button id="entry-chip-set-button" class="mdc-button mdc-button--dense">
Add Entry Chip
</button>
<div id="entry-chip-set" class="mdc-chip-set mdc-chip-set--entry">
<div class="demo-chip mdc-chip" tabindex="0">
<i class="material-icons mdc-chip__icon mdc-chip__icon--leading">face</i>
<i id="entry-leading-icon" class="material-icons mdc-chip__icon mdc-chip__icon--leading">face</i>
<div class="mdc-chip__text">Jane Smith</div>
<i class="material-icons mdc-chip__icon mdc-chip__icon--trailing" tabindex="0" role="button" title="More options">more_vert</i>
<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>
</div>
<div class="demo-chip mdc-chip" tabindex="0">
<i class="material-icons mdc-chip__icon mdc-chip__icon--leading">face</i>
Expand Down Expand Up @@ -231,10 +235,28 @@ <h2>Custom theme</h2>
<script src="/assets/material-components-web.js" async></script>
<script>
demoReady(function() {
var chipSets = document.querySelectorAll('.mdc-chip-set');
var entryChipSet = document.getElementById('entry-chip-set');
var chipSets = document.querySelectorAll('.mdc-chip-set:not(#entry-chip-set)');
var entryInput = document.getElementById('entry-chip-set-input');
var entryButton = document.getElementById('entry-chip-set-button');

[].forEach.call(chipSets, function(chipSet) {
mdc.chips.MDCChipSet.attachTo(chipSet);
});
var entryChipSetComponent = mdc.chips.MDCChipSet.attachTo(entryChipSet);

function addChip(evt) {
if ((evt.type === 'click' || evt.key === 'Enter' || evt.keyCode === 13) &&
entryInput.value !== '') {
var leadingIcon = document.getElementById('entry-leading-icon').cloneNode(true);
var trailingIcon = document.getElementById('entry-trailing-icon').cloneNode(true);
entryChipSetComponent.addChip(entryInput.value, leadingIcon, trailingIcon);
entryInput.value = '';
}
};
['click', 'keydown'].forEach(function(evtType) {
entryButton.addEventListener(evtType, addChip);
});
});
</script>
</body>
Expand Down
1 change: 1 addition & 0 deletions demos/chips.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

@import "./common";
@import "../packages/mdc-chips/mdc-chips";
@import "../packages/mdc-button/mdc-button";

.custom-chip-primary {
@include mdc-chip-fill-color-accessible($mdc-theme-primary);
Expand Down
11 changes: 9 additions & 2 deletions packages/mdc-chips/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@ Property | Value Type | Description

#### `MDCChipSet`

Method Signature | Description
--- | ---
`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

Property | Value Type | Description
--- | --- | ---
`chips` | Array<`MDCChip`> | An array of the `MDCChip` objects that represent chips in the set
Expand Down Expand Up @@ -220,8 +224,10 @@ Method Signature | Description
Method Signature | Description
--- | ---
`hasClass(className: string) => boolean` | Returns whether the chip set element has the given class
`registerInteractionHandler(evtType, handler) => void` | Registers an event handler on the root element for a given event
`deregisterInteractionHandler(evtType, handler) => void` | Deregisters an event handler on the root element for a given event
`registerInteractionHandler(evtType: string, handler: EventListener) => void` | Registers an event handler on the root element for a given event
`deregisterInteractionHandler(evtType: string, handler: EventListener) => void` | Deregisters an event handler on the root element for a given event
`createChipElement(text: string, leadingIcon: Element, trailingIcon: Element) => Element` | Returns a chip element with the given text, leading icon, and trailing icon
`appendChild(el: Element) => void` | Appends the given element as a child of the root element

### Foundations: `MDCChipFoundation` and `MDCChipSetFoundation`

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

Method Signature | Description
--- | ---
`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
`select(chipFoundation: MDCChipFoundation) => void` | Selects the given chip
`deselect(chipFoundation: MDCChipFoundation) => void` | Deselects the given chip
15 changes: 15 additions & 0 deletions packages/mdc-chips/chip-set/adapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,21 @@ class MDCChipSetAdapter {
* @param {function(!Event): undefined} handler
*/
deregisterInteractionHandler(evtType, handler) {}

/**
* Returns a chip element with the given text, leading icon, and trailing icon.
* @param {string} text
* @param {?Element} leadingIcon
* @param {?Element} trailingIcon
* @return {!Element}
*/
createChipElement(text, leadingIcon, trailingIcon) {}

/**
* Appends the given element as a child of the root element.
* @param {?Element} el
*/
appendChild(el) {}
}

export default MDCChipSetAdapter;
14 changes: 14 additions & 0 deletions packages/mdc-chips/chip-set/foundation.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,20 @@ class MDCChipSetFoundation extends MDCFoundation {
MDCChipFoundation.strings.INTERACTION_EVENT, this.chipInteractionHandler_);
}

/**
* Returns a new chip element with the given text, leading icon, and trailing icon,
* added to the root chip set element.
* @param {string} text
* @param {?Element} leadingIcon
* @param {?Element} trailingIcon
* @return {!Element}
*/
addChip(text, leadingIcon, trailingIcon) {
const chipEl = this.adapter_.createChipElement(text, leadingIcon, trailingIcon);
this.adapter_.appendChild(chipEl);
return chipEl;
}

/**
* Selects the given chip. Deselects all other chips if the chip set is of the choice variant.
* @param {!MDCChipFoundation} chipFoundation
Expand Down
35 changes: 33 additions & 2 deletions packages/mdc-chips/chip-set/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import MDCComponent from '@material/base/component';

import MDCChipSetAdapter from './adapter';
import MDCChipSetFoundation from './foundation';
import {MDCChip} from '../chip/index';
import {MDCChip, MDCChipFoundation} from '../chip/index';

/**
* @extends {MDCComponent<!MDCChipSetFoundation>}
Expand All @@ -34,6 +34,8 @@ class MDCChipSet extends MDCComponent {

/** @type {!Array<!MDCChip>} */
this.chips;
/** @type {(function(!Element): !MDCChip)} */
this.chipFactory_;
}

/**
Expand All @@ -49,7 +51,8 @@ class MDCChipSet extends MDCComponent {
* creates a new MDCChip.
*/
initialize(chipFactory = (el) => new MDCChip(el)) {
this.chips = this.instantiateChips_(chipFactory);
this.chipFactory_ = chipFactory;
this.chips = this.instantiateChips_(this.chipFactory_);
}

destroy() {
Expand All @@ -66,6 +69,17 @@ class MDCChipSet extends MDCComponent {
});
}

/**
* Creates a new chip in the chip set with the given text, leading icon, and trailing icon.
* @param {string} text
* @param {?Element} leadingIcon
* @param {?Element} trailingIcon
*/
addChip(text, leadingIcon, trailingIcon) {
const chipEl = this.foundation_.addChip(text, leadingIcon, trailingIcon);
this.chips.push(this.chipFactory_(chipEl));
}

/**
* @return {!MDCChipSetFoundation}
*/
Expand All @@ -74,6 +88,23 @@ class MDCChipSet extends MDCComponent {
hasClass: (className) => this.root_.classList.contains(className),
registerInteractionHandler: (evtType, handler) => this.root_.addEventListener(evtType, handler),
deregisterInteractionHandler: (evtType, handler) => this.root_.removeEventListener(evtType, handler),
createChipElement: (text, leadingIcon, trailingIcon) => {
const chipTextEl = document.createElement('div');
chipTextEl.classList.add(MDCChipFoundation.cssClasses.TEXT);
chipTextEl.appendChild(document.createTextNode(text));

const chipEl = document.createElement('div');
chipEl.classList.add(MDCChipFoundation.cssClasses.CHIP);
if (leadingIcon) {
chipEl.appendChild(leadingIcon);
}
chipEl.appendChild(chipTextEl);
if (trailingIcon) {
chipEl.appendChild(trailingIcon);
}
return chipEl;
},
appendChild: (el) => this.root_.appendChild(el),
})));
}

Expand Down
2 changes: 2 additions & 0 deletions packages/mdc-chips/chip/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ const strings = {
/** @enum {string} */
const cssClasses = {
CHECKMARK: 'mdc-chip__checkmark',
CHIP: 'mdc-chip',
HIDDEN_LEADING_ICON: 'mdc-chip__icon--leading-hidden',
LEADING_ICON: 'mdc-chip__icon--leading',
SELECTED: 'mdc-chip--selected',
TEXT: 'mdc-chip__text',
};

export {strings, cssClasses};
15 changes: 15 additions & 0 deletions test/unit/mdc-chips/mdc-chip-set.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,18 @@ test('#adapter.deregisterInteractionHandler removes a handler from the root elem
domEvents.emit(root, 'click');
td.verify(handler(td.matchers.anything()), {times: 0});
});

test('#adapter.createChipElement returns a new chip element', () => {
const {component} = setupTest();
const chipEl = component.getDefaultFoundation().adapter_.createChipElement('hello world');
assert.isTrue(chipEl.classList.contains('mdc-chip'));
assert.isTrue(chipEl.childNodes[0].classList.contains('mdc-chip__text'));
assert.equal(chipEl.childNodes[0].textContent, 'hello world');
});

test('#adapter.appendChild adds a child to the chip set element', () => {
const {root, component} = setupTest();
const chipEl = bel`<div class="mdc-chip"><div class="mdc-chip__text">hello world</div></div>`;
component.getDefaultFoundation().adapter_.appendChild(chipEl);
assert.equal(root.childNodes[3], chipEl);
});

0 comments on commit afe5367

Please sign in to comment.