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

feat(textfield): helperTextContent setter #1569

Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
3cfd6e9
feat(textfield): add API to get/set help text
patrickrodee Nov 8, 2017
ecdb071
fix(textfield): updated files to pass lint
patrickrodee Nov 8, 2017
a47b333
Merge branch 'master' into feat/textfield-helptext-accessor
patrickrodee Nov 8, 2017
71fff53
fix(textfield): changes according to review
patrickrodee Nov 16, 2017
76a58bf
fix(textfield): merged upstream changes
patrickrodee Nov 16, 2017
4f45cdb
Merge branch 'master' into feat/textfield-helptext-accessor
patrickrodee Nov 16, 2017
024fa61
fix(textfield): removed extraneous accessor
patrickrodee Nov 16, 2017
00b48f9
fix(textfield): removed extraneous methods
patrickrodee Nov 16, 2017
335a394
fix(textfield): removed more extranous methods
patrickrodee Nov 16, 2017
b605a4d
fix(textfield): removed extraneous tests
patrickrodee Nov 16, 2017
960c3fe
fix(textfield): resolved conflicts
patrickrodee Nov 16, 2017
d6af5c3
fix(textfield): resolved failing test issues
patrickrodee Nov 16, 2017
37c078d
fix(textfield): all tests finally pass and use new "helper text" name
patrickrodee Nov 16, 2017
af16d8d
fix(textfield): incorrect casing of "MDCTextField"
patrickrodee Nov 17, 2017
dde368a
Merge branch 'master' into feat/textfield-helptext-accessor
patrickrodee Nov 20, 2017
958a046
fix(textfield): removed helperTextContent getter
patrickrodee Nov 20, 2017
6a0d26d
Merge branch 'master' into feat/textfield-helptext-accessor
amsheehan Nov 21, 2017
f79f9b4
Merge branch 'master' into feat/textfield-helptext-accessor
patrickrodee Nov 21, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions packages/mdc-textfield/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,11 @@ being used as the text field's "help text". It defaults to `null`. If the text f
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.helptextValue

String. Proxies to the foundation's `getHelptextValue/setHelptextValue` methods when retrieved/set
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: should read getHelptextValue/setHelptextValue

I realize you were just following the pattern for MDCTextfield.disabled, but that should probably change too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Easy fix, thanks!

respectively.

##### MDCTextfield.disabled

Boolean. Proxies to the foundation's `isDisabled/setDisabled` methods when retrieved/set
Expand Down Expand Up @@ -414,6 +419,8 @@ complicated.
| setBottomLineAttr(attr: string, value: string) => void | Sets an attribute with a given value on the bottom line element |
| setHelptextAttr(name: string, value: string) => void | Sets an attribute with a given value on the help text element |
| removeHelptextAttr(name: string) => void | Removes an attribute from the help text element |
| setHelptextValue(value: string) => void | Sets the content of the help text element |
| getHelptextValue() => string | Retrieves the content of the help 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. |

#### The full foundation API
Expand Down
12 changes: 12 additions & 0 deletions packages/mdc-textfield/adapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,18 @@ class MDCTextfieldAdapter {
*/
removeHelptextAttr(name) {}

/**
* Sets the text value for the help text element
* @param {string} value
*/
setHelptextValue(value) {}

/**
* Returns the text value of the help text element
* @return {string|undefined}
*/
getHelptextValue() {}

/**
* Returns an object representing the native text input element, with a
* similar API shape. The object returned should include the value, disabled
Expand Down
16 changes: 16 additions & 0 deletions packages/mdc-textfield/foundation.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ class MDCTextfieldFoundation extends MDCFoundation {
setBottomLineAttr: () => {},
setHelptextAttr: () => {},
removeHelptextAttr: () => {},
setHelptextValue: () => {},
getHelptextValue: () => {},
getNativeInput: () => {},
});
}
Expand Down Expand Up @@ -310,6 +312,20 @@ class MDCTextfieldFoundation extends MDCFoundation {
}
}

/**
* @param {string} value Sets the content of the helper text field
*/
setHelptextValue(value) {
this.adapter_.setHelptextValue(value);
}

/**
* @return {string|undefined} The value (if any) of the helper text field
*/
getHelptextValue() {
return this.adapter_.getHelptextValue();
}

/**
* @return {!Element|!NativeInputType} The native text input from the
* host environment, or a dummy if none exists.
Expand Down
19 changes: 19 additions & 0 deletions packages/mdc-textfield/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,14 @@ class MDCTextfield extends MDCComponent {
this.foundation_.setValid(valid);
}

get helptextValue() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, thanks!

return this.foundation_.getHelptextValue();
}

set helptextValue(value) {
this.foundation_.setHelptextValue(value);
}

/**
* @return {!MDCTextfieldFoundation}
*/
Expand Down Expand Up @@ -249,6 +257,17 @@ class MDCTextfield extends MDCComponent {
this.helptextElement.removeAttribute(name);
}
},
setHelptextValue: (value) => {
if (this.helptextElement) {
this.helptextElement.textContent = value;
}
},
getHelptextValue: () => {
if (!this.helptextElement) {
return;
}
return this.helptextElement.textContent.trim();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason for adding trim()? I assume users would want to know if they have extra whitespace.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I was trying to ensure that the returned value was close to what the user expected but that sounds like a false assumption on my part.

For example:

<p class="mdc-text-field-helptext">
  Hello
</p>

would have a textContent of " Hello " when I would expect it to be just "Hello"

That being said, I see now that's an incorrect assumption. I'll remove .trim(). Thanks!

},
};
}
}
Expand Down
23 changes: 23 additions & 0 deletions test/unit/mdc-textfield/foundation.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ test('defaultAdapter returns a complete adapter implementation', () => {
'registerInputInteractionHandler', 'deregisterInputInteractionHandler',
'registerTransitionEndHandler', 'deregisterTransitionEndHandler',
'setBottomLineAttr', 'setHelptextAttr', 'removeHelptextAttr', 'getNativeInput',
'setHelptextValue', 'getHelptextValue',
]);
});

