-
Notifications
You must be signed in to change notification settings - Fork 2.9k
fix(Dialog): keep Dialog open when press click on content and release on overlay #22849
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
86a73ac
c8128d4
2983599
d42d7de
1f5cfa4
f6cfba3
66f5ab9
3a10561
d7a27df
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import * as React from 'react'; | ||
| import { Button, Dialog } from '@fluentui/react-northstar'; | ||
|
|
||
| export const selectors = { | ||
| trigger: 'trigger', | ||
| cancelButton: 'cancelButton', | ||
| }; | ||
|
|
||
| const DialogBlockBodyScrollExample = () => ( | ||
| <Dialog | ||
| cancelButton={{ content: 'Close', id: selectors.cancelButton }} | ||
| content={'dialog content'} | ||
| header="Action confirmation" | ||
| trigger={<Button id={selectors.trigger} content="Open a dialog" />} | ||
| /> | ||
| ); | ||
|
|
||
| export default DialogBlockBodyScrollExample; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| import { selectors } from './dialog-example'; | ||
|
|
||
| describe('Dialog', () => { | ||
| const trigger = `#${selectors.trigger}`; | ||
| const cancelButton = `#${selectors.cancelButton}`; | ||
|
|
||
| beforeEach(() => { | ||
| cy.gotoTestCase(__filename, trigger); | ||
| cy.get('body').click('bottomRight'); | ||
| }); | ||
|
|
||
| it('should open on click trigger', () => { | ||
| cy.clickOn(trigger); | ||
| cy.visible(cancelButton); | ||
| }); | ||
|
|
||
| it('should close on click cancel button', () => { | ||
| cy.clickOn(trigger); | ||
| cy.visible(cancelButton); | ||
|
|
||
| cy.clickOn(cancelButton); | ||
| cy.notExist(cancelButton); | ||
| }); | ||
|
|
||
| it('should close on click overlay', () => { | ||
| cy.clickOn(trigger); | ||
| cy.visible(cancelButton); | ||
|
|
||
| cy.get('.ui-dialog__overlay').click('topLeft'); | ||
| cy.notExist(cancelButton); | ||
| }); | ||
|
|
||
| it('should keep open when mouse down on button, and drag mouse outside of Dialog', () => { | ||
| cy.clickOn(trigger); | ||
| cy.visible(cancelButton); | ||
|
|
||
| // press click within Dialog content, drag mouse outside of Dialog content | ||
| cy.get(cancelButton).trigger('mousedown', { eventConstructor: 'MouseEvent', button: 0 }).trigger('mousemove', { | ||
| eventConstructor: 'MouseEvent', | ||
| clientX: 1, | ||
| clientY: 1, | ||
| pageX: 1, | ||
| pageY: 1, | ||
| screenX: 1, | ||
| screenY: 1, | ||
| }); // move mouse to top-left corner | ||
| cy.get('.ui-dialog__overlay').click('topLeft'); | ||
| cy.visible(cancelButton); | ||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -258,10 +258,24 @@ export const Dialog = (React.forwardRef<HTMLDivElement, DialogProps>((props, ref | |
| }, | ||
| }); | ||
|
|
||
| // when press left click on Dialog content and hold, and mouse up on Dialog overlay, Dialog should keep open | ||
| const isMouseDownInsideContent = React.useRef(false); | ||
| const registerMouseDownOnDialogContent = (e: React.MouseEvent) => { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should be testable in cypress by triggering a mousedown followed by a click somewhere else ?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Heyy, if I do It mimics the behavior of dragging mouse from content to outside of content. But unlike browser, cypress will not trigger an automatic click event after that. And if I chain it with a
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
but if you chain it with
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Aha I see what you meant. Let me try adding some tests
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ahaa it worked ❤️ on cypress with my change chained 'click' does not close dialog |
||
| if (e.button === 0) { | ||
| isMouseDownInsideContent.current = true; | ||
| } | ||
| if (unhandledProps.onMouseDown) { | ||
| _.invoke(unhandledProps, 'onMouseDown', e); | ||
| } | ||
| }; | ||
|
|
||
| const handleOverlayClick = (e: MouseEvent) => { | ||
| // Dialog has different conditions to close than Popup, so we don't need to iterate across all | ||
| // refs | ||
| const isInsideContentClick = doesNodeContainClick(contentRef.current, e, context.target); | ||
| const isInsideContentClick = | ||
| isMouseDownInsideContent.current || doesNodeContainClick(contentRef.current, e, context.target); | ||
| isMouseDownInsideContent.current = false; | ||
|
|
||
| const isInsideOverlayClick = doesNodeContainClick(overlayRef.current, e, context.target); | ||
|
|
||
| const shouldClose = !isInsideContentClick && isInsideOverlayClick; | ||
|
|
@@ -318,6 +332,7 @@ export const Dialog = (React.forwardRef<HTMLDivElement, DialogProps>((props, ref | |
| className: classes.root, | ||
| ref, | ||
| ...unhandledProps, | ||
| onMouseDown: registerMouseDownOnDialogContent, | ||
| })} | ||
| > | ||
| {Header.create(header, { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would add some comments here wth you are trying to do