Skip to content

Commit

Permalink
[Checkbox] Migrate to emotion (#24702)
Browse files Browse the repository at this point in the history
  • Loading branch information
natac13 authored Feb 9, 2021
1 parent a980bb5 commit 5f4b5cd
Show file tree
Hide file tree
Showing 50 changed files with 158 additions and 58 deletions.
3 changes: 2 additions & 1 deletion docs/pages/api-docs/checkbox.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"type": { "name": "enum", "description": "'medium'<br>&#124;&nbsp;'small'" },
"default": "'medium'"
},
"sx": { "type": { "name": "object" } },
"value": { "type": { "name": "any" } }
},
"name": "Checkbox",
Expand All @@ -38,6 +39,6 @@
"filename": "/packages/material-ui/src/Checkbox/Checkbox.js",
"inheritance": { "component": "IconButton", "pathname": "/api/icon-button/" },
"demos": "<ul><li><a href=\"/components/checkboxes/\">Checkboxes</a></li>\n<li><a href=\"/components/transfer-list/\">Transfer List</a></li></ul>",
"styledComponent": false,
"styledComponent": true,
"cssComponent": false
}
1 change: 1 addition & 0 deletions docs/translations/api-docs/checkbox/checkbox.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"onChange": "Callback fired when the state is changed.<br><br><strong>Signature:</strong><br><code>function(event: object) =&gt; void</code><br><em>event:</em> The event source of the callback. You can pull out the new checked state by accessing <code>event.target.checked</code> (boolean).",
"required": "If <code>true</code>, the <code>input</code> element is required.",
"size": "The size of the component. <code>small</code> is equivalent to the dense checkbox styling.",
"sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the <a href=\"/system/basics/#the-sx-prop\">`sx` page</a> for more details.",
"value": "The value of the component. The DOM API casts this to a string. The browser uses &quot;on&quot; as the default value."
},
"classDescriptions": {
Expand Down
1 change: 1 addition & 0 deletions framer/scripts/framerConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ export const componentSettings = {
'indeterminateIcon',
'onChange',
'required',
'sx',
'type',
'value',
],
Expand Down
1 change: 1 addition & 0 deletions packages/material-ui-unstyled/src/BadgeUnstyled/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { default } from './BadgeUnstyled';
export * from './BadgeUnstyled';

export { default as badgeUnstyledClasses } from './badgeUnstyledClasses';
export * from './badgeUnstyledClasses';
2 changes: 2 additions & 0 deletions packages/material-ui-unstyled/src/SliderUnstyled/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export { default } from './SliderUnstyled';
export * from './SliderUnstyled';

export { default as SliderValueLabelUnstyled } from './SliderValueLabelUnstyled';
export * from './SliderValueLabelUnstyled';

export { default as sliderUnstyledClasses } from './sliderUnstyledClasses';
export * from './sliderUnstyledClasses';
1 change: 1 addition & 0 deletions packages/material-ui/src/AlertTitle/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { default } from './AlertTitle';
export * from './AlertTitle';

export { default as alertTitleClasses } from './alertTitleClasses';
export * from './alertTitleClasses';
1 change: 1 addition & 0 deletions packages/material-ui/src/AlertTitle/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { default } from './AlertTitle';

export { default as alertTitleClasses } from './alertTitleClasses';
export * from './alertTitleClasses';
1 change: 1 addition & 0 deletions packages/material-ui/src/AppBar/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { default } from './AppBar';
export * from './AppBar';

export { default as appBarClasses } from './appBarClasses';
export * from './appBarClasses';
1 change: 1 addition & 0 deletions packages/material-ui/src/AppBar/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { default } from './AppBar';

export { default as appBarClasses } from './appBarClasses';
export * from './appBarClasses';
1 change: 1 addition & 0 deletions packages/material-ui/src/Avatar/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { default } from './Avatar';
export * from './Avatar';

export { default as avatarClasses } from './avatarClasses';
export * from './avatarClasses';
1 change: 1 addition & 0 deletions packages/material-ui/src/Avatar/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { default } from './Avatar';

export { default as avatarClasses } from './avatarClasses';
export * from './avatarClasses';
1 change: 1 addition & 0 deletions packages/material-ui/src/Button/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { default } from './Button';
export * from './Button';

export { default as buttonClasses } from './buttonClasses';
export * from './buttonClasses';
1 change: 1 addition & 0 deletions packages/material-ui/src/Button/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { default } from './Button';

export { default as buttonClasses } from './buttonClasses';
export * from './buttonClasses';
2 changes: 2 additions & 0 deletions packages/material-ui/src/ButtonBase/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export { default } from './ButtonBase';
export * from './ButtonBase';

export { default as buttonBaseClasses } from './buttonBaseClasses';
export * from './buttonBaseClasses';

export { default as touchRippleClasses } from './touchRippleClasses';
export * from './touchRippleClasses';
2 changes: 2 additions & 0 deletions packages/material-ui/src/ButtonBase/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export { default } from './ButtonBase';

export { default as buttonBaseClasses } from './buttonBaseClasses';
export * from './buttonBaseClasses';

export { default as touchRippleClasses } from './touchRippleClasses';
export * from './touchRippleClasses';
1 change: 1 addition & 0 deletions packages/material-ui/src/Card/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { default } from './Card';
export * from './Card';

export { default as cardClasses } from './cardClasses';
export * from './cardClasses';
1 change: 1 addition & 0 deletions packages/material-ui/src/Card/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { default } from './Card';

export { default as cardClasses } from './cardClasses';
export * from './cardClasses';
1 change: 1 addition & 0 deletions packages/material-ui/src/CardActions/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { default } from './CardActions';
export * from './CardActions';

export { default as cardActionsClasses } from './cardActionsClasses';
export * from './cardActionsClasses';
1 change: 1 addition & 0 deletions packages/material-ui/src/CardActions/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { default } from './CardActions';

export { default as cardActionsClasses } from './cardActionsClasses';
export * from './cardActionsClasses';
1 change: 1 addition & 0 deletions packages/material-ui/src/CardContent/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { default } from './CardContent';
export * from './CardContent';

export { default as cardContentClasses } from './cardContentClasses';
export * from './cardContentClasses';
1 change: 1 addition & 0 deletions packages/material-ui/src/CardContent/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { default } from './CardContent';

export { default as cardContentClasses } from './cardContentClasses';
export * from './cardContentClasses';
7 changes: 6 additions & 1 deletion packages/material-ui/src/Checkbox/Checkbox.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { SxProps } from '@material-ui/system';
import * as React from 'react';
import { InternalStandardProps as StandardProps } from '..';
import { InternalStandardProps as StandardProps, Theme } from '..';
import { SwitchBaseProps } from '../internal/SwitchBase';

export interface CheckboxProps
Expand Down Expand Up @@ -90,6 +91,10 @@ export interface CheckboxProps
* @default 'medium'
*/
size?: 'small' | 'medium';
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx?: SxProps<Theme>;
/**
* The value of the component. The DOM API casts this to a string.
* The browser uses "on" as the default value.
Expand Down
117 changes: 69 additions & 48 deletions packages/material-ui/src/Checkbox/Checkbox.js
Original file line number Diff line number Diff line change
@@ -1,68 +1,81 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { refType } from '@material-ui/utils';
import { refType, deepmerge } from '@material-ui/utils';
import { unstable_composeClasses as composeClasses } from '@material-ui/unstyled';
import SwitchBase from '../internal/SwitchBase';
import CheckBoxOutlineBlankIcon from '../internal/svg-icons/CheckBoxOutlineBlank';
import CheckBoxIcon from '../internal/svg-icons/CheckBox';
import { alpha } from '../styles/colorManipulator';
import IndeterminateCheckBoxIcon from '../internal/svg-icons/IndeterminateCheckBox';
import capitalize from '../utils/capitalize';
import withStyles from '../styles/withStyles';
import useThemeProps from '../styles/useThemeProps';
import experimentalStyled, { shouldForwardProp } from '../styles/experimentalStyled';
import checkboxClasses, { getCheckboxUtilityClass } from './checkboxClasses';

export const styles = (theme) => ({
/* Styles applied to the root element. */
root: {
color: theme.palette.text.secondary,
},
/* Pseudo-class applied to the root element if `checked={true}`. */
checked: {},
/* Pseudo-class applied to the root element if `disabled={true}`. */
disabled: {},
/* Pseudo-class applied to the root element if `indeterminate={true}`. */
indeterminate: {},
/* Styles applied to the root element if `color="primary"`. */
colorPrimary: {
'&$checked, &$indeterminate': {
color: theme.palette.primary.main,
'&:hover': {
backgroundColor: alpha(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,
},
const overridesResolver = (props, styles) => {
const { styleProps } = props;

return deepmerge(styles.root || {}, {
...(styleProps.indeterminate && styles.indeterminate),
...(styleProps.color !== 'default' && styles[`color${capitalize(styleProps.color)}`]),
});
};

const useUtilityClasses = (styleProps) => {
const { classes, indeterminate, color } = styleProps;

const slots = {
root: ['root', indeterminate && 'indeterminate', `color${capitalize(color)}`],
};

const finalClasses = composeClasses(slots, getCheckboxUtilityClass, classes);

return {
...classes, // forward the disabled and checked classes to the SwitchBase
...finalClasses,
};
};

const CheckboxRoot = experimentalStyled(
SwitchBase,
{ shouldForwardProp: (prop) => shouldForwardProp(prop) || prop === 'classes' },
{
name: 'MuiCheckbox',
slot: 'Root',
overridesResolver,
},
/* Styles applied to the root element if `color="secondary"`. */
colorSecondary: {
'&$checked, &$indeterminate': {
color: theme.palette.secondary.main,
)(({ theme, styleProps }) => ({
/* Styles applied to the root element. */
color: theme.palette.text.secondary,
/* Styles applied to the root element unless `color="default"`. */
...(styleProps.color !== 'default' && {
[`&.Mui-checked, &.${checkboxClasses.indeterminate}`]: {
color: theme.palette[styleProps.color].main,
'&:hover': {
backgroundColor: alpha(theme.palette.secondary.main, theme.palette.action.hoverOpacity),
backgroundColor: alpha(
theme.palette[styleProps.color].main,
theme.palette.action.hoverOpacity,
),
// Reset on touch devices, it doesn't add specificity
'@media (hover: none)': {
backgroundColor: 'transparent',
},
},
},
'&$disabled': {
'&.Mui-disabled': {
color: theme.palette.action.disabled,
},
},
});
}),
}));

const defaultCheckedIcon = <CheckBoxIcon />;
const defaultIcon = <CheckBoxOutlineBlankIcon />;
const defaultIndeterminateIcon = <IndeterminateCheckBoxIcon />;

const Checkbox = React.forwardRef(function Checkbox(props, ref) {
const Checkbox = React.forwardRef(function Checkbox(inProps, ref) {
const props = useThemeProps({ props: inProps, name: 'MuiCheckbox' });
const {
checkedIcon = defaultCheckedIcon,
classes,
color = 'secondary',
icon: iconProp = defaultIcon,
indeterminate = false,
Expand All @@ -75,16 +88,18 @@ const Checkbox = React.forwardRef(function Checkbox(props, ref) {
const icon = indeterminate ? indeterminateIconProp : iconProp;
const indeterminateIcon = indeterminate ? indeterminateIconProp : checkedIcon;

const styleProps = {
...props,
color,
indeterminate,
size,
};

const classes = useUtilityClasses(styleProps);

return (
<SwitchBase
<CheckboxRoot
type="checkbox"
classes={{
root: clsx(classes.root, classes[`color${capitalize(color)}`], {
[classes.indeterminate]: indeterminate,
}),
checked: classes.checked,
disabled: classes.disabled,
}}
color={color}
inputProps={{
'data-indeterminate': indeterminate,
Expand All @@ -100,8 +115,10 @@ const Checkbox = React.forwardRef(function Checkbox(props, ref) {
? size
: indeterminateIcon.props.fontSize,
})}
styleProps={styleProps}
ref={ref}
{...other}
classes={classes}
/>
);
});
Expand Down Expand Up @@ -188,11 +205,15 @@ Checkbox.propTypes = {
* @default 'medium'
*/
size: PropTypes.oneOf(['medium', 'small']),
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx: PropTypes.object,
/**
* The value of the component. The DOM API casts this to a string.
* The browser uses "on" as the default value.
*/
value: PropTypes.any,
};

export default withStyles(styles, { name: 'MuiCheckbox' })(Checkbox);
export default Checkbox;
15 changes: 7 additions & 8 deletions packages/material-ui/src/Checkbox/Checkbox.test.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
import * as React from 'react';
import { expect } from 'chai';
import { spy } from 'sinon';
import { getClasses, createMount, describeConformance, act, createClientRender } from 'test/utils';
import { createMount, describeConformanceV5, act, createClientRender } from 'test/utils';
import Checkbox from './Checkbox';
import FormControl from '../FormControl';
import IconButton from '../IconButton';
import classes from './checkboxClasses';

describe('<Checkbox />', () => {
const render = createClientRender();
let classes;
const mount = createMount();

before(() => {
classes = getClasses(<Checkbox />);
});

describeConformance(<Checkbox checked />, () => ({
describeConformanceV5(<Checkbox checked />, () => ({
classes,
inheritComponent: IconButton,
mount,
muiName: 'MuiCheckbox',
testVariantProps: { variant: 'foo' },
testStateOverrides: { prop: 'color', value: 'secondary', styleKey: 'colorSecondary' },
refInstanceof: window.HTMLSpanElement,
skip: ['componentProp'],
skip: ['componentProp', 'componentsProp', 'rootClass'],
}));

it('should have the classes required for Checkbox', () => {
Expand Down
7 changes: 7 additions & 0 deletions packages/material-ui/src/Checkbox/checkboxClasses.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { CheckboxClassKey } from './Checkbox';

declare const checkboxClasses: Record<CheckboxClassKey, string>;

export function getCheckboxUtilityClass(slot: string): string;

export default checkboxClasses;
16 changes: 16 additions & 0 deletions packages/material-ui/src/Checkbox/checkboxClasses.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { generateUtilityClass, generateUtilityClasses } from '@material-ui/unstyled';

export function getCheckboxUtilityClass(slot) {
return generateUtilityClass('MuiCheckbox', slot);
}

const checkboxClasses = generateUtilityClasses('MuiCheckbox', [
'root',
'checked',
'disabled',
'indeterminate',
'colorPrimary',
'colorSecondary',
]);

export default checkboxClasses;
Loading

0 comments on commit 5f4b5cd

Please sign in to comment.