fix(ui): keep mega menu open across hover gap
This commit is contained in:
@@ -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:*",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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,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",
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user