diff --git a/docs/pages/material-ui/api/chip.json b/docs/pages/material-ui/api/chip.json index c0aa34f7971e66..2d8251bf56d0f3 100644 --- a/docs/pages/material-ui/api/chip.json +++ b/docs/pages/material-ui/api/chip.json @@ -24,6 +24,7 @@ }, "default": "'medium'" }, + "skipFocusWhenDisabled": { "type": { "name": "bool" } }, "sx": { "type": { "name": "union", diff --git a/docs/translations/api-docs/chip/chip.json b/docs/translations/api-docs/chip/chip.json index 5012cbf664f9d0..2a39e6b8f90a2e 100644 --- a/docs/translations/api-docs/chip/chip.json +++ b/docs/translations/api-docs/chip/chip.json @@ -13,6 +13,7 @@ "label": "The content of the component.", "onDelete": "Callback fired when the delete icon is clicked. If set, the delete icon will be shown.", "size": "The size of the component.", + "skipFocusWhenDisabled": "If true, allows the disabled chip to escape focus. If false, allows the disabled chip to receive focus.", "sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the `sx` page for more details.", "variant": "The variant to use." }, diff --git a/packages/mui-material/src/Chip/Chip.d.ts b/packages/mui-material/src/Chip/Chip.d.ts index 9ff2c7a2767374..4e8644064f1a2c 100644 --- a/packages/mui-material/src/Chip/Chip.d.ts +++ b/packages/mui-material/src/Chip/Chip.d.ts @@ -72,10 +72,20 @@ export interface ChipTypeMap

{ * @default 'medium' */ size?: OverridableStringUnion<'small' | 'medium', ChipPropsSizeOverrides>; + /** + * If `true`, allows the disabled chip to escape focus. + * If `false`, allows the disabled chip to receive focus. + * @default false + */ + skipFocusWhenDisabled?: boolean; /** * The system prop that allows defining system overrides as well as additional CSS styles. */ sx?: SxProps; + /** + * @ignore + */ + tabIndex?: number; /** * The variant to use. * @default 'filled' diff --git a/packages/mui-material/src/Chip/Chip.js b/packages/mui-material/src/Chip/Chip.js index 44bbe36d98464a..87925389a8fc51 100644 --- a/packages/mui-material/src/Chip/Chip.js +++ b/packages/mui-material/src/Chip/Chip.js @@ -346,6 +346,8 @@ const Chip = React.forwardRef(function Chip(inProps, ref) { onKeyUp, size = 'medium', variant = 'filled', + tabIndex, + skipFocusWhenDisabled = false, // TODO v6: Rename to `focusableWhenDisabled`. ...other } = props; @@ -460,6 +462,7 @@ const Chip = React.forwardRef(function Chip(inProps, ref) { onKeyDown={handleKeyDown} onKeyUp={handleKeyUp} ref={handleRef} + tabIndex={skipFocusWhenDisabled && disabled ? -1 : tabIndex} ownerState={ownerState} {...moreProps} {...other} @@ -561,6 +564,12 @@ Chip.propTypes /* remove-proptypes */ = { PropTypes.oneOf(['medium', 'small']), PropTypes.string, ]), + /** + * If `true`, allows the disabled chip to escape focus. + * If `false`, allows the disabled chip to receive focus. + * @default false + */ + skipFocusWhenDisabled: PropTypes.bool, /** * The system prop that allows defining system overrides as well as additional CSS styles. */ @@ -569,6 +578,10 @@ Chip.propTypes /* remove-proptypes */ = { PropTypes.func, PropTypes.object, ]), + /** + * @ignore + */ + tabIndex: PropTypes.number, /** * The variant to use. * @default 'filled' diff --git a/packages/mui-material/src/Chip/Chip.test.js b/packages/mui-material/src/Chip/Chip.test.js index 990328fe9525d5..904aeb9701ca18 100644 --- a/packages/mui-material/src/Chip/Chip.test.js +++ b/packages/mui-material/src/Chip/Chip.test.js @@ -174,6 +174,29 @@ describe('', () => { expect(chip).to.have.class(classes.filledPrimary); }); + it('should not be focused when a deletable chip is disabled and skipFocusWhenDisabled is true', () => { + const { getByTestId } = render( + {}} + />, + ); + + const chip = getByTestId('chip'); + + simulatePointerDevice(); + act(() => { + fireEvent.keyDown(document.body, { key: 'Tab' }); + }); + + expect(chip).to.have.class(classes.root); + expect(chip).to.have.property('tabIndex', -1); + expect(chip).not.to.have.class(classes.focusVisible); + }); + it('should render with the root and filled clickable secondary class', () => { const { getByRole } = render( {}} variant="filled" />,