-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[TextField] Add in support for multiline text fields #6553
[TextField] Add in support for multiline text fields #6553
Conversation
…of `palette.accent.A200`
…d those along to `Input`
…ng consistently across inputs of type text and textareas
…istently for textareas and inputs of type text
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.
That's a good start, thanks for working on it!
src/TextField/TextField.js
Outdated
@@ -108,10 +123,14 @@ export default class TextField extends Component { | |||
)} | |||
<Input | |||
className={inputClassName} | |||
value={value} | |||
component={multiLine ? 'textarea' : 'input'} |
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 wondering, shouldn't it be the Input
responsibility to render a textarea
?
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.
yea I think that's right. I'll change this.
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.
When I started making this change I realized it didn't make as much sense as I thought :(
The <Input />
component takes a component
prop, and it feels wrong to sometimes determine the rendered component via the component
prop and other times determine the rendered component via the multiLine
prop. We'd have to do something like this:
const InputComponent = multiLine ? 'textarea' : ComponentProp;
Which feels like unexpected behavior to me. Still happy to change this over if you like, but at this point I'm leaning towards keeping it the way it is.
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 have two thoughs here:
- The
Input
component is public and can be used on his own, hence all the multiline logic should be at the same place, in theInput
. - Exposing a component property means user can override it. Hence, it should always take precedence, no matter the
multiline
state.
src/Input/Input.js
Outdated
@@ -67,6 +67,12 @@ export const styleSheet = createStyleSheet('MuiInput', (theme) => { | |||
appearance: 'none', | |||
}, | |||
}, | |||
multiLine: { | |||
resize: 'none', |
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.
We don't want to allow users to resize?
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 used v0 as the spec for this, which doesn't allow manual resizing for multiline text fields.
I should've used the official spec though...
Which says multiline text fields should work like this:
Note that the spec also talks about Text Areas which are different from multi-line text fields, and which I think we'll also want to implement in a separate PR.
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.
You raise a good point but I think that the concern is different. Mine isn't about the spec but the UX. What do we win by disabling the resize feature?
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.
If the users are allowed to resize the textbox it could result in unexpected things happening in the UI (the user could make it too wide, or too tall). Especially if we allow them to resize textareas horizontally, which I think would really be a break with convention.
We could allow users to resize textareas vertically but it would cause text to be cutoff mid-line unless we added javascript in to snap to (line-height * lines) sizes. Either solution here doesn't feel particularly clean to me.
My preference here would be to either a) not do this at all or b) handle this in a separate PR. Let me know though if you want me to add it in here and I can take care of it.
src/TextField/TextField.js
Outdated
@@ -18,6 +18,10 @@ export default class TextField extends Component { | |||
*/ | |||
className: PropTypes.string, | |||
/** | |||
* The default value for the TextField |
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.
Default value of the `Input` element.
src/Input/Input.js
Outdated
@@ -114,6 +124,10 @@ export default class Input extends Component { | |||
*/ | |||
inputClassName: PropTypes.string, | |||
/** | |||
* If true, a textarea element will be rendered. | |||
*/ | |||
multiLine: PropTypes.bool, |
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.
Should it be called multiline
? cc @mbrookes
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.
Yea, I actually had it as multiline
originally but I noticed that in v0 it was multiLine
so I refactored it to keep the API consistent. "multi-line" is one word, not two, so I think multiline
would be more correct here.
I know v1 is already going to be introducing breaking changes, so maybe we just change it to multiline
here?
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.
Breaking changes aren't a concern. That new property name sounds better.
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.
Sorry, missed the cc. FWIW, I agree.
src/Input/Input.js
Outdated
@@ -98,6 +104,10 @@ export default class Input extends Component { | |||
PropTypes.func, | |||
]), | |||
/** | |||
* The default value for the string |
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.
Default value of the input element.
src/Input/Input.js
Outdated
@@ -280,6 +302,7 @@ export default class Input extends Component { | |||
onFocus={this.handleFocus} | |||
onChange={this.handleChange} | |||
disabled={disabled} | |||
defaultValue={defaultValue} |
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 don't think that we need to explicit the property, it's already inside the other
variable when not destructured.
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.
Yea, that's a good point. So everything was working find with regular text fields based on an <input />
but the defaultValue wasn't getting set for <textarea>
's until I explicitly passed defaultValue through as prop.
This probably isn't the best solution... Any ideas on how to improve this? Or why it might not have been working via the other
object for textareas?
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 confirm, you don't need that line.
of course, thanks for the comments, I'll push up some changes in a bit 👨💻 |
Hey, so after I merged in the latest version of
You'd think this would be easy to fix -- just install the babel-runtime dependency -- but the babel runtime dependency is already installed. I tried adding it to the dependencies of the docs project and still I got the same error. I'm running OSX Sierra, can't imagine that's affecting anything given this in a node error but who knows. @oliviertassinari I know you added this recently, any ideas what the issue might be here? If not I can keep digging on this one. |
Alright so here's the issue: the babel runtime dependency doesn't specify a This is of course not the right solution to this problem. I'm not sure what the right solution is but I'd imagine that it involves changing what we're doing in webpack.dll.config.js. I wonder if we could change the way we're dealing with dependencies there. I'm also curious -- is it just me that's having this problem? Are you able to run |
@peteratticusberg any ideas about how to remove the On my original branch I ran into issues with input height not being increased with newline on some slower devices (Safari on iPhone SE, complex app). |
@oliviertassinari I recorded two new baselines, one for a Multiline TextField and another for the TextField demos page. It looks like Argos does not recognize these new baselines and is still testing against the old ones. Have you seen this happen before? Any ideas how to fix it? |
@peteratticusberg Thanks for pushing that branch forward! I'm gonna have a look at it tomorrow :). Regarding argos, that's expected. We shouldn't have to generate baselines in the first place, accepting changes is simpler (only members with write access can do so). |
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.
test/regressions/screenshots/chrome/TextField/TextFieldMultiLine.png
seems to be a dead image.
|
||
export default function TextFieldMultiline() { | ||
return ( | ||
<div> |
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 don't think that we need that extra div
.
src/TextField/TextField.js
Outdated
@@ -47,6 +51,10 @@ export default class TextField extends Component { | |||
*/ | |||
labelClassName: PropTypes.string, | |||
/** | |||
* If `true`, a textarea element will be rendered. |
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.
may be we could add instead of an input
.
src/Input/Input.js
Outdated
multiline: { | ||
resize: 'none', | ||
padding: '0', | ||
'margin-top': '12', |
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.
That's dead code, maybe you meant?
marginTop: 12,
src/Input/Input.js
Outdated
}, | ||
multiline: { | ||
resize: 'none', | ||
padding: '0', |
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.
padding: 0,
src/Input/Input.js
Outdated
padding: '0', | ||
'margin-top': '12', | ||
}, | ||
'multiline-wrapper': { |
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.
multilineWrapper: {
label="MultiLine" | ||
multiline | ||
defaultValue="Default Value" | ||
className={classes.input} |
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.
What about adding rowsMax={6}
?
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.
good call
src/Input/AutoResizingTextArea.js
Outdated
this.syncHeightWithShadow(undefined, event); | ||
}; | ||
|
||
getInputNode() { |
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 don't think that we need that function indirection
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.
yea I agree
src/Input/AutoResizingTextArea.js
Outdated
return this.input; | ||
} | ||
|
||
setValue(value) { |
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 don't think that we should expose such method
src/Input/AutoResizingTextArea.js
Outdated
rows={this.props.rows} | ||
defaultValue={this.props.defaultValue} | ||
readOnly | ||
value={this.props.value} |
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 guess we should add aria-hidden="true"
.
src/Input/AutoResizingTextArea.js
Outdated
tabIndex="-1" | ||
rows={1} | ||
readOnly | ||
value={''} |
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 guess we should add aria-hidden="true"
.
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.
good call
Thanks for the review! Will fix this stuff up. And that's weird, TextFieldMultiline.png should be present: https://github.com/peteratticusberg/material-ui/blob/3161ccab80b454250b3288eb7eadd4a42e850757/test/regressions/screenshots/chrome/regression-TextField/TextFieldMultiline.png |
… that we changed the label from MultiLine --> Multiline)
Alright! Addressed all those comments. Had to push up a new baseline for the TextField demo page (the difference was changing the label from MultiLine --> Multiline) don't know if we need to let argo know about that. Let me know if there's anything else you think we need to address before we merge this in. |
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.
Let's go for it, I have seen some small issue I'm gonna take care of. Thanks.
Awesome. Thanks for the help with this! 🎊 |
Keeps the api consistent with the api from v0.x.
Are we good with this implementation? Happy to make changes if need to be.