Skip to content

Commit

Permalink
[Button][base] Set active class when a subcomponent is clicked (#35410)
Browse files Browse the repository at this point in the history
  • Loading branch information
michaldudak committed Dec 13, 2022
1 parent e039510 commit 56c59c6
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 11 deletions.
40 changes: 40 additions & 0 deletions packages/mui-base/src/ButtonUnstyled/useButton.test.tsx
Expand Up @@ -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 (
<button {...getRootProps()} className={active ? 'active' : ''}>
<span>Click here</span>
</button>
);
}

const { getByText, getByRole } = render(<TestComponent />);
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 (
<div data-testid="parent">
<button {...getRootProps()} className={active ? 'active' : ''} />
</div>
);
}

const { getByRole, getByTestId } = render(<TestComponent />);
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', () => {
Expand Down
18 changes: 8 additions & 10 deletions packages/mui-base/src/ButtonUnstyled/useButton.ts
Expand Up @@ -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);

Expand Down Expand Up @@ -213,7 +212,6 @@ export default function useButton(parameters: UseButtonParameters) {
onKeyUp: createHandleKeyUp(externalEventHandlers),
onMouseDown: createHandleMouseDown(externalEventHandlers),
onMouseLeave: createHandleMouseLeave(externalEventHandlers),
onMouseUp: createHandleMouseUp(externalEventHandlers),
ref: handleRef,
};
};
Expand Down
1 change: 0 additions & 1 deletion packages/mui-base/src/ButtonUnstyled/useButton.types.ts
Expand Up @@ -12,7 +12,6 @@ export interface UseButtonRootSlotOwnProps {
onKeyUp: React.KeyboardEventHandler;
onMouseDown: React.MouseEventHandler;
onMouseLeave: React.MouseEventHandler;
onMouseUp: React.MouseEventHandler;
ref: React.Ref<any>;
}

Expand Down

0 comments on commit 56c59c6

Please sign in to comment.