diff --git a/docs/pages/experiments/md3/index.tsx b/docs/pages/experiments/md3/index.tsx new file mode 100644 index 00000000000000..61614b46bf6467 --- /dev/null +++ b/docs/pages/experiments/md3/index.tsx @@ -0,0 +1,342 @@ +import * as React from 'react'; +import Tooltip from '@mui/material/Tooltip'; +import IconButton from '@mui/material/IconButton'; +import TextField from '@mui/material/TextField'; +import Stack from '@mui/material/Stack'; +import MD2Button, { ButtonProps as MD2ButtonProps } from '@mui/material/Button'; +import { unstable_capitalize as capitalize } from '@mui/utils'; +import DeleteIcon from '@mui/icons-material/Delete'; +import SendIcon from '@mui/icons-material/Send'; +import Button, { ButtonProps } from '@mui/material-next/Button'; +import { CssVarsProvider, useColorScheme, extendTheme } from '@mui/material-next/styles'; +import DarkIcon from '@mui/icons-material/DarkModeOutlined'; +import LightIcon from '@mui/icons-material/LightModeOutlined'; +import CssBaseline from '@mui/material/CssBaseline'; + +function ModeSwitcher() { + const { mode, setMode } = useColorScheme(); + const [mounted, setMounted] = React.useState(false); + + React.useEffect(() => { + setMounted(true); + }, []); + + if (!mounted) { + return null; + } + + return ( + + { + if (mode === 'light') { + setMode('dark'); + } else { + setMode('light'); + } + }} + > + {mode === 'light' ? : } + + + ); +} + +const variants: ButtonProps['variant'][] = [ + 'elevated', + 'filled', + 'filledTonal', + 'outlined', + 'text', +]; +const colors: ButtonProps['color'][] = ['primary', 'secondary', 'tertiary']; +const sizes: ButtonProps['size'][] = ['small', 'medium', 'large']; + +const md2Variants: MD2ButtonProps['variant'][] = ['contained', 'outlined', 'text']; +const md2Colors: MD2ButtonProps['color'][] = [ + 'primary', + 'secondary', + 'success', + 'error', + 'info', + 'warning', +]; + +function DemoComponents() { + const [radius, setRadius] = React.useState('10'); + const [gap, setGap] = React.useState('0.5'); + + return ( + +

Enabled

+ + {variants.map((variant) => ( + + ))} + +

Disabled

+ + {variants.map((variant) => ( + + ))} + +

Colors

+ + {colors.map((color) => ( + + ))} + + + {colors.map((color) => ( + + ))} + + + {colors.map((color) => ( + + ))} + +

Extended buttons

+ + {colors.map((color) => ( + + ))} + + + + {colors.map((color) => ( + + ))} + + +

Sizes

+ + {sizes.map((size) => ( + + ))} + + + {sizes.map((size) => ( + + ))} + +

sx prop showcase

+ + + + + + +

CSS vars playground

+ + + { + setRadius(e.target.value); + }} + /> + { + setGap(e.target.value); + }} + /> + + + {sizes.map((size) => ( + + ))} + + +

Material Design 2 Buttons

