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] Make it meet guidelines #6566

Merged
merged 45 commits into from May 30, 2017
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
7f966d0
Adjusted styles accordingto specs, fixed #6425
kybarg Apr 10, 2017
10a5c0f
Merge branch 'callemall/next' into next-text-field-guidelines
kybarg Apr 11, 2017
6e8ad06
Fixes, simplified styles
kybarg Apr 11, 2017
b5fb82a
Removed dead `TextFieldLabel` component as for #6580
kybarg Apr 11, 2017
6cece85
Added colors according to specs, `InputLabel` disabled prop
kybarg Apr 12, 2017
7b7fa13
Avoiding label flicker and blurry text in webkit browsers
kybarg Apr 12, 2017
4716659
More smooth label animation.
kybarg Apr 12, 2017
6f83e5b
More smooth font-size animation
kybarg Apr 12, 2017
186a251
Proper error color, added `FormHelperText` component
kybarg Apr 12, 2017
7abcec9
FormHelperText docs
kybarg Apr 12, 2017
d02154c
Fixed lint errors
kybarg Apr 12, 2017
dffc976
Added new component to styles order, fixes
kybarg Apr 15, 2017
890217f
Merge remote-tracking branch 'refs/remotes/callemall/next' into next-…
kybarg Apr 15, 2017
0b15230
Fixed disabled border style
kybarg Apr 15, 2017
f27ea99
Solve conflicts
kybarg May 26, 2017
b11a2e8
FormHelperText exports
kybarg May 26, 2017
7a3d1f4
Merge remote-tracking branch 'refs/remotes/callemall/next' into next-…
kybarg May 26, 2017
710e605
Remove unused TextFieldLabel
kybarg May 26, 2017
ff1abe5
Merge remote-tracking branch 'callemall/next' into next-text-field-gu…
kybarg May 27, 2017
0061db1
Form helper fixes, test, docs
kybarg May 27, 2017
6af7c88
Merge remote-tracking branch 'refs/remotes/callemall/next' into next-…
kybarg May 27, 2017
0565e94
TextField tests for FormHelperText
kybarg May 27, 2017
c3bde34
Get rid of TextFieldLabel.md, added tests for InputLabel
kybarg May 27, 2017
c740da2
Added tests for FormControl
kybarg May 27, 2017
760eb25
Merge remote-tracking branch 'refs/remotes/callemall/next' into next-…
kybarg May 29, 2017
4e16f7c
Make dirty if `defaultValue` is set
kybarg May 29, 2017
e7e7f47
Fix helper text font
kybarg May 29, 2017
38d4043
Fix label "flicker" in webkit browsers.
kybarg May 29, 2017
2f70c6c
Use `theme.spacing.unit` instead of number values
kybarg May 29, 2017
1457b96
Disabled composed text field demo
kybarg May 29, 2017
5fe667a
Fixed type check
kybarg May 29, 2017
5d6970d
Fixed type check error
kybarg May 29, 2017
612b02c
Make `ComposedTextFiled` accept disabled prop
kybarg May 29, 2017
ae3d010
Fixed lint
kybarg May 29, 2017
3cd4b99
Fixed docs and input
kybarg May 29, 2017
9b40eee
Exposed FormHelperTextProps and InputLabelProps
kybarg May 29, 2017
428d870
Fixed docs
kybarg May 29, 2017
489de60
Merge remote-tracking branch 'refs/remotes/callemall/next' into next-…
kybarg May 29, 2017
a8a9a6c
Fixed multiline styles
kybarg May 29, 2017
3043877
Placeholder + Label behaviour
kybarg May 29, 2017
f30dbea
Fixes
kybarg May 29, 2017
0419922
Fixed lint errors
kybarg May 29, 2017
c37fe6e
Merge remote-tracking branch 'refs/remotes/callemall/next' into next-…
kybarg May 30, 2017
30be343
Typo fixes
kybarg May 30, 2017
60ae4d7
Typo fixes 2
kybarg May 30, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 15 additions & 0 deletions docs/src/pages/component-api/Form/FormHelperText.md
@@ -0,0 +1,15 @@
FormHelperText
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 the old format. We will have to regenerate the documentation (yarn docs:build).

