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

[Radio][Checkbox] Revert breaking changes #15483

Merged
merged 3 commits into from
Apr 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions docs/src/pages/demos/checkboxes/CheckboxLabels.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ import FavoriteBorder from '@material-ui/icons/FavoriteBorder';

const GreenCheckbox = withStyles({
root: {
'&:not($checked)': {
color: green[400],
},
color: green[400],
'&$checked': {
color: green[600],
},
Expand Down
4 changes: 1 addition & 3 deletions docs/src/pages/demos/checkboxes/CheckboxLabels.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ import FavoriteBorder from '@material-ui/icons/FavoriteBorder';

const GreenCheckbox = withStyles({
root: {
'&:not($checked)': {
color: green[400],
},
color: green[400],
'&$checked': {
color: green[600],
},
Expand Down
2 changes: 1 addition & 1 deletion docs/src/pages/demos/checkboxes/checkboxes.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ components: Checkbox, FormControl, FormGroup, FormLabel, FormControlLabel

<p class="description">Checkboxes allow the user to select one or more items from a set.</p>

Checkboxes can be used to turn an option on or off.
[Checkboxes](https://material.io/design/components/selection-controls.html#checkboxes) can be used to turn an option on or off.

If you have multiple options appearing in a list,
you can preserve space by using checkboxes instead of on/off switches.
Expand Down
4 changes: 1 addition & 3 deletions docs/src/pages/demos/radio-buttons/RadioButtons.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import RadioButtonCheckedIcon from '@material-ui/icons/RadioButtonChecked';

const GreenRadio = withStyles({
root: {
'&:not($checked)': {
color: green[400],
},
color: green[400],
'&$checked': {
color: green[600],
},
Expand Down
4 changes: 1 addition & 3 deletions docs/src/pages/demos/radio-buttons/RadioButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import RadioButtonCheckedIcon from '@material-ui/icons/RadioButtonChecked';

const GreenRadio = withStyles({
root: {
'&:not($checked)': {
color: green[400],
},
color: green[400],
'&$checked': {
color: green[600],
},
Expand Down
2 changes: 1 addition & 1 deletion docs/src/pages/demos/radio-buttons/radio-buttons.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ components: Radio, RadioGroup, FormControl, FormLabel, FormControlLabel

<p class="description">Radio buttons allow the user to select one option from a set.</p>

Use radio buttons when the user needs to see all available options.
Use [radio buttons](https://material.io/design/components/selection-controls.html#radio-buttons) when the user needs to see all available options.
If available options can be collapsed, consider using a dropdown menu because it uses less space.

Radio buttons should have the most commonly used option selected by default.
Expand Down
4 changes: 2 additions & 2 deletions docs/src/pages/demos/switches/switches.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ components: Switch, FormControl, FormGroup, FormLabel, FormControlLabel

<p class="description">Switches toggle the state of a single setting on or off.</p>

They are the preferred way to adjust settings on mobile.

[Switches](https://material.io/design/components/selection-controls.html#switches) are the preferred way to adjust settings on mobile.
The option that the switch controls, as well as the state it’s in,
should be made clear from the corresponding inline label.

{{"demo": "pages/demos/switches/Switches.js"}}

## Switches with FormControlLabel

`Switch` can also be used with a label description thanks to the `FormControlLabel` component.

{{"demo": "pages/demos/switches/SwitchLabels.js"}}
Expand Down
6 changes: 2 additions & 4 deletions docs/src/pages/guides/migration-v3/migration-v3.md
Original file line number Diff line number Diff line change
Expand Up @@ -272,11 +272,9 @@ You should be able to move the custom styles to the root class key.

- [ExpansionPanelActions] Rename the `action` CSS class `spacing`.

### Selection controls
### Switch

- [Switch][Radio][Checkbox] Improve specification compliance.

Refactore the implementation to make it easier to override the styles.
- [Switch] Refactor the implementation to make it easier to override the styles.
Rename the class names to match the specification wording:

```diff
Expand Down
6 changes: 5 additions & 1 deletion packages/material-ui/src/Checkbox/Checkbox.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ export interface CheckboxProps
indeterminateIcon?: React.ReactNode;
}

export type CheckboxClassKey = SwitchBaseClassKey | 'indeterminate';
export type CheckboxClassKey =
| SwitchBaseClassKey
| 'indeterminate'
| 'colorPrimary'
| 'colorSecondary';

declare const Checkbox: React.ComponentType<CheckboxProps>;

Expand Down
60 changes: 40 additions & 20 deletions packages/material-ui/src/Checkbox/Checkbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,64 @@
import React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { fade } from '../styles/colorManipulator';
import SwitchBase from '../internal/SwitchBase';
import CheckBoxOutlineBlankIcon from '../internal/svg-icons/CheckBoxOutlineBlank';
import CheckBoxIcon from '../internal/svg-icons/CheckBox';
import { fade } from '../styles/colorManipulator';
import IndeterminateCheckBoxIcon from '../internal/svg-icons/IndeterminateCheckBox';
import { capitalize } from '../utils/helpers';
import withStyles from '../styles/withStyles';

export const styles = theme => ({
/* Styles applied to the root element. */
root: {
'&:not($checked)': {
color: theme.palette.text.secondary,
'&:hover': {
backgroundColor: fade(theme.palette.action.active, theme.palette.action.hoverOpacity),
},
},
color: theme.palette.text.secondary,
},
/* Styles applied to the root element if `checked={true}`. */
checked: {},
/* Styles applied to the root element if `disabled={true}`. */
disabled: {},
/* Styles applied to the root element if `indeterminate={true}`. */
indeterminate: {},
/* Styles applied to the root element if `color="primary"`. */
colorPrimary: {
'&$checked': {
color: theme.palette.primary.main,
'&:hover': {
backgroundColor: fade(theme.palette.primary.main, theme.palette.action.hoverOpacity),
// Reset on touch devices, it doesn't add specificity
'@media (hover: none)': {
backgroundColor: 'transparent',
},
},
},
'&$disabled': {
color: theme.palette.action.disabled,
},
},
/* Styles applied to the root element if `color="secondary"`. */
colorSecondary: {
'&$checked': {
color: theme.palette.secondary.main,
'&:hover': {
backgroundColor: fade(theme.palette.secondary.main, theme.palette.action.hoverOpacity),
// Reset on touch devices, it doesn't add specificity
'@media (hover: none)': {
backgroundColor: 'transparent',
},
},
},
'&$disabled': {
color: theme.palette.action.disabled,
},
},
});

const Checkbox = React.forwardRef(function Checkbox(props, ref) {
const {
checkedIcon,
classes,
className,
color,
icon,
indeterminate,
indeterminateIcon,
Expand All @@ -44,14 +72,10 @@ const Checkbox = React.forwardRef(function Checkbox(props, ref) {
<SwitchBase
type="checkbox"
checkedIcon={indeterminate ? indeterminateIcon : checkedIcon}
className={clsx(
classes.root,
{
[classes.indeterminate]: indeterminate,
},
className,
)}
classes={{
root: clsx(classes.root, classes[`color${capitalize(color)}`], {
[classes.indeterminate]: indeterminate,
}),
checked: classes.checked,
disabled: classes.disabled,
}}
Expand Down Expand Up @@ -80,10 +104,6 @@ Checkbox.propTypes = {
* See [CSS API](#css) below for more details.
*/
classes: PropTypes.object.isRequired,
/**
* @ignore
*/
className: PropTypes.string,
/**
* The color of the component. It supports those theme colors that make sense for this component.
*/
Expand Down Expand Up @@ -116,7 +136,7 @@ Checkbox.propTypes = {
*/
indeterminateIcon: PropTypes.node,
/**
* Properties applied to the `input` element.
* [Attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Attributes) applied to the `input` element.
*/
inputProps: PropTypes.object,
/**
Expand Down
2 changes: 1 addition & 1 deletion packages/material-ui/src/Radio/Radio.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export interface RadioProps
icon?: React.ReactNode;
}

export type RadioClassKey = SwitchBaseClassKey;
export type RadioClassKey = SwitchBaseClassKey | 'colorPrimary' | 'colorSecondary';

declare const Radio: React.ComponentType<RadioProps>;

Expand Down
55 changes: 45 additions & 10 deletions packages/material-ui/src/Radio/Radio.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,67 @@

import React from 'react';
import PropTypes from 'prop-types';
import { fade } from '../styles/colorManipulator';
import clsx from 'clsx';
import SwitchBase from '../internal/SwitchBase';
import RadioButtonUncheckedIcon from '../internal/svg-icons/RadioButtonUnchecked';
import RadioButtonCheckedIcon from '../internal/svg-icons/RadioButtonChecked';
import { createChainedFunction } from '../utils/helpers';
import { fade } from '../styles/colorManipulator';
import { capitalize, createChainedFunction } from '../utils/helpers';
import withStyles from '../styles/withStyles';
import RadioGroupContext from '../RadioGroup/RadioGroupContext';

export const styles = theme => ({
/* Styles applied to the root element. */
root: {
'&:not($checked)': {
color: theme.palette.text.secondary,
'&:hover': {
backgroundColor: fade(theme.palette.action.active, theme.palette.action.hoverOpacity),
},
},
color: theme.palette.text.secondary,
},
/* Styles applied to the root element if `checked={true}`. */
checked: {},
/* Styles applied to the root element if `disabled={true}`. */
disabled: {},
/* Styles applied to the root element if `color="primary"`. */
colorPrimary: {
'&$checked': {
color: theme.palette.primary.main,
'&:hover': {
backgroundColor: fade(theme.palette.primary.main, theme.palette.action.hoverOpacity),
// Reset on touch devices, it doesn't add specificity
'@media (hover: none)': {
backgroundColor: 'transparent',
},
},
},
'&$disabled': {
color: theme.palette.action.disabled,
},
},
/* Styles applied to the root element if `color="secondary"`. */
colorSecondary: {
'&$checked': {
color: theme.palette.secondary.main,
'&:hover': {
backgroundColor: fade(theme.palette.secondary.main, theme.palette.action.hoverOpacity),
// Reset on touch devices, it doesn't add specificity
'@media (hover: none)': {
backgroundColor: 'transparent',
},
},
},
'&$disabled': {
color: theme.palette.action.disabled,
},
},
});

const Radio = React.forwardRef(function Radio(props, ref) {
const { checked: checkedProp, classes, name: nameProp, onChange: onChangeProp, ...other } = props;
const {
checked: checkedProp,
classes,
color,
name: nameProp,
onChange: onChangeProp,
...other
} = props;
const radioGroup = React.useContext(RadioGroupContext);

let checked = checkedProp;
Expand All @@ -49,7 +84,7 @@ const Radio = React.forwardRef(function Radio(props, ref) {
icon={<RadioButtonUncheckedIcon />}
checkedIcon={<RadioButtonCheckedIcon />}
classes={{
root: classes.root,
root: clsx(classes.root, classes[`color${capitalize(color)}`]),
checked: classes.checked,
disabled: classes.disabled,
}}
Expand Down
4 changes: 3 additions & 1 deletion pages/api/checkbox.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import Checkbox from '@material-ui/core/Checkbox';
| <span class="prop-name">id</span> | <span class="prop-type">string</span> | | The id of the `input` element. |
| <span class="prop-name">indeterminate</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the component appears indeterminate. This does not set the native input element to indeterminate due to inconsistent behavior across browsers. However, we set a `data-indeterminate` attribute on the input. |
| <span class="prop-name">indeterminateIcon</span> | <span class="prop-type">node</span> | <span class="prop-default">&lt;IndeterminateCheckBoxIcon /></span> | The icon to display when the component is indeterminate. |
| <span class="prop-name">inputProps</span> | <span class="prop-type">object</span> | | Properties applied to the `input` element. |
| <span class="prop-name">inputProps</span> | <span class="prop-type">object</span> | | [Attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Attributes) applied to the `input` element. |
| <span class="prop-name">inputRef</span> | <span class="prop-type">union:&nbsp;func&nbsp;&#124;<br>&nbsp;object<br></span> | | This property can be used to pass a ref callback to the `input` element. |
| <span class="prop-name">onChange</span> | <span class="prop-type">func</span> | | 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">type</span> | <span class="prop-type">string</span> | | The input component property `type`. |
Expand All @@ -50,6 +50,8 @@ This property accepts the following keys:
| <span class="prop-name">checked</span> | Styles applied to the root element if `checked={true}`.
| <span class="prop-name">disabled</span> | Styles applied to the root element if `disabled={true}`.
| <span class="prop-name">indeterminate</span> | Styles applied to the root element if `indeterminate={true}`.
| <span class="prop-name">colorPrimary</span> | Styles applied to the root element if `color="primary"`.
| <span class="prop-name">colorSecondary</span> | Styles applied to the root element if `color="secondary"`.

Have a look at [overriding with classes](/customization/overrides/#overriding-with-classes) section
and the [implementation of the component](https://github.com/mui-org/material-ui/blob/next/packages/material-ui/src/Checkbox/Checkbox.js)
Expand Down
2 changes: 2 additions & 0 deletions pages/api/radio.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ This property accepts the following keys:
| <span class="prop-name">root</span> | Styles applied to the root element.
| <span class="prop-name">checked</span> | Styles applied to the root element if `checked={true}`.
| <span class="prop-name">disabled</span> | Styles applied to the root element if `disabled={true}`.
| <span class="prop-name">colorPrimary</span> | Styles applied to the root element if `color="primary"`.
| <span class="prop-name">colorSecondary</span> | Styles applied to the root element if `color="secondary"`.

Have a look at [overriding with classes](/customization/overrides/#overriding-with-classes) section
and the [implementation of the component](https://github.com/mui-org/material-ui/blob/next/packages/material-ui/src/Radio/Radio.js)
Expand Down