+ + {md2Variants.map((variant) => ( + + {capitalize(variant as string)} + + ))} + + + {md2Colors.map((color) => ( + + {capitalize(color as string)} + + ))} + +
+ ); +} + +const customPalette = { + primary: { + '0': '#000000', + '10': '#3e001f', + '20': '#640036', + '30': '#8d004e', + '40': '#b70b68', + '50': '#d83181', + '60': '#fa4d9b', + '70': '#ff83b3', + '80': '#ffb0ca', + '90': '#ffd9e3', + '95': '#ffecf0', + '99': '#fffbff', + '100': '#ffffff', + }, + secondary: { + '0': '#000000', + '10': '#2b151d', + '20': '#422932', + '30': '#5a3f48', + '40': '#74565f', + '50': '#8e6f78', + '60': '#a98892', + '70': '#c5a2ac', + '80': '#e2bdc7', + '90': '#ffd9e3', + '95': '#ffecf0', + '99': '#fffbff', + '100': '#ffffff', + }, + tertiary: { + '0': '#000000', + '10': '#2f1500', + '20': '#48290c', + '30': '#623f21', + '40': '#7d5636', + '50': '#996e4c', + '60': '#b58763', + '70': '#d2a17c', + '80': '#f0bc95', + '90': '#ffdcc3', + '95': '#ffede3', + '99': '#fffbff', + '100': '#ffffff', + }, + neutral: { + '0': '#000000', + '10': '#201a1c', + '20': '#352f30', + '30': '#4c4546', + '40': '#645c5e', + '50': '#7e7577', + '60': '#988e90', + '70': '#b3a9aa', + '80': '#cfc4c5', + '90': '#ebe0e1', + '95': '#faeef0', + '99': '#fffbff', + '100': '#ffffff', + }, + neutralVariant: { + '0': '#000000', + '10': '#23191c', + '20': '#392d31', + '30': '#514347', + '40': '#695b5e', + '50': '#837377', + '60': '#9e8c91', + '70': '#b9a7ab', + '80': '#d5c2c6', + '90': '#f2dde2', + '95': '#ffecf0', + '99': '#fffbff', + '100': '#ffffff', + }, + error: { + '0': '#000000', + '10': '#410002', + '20': '#690005', + '30': '#93000a', + '40': '#ba1a1a', + '50': '#de3730', + '60': '#ff5449', + '70': '#ff897d', + '80': '#ffb4ab', + '90': '#ffdad6', + '95': '#ffedea', + '99': '#fffbff', + '100': '#ffffff', + }, +}; + +// custom MD3 theme +const cssVarsTheme = extendTheme({ + colorSchemes: { + light: { + ref: { + palette: customPalette, + }, + }, + dark: { + ref: { + palette: customPalette, + }, + }, + }, +}); + +export default function App() { + return ( + + + + + + + + ); +} diff --git a/packages/mui-material-next/src/Button/Button.js b/packages/mui-material-next/src/Button/Button.js deleted file mode 100644 index 548c275982f863..00000000000000 --- a/packages/mui-material-next/src/Button/Button.js +++ /dev/null @@ -1,658 +0,0 @@ -import * as React from 'react'; -import PropTypes from 'prop-types'; -import clsx from 'clsx'; -import { - elementTypeAcceptingRef, - refType, - unstable_capitalize as capitalize, - unstable_useForkRef as useForkRef, -} from '@mui/utils'; -import { useButton } from '@mui/base/ButtonUnstyled'; -import composeClasses from '@mui/base/composeClasses'; -import { useThemeProps, alpha } from '@mui/system'; -import styled, { rootShouldForwardProp } from '@mui/material/styles/styled'; -import useTouchRipple from '@mui/material/useTouchRipple'; -import TouchRipple from './TouchRipple'; -import buttonClasses, { getButtonUtilityClass } from './buttonClasses'; - -const useUtilityClasses = (styleProps) => { - const { - classes, - color, - disabled, - disableElevation, - focusVisible, - focusVisibleClassName, - fullWidth, - size, - variant, - } = styleProps; - - const slots = { - root: [ - 'root', - disabled && 'disabled', - focusVisible && 'focusVisible', - variant, - `${variant}${capitalize(color)}`, - `size${capitalize(size)}`, - `${variant}Size${capitalize(size)}`, - color === 'inherit' && 'colorInherit', - disableElevation && 'disableElevation', - fullWidth && 'fullWidth', - ], - label: ['label'], - startIcon: ['startIcon', `iconSize${capitalize(size)}`], - endIcon: ['endIcon', `iconSize${capitalize(size)}`], - }; - - const composedClasses = composeClasses(slots, getButtonUtilityClass, classes); - - if (focusVisible && focusVisibleClassName) { - composedClasses.root += ` ${focusVisibleClassName}`; - } - - return composedClasses; -}; - -const commonIconStyles = ({ size }) => ({ - ...(size === 'small' && { - '& > *:nth-of-type(1)': { - fontSize: 18, - }, - }), - ...(size === 'medium' && { - '& > *:nth-of-type(1)': { - fontSize: 20, - }, - }), - ...(size === 'large' && { - '& > *:nth-of-type(1)': { - fontSize: 22, - }, - }), -}); - -export const ButtonRoot = styled('button', { - shouldForwardProp: (prop) => rootShouldForwardProp(prop) || prop === 'classes', - name: 'MuiButton', - slot: 'Root', - overridesResolver: (props, styles) => { - const { ownerState } = props; - - return [ - styles.root, - styles[ownerState.variant], - styles[`${ownerState.variant}${capitalize(ownerState.color)}`], - styles[`size${capitalize(ownerState.size)}`], - styles[`${ownerState.variant}Size${capitalize(ownerState.size)}`], - ownerState.color === 'inherit' && styles.colorInherit, - ownerState.disableElevation && styles.disableElevation, - ownerState.fullWidth && styles.fullWidth, - ]; - }, -})(({ theme, ownerState }) => ({ - display: 'inline-flex', - alignItems: 'center', - justifyContent: 'center', - position: 'relative', - boxSizing: 'border-box', - WebkitTapHighlightColor: 'transparent', - backgroundColor: 'transparent', // Reset default value - // We disable the focus ring for mouse, touch and keyboard users. - outline: 0, - border: 0, - margin: 0, // Remove the margin in Safari - cursor: 'pointer', - userSelect: 'none', - verticalAlign: 'middle', - MozAppearance: 'none', // Reset - WebkitAppearance: 'none', // Reset - textDecoration: 'none', - // So we take precedent over the style of a native element. - color: 'inherit', - '&::-moz-focus-inner': { - borderStyle: 'none', // Remove Firefox dotted outline. - }, - [`&.${buttonClasses.disabled}`]: { - pointerEvents: 'none', // Disable link interactions - cursor: 'default', - }, - '@media print': { - colorAdjust: 'exact', - }, - ...theme.typography.button, - minWidth: 64, - padding: '6px 16px', - borderRadius: theme.shape.borderRadius, - transition: theme.transitions.create( - ['background-color', 'box-shadow', 'border-color', 'color'], - { duration: theme.transitions.duration.short }, - ), - '&:hover': { - textDecoration: 'none', - backgroundColor: alpha(theme.palette.text.primary, theme.palette.action.hoverOpacity), - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - backgroundColor: 'transparent', - }, - ...(ownerState.variant === 'text' && - ownerState.color !== 'inherit' && { - backgroundColor: alpha( - theme.palette[ownerState.color].main, - theme.palette.action.hoverOpacity, - ), - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - backgroundColor: 'transparent', - }, - }), - ...(ownerState.variant === 'outlined' && - ownerState.color !== 'inherit' && { - border: `1px solid ${theme.palette[ownerState.color].main}`, - backgroundColor: alpha( - theme.palette[ownerState.color].main, - theme.palette.action.hoverOpacity, - ), - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - backgroundColor: 'transparent', - }, - }), - ...(ownerState.variant === 'contained' && { - backgroundColor: theme.palette.grey.A100, - boxShadow: theme.shadows[4], - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - boxShadow: theme.shadows[2], - backgroundColor: theme.palette.grey[300], - }, - }), - ...(ownerState.variant === 'contained' && - ownerState.color !== 'inherit' && { - backgroundColor: theme.palette[ownerState.color].dark, - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - backgroundColor: theme.palette[ownerState.color].main, - }, - }), - }, - '&:active': { - ...(ownerState.variant === 'contained' && { - boxShadow: theme.shadows[8], - }), - }, - [`&.${buttonClasses.focusVisible}`]: { - ...(ownerState.variant === 'contained' && { - boxShadow: theme.shadows[6], - }), - }, - [`&.${buttonClasses.disabled}`]: { - color: theme.palette.action.disabled, - ...(ownerState.variant === 'outlined' && { - border: `1px solid ${theme.palette.action.disabledBackground}`, - }), - ...(ownerState.variant === 'outlined' && - ownerState.color === 'secondary' && { - border: `1px solid ${theme.palette.action.disabled}`, - }), - ...(ownerState.variant === 'contained' && { - color: theme.palette.action.disabled, - boxShadow: theme.shadows[0], - backgroundColor: theme.palette.action.disabledBackground, - }), - }, - ...(ownerState.variant === 'text' && { - padding: '6px 8px', - }), - ...(ownerState.variant === 'text' && - ownerState.color !== 'inherit' && { - color: theme.palette[ownerState.color].main, - }), - ...(ownerState.variant === 'outlined' && { - padding: '5px 15px', - border: `1px solid ${ - theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)' - }`, - }), - ...(ownerState.variant === 'outlined' && - ownerState.color !== 'inherit' && { - color: theme.palette[ownerState.color].main, - border: `1px solid ${alpha(theme.palette[ownerState.color].main, 0.5)}`, - }), - ...(ownerState.variant === 'contained' && { - color: theme.palette.getContrastText(theme.palette.grey[300]), - backgroundColor: theme.palette.grey[300], - boxShadow: theme.shadows[2], - }), - ...(ownerState.variant === 'contained' && - ownerState.color !== 'inherit' && { - color: theme.palette[ownerState.color].contrastText, - backgroundColor: theme.palette[ownerState.color].main, - }), - ...(ownerState.color === 'inherit' && { - color: 'inherit', - borderColor: 'currentColor', - }), - ...(ownerState.size === 'small' && - ownerState.variant === 'text' && { - padding: '4px 5px', - fontSize: theme.typography.pxToRem(13), - }), - ...(ownerState.size === 'large' && - ownerState.variant === 'text' && { - padding: '8px 11px', - fontSize: theme.typography.pxToRem(15), - }), - ...(ownerState.size === 'small' && - ownerState.variant === 'outlined' && { - padding: '3px 9px', - fontSize: theme.typography.pxToRem(13), - }), - ...(ownerState.size === 'large' && - ownerState.variant === 'outlined' && { - padding: '7px 21px', - fontSize: theme.typography.pxToRem(15), - }), - ...(ownerState.size === 'small' && - ownerState.variant === 'contained' && { - padding: '4px 10px', - fontSize: theme.typography.pxToRem(13), - }), - ...(ownerState.size === 'large' && - ownerState.variant === 'contained' && { - padding: '8px 22px', - fontSize: theme.typography.pxToRem(15), - }), - ...(ownerState.fullWidth && { - width: '100%', - }), - ...(ownerState.disableElevation && { - boxShadow: 'none', - '&:hover': { - boxShadow: 'none', - }, - [`&.${buttonClasses.focusVisible}`]: { - boxShadow: 'none', - }, - '&:active': { - boxShadow: 'none', - }, - [`&.${buttonClasses.disabled}`]: { - boxShadow: 'none', - }, - }), -})); - -const ButtonStartIcon = styled('span', { - name: 'MuiButton', - slot: 'StartIcon', - overridesResolver: (props, styles) => { - const { ownerState } = props; - - return [styles.startIcon, styles[`iconSize${capitalize(ownerState.size)}`]]; - }, -})(({ ownerState }) => ({ - display: 'inherit', - marginRight: 8, - marginLeft: -4, - ...(ownerState.size === 'small' && { - marginLeft: -2, - }), - ...commonIconStyles(ownerState), -})); - -const ButtonEndIcon = styled('span', { - name: 'MuiButton', - slot: 'EndIcon', - overridesResolver: (props, styles) => { - const { ownerState } = props; - - return [styles.endIcon, styles[`iconSize${capitalize(ownerState.size)}`]]; - }, -})(({ ownerState }) => ({ - display: 'inherit', - marginRight: -4, - marginLeft: 8, - ...(ownerState.size === 'small' && { - marginRight: -2, - }), - ...commonIconStyles(ownerState), -})); - -const Button = React.forwardRef(function Button(inProps, ref) { - const props = useThemeProps({ props: inProps, name: 'MuiButton' }); - const { - action, - centerRipple = false, - children, - className, - color = 'primary', - component = 'button', - disabled = false, - disableElevation = false, - disableFocusRipple = false, - disableRipple = false, - disableTouchRipple = false, - endIcon: endIconProp, - focusVisibleClassName, - fullWidth = false, - LinkComponent = 'a', - onBlur, - onClick, - onContextMenu, - onDragLeave, - onFocus, - onFocusVisible, - onKeyDown, - onKeyUp, - onMouseDown, - onMouseLeave, - onMouseUp, - onTouchEnd, - onTouchMove, - onTouchStart, - size = 'medium', - startIcon: startIconProp, - tabIndex = 0, - TouchRippleProps, - type, - variant = 'text', - ...other - } = props; - - const buttonRef = React.useRef(null); - const handleRef = useForkRef(buttonRef, ref); - - const rippleRef = React.useRef(null); - - let ComponentProp = component; - - if (ComponentProp === 'button' && (other.href || other.to)) { - ComponentProp = LinkComponent; - } - - const { focusVisible, setFocusVisible, getRootProps } = useButton({ - ...props, - component: ComponentProp, - ref: handleRef, - }); - - React.useImperativeHandle( - action, - () => ({ - focusVisible: () => { - setFocusVisible(true); - buttonRef.current.focus(); - }, - }), - [setFocusVisible], - ); - - const { enableTouchRipple, getRippleHandlers } = useTouchRipple({ - disabled, - disableFocusRipple, - disableRipple, - disableTouchRipple, - focusVisible, - rippleRef, - }); - - if (process.env.NODE_ENV !== 'production') { - // eslint-disable-next-line react-hooks/rules-of-hooks - React.useEffect(() => { - if (enableTouchRipple && !rippleRef.current) { - console.error( - [ - 'MUI: The `component` prop provided to Button is invalid.', - 'Please make sure the children prop is rendered in this custom component.', - ].join('\n'), - ); - } - }, [enableTouchRipple]); - } - - const ownerState = { - ...props, - centerRipple, - color, - component, - disabled, - disableElevation, - disableFocusRipple, - disableRipple, - disableTouchRipple, - focusVisible, - fullWidth, - size, - tabIndex, - type, - variant, - }; - - const classes = useUtilityClasses(ownerState); - - const startIcon = startIconProp && ( - - {startIconProp} - - ); - - const endIcon = endIconProp && ( - - {endIconProp} - - ); - - return ( - - {startIcon} - {children} - {endIcon} - {enableTouchRipple ? ( - /* TouchRipple is only needed client-side, x2 boost on the server. */ - - ) : null} - - ); -}); - -Button.propTypes /* remove-proptypes */ = { - // ----------------------------- Warning -------------------------------- - // | These PropTypes are generated from the TypeScript type definitions | - // | To update them edit the d.ts file and run "yarn proptypes" | - // ---------------------------------------------------------------------- - /** - * A ref for imperative actions. - * It exposes the `focusVisible()` action. - */ - action: refType, - /** - * If `true`, the ripples are centered. - * They won't start at the cursor interaction position. - * @default false - */ - centerRipple: PropTypes.bool, - /** - * The content of the component. - */ - children: PropTypes.node, - /** - * Override or extend the styles applied to the component. - */ - classes: PropTypes.object, - /** - * @ignore - */ - className: PropTypes.string, - /** - * The color of the component. It supports those theme colors that make sense for this component. - * @default 'primary' - */ - color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ - PropTypes.oneOf(['inherit', 'primary', 'secondary', 'success', 'error', 'info', 'warning']), - PropTypes.string, - ]), - /** - * The component used for the root node. - * Either a string to use a HTML element or a component. - */ - component: elementTypeAcceptingRef, - /** - * If `true`, the component is disabled. - * @default false - */ - disabled: PropTypes.bool, - /** - * If `true`, no elevation is used. - * @default false - */ - disableElevation: PropTypes.bool, - /** - * If `true`, the keyboard focus ripple is disabled. - * @default false - */ - disableFocusRipple: PropTypes.bool, - /** - * If `true`, the ripple effect is disabled. - * - * ⚠️ Without a ripple there is no styling for :focus-visible by default. Be sure - * to highlight the element by applying separate styles with the `.Mui-focusVisible` class. - * @default false - */ - disableRipple: PropTypes.bool, - /** - * If `true`, the touch ripple effect is disabled. - * @default false - */ - disableTouchRipple: PropTypes.bool, - /** - * Element placed after the children. - */ - endIcon: PropTypes.node, - /** - * @ignore - */ - focusVisibleClassName: PropTypes.string, - /** - * If `true`, the button will take up the full width of its container. - * @default false - */ - fullWidth: PropTypes.bool, - /** - * The URL to link to when the button is clicked. - * If defined, an `a` element will be used as the root node. - */ - href: PropTypes.string, - /** - * The component used to render a link when the `href` prop is provided. - * @default 'a' - */ - LinkComponent: PropTypes.elementType, - /** - * @ignore - */ - onBlur: PropTypes.func, - /** - * @ignore - */ - onClick: PropTypes.func, - /** - * @ignore - */ - onContextMenu: PropTypes.func, - /** - * @ignore - */ - onDragLeave: PropTypes.func, - /** - * @ignore - */ - onFocus: PropTypes.func, - /** - * Callback fired when the component is focused with a keyboard. - * We trigger a `onFocus` callback too. - */ - onFocusVisible: PropTypes.func, - /** - * @ignore - */ - onKeyDown: PropTypes.func, - /** - * @ignore - */ - onKeyUp: PropTypes.func, - /** - * @ignore - */ - onMouseDown: PropTypes.func, - /** - * @ignore - */ - onMouseLeave: PropTypes.func, - /** - * @ignore - */ - onMouseUp: PropTypes.func, - /** - * @ignore - */ - onTouchEnd: PropTypes.func, - /** - * @ignore - */ - onTouchMove: PropTypes.func, - /** - * @ignore - */ - onTouchStart: PropTypes.func, - /** - * The size of the component. - * `small` is equivalent to the dense button styling. - * @default 'medium' - */ - size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ - PropTypes.oneOf(['small', 'medium', 'large']), - PropTypes.string, - ]), - /** - * Element placed before the children. - */ - startIcon: PropTypes.node, - /** - * The system prop that allows defining system overrides as well as additional CSS styles. - */ - sx: PropTypes.oneOfType([ - PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), - PropTypes.func, - PropTypes.object, - ]), - /** - * @default 0 - */ - tabIndex: PropTypes.number, - /** - * Props applied to the `TouchRipple` element. - */ - TouchRippleProps: PropTypes.object, - /** - * @ignore - */ - type: PropTypes.oneOfType([PropTypes.oneOf(['button', 'reset', 'submit']), PropTypes.string]), - /** - * The variant to use. - * @default 'text' - */ - variant: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ - PropTypes.oneOf(['contained', 'outlined', 'text']), - PropTypes.string, - ]), -}; - -export default Button; diff --git a/packages/mui-material-next/src/Button/Button.spec.tsx b/packages/mui-material-next/src/Button/Button.spec.tsx index f5a06dce04dd3d..ab6ced74a40ca8 100644 --- a/packages/mui-material-next/src/Button/Button.spec.tsx +++ b/packages/mui-material-next/src/Button/Button.spec.tsx @@ -14,11 +14,11 @@ const FakeIcon =
Icon
; const buttonTest = () => (
- + - + diff --git a/packages/mui-material-next/src/Button/Button.test.js b/packages/mui-material-next/src/Button/Button.test.js index cfc5344335858a..fc3b6389b2a16d 100644 --- a/packages/mui-material-next/src/Button/Button.test.js +++ b/packages/mui-material-next/src/Button/Button.test.js @@ -1,6 +1,6 @@ import * as React from 'react'; import { expect } from 'chai'; -import { describeConformance, act, createRenderer, fireEvent } from 'test/utils'; +import { describeConformance, createRenderer } from 'test/utils'; import Button, { buttonClasses as classes } from '@mui/material/Button'; import ButtonBase from '@mui/material/ButtonBase'; @@ -280,26 +280,6 @@ describe(', - ); - const button = getByRole('button'); - - expect(button.querySelector('.touch-ripple')).not.to.equal(null); - }); - - it('can disable the ripple', () => { - const { getByRole } = render( - , - ); - const button = getByRole('button'); - - expect(button.querySelector('.touch-ripple')).to.equal(null); - }); - it('can disable the elevation', () => { const { getByRole } = render(); const button = getByRole('button'); @@ -307,41 +287,6 @@ describe(', - ); - const button = getByRole('button'); - - fireEvent.keyDown(document.body, { key: 'TAB' }); - act(() => { - button.focus(); - }); - - expect(button.querySelector('.pulsate-focus-visible')).not.to.equal(null); - }); - - it('can disable the focusRipple', () => { - const { getByRole } = render( - , - ); - const button = getByRole('button'); - - act(() => { - fireEvent.keyDown(document.body, { key: 'TAB' }); - button.focus(); - }); - - expect(button.querySelector('.pulsate-focus-visible')).to.equal(null); - }); - describe('server-side', () => { before(function beforeHook() { // Only run the test on node. @@ -366,7 +311,7 @@ describe(' - - - -
diff --git a/test/regressions/fixtures/ButtonNext/MultilineButtonNext.js b/test/regressions/fixtures/ButtonNext/MultilineButtonNext.js index 43a827747edf0b..546607ecc4db32 100644 --- a/test/regressions/fixtures/ButtonNext/MultilineButtonNext.js +++ b/test/regressions/fixtures/ButtonNext/MultilineButtonNext.js @@ -3,7 +3,7 @@ import Button from '@mui/material-next/Button'; export default function MultilineButtonNext() { return ( -