Skip to content

Commit

Permalink
[Checkbox, Radio, Switch] Fix id in internal input (#10196)
Browse files Browse the repository at this point in the history
* added id on internal input when its a radio or checkbox

* tests to prevent regression

* add id on wrapper when input isn't a checkbox/radio/switch

* [SwitchBase] Rename inputType to type

* document the id
  • Loading branch information
phsantiago authored and oliviertassinari committed Feb 10, 2018
1 parent 7ba71b8 commit 43e03d6
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 24 deletions.
3 changes: 2 additions & 1 deletion pages/api/checkbox.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ filename: /src/Checkbox/Checkbox.js
| disabled | bool | | If `true`, the switch will be disabled. |
| disableRipple | bool | | If `true`, the ripple effect will be disabled. |
| icon | node | | The icon to display when the component is unchecked. |
| id | string | | The id of the `input` element. |
| indeterminate | bool | false | If `true`, the component appears indeterminate. |
| indeterminateIcon | node | <IndeterminateCheckBoxIcon /> | The icon to display when the component is indeterminate. |
| inputProps | object | | Properties applied to the `input` element. |
| inputRef | func | | Use that property to pass a ref callback to the native input component. |
| inputType | string | | The input component property `type`. |
| name | string | | |
| onChange | 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<br>*checked:* The `checked` value of the switch |
| type | string | | The input component property `type`. |
| value | string | | The value of the component. |

Any other properties supplied will be [spread to the root element](/guides/api#spread).
Expand Down
3 changes: 2 additions & 1 deletion pages/api/radio.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ filename: /src/Radio/Radio.js
| disabled | bool | | If `true`, the switch will be disabled. |
| disableRipple | bool | | If `true`, the ripple effect will be disabled. |
| icon | node | | The icon to display when the component is unchecked. |
| id | string | | The id of the `input` element. |
| inputProps | object | | Properties applied to the `input` element. |
| inputRef | func | | Use that property to pass a ref callback to the native input component. |
| inputType | string | | The input component property `type`. |
| name | string | | |
| onChange | 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<br>*checked:* The `checked` value of the switch |
| type | string | | The input component property `type`. |
| value | string | | The value of the component. |

Any other properties supplied will be [spread to the root element](/guides/api#spread).
Expand Down
3 changes: 2 additions & 1 deletion pages/api/switch.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ filename: /src/Switch/Switch.js
| disabled | bool | | If `true`, the switch will be disabled. |
| disableRipple | bool | | If `true`, the ripple effect will be disabled. |
| icon | node | | The icon to display when the component is unchecked. |
| id | string | | The id of the `input` element. |
| inputProps | object | | Properties applied to the `input` element. |
| inputRef | func | | Use that property to pass a ref callback to the native input component. |
| inputType | string | | The input component property `type`. |
| name | string | | |
| onChange | 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<br>*checked:* The `checked` value of the switch |
| type | string | | The input component property `type`. |
| value | string | | The value of the component. |

Any other properties supplied will be [spread to the root element](/guides/api#spread).
Expand Down
12 changes: 8 additions & 4 deletions src/Checkbox/Checkbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ Checkbox.propTypes = {
* The icon to display when the component is unchecked.
*/
icon: PropTypes.node,
/**
* The id of the `input` element.
*/
id: PropTypes.string,
/**
* If `true`, the component appears indeterminate.
*/
Expand All @@ -77,10 +81,6 @@ Checkbox.propTypes = {
* Use that property to pass a ref callback to the native input component.
*/
inputRef: PropTypes.func,
/**
* The input component property `type`.
*/
inputType: PropTypes.string,
/*
* @ignore
*/
Expand All @@ -96,6 +96,10 @@ Checkbox.propTypes = {
* @ignore
*/
tabIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
/**
* The input component property `type`.
*/
type: PropTypes.string,
/**
* The value of the component.
*/
Expand Down
14 changes: 9 additions & 5 deletions src/Radio/Radio.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const styles = theme => ({
function Radio(props) {
return (
<SwitchBase
inputType="radio"
type="radio"
icon={<RadioButtonUncheckedIcon />}
checkedIcon={<RadioButtonCheckedIcon />}
{...props}
Expand Down Expand Up @@ -61,6 +61,10 @@ Radio.propTypes = {
* The icon to display when the component is unchecked.
*/
icon: PropTypes.node,
/**
* The id of the `input` element.
*/
id: PropTypes.string,
/**
* Properties applied to the `input` element.
*/
Expand All @@ -69,10 +73,6 @@ Radio.propTypes = {
* Use that property to pass a ref callback to the native input component.
*/
inputRef: PropTypes.func,
/**
* The input component property `type`.
*/
inputType: PropTypes.string,
/*
* @ignore
*/
Expand All @@ -88,6 +88,10 @@ Radio.propTypes = {
* @ignore
*/
tabIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
/**
* The input component property `type`.
*/
type: PropTypes.string,
/**
* The value of the component.
*/
Expand Down
12 changes: 8 additions & 4 deletions src/Switch/Switch.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ Switch.propTypes = {
* The icon to display when the component is unchecked.
*/
icon: PropTypes.node,
/**
* The id of the `input` element.
*/
id: PropTypes.string,
/**
* Properties applied to the `input` element.
*/
Expand All @@ -132,10 +136,6 @@ Switch.propTypes = {
* Use that property to pass a ref callback to the native input component.
*/
inputRef: PropTypes.func,
/**
* The input component property `type`.
*/
inputType: PropTypes.string,
/*
* @ignore
*/
Expand All @@ -151,6 +151,10 @@ Switch.propTypes = {
* @ignore
*/
tabIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
/**
* The input component property `type`.
*/
type: PropTypes.string,
/**
* The value of the component.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/internal/SwitchBase.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export type SwitchBase = React.Component<SwitchBaseProps>;
export interface CreateSwitchBaseOptions {
defaultIcon?: React.ReactNode;
defaultCheckedIcon?: React.ReactNode;
inputType?: string;
type?: string;
}

export default function createSwitch(options: CreateSwitchBaseOptions): SwitchBase;
22 changes: 15 additions & 7 deletions src/internal/SwitchBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,13 @@ class SwitchBase extends React.Component {
className: classNameProp,
disabled: disabledProp,
icon: iconProp,
id,
inputProps,
inputRef,
inputType,
name,
onChange,
tabIndex,
type,
value,
...other
} = this.props;
Expand All @@ -97,6 +98,8 @@ class SwitchBase extends React.Component {

const icon = checked ? checkedIcon : iconProp;

const hasLabelFor = type === 'checkbox' || type === 'radio';

return (
<IconButton
data-mui-test="SwitchBase"
Expand All @@ -109,7 +112,8 @@ class SwitchBase extends React.Component {
>
{icon}
<input
type={inputType}
id={hasLabelFor && id}
type={type}
name={name}
checked={checkedProp}
onChange={this.handleInputChange}
Expand Down Expand Up @@ -160,6 +164,10 @@ SwitchBase.propTypes = {
* The icon to display when the component is unchecked.
*/
icon: PropTypes.node,
/**
* The id of the `input` element.
*/
id: PropTypes.string,
/**
* If `true`, the component appears indeterminate.
*/
Expand All @@ -176,10 +184,6 @@ SwitchBase.propTypes = {
* Use that property to pass a ref callback to the native input component.
*/
inputRef: PropTypes.func,
/**
* The input component property `type`.
*/
inputType: PropTypes.string,
/*
* @ignore
*/
Expand All @@ -195,6 +199,10 @@ SwitchBase.propTypes = {
* @ignore
*/
tabIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
/**
* The input component property `type`.
*/
type: PropTypes.string,
/**
* The value of the component.
*/
Expand All @@ -205,7 +213,7 @@ SwitchBase.defaultProps = {
checkedIcon: <CheckBoxIcon />,
disableRipple: false,
icon: <CheckBoxOutlineBlankIcon />,
inputType: 'checkbox',
type: 'checkbox',
};

SwitchBase.contextTypes = {
Expand Down
12 changes: 12 additions & 0 deletions src/internal/SwitchBase.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,18 @@ describe('<SwitchBase />', () => {
assert.strictEqual(wrapper2.find('input').props()['aria-label'], 'foo');
});
});

describe('prop: id', () => {
it('should be able to add id to a checkbox input', () => {
const wrapper2 = shallow(<SwitchBase type="checkbox" id="foo" />);
assert.strictEqual(wrapper2.find('input').props().id, 'foo');
});

it('should be able to add id to a radio input', () => {
const wrapper2 = shallow(<SwitchBase type="radio" id="foo" />);
assert.strictEqual(wrapper2.find('input').props().id, 'foo');
});
});
});

describe('with muiFormControl context', () => {
Expand Down

0 comments on commit 43e03d6

Please sign in to comment.