diff --git a/docs/data/joy/components/chip/DeleteButtonChip.js b/docs/data/joy/components/chip/DeleteButtonChip.js
index 4d8230a43fd020..c3b093bf6d6bb9 100644
--- a/docs/data/joy/components/chip/DeleteButtonChip.js
+++ b/docs/data/joy/components/chip/DeleteButtonChip.js
@@ -1,7 +1,7 @@
+import * as React from 'react';
import Box from '@mui/joy/Box';
import Chip from '@mui/joy/Chip';
import ChipDelete from '@mui/joy/ChipDelete';
-import * as React from 'react';
export default function DeleteButtonChip() {
return (
@@ -10,14 +10,23 @@ export default function DeleteButtonChip() {
size="sm"
variant="outlined"
color="danger"
- endDecorator={}
+ endDecorator={ alert('Delete')} />}
>
Remove
- }>
+ alert('Delete')} />}
+ >
Delete
- }>
+ alert('Delete')} />}
+ >
Delete
diff --git a/docs/data/joy/components/chip/DeleteButtonChip.tsx b/docs/data/joy/components/chip/DeleteButtonChip.tsx
index 4d8230a43fd020..c3b093bf6d6bb9 100644
--- a/docs/data/joy/components/chip/DeleteButtonChip.tsx
+++ b/docs/data/joy/components/chip/DeleteButtonChip.tsx
@@ -1,7 +1,7 @@
+import * as React from 'react';
import Box from '@mui/joy/Box';
import Chip from '@mui/joy/Chip';
import ChipDelete from '@mui/joy/ChipDelete';
-import * as React from 'react';
export default function DeleteButtonChip() {
return (
@@ -10,14 +10,23 @@ export default function DeleteButtonChip() {
size="sm"
variant="outlined"
color="danger"
- endDecorator={}
+ endDecorator={ alert('Delete')} />}
>
Remove
- }>
+ alert('Delete')} />}
+ >
Delete
- }>
+ alert('Delete')} />}
+ >
Delete
diff --git a/docs/data/joy/components/chip/DeleteButtonChip.tsx.preview b/docs/data/joy/components/chip/DeleteButtonChip.tsx.preview
deleted file mode 100644
index f422aedbec814a..00000000000000
--- a/docs/data/joy/components/chip/DeleteButtonChip.tsx.preview
+++ /dev/null
@@ -1,14 +0,0 @@
-}
->
- Remove
-
-}>
- Delete
-
-}>
- Delete
-
\ No newline at end of file
diff --git a/docs/data/joy/components/chip/chip.md b/docs/data/joy/components/chip/chip.md
index 9595edf652ea6d..3088d6f17d69ed 100644
--- a/docs/data/joy/components/chip/chip.md
+++ b/docs/data/joy/components/chip/chip.md
@@ -49,7 +49,11 @@ Use the `startDecorator` and/or `endDecorator` props to add supporting icons to
### Delete button
To add a delete action inside a chip, use the complementary `ChipDelete` component.
-Note that its design will automatically adapt to the parent `Chip`.
+
+The `onDelete` callback is fired on `ChipDelete` either when:
+
+- `Backspace`, `Enter` or `Delete` is pressed.
+- The `ChipDelete` is clicked.
```jsx
import ChipDelete from '@mui/joy/ChipDelete';
diff --git a/packages/mui-joy/src/ChipDelete/ChipDelete.test.js b/packages/mui-joy/src/ChipDelete/ChipDelete.test.js
index f4a99280886acb..55fd5647ce561c 100644
--- a/packages/mui-joy/src/ChipDelete/ChipDelete.test.js
+++ b/packages/mui-joy/src/ChipDelete/ChipDelete.test.js
@@ -1,6 +1,7 @@
import * as React from 'react';
import { expect } from 'chai';
-import { createRenderer, describeConformance } from 'test/utils';
+import { spy } from 'sinon';
+import { createRenderer, describeConformance, act, fireEvent } from 'test/utils';
import { ThemeProvider } from '@mui/joy/styles';
import Chip from '@mui/joy/Chip';
import ChipDelete, { chipDeleteClasses as classes } from '@mui/joy/ChipDelete';
@@ -67,4 +68,32 @@ describe('', () => {
expect(getByRole('button')).to.have.class(classes.colorNeutral);
});
});
+ describe('Chip onDelete', () => {
+ it('should call onDelete function when backspace, enter or delete is pressed', () => {
+ const handleDelete = spy();
+ const { getByRole } = render( {}} />);
+ const chipDelete = getByRole('button');
+ act(() => {
+ chipDelete.focus();
+ });
+ fireEvent.keyDown(chipDelete, { key: 'Backspace' });
+ fireEvent.keyDown(chipDelete, { key: 'Enter' });
+ fireEvent.keyDown(chipDelete, { key: 'Delete' });
+ fireEvent.click(chipDelete);
+ expect(handleDelete.callCount).to.equal(4);
+ });
+
+ it('should not call onDelete function when ChipDelete is disabled', () => {
+ const handleDelete = spy();
+ const { getByRole } = render(
+ {}} />,
+ );
+ const chipDelete = getByRole('button');
+ act(() => {
+ chipDelete.focus();
+ });
+ fireEvent.click(chipDelete);
+ expect(handleDelete.callCount).to.equal(0);
+ });
+ });
});
diff --git a/packages/mui-joy/src/ChipDelete/ChipDelete.tsx b/packages/mui-joy/src/ChipDelete/ChipDelete.tsx
index ae77b64ae334c7..3b91c645582bd6 100644
--- a/packages/mui-joy/src/ChipDelete/ChipDelete.tsx
+++ b/packages/mui-joy/src/ChipDelete/ChipDelete.tsx
@@ -75,6 +75,9 @@ const ChipDelete = React.forwardRef(function ChipDelete(inProps, ref) {
variant: variantProp,
color: colorProp,
disabled: disabledProp,
+ onKeyDown,
+ onDelete,
+ onClick,
...other
} = props;
const chipContext = React.useContext(ChipContext);
@@ -101,6 +104,27 @@ const ChipDelete = React.forwardRef(function ChipDelete(inProps, ref) {
const classes = useUtilityClasses(ownerState);
+ const handleClickDelete = (event: React.MouseEvent) => {
+ if (!disabled && onDelete) {
+ onDelete(event);
+ }
+ if (onClick) {
+ onClick(event);
+ }
+ };
+
+ const handleKeyDelete = (event: React.KeyboardEvent) => {
+ if (['Backspace', 'Enter', 'Delete'].includes(event.key)) {
+ event.preventDefault();
+ if (!disabled && onDelete) {
+ onDelete(event);
+ }
+ }
+ if (onKeyDown) {
+ onKeyDown(event);
+ }
+ };
+
const rootProps = useSlotProps({
elementType: ChipDeleteRoot,
getSlotProps: getRootProps,
@@ -109,11 +133,14 @@ const ChipDelete = React.forwardRef(function ChipDelete(inProps, ref) {
ownerState,
additionalProps: {
as: component,
+ onKeyDown: handleKeyDelete,
+ onClick: handleClickDelete,
},
className: classes.root,
});
- return {children ?? };
+ const { onDelete: excludeOnDelete, ...restOfRootProps } = rootProps;
+ return {children ?? };
}) as OverridableComponent;
ChipDelete.propTypes /* remove-proptypes */ = {
@@ -143,6 +170,20 @@ ChipDelete.propTypes /* remove-proptypes */ = {
* If `undefined`, the value inherits from the parent chip via a React context.
*/
disabled: PropTypes.bool,
+ /**
+ * @ignore
+ */
+ onClick: PropTypes.func,
+ /**
+ * Callback fired when the component is not disabled and either:
+ * - `Backspace`, `Enter` or `Delete` is pressed.
+ * - The component is clicked.
+ */
+ onDelete: PropTypes.func,
+ /**
+ * @ignore
+ */
+ onKeyDown: PropTypes.func,
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
diff --git a/packages/mui-joy/src/ChipDelete/ChipDeleteProps.ts b/packages/mui-joy/src/ChipDelete/ChipDeleteProps.ts
index efdb0a9d84b34f..f94220f58e1001 100644
--- a/packages/mui-joy/src/ChipDelete/ChipDeleteProps.ts
+++ b/packages/mui-joy/src/ChipDelete/ChipDeleteProps.ts
@@ -23,6 +23,14 @@ export interface ChipDeleteTypeMap