=========



Props
-----

| Name | Type | Default | Description |
|:-----|:-----|:--------|:------------|
| children | node | | The content of the component. |
| className | string | | The CSS class name of the root element. |
| error | bool | | Whether the helper text should be displayed in an error state. |

Any other properties supplied will be spread to the root element.
19 changes: 0 additions & 19 deletions docs/src/pages/component-api/TextField/TextFieldLabel.md

This file was deleted.

24 changes: 23 additions & 1 deletion docs/src/pages/component-demos/text-fields/ComposedTextField.js
Expand Up @@ -6,14 +6,16 @@ import customPropTypes from 'material-ui/utils/customPropTypes';
import Input from 'material-ui/Input';
import InputLabel from 'material-ui/Input/InputLabel';
import FormControl from 'material-ui/Form/FormControl';
import FormHelperText from 'material-ui/Form/FormHelperText';

const styleSheet = createStyleSheet('ComposedTextField', () => ({
container: {
display: 'flex',
flexWrap: 'wrap',
},
input: {
margin: 10,
marginLeft: 10,
marginRight: 10,
},
}));

Expand Down Expand Up @@ -41,6 +43,26 @@ export default class ComposedTextField extends Component {
onChange={(event) => this.setState({ name: event.target.value })}
/>
</FormControl>
<FormControl className={classes.input}>
<InputLabel htmlFor="name">
Name
</InputLabel>
<Input
id="name"
value="Composed TextField"
/>
<FormHelperText>Some important helper text</FormHelperText>
</FormControl>
<FormControl className={classes.input} error>
<InputLabel htmlFor="name">
Name
</InputLabel>
<Input
id="name"
value="Composed TextField"
/>
<FormHelperText>Some important helper text</FormHelperText>
</FormControl>
</div>
);
}
Expand Down
15 changes: 15 additions & 0 deletions docs/src/pages/component-demos/text-fields/TextFields.js
Expand Up @@ -56,6 +56,21 @@ export default class TextFields extends Component {
defaultValue="Hello World"
className={classes.input}
/>
<TextField
id="name"
label="Name"
className={classes.input}
value={this.state.name}
onChange={(event) => this.setState({ name: event.target.value })}
disabled
/>
<TextField
id="name"
label="Name"
className={classes.input}
value="Example value"
helperText="Some important text"
/>
</div>
);
}
Expand Down
2 changes: 1 addition & 1 deletion docs/src/pages/component-demos/text-fields/text-fields.md
@@ -1,5 +1,5 @@
---
components: Input, TextField, TextFieldLabel
components: Input, TextField, FormHelperText
---

# Text Fields
Expand Down
14 changes: 13 additions & 1 deletion src/Form/FormControl.js
@@ -1,10 +1,11 @@
// @flow weak

import React, { Component } from 'react';
import React, { Children, Component } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { createStyleSheet } from 'jss-theme-reactor';
import customPropTypes from '../utils/customPropTypes';
import { isDirty } from '../Input/Input';

