Skip to content

Commit

Permalink
[FormControlLabel] Add labelPlacement prop (#12303)
Browse files Browse the repository at this point in the history
  • Loading branch information
mbrookes authored Jul 27, 2018
1 parent f432f8a commit da32979
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 45 deletions.
117 changes: 79 additions & 38 deletions docs/src/pages/demos/selection-controls/CheckboxesGroup.js
Original file line number Diff line number Diff line change
@@ -1,62 +1,103 @@
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import FormLabel from '@material-ui/core/FormLabel';
import FormControl from '@material-ui/core/FormControl';
import FormGroup from '@material-ui/core/FormGroup';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import FormHelperText from '@material-ui/core/FormHelperText';
import Checkbox from '@material-ui/core/Checkbox';

const styles = theme => ({
root: {
display: 'flex',
},
formControl: {
margin: theme.spacing.unit * 3,
},
});

class CheckboxesGroup extends React.Component {
state = {
gilad: true,
jason: false,
antoine: true,
antoine: false,
};

handleChange = name => event => {
this.setState({ [name]: event.target.checked });
};

render() {
const { classes } = this.props;
const { gilad, jason, antoine } = this.state;
const error = Object.values(this.state).filter(v => v).length !== 2;

return (
<FormControl component="fieldset">
<FormLabel component="legend">Assign responsibility</FormLabel>
<FormGroup>
<FormControlLabel
control={
<Checkbox
checked={this.state.gilad}
onChange={this.handleChange('gilad')}
value="gilad"
/>
}
label="Gilad Gray"
/>
<FormControlLabel
control={
<Checkbox
checked={this.state.jason}
onChange={this.handleChange('jason')}
value="jason"
/>
}
label="Jason Killian"
/>
<FormControlLabel
control={
<Checkbox
checked={this.state.antoine}
onChange={this.handleChange('antoine')}
value="antoine"
/>
}
label="Antoine Llorca"
/>
</FormGroup>
<FormHelperText>Be careful</FormHelperText>
</FormControl>
<div className={classes.root}>
<FormControl component="fieldset" className={classes.formControl}>
<FormLabel component="legend">Assign responsibility</FormLabel>
<FormGroup>
<FormControlLabel
control={
<Checkbox checked={gilad} onChange={this.handleChange('gilad')} value="gilad" />
}
label="Gilad Gray"
/>
<FormControlLabel
control={
<Checkbox checked={jason} onChange={this.handleChange('jason')} value="jason" />
}
label="Jason Killian"
/>
<FormControlLabel
control={
<Checkbox
checked={antoine}
onChange={this.handleChange('antoine')}
value="antoine"
/>
}
label="Antoine Llorca"
/>
</FormGroup>
<FormHelperText>Be careful</FormHelperText>
</FormControl>
<FormControl required error={error} component="fieldset" className={classes.formControl}>
<FormLabel component="legend">Pick two</FormLabel>
<FormGroup>
<FormControlLabel
control={
<Checkbox checked={gilad} onChange={this.handleChange('gilad')} value="gilad" />
}
label="Gilad Gray"
/>
<FormControlLabel
control={
<Checkbox checked={jason} onChange={this.handleChange('jason')} value="jason" />
}
label="Jason Killian"
/>
<FormControlLabel
control={
<Checkbox
checked={antoine}
onChange={this.handleChange('antoine')}
value="antoine"
/>
}
label="Antoine Llorca"
/>
</FormGroup>
<FormHelperText>You can display an error</FormHelperText>
</FormControl>
</div>
);
}
}

export default CheckboxesGroup;
CheckboxesGroup.propTypes = {
classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(CheckboxesGroup);
28 changes: 22 additions & 6 deletions docs/src/pages/demos/selection-controls/RadioButtonsGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class RadioButtonsGroup extends React.Component {

return (
<div className={classes.root}>
<FormControl component="fieldset" required className={classes.formControl}>
<FormControl component="fieldset" className={classes.formControl}>
<FormLabel component="legend">Gender</FormLabel>
<RadioGroup
aria-label="Gender"
Expand All @@ -54,7 +54,7 @@ class RadioButtonsGroup extends React.Component {
/>
</RadioGroup>
</FormControl>
<FormControl component="fieldset" required error className={classes.formControl}>
<FormControl component="fieldset" className={classes.formControl}>
<FormLabel component="legend">Gender</FormLabel>
<RadioGroup
aria-label="gender"
Expand All @@ -63,17 +63,33 @@ class RadioButtonsGroup extends React.Component {
value={this.state.value}
onChange={this.handleChange}
>
<FormControlLabel value="female" control={<Radio color="primary" />} label="Female" />
<FormControlLabel value="male" control={<Radio color="primary" />} label="Male" />
<FormControlLabel value="other" control={<Radio color="primary" />} label="Other" />
<FormControlLabel
value="female"
control={<Radio color="primary" />}
label="Female"
labelPlacement="start"
/>
<FormControlLabel
value="male"
control={<Radio color="primary" />}
label="Male"
labelPlacement="start"
/>
<FormControlLabel
value="other"
control={<Radio color="primary" />}
label="Other"
labelPlacement="start"
/>
<FormControlLabel
value="disabled"
disabled
control={<Radio />}
label="(Disabled option)"
labelPlacement="start"
/>
</RadioGroup>
<FormHelperText>You can display an error</FormHelperText>
<FormHelperText>labelPlacement start</FormHelperText>
</FormControl>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ export interface FormControlLabelProps
label: React.ReactNode;
name?: string;
onChange?: (event: React.ChangeEvent<{}>, checked: boolean) => void;
labelPlacement?: 'end' | 'start';
value?: string;
}

export type FormControlLabelClassKey = 'root' | 'disabled' | 'label';
export type FormControlLabelClassKey = 'root' | 'start' | 'disabled' | 'label';

declare const FormControlLabel: React.ComponentType<FormControlLabelProps>;

Expand Down
14 changes: 14 additions & 0 deletions packages/material-ui/src/FormControlLabel/FormControlLabel.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ export const styles = theme => ({
cursor: 'default',
},
},
/* Styles applied to the root element if `position="start"`. */
start: {
flexDirection: 'row-reverse',
},
/* Styles applied to the root element if `disabled={true}`. */
disabled: {},
/* Styles applied to the label's Typography component. */
Expand All @@ -45,6 +49,7 @@ function FormControlLabel(props, context) {
disabled: disabledProp,
inputRef,
label,
labelPlacement,
name,
onChange,
value,
Expand Down Expand Up @@ -74,6 +79,7 @@ function FormControlLabel(props, context) {
className={classNames(
classes.root,
{
[classes.start]: labelPlacement === 'start',
[classes.disabled]: disabled,
},
classNameProp,
Expand Down Expand Up @@ -121,6 +127,10 @@ FormControlLabel.propTypes = {
* The text to be used in an enclosing label element.
*/
label: PropTypes.node,
/**
* The position of the label.
*/
labelPlacement: PropTypes.oneOf(['end', 'start']),
/*
* @ignore
*/
Expand All @@ -139,6 +149,10 @@ FormControlLabel.propTypes = {
value: PropTypes.string,
};

FormControlLabel.defaultProps = {
labelPlacement: 'end',
};

FormControlLabel.contextTypes = {
muiFormControl: PropTypes.object,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ describe('<FormControlLabel />', () => {
});
});

describe('prop: labelPlacement', () => {
it('should disable have the `start` class', () => {
const wrapper = shallow(
<FormControlLabel label="Pizza" labelPlacement="start" control={<div />} />,
);
assert.strictEqual(wrapper.hasClass(classes.start), true);
});
});

it('should mount without issue', () => {
const wrapper = mount(<FormControlLabel label="Pizza" control={<Checkbox />} />);
assert.strictEqual(wrapper.type(), FormControlLabel);
Expand Down
2 changes: 2 additions & 0 deletions pages/api/form-control-label.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Use this component if you want to display an extra label.
| <span class="prop-name">disabled</span> | <span class="prop-type">bool |   | If `true`, the control will be disabled. |
| <span class="prop-name">inputRef</span> | <span class="prop-type">union:&nbsp;func&nbsp;&#124;<br>&nbsp;object<br> |   | Use that property to pass a ref callback to the native input component. |
| <span class="prop-name">label</span> | <span class="prop-type">node |   | The text to be used in an enclosing label element. |
| <span class="prop-name">labelPlacement</span> | <span class="prop-type">enum:&nbsp;'end'&nbsp;&#124;<br>&nbsp;'start'<br> | <span class="prop-default">'end'</span> | The position of the label. |
| <span class="prop-name">name</span> | <span class="prop-type">string |   | |
| <span class="prop-name">onChange</span> | <span class="prop-type">func |   | Callback fired when the state is changed.<br><br>**Signature:**<br>`function(event: object, checked: boolean) => void`<br>*event:* The event source of the callback. You can pull out the new value by accessing `event.target.checked`.<br>*checked:* The `checked` value of the switch |
| <span class="prop-name">value</span> | <span class="prop-type">string |   | The value of the component. |
Expand All @@ -37,6 +38,7 @@ This property accepts the following keys:
| Name | Description |
|:-----|:------------|
| <span class="prop-name">root</span> | Styles applied to the root element.
| <span class="prop-name">start</span> | Styles applied to the root element if `position="start"`.
| <span class="prop-name">disabled</span> | Styles applied to the root element if `disabled={true}`.
| <span class="prop-name">label</span> | Styles applied to the label's Typography component.

Expand Down

0 comments on commit da32979

Please sign in to comment.