diff --git a/src/js/components/overlays.js b/src/js/components/overlays.js
index d46a20f..2d49a67 100644
--- a/src/js/components/overlays.js
+++ b/src/js/components/overlays.js
@@ -20,7 +20,7 @@
}
function closeAll(except = null) {
- document.querySelectorAll(".dropdown.is-open, .popover.is-open, .tooltip.is-open").forEach(node => {
+ document.querySelectorAll(".dropdown.is-open, .popover.is-open:not([data-vmk-managed]), .tooltip.is-open").forEach(node => {
if(node !== except) {
closeNode(node);
}
diff --git a/src/js/components/popover.js b/src/js/components/popover.js
index b33d3d2..e5aaaac 100644
--- a/src/js/components/popover.js
+++ b/src/js/components/popover.js
@@ -45,12 +45,12 @@
return;
}
- root.querySelectorAll(".popover.is-open").forEach(popover => close(popover));
+ root.querySelectorAll(".popover.is-open:not([data-vmk-managed])").forEach(popover => close(popover));
});
root.addEventListener("keydown", event => {
if(event.key === "Escape") {
- root.querySelectorAll(".popover.is-open").forEach(popover => close(popover));
+ root.querySelectorAll(".popover.is-open:not([data-vmk-managed])").forEach(popover => close(popover));
}
});
diff --git a/src/scss/components/_cards.scss b/src/scss/components/_cards.scss
index a06c533..c3c27a6 100644
--- a/src/scss/components/_cards.scss
+++ b/src/scss/components/_cards.scss
@@ -447,6 +447,12 @@
.user-card-actions {
display: flex;
gap: $space-1;
+
+ .btn-icon {
+ width: 40px;
+ height: 40px;
+ font-size: 18px;
+ }
}
}
}
diff --git a/src/vue/components/GnButton.js b/src/vue/components/GnButton.js
index 09b44e3..c7dbb7d 100644
--- a/src/vue/components/GnButton.js
+++ b/src/vue/components/GnButton.js
@@ -32,9 +32,11 @@
return () => {
const hasIcon = Boolean(props.icon || props.loading);
const variant = normalizeVariant(props.variant);
+ const { onClick, class: classAttr, ...restAttrs } = attrs;
return h("button", {
- ...attrs,
+ ...restAttrs,
+ onClick,
type: props.type,
disabled: props.disabled || props.loading,
class: cx(
@@ -45,7 +47,7 @@
"with-icon": hasIcon,
"is-loading": props.loading
},
- attrs.class
+ classAttr
)
}, [
props.loading ? iconNode("essentials/loading") : iconNode(props.icon),
diff --git a/src/vue/components/GnPopover.js b/src/vue/components/GnPopover.js
index dc8f1e2..3b5a01f 100644
--- a/src/vue/components/GnPopover.js
+++ b/src/vue/components/GnPopover.js
@@ -49,7 +49,7 @@
onBeforeUnmount(close);
- return () => h("div", { ref: root, class: cx("popover", { "is-open": open.value }), "data-position": props.position }, [
+ return () => h("div", { ref: root, class: cx("popover", { "is-open": open.value }), "data-vmk-managed": "", "data-position": props.position }, [
slots.trigger?.({ open: open.value, toggle }) || h(GnButton, {
class: "popover-trigger",
variant: props.variant,
diff --git a/tests/functional.spec.js b/tests/functional.spec.js
index cfede50..5013fdc 100644
--- a/tests/functional.spec.js
+++ b/tests/functional.spec.js
@@ -64,6 +64,15 @@
await expect(popover).not.toHaveClass(/is-open/);
});
+ test("vue popover toggles and closes on outside click", async ({ page }) => {
+ const trigger = page.locator("#vue-popover-app .popover-trigger");
+ const popover = page.locator("#vue-popover-app .popover");
+ await trigger.click();
+ await expect(popover).toHaveClass(/is-open/);
+ await page.locator("body").click();
+ await expect(popover).not.toHaveClass(/is-open/);
+ });
+
test("navigation shell toggles sidebar", async ({ page }) => {
await page.setViewportSize({ width: 800, height: 600 });
const shell = page.locator(".navigation-shell").first();