Skip to content

Commit

Permalink
feat(text-field): Add methods to set text field icon aria-label and c…
Browse files Browse the repository at this point in the history
…ontent (#2771)

BREAKING CHANGE: Adds setContent adapter API to text field icon
  • Loading branch information
rlfriedman committed May 25, 2018
1 parent ac3c17e commit 02d7dca
Show file tree
Hide file tree
Showing 11 changed files with 115 additions and 5 deletions.
2 changes: 2 additions & 0 deletions packages/mdc-textfield/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,8 @@ Method Signature | Description
`activateFocus() => void` | Activates the focus state of the Text Field. Normally called in response to the input focus event.
`deactivateFocus() => void` | Deactivates the focus state of the Text Field. Normally called in response to the input blur event.
`setHelperTextContent(content: string) => void` | Sets the content of the helper text.
`setIconAriaLabel(label: string) => void` | Sets the aria label of the icon.
`setIconContent(content: string) => void` | Sets the text content of the icon.
`notchOutline(openNotch: boolean) => void` | Opens/closes the notched outline.

`MDCTextFieldFoundation` supports multiple optional sub-elements: helper text and icon. The foundations of these sub-elements must be passed in as constructor arguments to `MDCTextFieldFoundation`.
20 changes: 20 additions & 0 deletions packages/mdc-textfield/foundation.js
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,26 @@ class MDCTextFieldFoundation extends MDCFoundation {
}
}

/**
* Sets the aria label of the icon.
* @param {string} label
*/
setIconAriaLabel(label) {
if (this.icon_) {
this.icon_.setAriaLabel(label);
}
}

/**
* Sets the text content of the icon.
* @param {string} content
*/
setIconContent(content) {
if (this.icon_) {
this.icon_.setContent(content);
}
}

/**
* @return {boolean} True if the Text Field input fails in converting the
* user-supplied value.
Expand Down
3 changes: 3 additions & 0 deletions packages/mdc-textfield/icon/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ Method Signature | Description
`getAttr(attr: string) => string` | Gets the value of an attribute on the icon element.
`setAttr(attr: string, value: string) => void` | Sets an attribute with a given value on the icon element.
`removeAttr(attr: string) => void` | Removes an attribute from the icon element.
`setContent(content: string) => void` | Sets the text content of the icon element.
`registerInteractionHandler(evtType: string, handler: EventListener) => void` | Registers an event listener for a given event.
`deregisterInteractionHandler(evtType: string, handler: EventListener) => void` | Deregisters an event listener for a given event.
`notifyIconAction() => void` | Emits a custom event "MDCTextField:icon" denoting a user has clicked the icon, which bubbles to the top-level text field element.
Expand All @@ -142,4 +143,6 @@ Method Signature | Description
Method Signature | Description
--- | ---
`setDisabled(disabled: boolean) => void` | Updates the icon's disabled state.
`setAriaLabel(label: string) => void` | Updates the icon's aria-label.
`setContent(content: string) => void` | Updates the icon's text content.
`handleInteraction(evt: Event) => void` | Handles a text field interaction event.
6 changes: 6 additions & 0 deletions packages/mdc-textfield/icon/adapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ class MDCTextFieldIconAdapter {
*/
removeAttr(attr) {}

/**
* Sets the text content of the icon element.
* @param {string} content
*/
setContent(content) {}

