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 25 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
@@ -1,30 +1,26 @@
# TextFieldLabel
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. |
| classes | object | | Useful to extend the style applied to components. |
| disableAnimation | bool | false | If `true`, the transition animation is disabled. |
| error | bool | | If `true`, the label is displayed in an error state. |
| focused | bool | | If `true`, the input of this label is focused. |
| required | bool | | If `true`, the label will indicate that the input is required. |
| shrink | bool | false | If `true`, the label is shrunk. |
| 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.
## Classes

You can overrides all the class names injected by Material-UI thanks to the `classes` property.
This property accepts the following keys:
- `root`
- `shrink`
- `animated`
- `error`

Have a look at [overriding with class names](/customization/overrides#overriding-with-class-names)
section for more detail.

If using the `overrides` key of the theme as documented
[here](/customization/themes#customizing-all-instances-of-a-component-type),
you need to use the following style sheet name: `MuiTextFieldLabel`.
you need to use the following style sheet name: `MuiFormHelperText`.
15 changes: 15 additions & 0 deletions docs/src/pages/component-demos/text-fields/ComposedTextField.js
Expand Up @@ -6,6 +6,7 @@ import { withStyles, createStyleSheet } from 'material-ui/styles';
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', theme => ({
container: {
Expand Down Expand Up @@ -37,6 +38,20 @@ class ComposedTextField extends Component {
</InputLabel>
<Input id="name" value={this.state.name} onChange={this.handleChange} />
</FormControl>
<FormControl className={classes.input}>
<InputLabel htmlFor="name">
Name
</InputLabel>
<Input id="name" value={this.state.name} onChange={this.handleChange} />
<FormHelperText>Some important helper text</FormHelperText>
</FormControl>
<FormControl className={classes.input} error>
<InputLabel htmlFor="name">
Name
</InputLabel>
<Input id="name" value={this.state.name} onChange={this.handleChange} />
<FormHelperText>Some important helper text</FormHelperText>
</FormControl>
</div>
);
}
Expand Down
8 changes: 8 additions & 0 deletions docs/src/pages/component-demos/text-fields/TextFields.js
Expand Up @@ -77,6 +77,14 @@ class TextFields extends Component {
defaultValue="2017-05-24"
className={classes.input}
/>
<TextField
id="helperText"
label="Helper text"
type="text"
defaultValue="Default Value"
className={classes.input}
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
16 changes: 15 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 withStyles from '../styles/withStyles';
import { isDirty } from '../Input/Input';

export const styleSheet = createStyleSheet('MuiFormControl', {
root: {
Expand Down Expand Up @@ -49,6 +50,19 @@ class FormControl extends Component {
};
}

componentWillMount() {
Children.forEach(this.props.children, child => {
if (
child &&
child.type &&
(child.type.name === 'Input' || (child.type.Naked && child.type.Naked.name === 'Input')) &&
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure we want to rely on Naked here. What about using muiName instead? You can find other examples on the code base.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@oliviertassinari Thought muiName was removed fro purpose)

isDirty(child.props)
) {
this.setState({ dirty: true });
}
});
}

handleFocus = () => {
if (this.props.onFocus) {
this.props.onFocus();
Expand Down
13 changes: 13 additions & 0 deletions src/Form/FormControl.spec.js
Expand Up @@ -4,6 +4,7 @@ import React from 'react';
import { spy } from 'sinon';
import { assert } from 'chai';
import { createShallow } from '../test-utils';
import Input from '../Input';
import FormControl, { styleSheet } from './FormControl';

describe('<FormControl />', () => {
Expand Down Expand Up @@ -47,6 +48,18 @@ describe('<FormControl />', () => {
});
});

describe('should be dirty if has input with value set', () => {
let wrapper;

beforeEach(() => {
wrapper = shallow(<FormControl><Input value="bar" /></FormControl>);
});

it('should be dirty initially', () => {
assert.strictEqual(wrapper.state().dirty, true);
});
});

describe('muiFormControl child context', () => {
let wrapper;
let muiFormControlContext;
Expand Down
69 changes: 69 additions & 0 deletions src/Form/FormHelperText.js
@@ -0,0 +1,69 @@
// @flow weak

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

export const styleSheet = createStyleSheet('MuiFormHelperText', theme => ({
root: {
color: theme.palette.input.helperText,
fontSize: 12,
lineHeight: 1.4,
margin: 0,
},
error: {
color: theme.palette.error.A400,
},
}));

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

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,
/**
* Useful to extend the style applied to components.
*/
classes: PropTypes.object.isRequired,
/**
* 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,
};

export default withStyles(styleSheet)(FormHelperText);
63 changes: 63 additions & 0 deletions src/Form/FormHelperText.spec.js
@@ -0,0 +1,63 @@
// @flow

import React from 'react';
import { assert } from 'chai';
import { createShallow } from '../test-utils';
import FormHelperText, { styleSheet } from './FormHelperText';

describe('<FormHelperText />', () => {
let shallow;
let classes;

before(() => {
shallow = createShallow({ dive: true });
classes = shallow.context.styleManager.render(styleSheet);
});

it('should render a <p />', () => {
const wrapper = shallow(<FormHelperText className="woof" />);
assert.strictEqual(wrapper.name(), 'p');
assert.strictEqual(wrapper.hasClass(classes.root), true, 'should have the root class');
assert.strictEqual(wrapper.hasClass('woof'), true, 'should have the user class');
});

describe('prop: error', () => {
it('should show an error class', () => {
Copy link
Member

Choose a reason for hiding this comment

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

'should have an error class' / 'should set the error class'?

const wrapper = shallow(<FormHelperText error />);
assert.strictEqual(wrapper.hasClass(classes.error), true);
});
});

describe('with muiFormControl context', () => {
let wrapper;
let muiFormControl;

function setFormControlContext(muiFormControlContext) {
muiFormControl = muiFormControlContext;
wrapper.setContext({ ...wrapper.context(), muiFormControl });
}

beforeEach(() => {
wrapper = shallow(<FormHelperText>Foo</FormHelperText>);
});
['error'].forEach(visualState => {
describe(visualState, () => {
beforeEach(() => {
setFormControlContext({ [visualState]: true });
});

it(`should have the ${visualState} class`, () => {
assert.strictEqual(wrapper.hasClass(classes[visualState]), true);
});

it('should be overridden by props', () => {
assert.strictEqual(wrapper.hasClass(classes[visualState]), true);
wrapper.setProps({ [visualState]: false });
assert.strictEqual(wrapper.hasClass(classes[visualState]), false);
wrapper.setProps({ [visualState]: true });
assert.strictEqual(wrapper.hasClass(classes[visualState]), true);
});
});
});
});
});
6 changes: 3 additions & 3 deletions src/Form/FormLabel.js
Expand Up @@ -8,18 +8,18 @@ import { createStyleSheet } from 'jss-theme-reactor';
import withStyles from '../styles/withStyles';

export const styleSheet = createStyleSheet('MuiFormLabel', theme => {
const focusColor = theme.palette.primary[500];
const focusColor = theme.palette.primary[theme.palette.type === 'light' ? 'A700' : 'A200'];
Copy link
Member

Choose a reason for hiding this comment

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

A colors are supposed to used only with the .accent color. Use 700 and 200 instead with the primary color.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

According to the latest specs it should be accent color.
I guess they made that decision to avoid merger with other elements.

Copy link
Member

Choose a reason for hiding this comment

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

Where do you see that? I have found the following:

To signal that the field is active, the primary color of the UI is applied to the input line, label text, and cursor.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Focus section, same with error section
image

Copy link
Member

Choose a reason for hiding this comment

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

Oh, sounds good then 👍

return {
root: {
fontFamily: theme.typography.fontFamily,
color: theme.palette.text.secondary,
color: theme.palette.input.labelText,
lineHeight: 1,
},
focused: {
color: focusColor,
},
error: {
color: theme.palette.error[500],
color: theme.palette.error.A400,
Copy link
Member

Choose a reason for hiding this comment

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

Same comment regarding A.

},
};
});
Expand Down
1 change: 1 addition & 0 deletions src/Form/index.js
Expand Up @@ -3,3 +3,4 @@
export { default as FormGroup } from './FormGroup';
export { default as FormLabel } from './FormLabel';
export { default as FormControl } from './FormControl';
export { default as FormHelperText } from './FormHelperText';
29 changes: 21 additions & 8 deletions src/Input/Input.js
Expand Up @@ -7,7 +7,7 @@ import { createStyleSheet } from 'jss-theme-reactor';
import withStyles from '../styles/withStyles';
import Textarea from './Textarea';

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

Expand All @@ -19,12 +19,15 @@ export const styleSheet = createStyleSheet('MuiInput', theme => ({
fontFamily: theme.typography.fontFamily,
},
formControl: {
marginTop: 10,
marginBottom: 10,
marginTop: 8,
marginBottom: 8,
'label + &': {
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?

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 theme.spacing.unit * 4

},
},
inkbar: {
'&:after': {
backgroundColor: theme.palette.primary[500],
backgroundColor: theme.palette.primary[theme.palette.type === 'light' ? 'A700' : 'A200'],
left: 0,
bottom: -2,
// Doing the other way around crash on IE11 "''" https://github.com/cssinjs/jss/issues/242
Expand All @@ -45,21 +48,21 @@ export const styleSheet = createStyleSheet('MuiInput', theme => ({
focused: {},
error: {
'&:after': {
backgroundColor: theme.palette.error[500],
backgroundColor: theme.palette.error.A400,
transform: 'scaleX(1)', // error is always underlined in red
},
},
input: {
font: 'inherit',
padding: '6px 0',
padding: '8px 0',
Copy link
Member

Choose a reason for hiding this comment

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

😄 . you can use theme.spacing.unit over 8.

border: 0,
display: 'block',
boxSizing: 'content-box',
verticalAlign: 'middle',
whiteSpace: 'normal',
background: 'none',
margin: 0, // Reset for Safari
color: theme.palette.text.primary,
color: theme.palette.input.inputText,
width: '100%',
'&:focus': {
outline: 0,
Expand All @@ -84,9 +87,19 @@ export const styleSheet = createStyleSheet('MuiInput', theme => ({
color: theme.palette.text.disabled,
},
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: 7,
transition: theme.transitions.create('border-color', {
duration: theme.transitions.duration.shorter,
easing: theme.transitions.easing.ease,
}),
},
'&$disabled': {
borderBottomStyle: 'dotted',
borderImage: `linear-gradient(to right, ${theme.palette.input.bottomLine} 33%, transparent 0%)
100 0 / 0 0 1px / 0 0 0 3px repeat`,
},
},
}));
Expand Down