diff --git a/packages/mdc-chips/README.md b/packages/mdc-chips/README.md index d934c103f5b..0677ca2dfee 100644 --- a/packages/mdc-chips/README.md +++ b/packages/mdc-chips/README.md @@ -310,6 +310,7 @@ Method Signature | Description `focusPrimaryAction() => void` | Proxies to the foundation's `focusPrimaryAction` method `focusTrailingAction() => void` | Proxies to the foundation's `focusTrailingAction` method `removeFocus() => void` | Proxies to the foundation's `removeFocus` method +`setSelectedFromChipSet(selected: boolean) => void` | Proxies to the foundation's `setSelectedFromChipset` method (only called from the chip set) Property | Value Type | Description --- | --- | --- @@ -392,7 +393,7 @@ Method Signature | Description --- | --- `hasClass(className: string) => boolean` | Returns whether the chip set element has the given class `removeChipAtIndex(index: number) => void` | Removes the chip with the given `index` from the chip set -`selectChipAtIndex(index: string, selected: boolean) => void` | Sets the selected state of the chip at the given `index` +`selectChipAtIndex(index: string, selected: boolean) => void` | Calls `MDCChip#setSelectedFromChipSet(selected)` on the chip at the given `index` `getIndexOfChipById(id: string) => number` | Returns the index of the chip with the matching `id` or -1 `focusChipPrimaryActionAtIndex(index: number) => void` | Calls `MDCChip#focusPrimaryAction()` on the chip at the given `index` `focusChipTrailingActionAtIndex(index: number) => void` | Calls `MDCChip#focusTrailingAction()` on the chip at the given `index` @@ -408,6 +409,7 @@ Method Signature | Description --- | --- `isSelected() => boolean` | Returns true if the chip is selected `setSelected(selected: boolean) => void` | Sets the chip's selected state +`setSelectedFromChipSet(selected: boolean) => void` | Sets the chip's selected state (called from the chip set) `getShouldRemoveOnTrailingIconClick() => boolean` | Returns whether a trailing icon click should trigger exit/removal of the chip `setShouldRemoveOnTrailingIconClick(shouldRemove: boolean) => void` | Sets whether a trailing icon click should trigger exit/removal of the chip `getDimensions() => ClientRect` | Returns the dimensions of the chip. This is used for applying ripple to the chip. diff --git a/packages/mdc-chips/chip-set/component.ts b/packages/mdc-chips/chip-set/component.ts index ea7b88ae047..cda345832c7 100644 --- a/packages/mdc-chips/chip-set/component.ts +++ b/packages/mdc-chips/chip-set/component.ts @@ -132,7 +132,7 @@ export class MDCChipSet extends MDCComponent { }, selectChipAtIndex: (index, selected) => { if (index >= 0 && index < this.chips_.length) { - this.chips_[index].selected = selected; + this.chips_[index].setSelectedFromChipSet(selected); } }, }; diff --git a/packages/mdc-chips/chip/component.ts b/packages/mdc-chips/chip/component.ts index c6aeaf1bed2..6fa34be3a2a 100644 --- a/packages/mdc-chips/chip/component.ts +++ b/packages/mdc-chips/chip/component.ts @@ -217,6 +217,10 @@ export class MDCChip extends MDCComponent implements MDCRippl return new MDCChipFoundation(adapter); } + setSelectedFromChipSet(selected: boolean) { + this.foundation_.setSelectedFromChipSet(selected); + } + focusPrimaryAction() { this.foundation_.focusPrimaryAction(); } diff --git a/packages/mdc-chips/chip/foundation.ts b/packages/mdc-chips/chip/foundation.ts index d28399317df..371260d891f 100644 --- a/packages/mdc-chips/chip/foundation.ts +++ b/packages/mdc-chips/chip/foundation.ts @@ -84,14 +84,11 @@ export class MDCChipFoundation extends MDCFoundation { } setSelected(selected: boolean) { - if (selected) { - this.adapter_.addClass(cssClasses.SELECTED); - this.adapter_.setPrimaryActionAttr(strings.ARIA_CHECKED, 'true'); - } else { - this.adapter_.removeClass(cssClasses.SELECTED); - this.adapter_.setPrimaryActionAttr(strings.ARIA_CHECKED, 'false'); - } - this.adapter_.notifySelection(selected); + this.setSelected_(selected, true); + } + + setSelectedFromChipSet(selected: boolean) { + this.setSelected_(selected, false); } getShouldRemoveOnTrailingIconClick() { @@ -327,6 +324,20 @@ export class MDCChipFoundation extends MDCFoundation { const isDeletable = this.adapter_.hasClass(cssClasses.DELETABLE); return isDeletable && (evt.key === strings.BACKSPACE_KEY || evt.key === strings.DELETE_KEY); } + + private setSelected_(selected: boolean, shouldNotify: boolean) { + if (selected) { + this.adapter_.addClass(cssClasses.SELECTED); + this.adapter_.setPrimaryActionAttr(strings.ARIA_CHECKED, 'true'); + } else { + this.adapter_.removeClass(cssClasses.SELECTED); + this.adapter_.setPrimaryActionAttr(strings.ARIA_CHECKED, 'false'); + } + + if (shouldNotify) { + this.adapter_.notifySelection(selected); + } + } } // tslint:disable-next-line:no-default-export Needed for backward compatibility with MDC Web v0.44.0 and earlier. diff --git a/test/unit/mdc-chips/mdc-chip-set.test.js b/test/unit/mdc-chips/mdc-chip-set.test.js index dc0467a5457..ffa11779711 100644 --- a/test/unit/mdc-chips/mdc-chip-set.test.js +++ b/test/unit/mdc-chips/mdc-chip-set.test.js @@ -57,6 +57,7 @@ class FakeChip { this.focusTrailingAction = td.func('.focusTrailingAction'); this.remove = td.func('.remove'); this.removeFocus = td.func('.removeFocus'); + this.setSelectedFromChipSet = td.func('.setSelectedFromChipSet'); this.selected = false; } } @@ -177,11 +178,11 @@ test('#adapter.removeChipAtIndex does nothing if the given object is not in the assert.equal(component.chips.length, 3); }); -test('#adapter.selectChipAtIndex sets selected on chip object', () => { +test('#adapter.selectChipAtIndex calls setSelectedFromChipSet on chip object', () => { const {component} = setupTest(); const chip = component.chips[0]; component.getDefaultFoundation().adapter_.selectChipAtIndex(0, true); - assert.equal(chip.selected, true); + td.verify(chip.setSelectedFromChipSet(true)); }); test('#adapter.getChipListCount returns the number of chips', () => { diff --git a/test/unit/mdc-chips/mdc-chip.foundation.test.js b/test/unit/mdc-chips/mdc-chip.foundation.test.js index 555ab61f39b..76dbf581f3f 100644 --- a/test/unit/mdc-chips/mdc-chip.foundation.test.js +++ b/test/unit/mdc-chips/mdc-chip.foundation.test.js @@ -92,18 +92,25 @@ test('#setSelected sets aria-checked="false" if false', () => { td.verify(mockAdapter.setPrimaryActionAttr(strings.ARIA_CHECKED, 'false')); }); -test('#setSelected removes calls adapter.notifySelection when selected is true', () => { +test('#setSelected notifies of selection when selected is true', () => { const {foundation, mockAdapter} = setupTest(); foundation.setSelected(true); td.verify(mockAdapter.notifySelection(true)); }); -test('#setSelected removes calls adapter.notifySelection when selected is false', () => { +test('#setSelected notifies of unselection when selected is false', () => { const {foundation, mockAdapter} = setupTest(); foundation.setSelected(false); td.verify(mockAdapter.notifySelection(false)); }); +test('#setSelectedFromChipSet does not notify', () => { + const {foundation, mockAdapter} = setupTest(); + foundation.setSelectedFromChipSet(false); + foundation.setSelectedFromChipSet(true); + td.verify(mockAdapter.notifySelection(td.matchers.isA(Boolean)), {times: 0}); +}); + test('#getDimensions returns adapter.getRootBoundingClientRect when there is no checkmark bounding rect', () => { const {foundation, mockAdapter} = setupTest(); td.when(mockAdapter.getCheckmarkBoundingClientRect()).thenReturn(null); diff --git a/test/unit/mdc-chips/mdc-chip.test.js b/test/unit/mdc-chips/mdc-chip.test.js index efcb4b17558..671b1768557 100644 --- a/test/unit/mdc-chips/mdc-chip.test.js +++ b/test/unit/mdc-chips/mdc-chip.test.js @@ -420,6 +420,12 @@ test('#set shouldRemoveOnTrailingIconClick proxies to foundation', () => { td.verify(mockFoundation.setShouldRemoveOnTrailingIconClick(false)); }); +test('#setSelectedFromChipSet proxies to the same foundation method', () => { + const {component, mockFoundation} = setupMockFoundationTest(); + component.setSelectedFromChipSet(true); + td.verify(mockFoundation.setSelectedFromChipSet(true)); +}); + test('#beginExit proxies to foundation', () => { const {component, mockFoundation} = setupMockFoundationTest(); component.beginExit();