-
Notifications
You must be signed in to change notification settings - Fork 2.1k
chore(text-field): Pass subelement foundations through MDCTextField super constructor #1684
Changes from 4 commits
4979977
c7cc018
b8ade36
3549f18
0184dac
6a3d0d6
67dd9c6
1b9f01b
412b7ab
7b6feb2
d4c6da7
57a411d
85018b2
180f341
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,9 +15,11 @@ | |
* limitations under the License. | ||
*/ | ||
|
||
/* eslint-disable no-unused-vars */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To ensure checking isn't disabled for the entire file, this line could be removed and a line-specific lint disable comment could be added above There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done! Here and in index.js |
||
import MDCFoundation from '@material/base/foundation'; | ||
import {MDCTextFieldAdapter, NativeInputType} from './adapter'; | ||
import MDCTextFieldBottomLineFoundation from './bottom-line/foundation'; | ||
import MDCTextFieldHelperTextFoundation from './helper-text/foundation'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See above. Adding this line above line 22 ensures that the |
||
import {cssClasses, strings} from './constants'; | ||
|
||
|
||
|
@@ -57,17 +59,23 @@ class MDCTextFieldFoundation extends MDCFoundation { | |
registerBottomLineEventHandler: () => {}, | ||
deregisterBottomLineEventHandler: () => {}, | ||
getNativeInput: () => {}, | ||
getBottomLineFoundation: () => {}, | ||
getHelperTextFoundation: () => {}, | ||
}); | ||
} | ||
|
||
/** | ||
* @param {!MDCTextFieldAdapter=} adapter | ||
* @param {!MDCTextFieldBottomLineFoundation=} bottomLineFoundation | ||
* @param {!MDCTextFieldHelperTextFoundation=} helperTextFoundation | ||
*/ | ||
constructor(adapter = /** @type {!MDCTextFieldAdapter} */ ({})) { | ||
constructor(adapter = /** @type {!MDCTextFieldAdapter} */ ({}), | ||
bottomLineFoundation, helperTextFoundation) { | ||
super(Object.assign(MDCTextFieldFoundation.defaultAdapter, adapter)); | ||
|
||
/** @type {!MDCTextFieldBottomLineFoundation|undefined} */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FYI, this is the correct way to annotate an optional property/param. I talked to Brendan (our resident Closure Compiler expert) and crawled through the JS Style Guide and Closure Compiler JSDoc wiki, and they all seem to suggest that your style is the right one. The rest of our code base uses a nullable type instead of We should probably update the rest of our components to use your style of annotations at some point. |
||
this.bottomLine_ = bottomLineFoundation; | ||
/** @type {!MDCTextFieldHelperTextFoundation|undefined} */ | ||
this.helperText_ = helperTextFoundation; | ||
|
||
/** @private {boolean} */ | ||
this.isFocused_ = false; | ||
/** @private {boolean} */ | ||
|
@@ -150,15 +158,13 @@ class MDCTextFieldFoundation extends MDCFoundation { | |
activateFocus() { | ||
const {FOCUSED, LABEL_FLOAT_ABOVE, LABEL_SHAKE} = MDCTextFieldFoundation.cssClasses; | ||
this.adapter_.addClass(FOCUSED); | ||
const bottomLine = this.adapter_.getBottomLineFoundation(); | ||
if (bottomLine) { | ||
bottomLine.activate(); | ||
if (this.bottomLine_) { | ||
this.bottomLine_.activate(); | ||
} | ||
this.adapter_.addClassToLabel(LABEL_FLOAT_ABOVE); | ||
this.adapter_.removeClassFromLabel(LABEL_SHAKE); | ||
const helperText = this.adapter_.getHelperTextFoundation(); | ||
if (helperText) { | ||
helperText.showToScreenReader(); | ||
if (this.helperText_) { | ||
this.helperText_.showToScreenReader(); | ||
} | ||
this.isFocused_ = true; | ||
} | ||
|
@@ -169,9 +175,8 @@ class MDCTextFieldFoundation extends MDCFoundation { | |
* @param {!Event} evt | ||
*/ | ||
setBottomLineTransformOrigin(evt) { | ||
const bottomLine = this.adapter_.getBottomLineFoundation(); | ||
if (bottomLine) { | ||
bottomLine.setTransformOrigin(evt); | ||
if (this.bottomLine_) { | ||
this.bottomLine_.setTransformOrigin(evt); | ||
} | ||
} | ||
|
||
|
@@ -190,12 +195,11 @@ class MDCTextFieldFoundation extends MDCFoundation { | |
* for animations to finish. | ||
*/ | ||
handleBottomLineAnimationEnd() { | ||
const bottomLine = this.adapter_.getBottomLineFoundation(); | ||
// We need to wait for the bottom line to be entirely transparent | ||
// before removing the class. If we do not, we see the line start to | ||
// scale down before disappearing | ||
if (!this.isFocused_ && bottomLine) { | ||
bottomLine.deactivate(); | ||
if (!this.isFocused_ && this.bottomLine_) { | ||
this.bottomLine_.deactivate(); | ||
} | ||
} | ||
|
||
|
@@ -233,9 +237,8 @@ class MDCTextFieldFoundation extends MDCFoundation { | |
this.adapter_.addClassToLabel(LABEL_SHAKE); | ||
this.adapter_.addClass(INVALID); | ||
} | ||
const helperText = this.adapter_.getHelperTextFoundation(); | ||
if (helperText) { | ||
helperText.setValidity(isValid); | ||
if (this.helperText_) { | ||
this.helperText_.setValidity(isValid); | ||
} | ||
} | ||
|
||
|
@@ -275,9 +278,8 @@ class MDCTextFieldFoundation extends MDCFoundation { | |
* @param {string} content Sets the content of the helper text. | ||
*/ | ||
setHelperTextContent(content) { | ||
const helperText = this.adapter_.getHelperTextFoundation(); | ||
if (helperText) { | ||
helperText.setContent(content); | ||
if (this.helperText_) { | ||
this.helperText_.setContent(content); | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,11 +18,12 @@ | |
import MDCComponent from '@material/base/component'; | ||
import {MDCRipple} from '@material/ripple'; | ||
|
||
/* eslint-disable no-unused-vars */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above. Could be removed to ensure unused var check is only removed for specific lines |
||
import {cssClasses, strings} from './constants'; | ||
import {MDCTextFieldAdapter} from './adapter'; | ||
import MDCTextFieldFoundation from './foundation'; | ||
import {MDCTextFieldBottomLine} from './bottom-line'; | ||
import {MDCTextFieldHelperText} from './helper-text'; | ||
import {MDCTextFieldBottomLine, MDCTextFieldBottomLineFoundation} from './bottom-line'; | ||
import {MDCTextFieldHelperText, MDCTextFieldHelperTextFoundation} from './helper-text'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above. Adding |
||
|
||
/** | ||
* @extends {MDCComponent<!MDCTextFieldFoundation>} | ||
|
@@ -142,50 +143,41 @@ class MDCTextField extends MDCComponent { | |
* @return {!MDCTextFieldFoundation} | ||
*/ | ||
getDefaultFoundation() { | ||
return new MDCTextFieldFoundation(/** @type {!MDCTextFieldAdapter} */ (Object.assign({ | ||
addClass: (className) => this.root_.classList.add(className), | ||
removeClass: (className) => this.root_.classList.remove(className), | ||
addClassToLabel: (className) => { | ||
const label = this.label_; | ||
if (label) { | ||
label.classList.add(className); | ||
} | ||
}, | ||
removeClassFromLabel: (className) => { | ||
const label = this.label_; | ||
if (label) { | ||
label.classList.remove(className); | ||
} | ||
}, | ||
eventTargetHasClass: (target, className) => target.classList.contains(className), | ||
registerTextFieldInteractionHandler: (evtType, handler) => this.root_.addEventListener(evtType, handler), | ||
deregisterTextFieldInteractionHandler: (evtType, handler) => this.root_.removeEventListener(evtType, handler), | ||
notifyIconAction: () => this.emit(MDCTextFieldFoundation.strings.ICON_EVENT, {}), | ||
registerBottomLineEventHandler: (evtType, handler) => { | ||
if (this.bottomLine_) { | ||
this.bottomLine_.listen(evtType, handler); | ||
} | ||
}, | ||
deregisterBottomLineEventHandler: (evtType, handler) => { | ||
if (this.bottomLine_) { | ||
this.bottomLine_.unlisten(evtType, handler); | ||
} | ||
}, | ||
getBottomLineFoundation: () => { | ||
if (this.bottomLine_) { | ||
return this.bottomLine_.foundation; | ||
} | ||
return undefined; | ||
return new MDCTextFieldFoundation( | ||
/** @type {!MDCTextFieldAdapter} */ (Object.assign({ | ||
addClass: (className) => this.root_.classList.add(className), | ||
removeClass: (className) => this.root_.classList.remove(className), | ||
addClassToLabel: (className) => { | ||
const label = this.label_; | ||
if (label) { | ||
label.classList.add(className); | ||
} | ||
}, | ||
removeClassFromLabel: (className) => { | ||
const label = this.label_; | ||
if (label) { | ||
label.classList.remove(className); | ||
} | ||
}, | ||
eventTargetHasClass: (target, className) => target.classList.contains(className), | ||
registerTextFieldInteractionHandler: (evtType, handler) => this.root_.addEventListener(evtType, handler), | ||
deregisterTextFieldInteractionHandler: (evtType, handler) => this.root_.removeEventListener(evtType, handler), | ||
notifyIconAction: () => this.emit(MDCTextFieldFoundation.strings.ICON_EVENT, {}), | ||
registerBottomLineEventHandler: (evtType, handler) => { | ||
if (this.bottomLine_) { | ||
this.bottomLine_.listen(evtType, handler); | ||
} | ||
}, | ||
deregisterBottomLineEventHandler: (evtType, handler) => { | ||
if (this.bottomLine_) { | ||
this.bottomLine_.unlisten(evtType, handler); | ||
} | ||
}, | ||
}, | ||
getHelperTextFoundation: () => { | ||
if (this.helperText_) { | ||
return this.helperText_.foundation; | ||
} | ||
return undefined; | ||
}, | ||
}, | ||
this.getInputAdapterMethods_(), | ||
this.getIconAdapterMethods_()))); | ||
this.getInputAdapterMethods_(), | ||
this.getIconAdapterMethods_())), | ||
this.getBottomLineFoundation_(), | ||
this.getHelperTextFoundation_()); | ||
} | ||
|
||
/** | ||
|
@@ -217,6 +209,30 @@ class MDCTextField extends MDCComponent { | |
getNativeInput: () => this.input_, | ||
}; | ||
} | ||
|
||
/** | ||
* Returns the foundation for the bottom line element. Returns undefined if | ||
* there is no bottom line element. | ||
* @return {!MDCTextFieldBottomLineFoundation|undefined} | ||
*/ | ||
getBottomLineFoundation_() { | ||
if (this.bottomLine_) { | ||
return this.bottomLine_.foundation; | ||
} | ||
return undefined; | ||
} | ||
|
||
/** | ||
* Returns the foundation for the helper text element. Returns undefined if | ||
* there is no helper text element. | ||
* @return {!MDCTextFieldHelperTextFoundation|undefined} | ||
*/ | ||
getHelperTextFoundation_() { | ||
if (this.helperText_) { | ||
return this.helperText_.foundation; | ||
} | ||
return undefined; | ||
} | ||
} | ||
|
||
export {MDCTextField, MDCTextFieldFoundation}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Outside the scope of the PR but is there a standard for how we refer to components? Are they referred to by their back-tick wrapped class name (
MDCTextField
) or as sentence case (MDC TextField)? Just curious because in some cases it's wrapped in back ticks and others it's not.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if there is a formal standard, but I think when it's referenced as a concept then I use sentence case, and when it's referenced as code I use markdown. I changed some references above to be in markdown.