diff --git a/packages/material-ui/src/internal/SwitchBase.d.ts b/packages/material-ui/src/internal/SwitchBase.d.ts index e85fc6801e2af1..5138340dfafcfd 100644 --- a/packages/material-ui/src/internal/SwitchBase.d.ts +++ b/packages/material-ui/src/internal/SwitchBase.d.ts @@ -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. diff --git a/packages/material-ui/src/internal/SwitchBase.js b/packages/material-ui/src/internal/SwitchBase.js index 1a91d64e9a375f..c05fe05b8e6a38 100644 --- a/packages/material-ui/src/internal/SwitchBase.js +++ b/packages/material-ui/src/internal/SwitchBase.js @@ -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. @@ -35,7 +61,6 @@ const SwitchBase = React.forwardRef(function SwitchBase(props, ref) { autoFocus, checked: checkedProp, checkedIcon, - classes, className, defaultChecked, disabled: disabledProp, @@ -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 ( - - {checked ? checkedIcon : icon} - + ); }); @@ -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 */ @@ -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 */ @@ -240,4 +272,4 @@ SwitchBase.propTypes = { value: PropTypes.any, }; -export default withStyles(styles, { name: 'PrivateSwitchBase' })(SwitchBase); +export default SwitchBase; diff --git a/packages/material-ui/src/internal/SwitchBase.test.js b/packages/material-ui/src/internal/SwitchBase.test.js index 3f26a11e1b45d7..4d8f177e24ecf1 100644 --- a/packages/material-ui/src/internal/SwitchBase.test.js +++ b/packages/material-ui/src/internal/SwitchBase.test.js @@ -1,21 +1,17 @@ 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('', () => { const render = createClientRender(); const mount = createMount(); - let classes; - before(() => { - classes = getClasses(); - }); - - describeConformance( + describeConformanceV5( , () => ({ classes, @@ -23,6 +19,8 @@ describe('', () => { mount, refInstanceof: window.HTMLSpanElement, testComponentPropWith: 'div', + testVariantProps: { disabled: true }, + skip: ['componentsProp', 'themeDefaultProps', 'themeStyleOverrides', 'themeVariants'], }), ); diff --git a/packages/material-ui/src/internal/switchBaseClasses.d.ts b/packages/material-ui/src/internal/switchBaseClasses.d.ts new file mode 100644 index 00000000000000..fb5d277321fa69 --- /dev/null +++ b/packages/material-ui/src/internal/switchBaseClasses.d.ts @@ -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; diff --git a/packages/material-ui/src/internal/switchBaseClasses.js b/packages/material-ui/src/internal/switchBaseClasses.js new file mode 100644 index 00000000000000..500b38230b279e --- /dev/null +++ b/packages/material-ui/src/internal/switchBaseClasses.js @@ -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; diff --git a/test/utils/describeConformanceV5.js b/test/utils/describeConformanceV5.js index aea06cf018e1bb..6103656a7abf2b 100644 --- a/test/utils/describeConformanceV5.js +++ b/test/utils/describeConformanceV5.js @@ -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]: {