diff --git a/packages/bbui/src/Actions/click_outside.js b/packages/bbui/src/Actions/click_outside.js index 1a8baa1bfc..124f43ff04 100644 --- a/packages/bbui/src/Actions/click_outside.js +++ b/packages/bbui/src/Actions/click_outside.js @@ -1,8 +1,14 @@ +// These class names will never trigger a callback if clicked, no matter what const ignoredClasses = [ ".download-js-link", ".spectrum-Menu", ".date-time-popover", ] + +// These class names will only trigger a callback when clicked if the registered +// component is not nested inside them. For example, clicking inside a modal +// will not close the modal, or clicking inside a popover will not close the +// popover. const conditionallyIgnoredClasses = [ ".spectrum-Underlay", ".drawer-wrapper", @@ -11,11 +17,9 @@ const conditionallyIgnoredClasses = [ let clickHandlers = [] let candidateTarget -/** - * Handle a body click event - */ +// Processes a "click outside" event and invokes callbacks if our source element +// is valid const handleClick = event => { - console.log("CLOSE") // Ignore click if this is an ignored class if (event.target.closest('[data-ignore-click-outside="true"]')) { return @@ -46,23 +50,32 @@ const handleClick = event => { }) } +// On mouse up we only trigger a "click outside" callback if we targetted the +// same element that we did on mouse down. This fixes all sorts of issues where +// we get annoying callbacks firing when we drag to select text. const handleMouseUp = e => { - console.log("up") if (candidateTarget === e.target) { handleClick(e) } candidateTarget = null } +// On mouse down we store which element was targetted for comparison later const handleMouseDown = e => { + // Only handle the primary mouse button here. + // We handle context menu (right click) events in another handler. if (e.button !== 0) { return } candidateTarget = e.target + + // Clear any previous listeners in case of multiple down events, and register + // a single mouse up listener document.removeEventListener("mouseup", handleMouseUp) document.addEventListener("mouseup", handleMouseUp, true) } +// Global singleton listeners for our events document.addEventListener("mousedown", handleMouseDown) document.addEventListener("contextmenu", handleClick) diff --git a/packages/frontend-core/src/components/grid/stores/menu.js b/packages/frontend-core/src/components/grid/stores/menu.js index ea32285a95..d7f0e21b84 100644 --- a/packages/frontend-core/src/components/grid/stores/menu.js +++ b/packages/frontend-core/src/components/grid/stores/menu.js @@ -17,6 +17,7 @@ export const createActions = context => { const open = (cellId, e) => { e.preventDefault() + e.stopPropagation() // Get DOM node for grid data wrapper to compute relative position to const gridNode = document.getElementById(gridID)