diff --git a/packages/mui-base/src/ButtonUnstyled/useButton.test.tsx b/packages/mui-base/src/ButtonUnstyled/useButton.test.tsx
index 18aebe3319c1ab..b3f066f44091ad 100644
--- a/packages/mui-base/src/ButtonUnstyled/useButton.test.tsx
+++ b/packages/mui-base/src/ButtonUnstyled/useButton.test.tsx
@@ -41,6 +41,46 @@ describe('useButton', () => {
fireEvent.keyUp(button, { key: ' ' });
expect(button).not.to.have.class('active');
});
+
+ it('is set when clicked on an element inside the button', () => {
+ function TestComponent() {
+ const buttonRef = React.useRef(null);
+ const { active, getRootProps } = useButton({ ref: buttonRef });
+
+ return (
+
+ );
+ }
+
+ const { getByText, getByRole } = render();
+ const span = getByText('Click here');
+ const button = getByRole('button');
+ fireEvent.mouseDown(span);
+ expect(button).to.have.class('active');
+ });
+
+ it('is unset when mouse button is released above another element', () => {
+ function TestComponent() {
+ const buttonRef = React.useRef(null);
+ const { active, getRootProps } = useButton({ ref: buttonRef });
+
+ return (
+
+
+
+ );
+ }
+
+ const { getByRole, getByTestId } = render();
+ const button = getByRole('button');
+ const background = getByTestId('parent');
+ fireEvent.mouseDown(button);
+ expect(button).to.have.class('active');
+ fireEvent.mouseUp(background);
+ expect(button).not.to.have.class('active');
+ });
});
describe('when using a span element', () => {
diff --git a/packages/mui-base/src/ButtonUnstyled/useButton.ts b/packages/mui-base/src/ButtonUnstyled/useButton.ts
index ec5e1cfea2cfc3..5ad1c81dc671a8 100644
--- a/packages/mui-base/src/ButtonUnstyled/useButton.ts
+++ b/packages/mui-base/src/ButtonUnstyled/useButton.ts
@@ -91,21 +91,20 @@ export default function useButton(parameters: UseButtonParameters) {
};
const createHandleMouseDown = (otherHandlers: EventHandlers) => (event: React.MouseEvent) => {
- if (event.target === event.currentTarget && !disabled) {
+ if (!disabled) {
setActive(true);
+ document.addEventListener(
+ 'mouseup',
+ () => {
+ setActive(false);
+ },
+ { once: true },
+ );
}
otherHandlers.onMouseDown?.(event);
};
- const createHandleMouseUp = (otherHandlers: EventHandlers) => (event: React.MouseEvent) => {
- if (event.target === event.currentTarget) {
- setActive(false);
- }
-
- otherHandlers.onMouseUp?.(event);
- };
-
const createHandleKeyDown = (otherHandlers: EventHandlers) => (event: React.KeyboardEvent) => {
otherHandlers.onKeyDown?.(event);
@@ -213,7 +212,6 @@ export default function useButton(parameters: UseButtonParameters) {
onKeyUp: createHandleKeyUp(externalEventHandlers),
onMouseDown: createHandleMouseDown(externalEventHandlers),
onMouseLeave: createHandleMouseLeave(externalEventHandlers),
- onMouseUp: createHandleMouseUp(externalEventHandlers),
ref: handleRef,
};
};
diff --git a/packages/mui-base/src/ButtonUnstyled/useButton.types.ts b/packages/mui-base/src/ButtonUnstyled/useButton.types.ts
index 60dddbfe2d5b13..d2665a2ac3dd10 100644
--- a/packages/mui-base/src/ButtonUnstyled/useButton.types.ts
+++ b/packages/mui-base/src/ButtonUnstyled/useButton.types.ts
@@ -12,7 +12,6 @@ export interface UseButtonRootSlotOwnProps {
onKeyUp: React.KeyboardEventHandler;
onMouseDown: React.MouseEventHandler;
onMouseLeave: React.MouseEventHandler;
- onMouseUp: React.MouseEventHandler;
ref: React.Ref;
}