/**
* Registers an event listener on the icon element for a given event.
* @param {string} evtType
Expand Down
16 changes: 12 additions & 4 deletions packages/mdc-textfield/icon/foundation.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class MDCTextFieldIconFoundation extends MDCFoundation {
getAttr: () => {},
setAttr: () => {},
removeAttr: () => {},
setContent: () => {},
registerInteractionHandler: () => {},
deregisterInteractionHandler: () => {},
notifyIconAction: () => {},
Expand Down Expand Up @@ -73,10 +74,7 @@ class MDCTextFieldIconFoundation extends MDCFoundation {
});
}

/**
* Sets the content of the helper text field.
* @param {boolean} disabled
*/
/** @param {boolean} disabled */
setDisabled(disabled) {
if (!this.savedTabIndex_) {
return;
Expand All @@ -91,6 +89,16 @@ class MDCTextFieldIconFoundation extends MDCFoundation {
}
}

/** @param {string} label */
setAriaLabel(label) {
this.adapter_.setAttr('aria-label', label);
}

/** @param {string} content */
setContent(content) {
this.adapter_.setContent(content);
}

/**
* Handles an interaction event
* @param {!Event} evt
Expand Down
3 changes: 3 additions & 0 deletions packages/mdc-textfield/icon/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ class MDCTextFieldIcon extends MDCComponent {
getAttr: (attr) => this.root_.getAttribute(attr),
setAttr: (attr, value) => this.root_.setAttribute(attr, value),
removeAttr: (attr) => this.root_.removeAttribute(attr),
setContent: (content) => {
this.root_.textContent = content;
},
registerInteractionHandler: (evtType, handler) => this.root_.addEventListener(evtType, handler),
deregisterInteractionHandler: (evtType, handler) => this.root_.removeEventListener(evtType, handler),
notifyIconAction: () => this.emit(
Expand Down
16 changes: 16 additions & 0 deletions packages/mdc-textfield/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,22 @@ class MDCTextField extends MDCComponent {
this.foundation_.setHelperTextContent(content);
}

/**
* Sets the aria label of the icon.
* @param {string} label
*/
set iconAriaLabel(label) {
this.foundation_.setIconAriaLabel(label);
}

/**
* Sets the text content of the icon.
* @param {string} content
*/
set iconContent(content) {
this.foundation_.setIconContent(content);
}

/**
* Recomputes the outline SVG path for the outline element.
*/
Expand Down
14 changes: 14 additions & 0 deletions test/unit/mdc-textfield/foundation.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ const setupTest = () => {
});
const icon = td.object({
setDisabled: () => {},
setAriaLabel: () => {},
setContent: () => {},
registerInteractionHandler: () => {},
deregisterInteractionHandler: () => {},
handleInteraction: () => {},
Expand Down Expand Up @@ -373,6 +375,18 @@ test('#setHelperTextContent sets the content of the helper text element', () =>
td.verify(helperText.setContent('foo'));
});

test('#setIconAriaLabel sets the aria-label of the icon element', () => {
const {foundation, icon} = setupTest();
foundation.setIconAriaLabel('foo');
td.verify(icon.setAriaLabel('foo'));
});

test('#setIconContent sets the content of the icon element', () => {
const {foundation, icon} = setupTest();
foundation.setIconContent('foo');
td.verify(icon.setContent('foo'));
});

test('#notchOutline updates the SVG path of the outline element', () => {
const {foundation, mockAdapter} = setupTest();
td.when(mockAdapter.getLabelWidth()).thenReturn(30);
Expand Down
20 changes: 19 additions & 1 deletion test/unit/mdc-textfield/mdc-text-field-icon-foundation.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ test('exports strings', () => {

test('defaultAdapter returns a complete adapter implementation', () => {
verifyDefaultAdapter(MDCTextFieldIconFoundation, [
'getAttr', 'setAttr', 'removeAttr', 'registerInteractionHandler', 'deregisterInteractionHandler',
'getAttr', 'setAttr', 'removeAttr', 'setContent', 'registerInteractionHandler', 'deregisterInteractionHandler',
'notifyIconAction',
]);
});
Expand Down Expand Up @@ -94,6 +94,24 @@ test('#setDisabled does not change icon tabindex or role when set to false if ic
td.verify(mockAdapter.setAttr('role', td.matchers.isA(String)), {times: 0});
});

test('#setAriaLabel updates the aria-label', () => {
const {foundation, mockAdapter} = setupTest();
const ariaLabel = 'Test label';
foundation.init();

foundation.setAriaLabel(ariaLabel);
td.verify(mockAdapter.setAttr('aria-label', ariaLabel));
});

test('#setContent updates the text content', () => {
const {foundation, mockAdapter} = setupTest();
const content = 'test';
foundation.init();

foundation.setContent(content);
td.verify(mockAdapter.setContent(content));
});

test('on click notifies custom icon event', () => {
const {foundation, mockAdapter} = setupTest();
const evt = {
Expand Down
6 changes: 6 additions & 0 deletions test/unit/mdc-textfield/mdc-text-field-icon.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ test('#adapter.removeAttr removes a given attribute from the element', () => {
assert.isFalse(root.hasAttribute('role'));
});

test('#adapter.setContent sets the text content of the element', () => {
const {root, component} = setupTest();
component.getDefaultFoundation().adapter_.setContent('foo');
assert.equal(root.textContent, 'foo');
});

test('#adapter.registerInteractionHandler adds event listener for a given event to the element', () => {
const {root, component} = setupTest();
const handler = td.func('keydown handler');
Expand Down
14 changes: 14 additions & 0 deletions test/unit/mdc-textfield/mdc-text-field.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,20 @@ test('set helperTextContent has no effect when no helper text element is present
});
});

test('set iconAriaLabel has no effect when no icon element is present', () => {
const {component} = setupTest();
assert.doesNotThrow(() => {
component.iconAriaLabel = 'foo';
});
});

test('set iconContent has no effect when no icon element is present', () => {
const {component} = setupTest();
assert.doesNotThrow(() => {
component.iconContent = 'foo';
});
});

test('#adapter.addClass adds a class to the root element', () => {
const {root, component} = setupTest();
component.getDefaultFoundation().adapter_.addClass('foo');
Expand Down

0 comments on commit 02d7dca

Please sign in to comment.