Skip to content
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] Initial implementation of optional underline #2476

Merged
merged 1 commit into from
Dec 16, 2015

Conversation

newoga
Copy link
Contributor

@newoga newoga commented Dec 11, 2015

This resolves #2475. Related to and possibly fixes #2448 and #2233.

Done:

  • Implemented a separate stateless text-field-underline.jsx component that defines its own style defaults, accepts disable, focus, and error state, and disabled, focus, and error style override configuration through props
  • Simplified text-field.jsx to pass underlineStyle configurations to text-field-underline.jsx component

Todo:
- Create disabled underline example in docs Will do in a separate pull request since the TextField docs still need to be migrated to the new format.

Note:
The new text-field-underline.jsx currently takes the muiTheme through props from its parent text-field.jsx component. Stateless components also support context if we wanted to to make it work like the other components. Though for components like this that aren't meant to be alone, maybe we should consider accepting everything through props for simplicity. I'm open to discussing this though.

@newoga
Copy link
Contributor Author

newoga commented Dec 11, 2015

On a separate note:

If we like the idea of using a separate component for the text-field-underline, we can easily use the same pattern for helper/error, floating text, etc. Should make the code easier to reason about, esp with the inline styles.

@@ -55,6 +55,7 @@ const TextField = React.createClass({
rowsMax: React.PropTypes.number,
style: React.PropTypes.object,
type: React.PropTypes.string,
underline: React.PropTypes.bool,
Copy link
Member

Choose a reason for hiding this comment

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

maybe underlineVisible? underline feels like you need to pass the "Underline" node through this prop. @oliviertassinari Thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah that's true, I can see that being confused for a prop that accept a component.

Naming things is hard 😸

Copy link
Member

Choose a reason for hiding this comment

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

Naming things is hard

Couldn't agree more >.>

Copy link
Member

Choose a reason for hiding this comment

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

what about underlineShow?

Copy link
Member

Choose a reason for hiding this comment

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

that's good 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.

Let me know which one you want! I'm fine with either 😄

Now that I think about it, as a general rule, using a "positive-form" adjective might have a slight advantage over a verb/noun because some people specify boolean props as truthy without explicitly specifying the value of the prop as true.

For example some people and use eslint rules for this pattern:

/* CORRECT */
<Component
   active
/>

/* WRONG */
<MyComponent
   active={true}
/>

/* CORRECT */
<MyComponent
   active={false}
/>

Copy link
Member

Choose a reason for hiding this comment

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

go with underlineShow, easier to spell 😬

@alitaheri
Copy link
Member

@oliviertassinari Do you think the generator can understand stateless functional components? (or whatever the hell facebook finally decides to call them)

@oliviertassinari
Copy link
Member

@alitaheri
Copy link
Member

nice 👍

@newoga
Copy link
Contributor Author

newoga commented Dec 11, 2015

Yeah I really like stateless functional components if you haven't realized 😅

I wanted to "test the waters" to see what you two thought, if you'd prefer me to write it createClass style, let me know. It's an easy switch.

@alitaheri
Copy link
Member

@newoga I like them too, besides there can be heavily optimized by React, when they actually get around to it. I'm alright with this. @oliviertassinari ?should be migrate the stateless components to take advantage of these things?

@newoga
Copy link
Contributor Author

newoga commented Dec 11, 2015

If we go through with this, I'll throw out another style question/suggestion:

If we followed Airbnb's style guide, for example, we would define the propTypes and defaultProps as consts at the top of the file, then set them at the bottom.

So we would make this change to the order...:

import React from 'react';

const propTypes = {
};

const defaultProps = {
};

const TextFieldUnderline = (props) => {
  // impl
}

TextFieldUnderline.propTypes = propTypes;
TextFieldUnderline.defaultProps = defaultProps;

export default TextFieldUnderline;

Personally, I think I like this more so that when we add documentation to the props, they remain at the top of the file above the implementation instead of at the bottom...

@oliviertassinari
Copy link
Member

I want to enforce react/sort-comp at some point. I completely agree 💯.

@oliviertassinari
Copy link
Member

According to the react doc about the stateless component:

Functional components do not have lifecycle methods, but you can set .propTypes and .defaultProps as properties on the function.

This pattern is designed to encourage the creation of these simple components that should comprise large portions of your apps. In the future, we’ll also be able to make performance optimizations specific to these components by avoiding unnecessary checks and memory allocations.

Seems like as soon as we don't need a state, we should use this pattern 👍

@alitaheri
Copy link
Member

@oliviertassinari Yeah, this is a great pattern. 👍 👍

@newoga
Copy link
Contributor Author

newoga commented Dec 11, 2015

Yay! 🎆

@newoga
Copy link
Contributor Author

newoga commented Dec 11, 2015

I think I'm pretty much done with this too. Let me know if you need anything else, otherwise I can squash and push.

Note: This pull request and #2473 has the same change to src/util/styles.js to add the merge() function from ImmutabilityHelper. So might make sense to merge one into master first, then update the other from master, unless there's some git magic I don't know about.

@alitaheri
Copy link
Member

😱 😱 😱 You did a merge instead of rebase in your branch :D :D You're gonna hate git for the first time in your life when you try to squash this :D

I'll review right away

P.S. I had this issue before, I can help you if you get clueless.

@alitaheri
Copy link
Member

@newoga I'm all good

@oliviertassinari Take a look too.

@oliviertassinari
Copy link
Member

Looks fine so far, I'm gonna test it.

@neverfox
Copy link
Contributor

@newoga @subjectix @oliviertassinari

Seems like as soon as we don't need a state, we should use this pattern

It is a great pattern but I'm very concerned about material-ui going in this direction while it's still not supported by babel-plugin-react-transform. Maybe this shouldn't be a concern because it wouldn't be likely that anyone would be changing the source on-the-fly? Discussed on #2493

disabled: React.PropTypes.bool,

/**
* Override the inline-styles of the underline when parent TextField is disabled
Copy link
Member

Choose a reason for hiding this comment

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

What about considering the descriptions as a phrase and adding a dot at the end?

Copy link
Member

Choose a reason for hiding this comment

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

and use markdown in them too 😁

@oliviertassinari
Copy link
Member

I think that we should create a TextField folder and move the text-field.jsx and the new text-field-underline.jsx inside this folder.
It's more common to see the file of component using uppercase (#1793).
Hence, I think that the file structure should be something like:

-TextField/
 -TextField.jsx
 -TextFieldUnderline.jsx
-text-field.jsx (with a simple reference to TextField/TextField.jsx)

@newoga
Copy link
Contributor Author

newoga commented Dec 14, 2015

@oliviertassinari I agree on the folder/new naming structure. Also, at some point in the future I think it'd be nice if the import matched the component name like mentioned in #1793. Would it make sense to export the component under two names and deprecate the access to the other one?
Maybe something like:

+-- TextField
|   +-- TextField.jsx
|   +-- TextFieldUnderline.jsx
|   +-- index.js -- this would default export TextField.jsx
text-field.jsx

Maybe we could make a util file like deprecatedExport.js:

import warning from 'warning';

function deprecatedExport(Component, deprecated, supported) {
  warning(false,
    `Importing ${Component.displayName} from '${deprecated}' has been deprecated, use '${supported}' instead.`);
  return Component;
}

export default deprecatedExport;

And then, like you suggested, we can rewrite text-field.jsx to export TextField.jsx from the new location and warn the developer:

import TextField from './TextField';
import deprecatedExport from './deprecatedExport';

export default deprecatedExport(TextField, 'material-ui/lib/text-field', 'material-ui/lib/TextField');

@alitaheri
Copy link
Member

@newoga I like your idea 👍 👍

@newoga
Copy link
Contributor Author

newoga commented Dec 14, 2015

@oliviertassinari @subjectix If we like this deprecatedExport approach, should I submit that as a separate pull request that we can merge sooner?

@oliviertassinari
Copy link
Member

@newoga I'm ok with this 👍.

@alitaheri
Copy link
Member

@newoga Yeah that's a great idea 👍

@newoga
Copy link
Contributor Author

newoga commented Dec 14, 2015

Alright, I changed this set of components to the new PascalCase format in an appropriate TextField folder. I changed text-field.jsx to point to the new location, but did not add the deprecation warning (so it will just work).

I also made some documentation improvements like adding periods and markdown formatting such as code hint TextField.

@oliviertassinari, you had mentioned previously that you think the descriptions should be phrases with a period at the end. I added a period, but could you please give me an example description for one of the props? 😄 Just want to make sure I understand you correctly, I can fix the others afterwards.

@oliviertassinari
Copy link
Member

@newoga The description is fine now. My point was simply to add a dot at the end.
@subjectix I'm ok with this PR. I guess that after a squash down of commit we can merge 👍.

@newoga
Copy link
Contributor Author

newoga commented Dec 15, 2015

Oh okay, sounds good. I'll squash now.

@alitaheri
Copy link
Member

@newoga Thanks a lot. you're a huge help 👍 👍

alitaheri added a commit that referenced this pull request Dec 16, 2015
[WIP][TextField] Initial implementation of optional underline
@alitaheri alitaheri merged commit 8fd6c8e into mui:master Dec 16, 2015
@newoga newoga deleted the wip/textfield-underline branch December 16, 2015 20:52
@alitaheri alitaheri changed the title [WIP][TextField] Initial implementation of optional underline [TextField] Initial implementation of optional underline Dec 24, 2015
@zannager zannager added the component: text field This is the name of the generic UI component, not the React module! label Mar 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: text field This is the name of the generic UI component, not the React module!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[TextField] Optional underline Text field underline when selected has two separate lines drawn
5 participants