export const styleSheet = createStyleSheet('MuiFormControl', () => {
return {
Expand Down Expand Up @@ -78,6 +79,17 @@ export default class FormControl extends Component {
};
}

componentWillMount() {
let dirty = false;
Children.forEach(this.props.children, (child) => {
if (child && child.type && child.type.name === 'Input' && isDirty(child.props)) {
dirty = true;
}
});

this.setState({ dirty });
}

handleFocus = () => {
if (!this.state.focused) {
this.setState({ focused: true });
Expand Down
70 changes: 70 additions & 0 deletions src/Form/FormHelperText.js
@@ -0,0 +1,70 @@
// @flow weak
/* eslint-disable jsx-a11y/label-has-for */

import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { createStyleSheet } from 'jss-theme-reactor';
import customPropTypes from '../utils/customPropTypes';

export const styleSheet = createStyleSheet('MuiFormHelperText', (theme) => {
return {
root: {
color: theme.palette.input.helperText,
fontSize: 12,
lineHeight: 1.4,
Copy link
Member

Choose a reason for hiding this comment

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

Wouldn't 1.3' round to 1.3?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

1.3 results to 15px line-height in webkit...

Copy link
Member

Choose a reason for hiding this comment

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

Gotcha.

margin: 0,
},
error: {
color: theme.palette.error.A400,
},
};
});

export default function FormHelperText(props, context) {
const {
children,
className: classNameProp,
error: errorProp,
...other
} = props;

const { muiFormControl, styleManager } = context;
const classes = styleManager.render(styleSheet);

let error = errorProp;

if (muiFormControl && typeof error === 'undefined') {
error = muiFormControl.error;
}

const className = classNames(classes.root, {
[classes.error]: error,
}, classNameProp);

return (
<p className={className} {...other}>
{children}
</p>
);
}

FormHelperText.propTypes = {
/**
* The content of the component.
*/
children: PropTypes.node,
/**
* The CSS class name of the root element.
Copy link
Member

Choose a reason for hiding this comment

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

We went with ignoring those from the documentation as quite idiomatic in the React world:

  /**
   * @ignore
   */

*/
className: PropTypes.string,
/**
* Whether the helper text should be displayed in an error state.
*/
Copy link
Member

Choose a reason for hiding this comment

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

'If true,'

error: PropTypes.bool,
};

FormHelperText.contextTypes = {
muiFormControl: PropTypes.object,
styleManager: customPropTypes.muiRequired,
};
7 changes: 4 additions & 3 deletions src/Form/FormLabel.js
Expand Up @@ -8,17 +8,18 @@ import { createStyleSheet } from 'jss-theme-reactor';
import customPropTypes from '../utils/customPropTypes';

export const styleSheet = createStyleSheet('MuiFormLabel', (theme) => {
const focusColor = theme.palette.primary.A200;
const { palette } = theme;
const focusColor = palette.type === 'light' ? palette.primary.A700 : palette.primary.A200;
return {
root: {
color: theme.palette.text.secondary,
color: palette.input.labelText,
lineHeight: 1,
},
focused: {
color: focusColor,
},
error: {
color: theme.palette.error[500],
color: palette.error.A400,
},
};
});
Expand Down
1 change: 1 addition & 0 deletions src/Form/index.js
Expand Up @@ -3,3 +3,4 @@
export FormGroup from './FormGroup';
export FormLabel from './FormLabel';
export FormControl from './FormControl';
export FormHelperText from './FormHelperText';
25 changes: 17 additions & 8 deletions src/Input/Input.js
Expand Up @@ -6,7 +6,7 @@ import classNames from 'classnames';
import { createStyleSheet } from 'jss-theme-reactor';
import customPropTypes from '../utils/customPropTypes';

function isDirty(obj) {
export function isDirty(obj) {
return obj && obj.value && obj.value.length > 0;
}

Expand All @@ -16,15 +16,16 @@ export const styleSheet = createStyleSheet('MuiInput', (theme) => {
wrapper: {
// Mimics the default input display property used by browsers for an input.
display: 'inline-block',
marginBottom: 8,
marginTop: 8,
Copy link
Member

Choose a reason for hiding this comment

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

Hum, why changing that? The less our component impact the layout, the better.

position: 'relative',
},
formControl: {
marginTop: 10,
marginBottom: 10,
marginTop: 32,
Copy link
Member

Choose a reason for hiding this comment

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

Oh, why changing that?

},
inkbar: {
'&:after': {
backgroundColor: palette.primary.A200,
backgroundColor: palette.type === 'light' ? palette.primary.A700 : palette.primary.A200,
left: 0,
bottom: -1,
// Doing the other way around crash on IE11 "''" https://github.com/cssinjs/jss/issues/242
Expand All @@ -45,7 +46,7 @@ export const styleSheet = createStyleSheet('MuiInput', (theme) => {
focused: {},
error: {
'&:after': {
backgroundColor: palette.error[500],
backgroundColor: palette.error.A400,
transform: 'scaleX(1)', // error is always underlined in red
},
},
Expand All @@ -59,7 +60,7 @@ export const styleSheet = createStyleSheet('MuiInput', (theme) => {
background: 'none',
lineHeight: 1,
appearance: 'textfield', // Improve type search style.
color: theme.palette.text.primary,
color: theme.palette.input.inputText,
width: '100%',
'&:focus': {
outline: 0,
Expand All @@ -69,11 +70,19 @@ export const styleSheet = createStyleSheet('MuiInput', (theme) => {
},
},
disabled: {
color: theme.palette.text.disabled,
color: theme.palette.input.disabled,
cursor: 'not-allowed',
},
underline: {
borderBottom: `1px solid ${theme.palette.text.divider}`,
borderBottom: `1px solid ${theme.palette.input.bottomLine}`,
'&:hover:not($disabled)': {
borderBottom: `2px solid ${theme.palette.text.primary}`,
marginBottom: -1,
transition: transitions.create('border-color', {
duration: transitions.duration.shorter,
easing: transitions.easing.ease,
}),
},
'&$disabled': {
Copy link
Member

Choose a reason for hiding this comment

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

I think that our convention is the following '& $disabled': {

borderBottomStyle: 'dotted',
Copy link
Member

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 that style.

},
Expand Down
18 changes: 15 additions & 3 deletions src/Input/InputLabel.js
Expand Up @@ -12,28 +12,34 @@ export const styleSheet = createStyleSheet('MuiInputLabel', (theme) => {
return {
root: {
transformOrigin: 'top left',
fontSmoothing: 'antialiased',
Copy link
Member

Choose a reason for hiding this comment

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

Ohh, that's a tough topic! I think that it far out of the scope of this PR.

  1. Is antialiasing better than a sub-pixel smoothing? (I think it's)
  2. Do we want to apply it on all the components/the whole page? (I don't think that whole page is a good call for isolation)
  3. Who do we apply it to all the components? (I guess that we could create a theme object spread to all the root element of our component)

},
formControl: {
position: 'absolute',
left: 0,
top: 0,
transform: 'translate(0, 18px) scale(1)',
transform: 'translate(0, 40px)',
},
shrink: {
transform: 'translate(0, 0px) scale(0.75)',
fontSize: 12,
transform: 'translate(0, 18px)',
transformOrigin: 'top left',
},
animated: {
transition: transitions.create('transform', {
transition: transitions.create(['transform', 'font-size'], {
Copy link
Member

Choose a reason for hiding this comment

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

Hum, I see two advantages of animating the scale:

  1. Better performance
  2. Simpler font size override

duration: transitions.duration.shorter,
easing: transitions.easing.easeOut,
}),
},
disabled: {
color: theme.palette.input.disabled,
},
};
});

export default function InputLabel(props, context) {
const {
disabled,
disableAnimation,
children,
className: classNameProp,
Expand All @@ -54,6 +60,7 @@ export default function InputLabel(props, context) {
[classes.formControl]: muiFormControl,
[classes.animated]: !disableAnimation,
[classes.shrink]: shrink,
[classes.disabled]: disabled,
}, classNameProp);

return (
Expand All @@ -76,6 +83,10 @@ InputLabel.propTypes = {
* If `true`, the transition animation is disabled.
*/
disableAnimation: PropTypes.bool,
/**
* If `true`, apply disabled class.
Copy link
Member

Choose a reason for hiding this comment

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

'If true, apply the disabled CSS class'.

Hmmm, now I wonder if all the others should follow that pattern. It's clearer to the user what the outcome of applying this prop is when it comes to custom styling.

*/
disabled: PropTypes.bool,
/**
* If `true`, the label will be displayed in an error state.
*/
Expand All @@ -95,6 +106,7 @@ InputLabel.propTypes = {
};

InputLabel.defaultProps = {
disabled: false,
disableAnimation: false,
};

Expand Down