Skip to content

Commit

Permalink
ignore default prevented event to support links
Browse files Browse the repository at this point in the history
  • Loading branch information
oliviertassinari committed Dec 11, 2019
1 parent 9829b80 commit 93cba61
Show file tree
Hide file tree
Showing 5 changed files with 9 additions and 39 deletions.
1 change: 0 additions & 1 deletion docs/pages/api/click-away-listener.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ For instance, if you need to hide a menu when people click anywhere else on your

| Name | Type | Default | Description |
|:-----|:-----|:--------|:------------|
| <span class="prop-name">allowPreventDefaultEvents</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the component skips the check to see if events used event.preventDefault().<br>The usage of this prop is recommended. It will become the default and unique behavior in v5. |
| <span class="prop-name required">children&nbsp;*</span> | <span class="prop-type">element</span> | | The wrapped element.<br>⚠️ [Needs to be able to hold a ref](/guides/composition/#caveat-with-refs). |
| <span class="prop-name">mouseEvent</span> | <span class="prop-type">'onClick'<br>&#124;&nbsp;'onMouseDown'<br>&#124;&nbsp;'onMouseUp'<br>&#124;&nbsp;false</span> | <span class="prop-default">'onClick'</span> | The mouse event to listen to. You can disable the listener by providing `false`. |
| <span class="prop-name required">onClickAway&nbsp;*</span> | <span class="prop-type">func</span> | | Callback fired when a "click away" event is detected. |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as React from 'react';

export interface ClickAwayListenerProps {
allowPreventDefaultEvents?: boolean;
children: React.ReactNode;
mouseEvent?: 'onClick' | 'onMouseDown' | 'onMouseUp' | false;
onClickAway: (event: React.MouseEvent<Document>) => void;
Expand Down
26 changes: 7 additions & 19 deletions packages/material-ui/src/ClickAwayListener/ClickAwayListener.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,7 @@ function mapEventPropToEvent(eventProp) {
* For instance, if you need to hide a menu when people click anywhere else on your page.
*/
const ClickAwayListener = React.forwardRef(function ClickAwayListener(props, ref) {
const {
allowPreventDefaultEvents = false,
children,
mouseEvent = 'onClick',
touchEvent = 'onTouchEnd',
onClickAway,
} = props;
const { children, mouseEvent = 'onClick', touchEvent = 'onTouchEnd', onClickAway } = props;
const movedRef = React.useRef(false);
const nodeRef = React.useRef(null);
const mountedRef = React.useRef(false);
Expand All @@ -46,11 +40,12 @@ const ClickAwayListener = React.forwardRef(function ClickAwayListener(props, ref
const handleRef = useForkRef(children.ref, handleOwnRef);

const handleClickAway = useEventCallback(event => {
// Ignore events that have been `event.preventDefault()` marked unless
// allowPreventDefaultEvents is true.
if (!allowPreventDefaultEvents && event.defaultPrevented) {
return;
}
// The handler doesn't take event.defaultPrevented into account:
//
// event.preventDefault() is meant to stop default behaviours like
// clicking a checkbox to check it, hitting a button to submit a form,
// and hitting left arrow to move the cursor in a text input etc.
// Only special HTML elements have these default behaviors.

// IE 11 support, which trigger the handleClickAway even after the unbind
if (!mountedRef.current) {
Expand Down Expand Up @@ -120,13 +115,6 @@ const ClickAwayListener = React.forwardRef(function ClickAwayListener(props, ref
});

ClickAwayListener.propTypes = {
/**
* If `true`, the component skips the check to see if events used event.preventDefault().
*
* The usage of this prop is recommended.
* It will become the default and unique behavior in v5.
*/
allowPreventDefaultEvents: PropTypes.bool,
/**
* The wrapped element.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe('<ClickAwayListener />', () => {
expect(handleClickAway.callCount).to.equal(0);
});

it('should not be called when defaultPrevented', () => {
it('should be called when preventDefault is `true`', () => {
const handleClickAway = spy();
render(
<ClickAwayListener onClickAway={handleClickAway}>
Expand All @@ -51,22 +51,6 @@ describe('<ClickAwayListener />', () => {
const preventDefault = event => event.preventDefault();
document.body.addEventListener('click', preventDefault);

fireEvent.click(document.body);
expect(handleClickAway.callCount).to.equal(0);

document.body.removeEventListener('click', preventDefault);
});

it('should be called when preventDefault and allowPreventDefaultEvents is `true`', () => {
const handleClickAway = spy();
render(
<ClickAwayListener allowPreventDefaultEvents onClickAway={handleClickAway}>
<span />
</ClickAwayListener>,
);
const preventDefault = event => event.preventDefault();
document.body.addEventListener('click', preventDefault);

fireEvent.click(document.body);
expect(handleClickAway.callCount).to.equal(1);

Expand Down
2 changes: 1 addition & 1 deletion packages/material-ui/src/Modal/Modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ const Modal = React.forwardRef(function Modal(inProps, ref) {
};

const handleKeyDown = event => {
// We don't take event.defaultPrevented into account:
// The handler doesn't take event.defaultPrevented into account:
//
// event.preventDefault() is meant to stop default behaviours like
// clicking a checkbox to check it, hitting a button to submit a form,
Expand Down

0 comments on commit 93cba61

Please sign in to comment.