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

Commit

Permalink
fix(select): Make compatible with rich list-items
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 314600015
  • Loading branch information
allan-chen authored and copybara-github committed Jun 3, 2020
1 parent 9b0b5f2 commit 0a7895f
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 15 deletions.
1 change: 1 addition & 0 deletions packages/mdc-list/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ Property | Value Type | Description
Method Signature | Description
--- | ---
`layout() => void` | Recalculates layout and orientation.
`getPrimaryText(item: Element) => string` | Fetches the primary text in the given element.
`initializeListType() => void` | Initialize `selectedIndex` value based on pre-selected checkbox list items, single selection or radio.
`setEnabled(itemIndex: number, isEnabled: boolean) => void` | Updates the list item at `itemIndex` to the desired `isEnabled` state.

Expand Down
30 changes: 19 additions & 11 deletions packages/mdc-list/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,23 @@ export class MDCList extends MDCComponent<MDCListFoundation> {
this.foundation.layout();
}

/**
* Extracts the primary text from a list item.
* @param item The list item element.
* @return The primary text in the element.
*/
getPrimaryText(item: Element): string {
const primaryText =
item.querySelector(`.${cssClasses.LIST_ITEM_PRIMARY_TEXT_CLASS}`);
if (primaryText) {
return primaryText.textContent || '';
}

const singleLineText =
item.querySelector(`.${cssClasses.LIST_ITEM_TEXT_CLASS}`);
return (singleLineText && singleLineText.textContent) || '';
}

/**
* Initialize selectedIndex value based on pre-selected checkbox list items, single selection or radio.
*/
Expand Down Expand Up @@ -171,17 +188,8 @@ export class MDCList extends MDCComponent<MDCListFoundation> {
getFocusedElementIndex: () =>
this.listElements.indexOf(document.activeElement!),
getListItemCount: () => this.listElements.length,
getPrimaryTextAtIndex: (index) => {
const primaryText = this.listElements[index].querySelector(
`.${cssClasses.LIST_ITEM_PRIMARY_TEXT_CLASS}`);
if (primaryText) {
return primaryText.textContent || '';
}

const singleLineText = this.listElements[index].querySelector(
`.${cssClasses.LIST_ITEM_TEXT_CLASS}`);
return (singleLineText && singleLineText.textContent) || '';
},
getPrimaryTextAtIndex: (index) =>
this.getPrimaryText(this.listElements[index]),
hasCheckboxAtIndex: (index) => {
const listItem = this.listElements[index];
return !!listItem.querySelector(strings.CHECKBOX_SELECTOR);
Expand Down
16 changes: 16 additions & 0 deletions packages/mdc-list/test/component.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,22 @@ describe('MDCList', () => {
expect(0).toEqual(root.querySelectorAll('button:not([tabindex])').length);
});

it('#getPrimaryText returns the appropriate text for one line list', () => {
const {root, component} = setupTest();
const item = root.querySelectorAll('.mdc-list-item')[2] as HTMLElement;
document.body.appendChild(root);
expect(component.getPrimaryText(item)).toEqual('Pasta');
document.body.removeChild(root);
});

it('#getPrimaryText returns the appropriate text for two line list', () => {
const {root, component} = setupTest(getTwoLineFixture());
const item = root.querySelectorAll('.mdc-list-item')[2] as HTMLElement;
document.body.appendChild(root);
expect(component.getPrimaryText(item)).toEqual('Pasta');
document.body.removeChild(root);
});

it('vertical calls setVerticalOrientation on foundation', () => {
const {component, mockFoundation} = setupTest();
component.vertical = false;
Expand Down
1 change: 1 addition & 0 deletions packages/mdc-menu/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ Method Signature | Description
`setIsHoisted(isHoisted: boolean) => void` | Proxies to the menu surface's `setIsHoisted(isHoisted: boolean)` method.
`setAnchorElement(element: Element) => void` | Proxies to the menu surface's `setAnchorElement(element)` method.
`getOptionByIndex(index: number) => Element \| null` | Returns the list item at the `index` specified.
`getPrimaryTextAtIndex(index: number) => string` | Returns the primary text at the `index` specified.
`getDefaultFoundation() => MDCMenuFoundation` | Returns the foundation.
`setDefaultFocusState(focusState: DefaultFocusState) => void` | Sets default focus state where the menu should focus every time when menu is opened. Focuses the list root (`DefaultFocusState.LIST_ROOT`) element by default.
`setEnabled(index: number, isEnabled: boolean) => void` | Sets the enabled state to `isEnabled` for the menu item at given `index`.
Expand Down
12 changes: 12 additions & 0 deletions packages/mdc-menu/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,18 @@ export class MDCMenu extends MDCComponent<MDCMenuFoundation> {
}
}

/**
* @param index A menu item's index.
* @return The primary text within the menu at the index specified.
*/
getPrimaryTextAtIndex(index: number): string {
const item = this.getOptionByIndex(index);
if (item && this.list_) {
return this.list_.getPrimaryText(item) || '';
}
return '';
}

setFixedPosition(isFixed: boolean) {
this.menuSurface_.setFixedPosition(isFixed);
}
Expand Down
15 changes: 12 additions & 3 deletions packages/mdc-menu/test/component.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,12 @@ function getFixtureWithMultipleSelectionGroups(open = false) {
}

class FakeList {
destroy: Function = jasmine.createSpy('.destroy');
itemsContainer: Function = jasmine.createSpy('.root_');
layout: Function = jasmine.createSpy('layout');
destroy: jasmine.Spy = jasmine.createSpy('.destroy');
itemsContainer: jasmine.Spy = jasmine.createSpy('.root_');
layout: jasmine.Spy = jasmine.createSpy('layout');
wrapFocus: boolean = true;
listElements: HTMLElement[];
getPrimaryText: jasmine.Spy = jasmine.createSpy('.getPrimaryText');

constructor(root: HTMLElement) {
this.listElements = [].slice.call(root.querySelectorAll('.mdc-list-item'))
Expand Down Expand Up @@ -294,6 +295,14 @@ describe('MDCMenu', () => {
expect(component.getOptionByIndex(items.length)).toBe(null);
});

it('getPrimaryTextAtIndex', () => {
const {component, list} = setupTestWithFakes();
list.getPrimaryText.withArgs(jasmine.any(Element))
.and.returnValue('Another Item');

expect(component.getPrimaryTextAtIndex(1)).toEqual('Another Item');
});

it('setFixedPosition', () => {
const {component, menuSurface} = setupTestWithFakes();
component.setFixedPosition(true);
Expand Down
2 changes: 1 addition & 1 deletion packages/mdc-select/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ export class MDCSelect extends MDCComponent<MDCSelectFoundation> {
getMenuItemValues: () => this.menu.items.map(
(el) => el.getAttribute(strings.VALUE_ATTR) || ''),
getMenuItemTextAtIndex: (index: number) =>
this.menu.items[index].textContent as string,
this.menu.getPrimaryTextAtIndex(index),
addClassAtIndex: (index: number, className: string) => {
this.menu.items[index].classList.add(className);
},
Expand Down

0 comments on commit 0a7895f

Please sign in to comment.