From 875e39372a64a23b346c5def1fbe1092a4292c46 Mon Sep 17 00:00:00 2001 From: Patrick RoDee Date: Tue, 21 Nov 2017 15:12:32 -0800 Subject: [PATCH] feat(textfield): helperTextContent setter (#1569) BREAKING CHANGE: Adds adapter method to set helper text content. --- packages/mdc-textfield/README.md | 5 ++++ packages/mdc-textfield/adapter.js | 6 ++++ packages/mdc-textfield/foundation.js | 8 ++++++ packages/mdc-textfield/index.js | 12 ++++++++ test/unit/mdc-textfield/foundation.test.js | 7 +++++ .../unit/mdc-textfield/mdc-text-field.test.js | 28 +++++++++++++++++++ 6 files changed, 66 insertions(+) diff --git a/packages/mdc-textfield/README.md b/packages/mdc-textfield/README.md index 681052201f4..3cd260c66bd 100644 --- a/packages/mdc-textfield/README.md +++ b/packages/mdc-textfield/README.md @@ -373,6 +373,10 @@ being used as the text field's "helper text". It defaults to `null`. If the text contains an `aria-controls` attribute on instantiation of the component, it will look for an element with the corresponding id within the document and automatically assign it to this property. +##### MDCTextField.helperTextContent + +String setter. Proxies to the foundation's `setHelperTextContent` method when set. + ##### MDCTextField.disabled Boolean. Proxies to the foundation's `isDisabled/setDisabled` methods when retrieved/set @@ -413,6 +417,7 @@ complicated. | deregisterBottomLineEventHandler(evtType: string, handler: EventListener) => void | Deregisters an event listener on the bottom line element for a given event | | setHelperTextAttr(name: string, value: string) => void | Sets an attribute with a given value on the helper text element | | removeHelperTextAttr(name: string) => void | Removes an attribute from the helper text element | +| setHelperTextContent(content: string) => void | Sets the content of the helper text element | | getNativeInput() => {value: string, disabled: boolean, badInput: boolean, checkValidity: () => boolean}? | Returns an object representing the native text input element, with a similar API shape. The object returned should include the `value`, `disabled` and `badInput` properties, as well as the `checkValidity()` function. We _never_ alter the value within our code, however we _do_ update the disabled property, so if you choose to duck-type the return value for this method in your implementation it's important to keep this in mind. Also note that this method can return null, which the foundation will handle gracefully. | | getBottomLineFoundation() => MDCTextFieldBottomLineFoundation | Returns the instance of the bottom line element's foundation | diff --git a/packages/mdc-textfield/adapter.js b/packages/mdc-textfield/adapter.js index 6eff5f50ae7..88de5fba68a 100644 --- a/packages/mdc-textfield/adapter.js +++ b/packages/mdc-textfield/adapter.js @@ -164,6 +164,12 @@ class MDCTextFieldAdapter { */ removeHelperTextAttr(name) {} + /** + * Sets the text content for the help text element + * @param {string} content + */ + setHelperTextContent(content) {} + /** * Returns an object representing the native text input element, with a * similar API shape. The object returned should include the value, disabled diff --git a/packages/mdc-textfield/foundation.js b/packages/mdc-textfield/foundation.js index 6f25d74d75e..ef5e8f0f977 100644 --- a/packages/mdc-textfield/foundation.js +++ b/packages/mdc-textfield/foundation.js @@ -61,6 +61,7 @@ class MDCTextFieldFoundation extends MDCFoundation { deregisterBottomLineEventHandler: () => {}, setHelperTextAttr: () => {}, removeHelperTextAttr: () => {}, + setHelperTextContent: () => {}, getNativeInput: () => {}, getBottomLineFoundation: () => {}, }); @@ -311,6 +312,13 @@ class MDCTextFieldFoundation extends MDCFoundation { } } + /** + * @param {string} content Sets the content of the helper text field + */ + setHelperTextContent(content) { + this.adapter_.setHelperTextContent(content); + } + /** * @return {!Element|!NativeInputType} The native text input from the * host environment, or a dummy if none exists. diff --git a/packages/mdc-textfield/index.js b/packages/mdc-textfield/index.js index aedbee0b0f9..a4303cc8904 100644 --- a/packages/mdc-textfield/index.js +++ b/packages/mdc-textfield/index.js @@ -124,6 +124,13 @@ class MDCTextField extends MDCComponent { this.foundation_.setValid(valid); } + /** + * @param {string} content Sets the Helper Text element textContent. + */ + set helperTextContent(content) { + this.foundation_.setHelperTextContent(content); + } + /** * @return {!MDCTextFieldFoundation} */ @@ -236,6 +243,11 @@ class MDCTextField extends MDCComponent { this.helperTextElement.removeAttribute(name); } }, + setHelperTextContent: (content) => { + if (this.helperTextElement) { + this.helperTextElement.textContent = content; + } + }, }; } } diff --git a/test/unit/mdc-textfield/foundation.test.js b/test/unit/mdc-textfield/foundation.test.js index 8339054b371..50c60f36e72 100644 --- a/test/unit/mdc-textfield/foundation.test.js +++ b/test/unit/mdc-textfield/foundation.test.js @@ -43,6 +43,7 @@ test('defaultAdapter returns a complete adapter implementation', () => { 'registerInputInteractionHandler', 'deregisterInputInteractionHandler', 'registerBottomLineEventHandler', 'deregisterBottomLineEventHandler', 'setHelperTextAttr', 'removeHelperTextAttr', 'getNativeInput', 'getBottomLineFoundation', + 'setHelperTextContent', ]); }); @@ -181,6 +182,12 @@ test('#init does not add mdc-text-field__label--float-above class if the input d td.verify(mockAdapter.addClassToLabel(cssClasses.LABEL_FLOAT_ABOVE), {times: 0}); }); +test('#setHelperTextContent sets the content of the helper text element', () => { + const {foundation, mockAdapter} = setupTest(); + foundation.setHelperTextContent('foo'); + td.verify(mockAdapter.setHelperTextContent('foo')); +}); + test('on input focuses if input event occurs without any other events', () => { const {foundation, mockAdapter} = setupTest(); let input; diff --git a/test/unit/mdc-textfield/mdc-text-field.test.js b/test/unit/mdc-textfield/mdc-text-field.test.js index 92c4d9f53ba..c4d6764d1b2 100644 --- a/test/unit/mdc-textfield/mdc-text-field.test.js +++ b/test/unit/mdc-textfield/mdc-text-field.test.js @@ -138,6 +138,21 @@ test('set valid updates the component styles', () => { assert.isNotOk(root.classList.contains(cssClasses.INVALID)); }); +test('set helperTextContent updates the helper text element content', () => { + const {component} = setupTest(); + const helptext = getHelperText(); + component.helperTextElement = helptext; + component.helperTextContent = 'foo'; + assert.equal(helptext.textContent, 'foo'); +}); + +test('set helperTextContent has no effect when no helper text element is present', () => { + const {component} = setupTest(); + assert.isNull(component.helperTextElement); + component.helperTextContent = 'foo'; + assert.isNull(component.helperTextElement); +}); + test('#adapter.setIconAttr sets a given attribute to a given value to the icon element', () => { const {icon, component} = setupTest(); @@ -311,6 +326,19 @@ test('#adapter.removeHelperTextAttr removes an attribute on the helper text elem assert.isNotOk(helperText.hasAttribute('aria-label')); }); +test('#adapter.setHelperTextContent does nothing if no help text element present', () => { + const {component} = setupTest(); + assert.doesNotThrow(() => component.getDefaultFoundation().adapter_.setHelperTextContent('foo')); +}); + +test('#adapter.setHelperTextContent updates the text content of the help text element', () => { + const {component} = setupTest(); + const helptext = getHelperText(); + component.helperTextElement = helptext; + component.getDefaultFoundation().adapter_.setHelperTextContent('foo'); + assert.equal(helptext.textContent, 'foo'); +}); + test(`#adapter.notifyIconAction emits ${strings.ICON_EVENT}`, () => { const {component} = setupTest(); const handler = td.func('leadingHandler');