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

[Switch] Migrate SwitchBase to emotion #24552

Merged
merged 12 commits into from
Jan 25, 2021
2 changes: 1 addition & 1 deletion packages/material-ui/src/internal/SwitchBase.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export interface SwitchBaseProps
root?: string;
checked?: string;
disabled?: string;
inpit?: string;
input?: string;
};
/**
* The default checked state. Use when the component is not controlled.
Expand Down
96 changes: 64 additions & 32 deletions packages/material-ui/src/internal/SwitchBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,56 @@ import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { refType } from '@material-ui/utils';
import { unstable_composeClasses as composeClasses } from '@material-ui/unstyled';
import experimentalStyled from '../styles/experimentalStyled';
import useControlled from '../utils/useControlled';
import useFormControl from '../FormControl/useFormControl';
import withStyles from '../styles/withStyles';
import IconButton from '../IconButton';
import { getSwitchBaseUtilityClass } from './switchBaseClasses';

export const styles = {
root: {
padding: 9,
const useUtilityClasses = (styleProps) => {
const { classes, checked, disabled } = styleProps;

const slots = {
root: ['root', checked && 'checked', disabled && 'disabled'],
input: ['input'],
};

return composeClasses(slots, getSwitchBaseUtilityClass, classes);
};

const SwitchBaseRoot = experimentalStyled(
IconButton,
{},
{
name: 'PrivateSwitchBase',
slot: 'Root',
},
checked: {},
disabled: {},
input: {
cursor: 'inherit',
position: 'absolute',
opacity: 0,
width: '100%',
height: '100%',
top: 0,
left: 0,
margin: 0,
padding: 0,
zIndex: 1,
)({
/* Styles applied to the root element. */
padding: 9,
});

const SwitchBaseInput = experimentalStyled(
'input',
{},
{
name: 'PrivateSwitchBase',
slot: 'Input',
},
};
)({
/* Styles applied to the internal input element. */
cursor: 'inherit',
position: 'absolute',
opacity: 0,
width: '100%',
height: '100%',
top: 0,
left: 0,
margin: 0,
padding: 0,
zIndex: 1,
});

/**
* @ignore - internal component.
Expand All @@ -35,7 +61,6 @@ const SwitchBase = React.forwardRef(function SwitchBase(props, ref) {
autoFocus,
checked: checkedProp,
checkedIcon,
classes,
className,
defaultChecked,
disabled: disabledProp,
Expand Down Expand Up @@ -109,26 +134,28 @@ const SwitchBase = React.forwardRef(function SwitchBase(props, ref) {

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

const styleProps = {
...props,
checked,
disabled,
};

const classes = useUtilityClasses(styleProps);

return (
<IconButton
<SwitchBaseRoot
component="span"
className={clsx(
classes.root,
{
[classes.checked]: checked,
[classes.disabled]: disabled,
},
className,
)}
className={clsx(classes.root, className)}
disabled={disabled}
tabIndex={null}
role={undefined}
onFocus={handleFocus}
onBlur={handleBlur}
styleProps={styleProps}
ref={ref}
{...other}
>
<input
<SwitchBaseInput
autoFocus={autoFocus}
checked={checkedProp}
defaultChecked={defaultChecked}
Expand All @@ -140,13 +167,14 @@ const SwitchBase = React.forwardRef(function SwitchBase(props, ref) {
readOnly={readOnly}
ref={inputRef}
required={required}
styleProps={styleProps}
tabIndex={tabIndex}
type={type}
value={value}
{...inputProps}
/>
{checked ? checkedIcon : icon}
</IconButton>
</SwitchBaseRoot>
);
});

Expand All @@ -169,7 +197,7 @@ SwitchBase.propTypes = {
* Override or extend the styles applied to the component.
* See [CSS API](#css) below for more details.
*/
classes: PropTypes.object.isRequired,
classes: PropTypes.object,
/**
* @ignore
*/
Expand Down Expand Up @@ -226,6 +254,10 @@ SwitchBase.propTypes = {
* If `true`, the `input` element is required.
*/
required: PropTypes.bool,
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx: PropTypes.object,
/**
* @ignore
*/
Expand All @@ -240,4 +272,4 @@ SwitchBase.propTypes = {
value: PropTypes.any,
};

export default withStyles(styles, { name: 'PrivateSwitchBase' })(SwitchBase);
export default SwitchBase;
12 changes: 5 additions & 7 deletions packages/material-ui/src/internal/SwitchBase.test.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,26 @@
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 SwitchBase from './SwitchBase';
import FormControl, { useFormControl } from '../FormControl';
import IconButton from '../IconButton';
import classes from './switchBaseClasses';

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

before(() => {
classes = getClasses(<SwitchBase icon="unchecked" checkedIcon="checked" type="checkbox" />);
});

describeConformance(
describeConformanceV5(
<SwitchBase checkedIcon="checked" icon="unchecked" type="checkbox" />,
() => ({
classes,
inheritComponent: IconButton,
mount,
refInstanceof: window.HTMLSpanElement,
testComponentPropWith: 'div',
testVariantProps: { disabled: true },
skip: ['componentsProp', 'themeDefaultProps', 'themeStyleOverrides', 'themeVariants'],
}),
);

Expand Down
12 changes: 12 additions & 0 deletions packages/material-ui/src/internal/switchBaseClasses.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export interface SwitchBaseClasses {
root: string;
checked: string;
disabled: string;
input: string;
}

declare const switchBaseClasses: SwitchBaseClasses;

export function getSwitchBaseUtilityClass(slot: string): string;

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

export function getSwitchBaseUtilityClass(slot) {
return generateUtilityClass('PrivateSwitchBase', slot);
}

const switchBaseClasses = generateUtilityClasses('PrivateSwitchBase', [
'root',
'checked',
'disabled',
'input',
]);

export default switchBaseClasses;
3 changes: 2 additions & 1 deletion test/utils/describeConformanceV5.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ function testThemeDefaultProps(element, getOptions) {

describe('theme: default components', () => {
it("respect theme's defaultProps", () => {
const { muiName, testThemeComponentsDefaultPropName: testProp = 'id' } = getOptions();
const testProp = 'data-id';
const { muiName } = getOptions();
const theme = createMuiTheme({
components: {
[muiName]: {
Expand Down