Skip to content

Commit

Permalink
Merge branch 'master' into fix/list/allow-activated-or-selected-class
Browse files Browse the repository at this point in the history
  • Loading branch information
williamernest committed Aug 21, 2018
2 parents 06121ac + 33495a3 commit cb31cb9
Show file tree
Hide file tree
Showing 5 changed files with 224 additions and 58 deletions.
25 changes: 18 additions & 7 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,29 @@
We release a new version of MDC Web every 2 weeks. We also limit our breaking changes to one release at the end of the month. This roadmap is based on the more general [material components roadmap](https://github.com/material-components/material-components/blob/develop/ROADMAP.md), but specific to MDC Web.

## Current Release
### 0.38.0 - July 2018
### 0.38.0 - July 2018 (R17)
- New tabs
- New switch

### 0.39.0 - August 2018
- [Shape Theme](https://material.io/go/design-shape) released
## Future Releases
### 0.39.0 - August 2018 (R18)
- New navigation drawer
- New menu
- Updates to chip set API
- Support SVGs in icon toggle

### 0.40.0 through 0.42.0 - Forecast for September-November
- New Sheet types – Additional components that extends the capabilities and usage patterns of sheets
- Color Theme: Dark – capability for apps to adjust their color schemes to maximum usable darkness that is still aesthetically appealing
- New navigation patterns
### 0.40.0 - September 2018 (R19)
- [Shape Theme](https://material.io/go/design-shape)
- New dialog

### 0.41.0 - October 2018 (R20)
- Text field prefix and suffix support
- Text field with a drop down menu (aka a Select)

### 0.42.0 - November 2018 (R21)
- Shadows Theme
- New side sheet
- Cascading menus

### 0.43.0 - December 2018 (R22)
- Polish and bug fixes
7 changes: 4 additions & 3 deletions packages/mdc-chips/chip/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ class MDCChip extends MDCComponent {
return new MDCChip(root);
}

initialize() {
initialize(
rippleFactory = (el, foundation) => new MDCRipple(el, foundation)) {
this.id = this.root_.id;
this.leadingIcon_ = this.root_.querySelector(strings.LEADING_ICON_SELECTOR);
this.trailingIcon_ = this.root_.querySelector(strings.TRAILING_ICON_SELECTOR);
Expand All @@ -78,9 +79,9 @@ class MDCChip extends MDCComponent {
return {height, width};
},
});
this.ripple_ = new MDCRipple(this.root_, new MDCRippleFoundation(adapter));
this.ripple_ = rippleFactory(this.root_, new MDCRippleFoundation(adapter));
} else {
this.ripple_ = new MDCRipple(this.root_);
this.ripple_ = rippleFactory(this.root_);
}
}

Expand Down
72 changes: 55 additions & 17 deletions test/unit/mdc-chips/mdc-chip-set.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@

import bel from 'bel';
import {assert} from 'chai';
import domEvents from 'dom-events';
import td from 'testdouble';

import {MDCChipSet} from '../../../packages/mdc-chips/chip-set';
import {MDCChipSet, MDCChipSetFoundation} from '../../../packages/mdc-chips/chip-set';
import {MDCChipFoundation} from '../../../packages/mdc-chips/chip';

const getFixture = () => bel`
<div class="mdc-chip-set">
Expand Down Expand Up @@ -48,28 +50,66 @@ class FakeChip {
}
}

test('#constructor instantiates child chip components', () => {
function setupTest() {
const root = getFixture();
const component = new MDCChipSet(root, undefined, (el) => new FakeChip(el));
return {root, component};
}

function setupMockFoundationTest() {
const root = getFixture();
const MockFoundationConstructor = td.constructor(MDCChipSetFoundation);
const mockFoundation = new MockFoundationConstructor();
const component = new MDCChipSet(root, mockFoundation);
return {root, component, mockFoundation};
}

test('#constructor instantiates child chip components', () => {
const {component} = setupTest();
assert.equal(component.chips.length, 3);
assert.instanceOf(component.chips[0], FakeChip);
assert.instanceOf(component.chips[1], FakeChip);
assert.instanceOf(component.chips[2], FakeChip);
});

test('#destroy cleans up child chip components', () => {
const root = getFixture();
const component = new MDCChipSet(root, undefined, (el) => new FakeChip(el));
const {component} = setupTest();
component.destroy();
td.verify(component.chips[0].destroy());
td.verify(component.chips[1].destroy());
td.verify(component.chips[2].destroy());
});

test('#initialSyncWithDOM sets up event handlers', () => {
const {root, mockFoundation} = setupMockFoundationTest();

domEvents.emit(root, MDCChipFoundation.strings.INTERACTION_EVENT);
td.verify(mockFoundation.handleChipInteraction(td.matchers.anything()), {times: 1});

domEvents.emit(root, MDCChipFoundation.strings.REMOVAL_EVENT);
td.verify(mockFoundation.handleChipRemoval(td.matchers.anything()), {times: 1});
});

test('#destroy removes event handlers', () => {
const {root, component, mockFoundation} = setupMockFoundationTest();
component.destroy();

domEvents.emit(root, MDCChipFoundation.strings.INTERACTION_EVENT);
td.verify(mockFoundation.handleChipInteraction(td.matchers.anything()), {times: 0});

domEvents.emit(root, MDCChipFoundation.strings.REMOVAL_EVENT);
td.verify(mockFoundation.handleChipRemoval(td.matchers.anything()), {times: 0});
});

test('get selectedChipIds proxies to foundation', () => {
const {component, mockFoundation} = setupMockFoundationTest();
component.selectedChipIds;
td.verify(mockFoundation.getSelectedChipIds());
});

test('#addChip adds a new chip to the chip set', () => {
const root = getFixture();
const component = new MDCChipSet(root, undefined, (el) => new FakeChip(el));
component.initialSyncWithDOM();
const {component} = setupTest();
// component.initialSyncWithDOM(); // TODO: why is this here?

const chipEl = bel`
<div class="mdc-chip">
Expand All @@ -82,30 +122,28 @@ test('#addChip adds a new chip to the chip set', () => {
assert.instanceOf(component.chips[3], FakeChip);
});

function setupTest() {
const root = getFixture();
const component = new MDCChipSet(root);
return {root, component};
}

test('#adapter.hasClass returns true if class is set on chip set element', () => {
const {root, component} = setupTest();
root.classList.add('foo');
assert.isTrue(component.getDefaultFoundation().adapter_.hasClass('foo'));
});

test('#adapter.removeChip removes the chip object from the chip set', () => {
const root = getFixture();
const component = new MDCChipSet(root, undefined, (el) => new FakeChip(el));
const {component} = setupTest();
const chip = component.chips[0];
component.getDefaultFoundation().adapter_.removeChip(chip.id);
assert.equal(component.chips.length, 2);
td.verify(chip.destroy());
});

test('#adapter.removeChip does nothing if the given object is not in the chip set', () => {
const {component} = setupTest();
component.getDefaultFoundation().adapter_.removeChip('chip0');
assert.equal(component.chips.length, 3);
});

test('#adapter.setSelected sets selected on chip object', () => {
const root = getFixture();
const component = new MDCChipSet(root, undefined, (el) => new FakeChip(el));
const {component} = setupTest();
const chip = component.chips[0];
component.getDefaultFoundation().adapter_.setSelected(chip.id, true);
assert.equal(chip.selected, true);
Expand Down
30 changes: 27 additions & 3 deletions test/unit/mdc-chips/mdc-chip.foundation.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,16 +185,40 @@ test('#handleTransitionEnd does nothing on checkmark opacity transition end, if
td.verify(mockAdapter.removeClassFromLeadingIcon(cssClasses.HIDDEN_LEADING_ICON), {times: 0});
});

test('#handleTrailingIconInteraction emits custom event on click in trailing icon', () => {
test('#handleTransitionEnd does nothing for width property when not exiting', () => {
const {foundation, mockAdapter} = setupTest();
const mockEvt = {
type: 'transitionend',
target: {},
propertyName: 'width',
};

foundation.handleTransitionEnd(mockEvt);

td.verify(mockAdapter.notifyRemoval(), {times: 0});
td.verify(mockAdapter.addClassToLeadingIcon(cssClasses.HIDDEN_LEADING_ICON), {times: 0});
td.verify(mockAdapter.removeClassFromLeadingIcon(cssClasses.HIDDEN_LEADING_ICON), {times: 0});
});


test('#handleTrailingIconInteraction emits custom event on click or enter key in trailing icon', () => {
const {foundation, mockAdapter} = setupTest();
const mockEvt = {
type: 'click',
stopPropagation: td.func('stopPropagation'),
};

foundation.handleTrailingIconInteraction(mockEvt);
td.verify(mockAdapter.notifyTrailingIconInteraction());
td.verify(mockEvt.stopPropagation());
td.verify(mockAdapter.notifyTrailingIconInteraction(), {times: 1});
td.verify(mockEvt.stopPropagation(), {times: 1});

foundation.handleTrailingIconInteraction(Object.assign(mockEvt, {type: 'keydown', keyCode: 13}));
td.verify(mockAdapter.notifyTrailingIconInteraction(), {times: 2});
td.verify(mockEvt.stopPropagation(), {times: 2});

foundation.handleTrailingIconInteraction(Object.assign(mockEvt, {type: 'keydown', key: 'Enter'}));
td.verify(mockAdapter.notifyTrailingIconInteraction(), {times: 3});
td.verify(mockEvt.stopPropagation(), {times: 3});
});

test(`#handleTrailingIconInteraction adds ${cssClasses.CHIP_EXIT} class by default on click in trailing icon`, () => {
Expand Down
Loading

0 comments on commit cb31cb9

Please sign in to comment.