Fix certain types of popover not working inside modals or side panels (#9424)
This commit is contained in:
parent
3c1de8f903
commit
a9a729cb85
|
@ -1,4 +1,4 @@
|
||||||
const ignoredClasses = [".flatpickr-calendar"]
|
const ignoredClasses = [".flatpickr-calendar", ".spectrum-Popover"]
|
||||||
let clickHandlers = []
|
let clickHandlers = []
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,7 +19,7 @@ const handleClick = event => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore clicks for modals, unless the handler is registered from a modal
|
// Ignore clicks for modals, unless the handler is registered from a modal
|
||||||
const sourceInModal = handler.element.closest(".spectrum-Modal") != null
|
const sourceInModal = handler.anchor.closest(".spectrum-Modal") != null
|
||||||
const clickInModal = event.target.closest(".spectrum-Modal") != null
|
const clickInModal = event.target.closest(".spectrum-Modal") != null
|
||||||
if (clickInModal && !sourceInModal) {
|
if (clickInModal && !sourceInModal) {
|
||||||
return
|
return
|
||||||
|
@ -33,10 +33,10 @@ document.documentElement.addEventListener("click", handleClick, true)
|
||||||
/**
|
/**
|
||||||
* Adds or updates a click handler
|
* Adds or updates a click handler
|
||||||
*/
|
*/
|
||||||
const updateHandler = (id, element, callback) => {
|
const updateHandler = (id, element, anchor, callback) => {
|
||||||
let existingHandler = clickHandlers.find(x => x.id === id)
|
let existingHandler = clickHandlers.find(x => x.id === id)
|
||||||
if (!existingHandler) {
|
if (!existingHandler) {
|
||||||
clickHandlers.push({ id, element, callback })
|
clickHandlers.push({ id, element, anchor, callback })
|
||||||
} else {
|
} else {
|
||||||
existingHandler.callback = callback
|
existingHandler.callback = callback
|
||||||
}
|
}
|
||||||
|
@ -51,12 +51,22 @@ const removeHandler = id => {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Svelte action to apply a click outside handler for a certain element
|
* Svelte action to apply a click outside handler for a certain element
|
||||||
|
* opts.anchor is an optional param specifying the real root source of the
|
||||||
|
* component being observed. This is required for things like popovers, where
|
||||||
|
* the element using the clickoutside action is the popover, but the popover is
|
||||||
|
* rendered at the root of the DOM somewhere, whereas the popover anchor is the
|
||||||
|
* element we actually want to consider when determining the source component.
|
||||||
*/
|
*/
|
||||||
export default (element, callback) => {
|
export default (element, opts) => {
|
||||||
const id = Math.random()
|
const id = Math.random()
|
||||||
updateHandler(id, element, callback)
|
const update = newOpts => {
|
||||||
|
const callback = newOpts?.callback || newOpts
|
||||||
|
const anchor = newOpts?.anchor || element
|
||||||
|
updateHandler(id, element, anchor, callback)
|
||||||
|
}
|
||||||
|
update(opts)
|
||||||
return {
|
return {
|
||||||
update: newCallback => updateHandler(id, element, newCallback),
|
update,
|
||||||
destroy: () => removeHandler(id),
|
destroy: () => removeHandler(id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,10 @@
|
||||||
<div
|
<div
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
use:positionDropdown={{ anchor, align, maxWidth, useAnchorWidth }}
|
use:positionDropdown={{ anchor, align, maxWidth, useAnchorWidth }}
|
||||||
use:clickOutside={handleOutsideClick}
|
use:clickOutside={{
|
||||||
|
callback: handleOutsideClick,
|
||||||
|
anchor,
|
||||||
|
}}
|
||||||
on:keydown={handleEscape}
|
on:keydown={handleEscape}
|
||||||
class={"spectrum-Popover is-open " + (tooltipClasses || "")}
|
class={"spectrum-Popover is-open " + (tooltipClasses || "")}
|
||||||
role="presentation"
|
role="presentation"
|
||||||
|
|
Loading…
Reference in New Issue