From b39a6b1bdb015460258ff54715a730996c15c918 Mon Sep 17 00:00:00 2001 From: Abhinay Omkar Date: Wed, 5 Dec 2018 15:21:35 +0530 Subject: [PATCH] fix(list): Add notifyAction adapter for action on list item. --- packages/mdc-list/README.md | 2 ++ packages/mdc-list/adapter.js | 11 +++++++++++ packages/mdc-list/constants.js | 1 + packages/mdc-list/foundation.js | 10 +++++++++- packages/mdc-list/index.js | 7 +++++++ 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/packages/mdc-list/README.md b/packages/mdc-list/README.md index a6a78250a13..180edc25a1d 100644 --- a/packages/mdc-list/README.md +++ b/packages/mdc-list/README.md @@ -499,6 +499,7 @@ Method Signature | Description `getListItemCount() => Number` | Returns the total number of list items (elements with `mdc-list-item` class) that are direct children of the `root_` element. `getFocusedElementIndex() => Number` | Returns the `index` value of the currently focused element. `getListItemIndex(ele: Element) => Number` | Returns the `index` value of the provided `ele` element. +`getAttributeForElementIndex(index: number, attr: string) => string` | Gets the `attr` attribute value for the list item at `index`. `setAttributeForElementIndex(index: Number, attr: String, value: String) => void` | Sets the `attr` attribute to `value` for the list item at `index`. `addClassForElementIndex(index: Number, className: String) => void` | Adds the `className` class to the list item at `index`. `removeClassForElementIndex(index: Number, className: String) => void` | Removes the `className` class to the list item at `index`. @@ -509,6 +510,7 @@ Method Signature | Description `hasCheckboxAtIndex(index: number) => boolean` | Returns true if checkbox is present at given list item index. `isCheckboxCheckedAtIndex(index: number) => boolean` | Returns true if checkbox inside a list item is checked. `setCheckedCheckboxOrRadioAtIndex(index: number, isChecked: boolean) => void` | Sets the checked status of checkbox or radio at given list item index. +`notifyAction(index: number) => void` | Notifies user action on list item including keyboard and mouse actions. ### `MDCListFoundation` diff --git a/packages/mdc-list/adapter.js b/packages/mdc-list/adapter.js index 517b3004ccc..a64a9a2f441 100644 --- a/packages/mdc-list/adapter.js +++ b/packages/mdc-list/adapter.js @@ -44,6 +44,12 @@ class MDCListAdapter { * @return {number} */ getFocusedElementIndex() {} + /** + * @param {number} index + * @param {string} attribute + */ + getAttributeForElementIndex(index, attr) {} + /** * @param {number} index * @param {string} attribute @@ -113,6 +119,11 @@ class MDCListAdapter { * @param {boolean} isChecked */ setCheckedCheckboxOrRadioAtIndex(index, isChecked) {} + + /** + * Notifies user action on list item. + */ + notifyAction(index) {} } export default MDCListAdapter; diff --git a/packages/mdc-list/constants.js b/packages/mdc-list/constants.js index a0125e9b4bf..9c9fef5969a 100644 --- a/packages/mdc-list/constants.js +++ b/packages/mdc-list/constants.js @@ -45,6 +45,7 @@ const strings = { .${cssClasses.LIST_ITEM_CLASS} input[type="radio"]:not(:disabled), .${cssClasses.LIST_ITEM_CLASS} input[type="checkbox"]:not(:disabled)`, ENABLED_ITEMS_SELECTOR: '.mdc-list-item:not(.mdc-list-item--disabled)', + ACTION_EVENT: 'MDCList:action', }; export {strings, cssClasses}; diff --git a/packages/mdc-list/foundation.js b/packages/mdc-list/foundation.js index 5956b1fd0c7..dfd57b9fb7d 100644 --- a/packages/mdc-list/foundation.js +++ b/packages/mdc-list/foundation.js @@ -47,6 +47,7 @@ class MDCListFoundation extends MDCFoundation { return /** @type {!MDCListAdapter} */ ({ getListItemCount: () => {}, getFocusedElementIndex: () => {}, + getAttributeForElementIndex: () => {}, setAttributeForElementIndex: () => {}, removeAttributeForElementIndex: () => {}, addClassForElementIndex: () => {}, @@ -58,6 +59,7 @@ class MDCListFoundation extends MDCFoundation { hasCheckboxAtIndex: () => {}, isCheckboxCheckedAtIndex: () => {}, setCheckedCheckboxOrRadioAtIndex: () => {}, + notifyAction: () => {}, }); } @@ -265,7 +267,11 @@ class MDCListFoundation extends MDCFoundation { } // Explicitly activate links, since we're preventing default on Enter, and Space doesn't activate them. - this.adapter_.followHref(currentIndex); + if (this.adapter_.getAttributeForElementIndex(currentIndex, 'href')) { + this.adapter_.followHref(currentIndex); + } else { + this.adapter_.notifyAction(currentIndex); + } } } } @@ -285,6 +291,8 @@ class MDCListFoundation extends MDCFoundation { if (this.isSingleSelectionList_ || this.hasCheckboxOrRadioAtIndex_(index)) { this.setSelectedIndex(index); } + + this.adapter_.notifyAction(index); } /** diff --git a/packages/mdc-list/index.js b/packages/mdc-list/index.js index 4f9a33f49dd..2284625ac9d 100644 --- a/packages/mdc-list/index.js +++ b/packages/mdc-list/index.js @@ -206,6 +206,10 @@ class MDCList extends MDCComponent { return new MDCListFoundation(/** @type {!MDCListAdapter} */ (Object.assign({ getListItemCount: () => this.listElements.length, getFocusedElementIndex: () => this.listElements.indexOf(document.activeElement), + getAttributeForElementIndex: (index, attr) => { + const element = this.listElements[index]; + return element.getAttribute(attr); + }, setAttributeForElementIndex: (index, attr, value) => { const element = this.listElements[index]; if (element) { @@ -269,6 +273,9 @@ class MDCList extends MDCComponent { event.initEvent('change', true, true); toggleEl.dispatchEvent(event); }, + notifyAction: (index) => { + this.emit(strings.ACTION_EVENT, index, /** shouldBubble */ true); + }, }))); } }