fix(ui): keep mega menu open across hover gap
Quality / quality (windows-latest) (push) Waiting to run
Quality / quality (ubuntu-latest) (push) Failing after 9m51s

This commit is contained in:
2026-08-24 22:08:46 +05:30
parent d2d830e7e2
commit f5538ed621
5 changed files with 34 additions and 5 deletions
+1 -1
View File
@@ -688,7 +688,7 @@
}, },
"packages/ui": { "packages/ui": {
"name": "@wrnexus/ui", "name": "@wrnexus/ui",
"version": "0.8.31", "version": "0.8.32",
"dependencies": { "dependencies": {
"@wrnexus/core": "workspace:*", "@wrnexus/core": "workspace:*",
}, },
+1 -1
View File
@@ -55,7 +55,7 @@
"packages/ui/components/Map.wrn": "3e6d5de5a21dd050c5c65950d6fb2f89af4024e1856a48f055b65b88fcd7b890", "packages/ui/components/Map.wrn": "3e6d5de5a21dd050c5c65950d6fb2f89af4024e1856a48f055b65b88fcd7b890",
"packages/ui/components/MarketingSectionHeader.wrn": "39b79499b77dc1c7d34e4e5ecb45a9ddc6182f78c2a2586671c4fa07f44679ad", "packages/ui/components/MarketingSectionHeader.wrn": "39b79499b77dc1c7d34e4e5ecb45a9ddc6182f78c2a2586671c4fa07f44679ad",
"packages/ui/components/Marquee.wrn": "81cd80732be34c8d7e4bf28b00347e1a9273166afdf66589d9f5d5774b69403b", "packages/ui/components/Marquee.wrn": "81cd80732be34c8d7e4bf28b00347e1a9273166afdf66589d9f5d5774b69403b",
"packages/ui/components/MegaMenu.wrn": "c86a18489b5316047466b54a7c0b439e1b56539ab446ac88eb413a0d2c33781b", "packages/ui/components/MegaMenu.wrn": "1fdd962bfc30a5f0eaa563e5b055760d86f9c737f0d664286977894485d7b045",
"packages/ui/components/MetricCard.wrn": "513a6e99be3d9db46d96af9942b51331a0a048b184603e77e814506f0a52bdc5", "packages/ui/components/MetricCard.wrn": "513a6e99be3d9db46d96af9942b51331a0a048b184603e77e814506f0a52bdc5",
"packages/ui/components/MetricGrid.wrn": "1fcebf51dcbe8520fe16bda904c1ef206c25c3900438d53877492c64ea21a1a5", "packages/ui/components/MetricGrid.wrn": "1fcebf51dcbe8520fe16bda904c1ef206c25c3900438d53877492c64ea21a1a5",
"packages/ui/components/Modal.wrn": "7fa4b877772736f29f690e24d8742922b310397ef3083f0b78acb67a9f0d14b2", "packages/ui/components/Modal.wrn": "7fa4b877772736f29f690e24d8742922b310397ef3083f0b78acb67a9f0d14b2",
+22 -2
View File
@@ -44,6 +44,7 @@ component MegaMenu {
} }
state visible = defaultOpen state visible = defaultOpen
state closeTimer = null
functions { functions {
shared function columnList() { shared function columnList() {
@@ -59,15 +60,32 @@ component MegaMenu {
} }
client function showPanel(sourceEvent) { client function showPanel(sourceEvent) {
cancelScheduledHide()
visible = true visible = true
output.open({ sourceEvent: sourceEvent }) output.open({ sourceEvent: sourceEvent })
} }
client function hidePanel(reason) { client function hidePanel(reason) {
cancelScheduledHide()
visible = false visible = false
output.close({ reason: reason }) output.close({ reason: reason })
} }
client function cancelScheduledHide() {
if (closeTimer) {
window.clearTimeout(closeTimer)
closeTimer = null
}
}
client function scheduleHide() {
cancelScheduledHide()
closeTimer = window.setTimeout(function () {
closeTimer = null
hidePanel("pointer-leave")
}, 220)
}
client function togglePanel(sourceEvent) { client function togglePanel(sourceEvent) {
if (visible) { if (visible) {
hidePanel("toggle") hidePanel("toggle")
@@ -121,7 +139,8 @@ component MegaMenu {
data-full-width='{fullWidth ? "true" : "false"}' data-full-width='{fullWidth ? "true" : "false"}'
data-column-count='{columnCount}' data-column-count='{columnCount}'
@keydown='handleKeydown(event)' @keydown='handleKeydown(event)'
@mouseleave='hidePanel("pointer-leave")' @mouseenter='cancelScheduledHide()'
@mouseleave='scheduleHide()'
> >
<button <button
type="button" type="button"
@@ -141,6 +160,7 @@ component MegaMenu {
data-wrn-anchored="true" data-wrn-anchored="true"
data-show="visible" data-show="visible"
data-wrn-roving="both" data-wrn-roving="both"
@mouseenter='cancelScheduledHide()'
> >
<div class="wrn-mega__layout"> <div class="wrn-mega__layout">
{#if railList().length > 0} {#if railList().length > 0}
@@ -278,7 +298,7 @@ component MegaMenu {
left: 0; left: 0;
right: 0; right: 0;
bottom: 100%; bottom: 100%;
height: 0.6rem; height: 0.85rem;
} }
.wrn-mega__panel { .wrn-mega__panel {
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@wrnexus/ui", "name": "@wrnexus/ui",
"version": "0.8.31", "version": "0.8.32",
"private": true, "private": true,
"type": "module", "type": "module",
"main": "src/index.ts", "main": "src/index.ts",
+9
View File
@@ -3133,6 +3133,15 @@ test("mega menu keeps hover activation and click activation from cancelling each
expect(source).toContain("max-height: calc(100dvh - 5.5rem)"); expect(source).toContain("max-height: calc(100dvh - 5.5rem)");
}); });
test("mega menu gives the pointer time to cross from its trigger into a floating panel", () => {
const source = readFileSync(uiComponentPath("MegaMenu"), "utf8");
expect(source).toContain("state closeTimer = null");
expect(source).toContain("@mouseleave='scheduleHide()'");
expect(source).toContain("@mouseenter='cancelScheduledHide()'");
expect(source).toContain("}, 220)");
expect(source).not.toContain('@mouseleave=\'hidePanel("pointer-leave")\'');
});
test("navbar pins full-width mega panels to desktop viewport gutters", () => { test("navbar pins full-width mega panels to desktop viewport gutters", () => {
const source = readFileSync(uiComponentPath("Navbar"), "utf8"); const source = readFileSync(uiComponentPath("Navbar"), "utf8");
expect(source).toMatch(/\.wrn-navbar__mega\[data-full-width="true"\] \.wrn-mega__panel \{[^}]*position: fixed/s); expect(source).toMatch(/\.wrn-navbar__mega\[data-full-width="true"\] \.wrn-mega__panel \{[^}]*position: fixed/s);