Expand Down Expand Up @@ -173,6 +174,28 @@ test('#init does not add mdc-textfield__label--float-above class if the input do
td.verify(mockAdapter.addClassToLabel(cssClasses.LABEL_FLOAT_ABOVE), {times: 0});
});

test('#setHelptextValue has no effect when no help text element is present', () => {
const {foundation} = setupTest();
foundation.setHelptextValue('foo');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmmm... I wonder if there's a way to make this a more isolated and specific test. It's not really testing what we're saying it's testing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

});

test('#setHelptextValue sets the value of the help text element', () => {
const {foundation, mockAdapter} = setupTest();
foundation.setHelptextValue('foo');
td.verify(mockAdapter.setHelptextValue('foo'));
});

test('#getHelptextValue has no effect when no help text element is present', () => {
const {foundation} = setupTest();
foundation.getHelptextValue();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

});

test('#getHelptextValue retrieves the value of the help text element', () => {
const {foundation, mockAdapter} = setupTest();
foundation.getHelptextValue();
td.verify(mockAdapter.getHelptextValue());
});

test('on input focuses if input event occurs without any other events', () => {
const {foundation, mockAdapter} = setupTest();
let input;
Expand Down
42 changes: 42 additions & 0 deletions test/unit/mdc-textfield/mdc-textfield.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,22 @@ test('set valid updates the component styles', () => {
assert.isNotOk(root.classList.contains(cssClasses.INVALID));
});

test('set helptextValue updates the help text element content', () => {
const {component} = setupTest();
const helptext = getHelptext();
component.helptextElement = helptext;
component.helptextValue = 'foo';
assert.equal(helptext.textContent, 'foo');
});

test('get helptextValue retrieves the help text element content', () => {
const {component} = setupTest();
const helptext = getHelptext();
component.helptextElement = helptext;
helptext.textContent = 'foo';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to set anything here first, right? The fixture has a value already.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, good find. I'll switch the check for the fixture's default value. Thanks!

assert.equal(component.helptextValue, 'foo');
});

test('#adapter.addClassToBottomLine adds a class to the bottom line', () => {
const {bottomLine, component} = setupTest();
component.getDefaultFoundation().adapter_.addClassToBottomLine('foo');
Expand Down Expand Up @@ -330,6 +346,32 @@ test('#adapter.removeHelptextAttr removes an attribute on the help text element'
assert.isNotOk(helptext.hasAttribute('aria-label'));
});

test('#adapter.setHelptextValue does nothing if no help text element present', () => {
const {component} = setupTest();
assert.doesNotThrow(() => component.getDefaultFoundation().adapter_.setHelptextValue('foo'));
});

test('#adapter.setHelptextValue updates the text content of the help text element', () => {
const {component} = setupTest();
const helptext = getHelptext();
component.helptextElement = helptext;
component.getDefaultFoundation().adapter_.setHelptextValue('foo');
assert.equal(helptext.textContent, 'foo');
});

test('#adapter.getHelptextValue does nothing if no help text element present', () => {
const {component} = setupTest();
assert.doesNotThrow(() => component.getDefaultFoundation().adapter_.getHelptextValue());
});

test('#adapter.getHelptextValue retrieves the text content of the help text element', () => {
const {component} = setupTest();
const helptext = getHelptext();
component.helptextElement = helptext;
component.getDefaultFoundation().adapter_.setHelptextValue('foo');
assert.equal(component.getDefaultFoundation().adapter_.getHelptextValue(), 'foo');
});

test(`#adapter.notifyIconAction emits ${strings.ICON_EVENT}`, () => {
const {component} = setupTest();
const handler = td.func('leadingHandler');
Expand Down