Skip to content

Commit

Permalink
fix: fix diagonal submenu problem
Browse files Browse the repository at this point in the history
  • Loading branch information
cuong-vuong-holistics committed Jul 29, 2024
1 parent b77c27b commit 987a347
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 15 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

## v5.2.2-holistics.2

### 🩹 Fixes

- Add `fixDiagonalSubmenuProblem` prop, fix [#916](https://github.com/Akryum/floating-vue/issues/916)

### ❤️ Contributors

- Cuong Vuong ([@cuong-vuong-holistics](https://github.com/cuong-vuong-holistics))

## v5.2.2-holistics.1

### 🚀 Performance Improvements
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
This fork has the `@holistics/floating-vue` package that tries to fix the following issues:

- **[Performance]** Disable toggling CSS class of `<body>`: this makes the entire page reflow whenever some floating elements are shown/all are hidden ([PR #1019](https://github.com/Akryum/floating-vue/pull/1019)). Can be re-enabled via `toggleBodyClass` prop.
- **[Fix]** Properly fix diagonal submenu problem ([#916](https://github.com/Akryum/floating-vue/issues/916)) via `fixDiagonalSubmenuProblem` prop

### 📦️ Versioning and syncing

Expand Down
1 change: 1 addition & 0 deletions packages/floating-vue/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
This fork has the `@holistics/floating-vue` package that tries to fix the following issues:

- **[Performance]** Disable toggling CSS class of `<body>`: this makes the entire page reflow whenever some floating elements are shown/all are hidden ([PR #1019](https://github.com/Akryum/floating-vue/pull/1019)). Can be re-enabled via `toggleBodyClass` prop.
- **[Fix]** Properly fix diagonal submenu problem ([#916](https://github.com/Akryum/floating-vue/issues/916)) via `fixDiagonalSubmenuProblem` prop

### 📦️ Versioning and syncing

Expand Down
2 changes: 1 addition & 1 deletion packages/floating-vue/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@holistics/floating-vue",
"version": "5.2.2-holistics.1",
"version": "5.2.2-holistics.2",
"description": "Holistics fork of Floating Vue - Easy Vue tooltips, dropdowns, menus & popovers using floating-ui",
"contributors": [
"Guillaume Chau <guillaume.b.chau@gmail.com>",
Expand Down
72 changes: 58 additions & 14 deletions packages/floating-vue/src/components/Popper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,17 @@ function defaultPropFactory (prop: string) {

const PROVIDE_KEY = '__floating-vue__popper'

function normalizeTriggers (
commonTriggers: string[],
customTriggers?: string[] | ((commonTriggers: string[]) => string[]),
) {
if (customTriggers != null) {
return typeof customTriggers === 'function' ? customTriggers(commonTriggers) : customTriggers
}

return commonTriggers
}

const createPopper = () => defineComponent({
name: 'VPopper',

Expand Down Expand Up @@ -282,6 +293,11 @@ const createPopper = () => defineComponent({
type: Boolean,
default: undefined,
},

fixDiagonalSubmenuProblem: {
type: [Boolean, Number],
default: undefined,
},
},

emits: {
Expand Down Expand Up @@ -362,7 +378,18 @@ const createPopper = () => defineComponent({
return this[PROVIDE_KEY]?.parentPopper
},

hasPopperShowTriggerHover () {
shouldFixDiagonalSubmenuProblem () {
return this.fixDiagonalSubmenuProblem === true || typeof this.fixDiagonalSubmenuProblem === 'number'
},

hasHoverableTrigger () {
if (this.shouldFixDiagonalSubmenuProblem) {
const showTriggers = normalizeTriggers(this.triggers, this.showTriggers)
const popperShowTriggers = normalizeTriggers(this.popperTriggers, this.popperShowTriggers)

return showTriggers.includes('hover') && popperShowTriggers.includes('hover')
}

return this.popperTriggers?.includes('hover') || this.popperShowTriggers?.includes('hover')
},
},
Expand Down Expand Up @@ -468,16 +495,24 @@ const createPopper = () => defineComponent({
}

// Abort if aiming for the popper
if (this.hasPopperShowTriggerHover && this.$_isAimingPopper()) {
if (this.hasHoverableTrigger && this.$_isAimingPopper()) {
if (this.parentPopper) {
this.parentPopper.lockedChild = this
clearTimeout(this.parentPopper.lockedChildTimer)

let timeout = 1000
if (this.fixDiagonalSubmenuProblem === true) {
timeout = 250
} else if (typeof this.fixDiagonalSubmenuProblem === 'number') {
timeout = this.fixDiagonalSubmenuProblem
}

this.parentPopper.lockedChildTimer = setTimeout(() => {
if (this.parentPopper.lockedChild === this) {
this.parentPopper.lockedChild.hide({ skipDelay })
this.parentPopper.lockedChild = null
}
}, 1000)
}, timeout)
}
return
}
Expand All @@ -492,6 +527,12 @@ const createPopper = () => defineComponent({
this.$emit('update:shown', false)
},

handlePopperNodeHovered () {
if (this.parentPopper?.lockedChild === this) {
this.parentPopper.lockedChild = null
}
},

init () {
if (!this.isDisposed) return
this.isDisposed = false
Expand Down Expand Up @@ -904,8 +945,17 @@ const createPopper = () => defineComponent({
!this.$_preventShow && this.show({ event })
}

this.$_registerTriggerListeners(this.$_targetNodes, SHOW_EVENT_MAP, this.triggers, this.showTriggers, handleShow)
this.$_registerTriggerListeners([this.$_popperNode], SHOW_EVENT_MAP, this.popperTriggers, this.popperShowTriggers, handleShow)
const showTriggers = normalizeTriggers(this.triggers, this.showTriggers)
const hideTriggers = normalizeTriggers(this.triggers, this.hideTriggers)
const popperShowTriggers = normalizeTriggers(this.popperTriggers, this.popperShowTriggers)
const popperHideTriggers = normalizeTriggers(this.popperTriggers, this.popperHideTriggers)

this.$_registerTriggerListeners(this.$_targetNodes, SHOW_EVENT_MAP, showTriggers, handleShow)
this.$_registerTriggerListeners([this.$_popperNode], SHOW_EVENT_MAP, popperShowTriggers, handleShow)

if (this.shouldFixDiagonalSubmenuProblem && this.hasHoverableTrigger) {
this.$_registerTriggerListeners([this.$_popperNode], SHOW_EVENT_MAP, popperShowTriggers, this.handlePopperNodeHovered)
}

// Add trigger hide events

Expand All @@ -916,8 +966,8 @@ const createPopper = () => defineComponent({
this.hide({ event })
}

this.$_registerTriggerListeners(this.$_targetNodes, HIDE_EVENT_MAP, this.triggers, this.hideTriggers, handleHide)
this.$_registerTriggerListeners([this.$_popperNode], HIDE_EVENT_MAP, this.popperTriggers, this.popperHideTriggers, handleHide)
this.$_registerTriggerListeners(this.$_targetNodes, HIDE_EVENT_MAP, hideTriggers, handleHide)
this.$_registerTriggerListeners([this.$_popperNode], HIDE_EVENT_MAP, popperHideTriggers, handleHide)
},

$_registerEventListeners (targetNodes: Element[], eventType: string, handler: (event: Event) => void) {
Expand All @@ -929,13 +979,7 @@ const createPopper = () => defineComponent({
: undefined))
},

$_registerTriggerListeners (targetNodes: Element[], eventMap: Record<string, string>, commonTriggers, customTrigger, handler: (event: Event) => void) {
let triggers = commonTriggers

if (customTrigger != null) {
triggers = typeof customTrigger === 'function' ? customTrigger(triggers) : customTrigger
}

$_registerTriggerListeners (targetNodes: Element[], eventMap: Record<string, string>, triggers: string[], handler: (event: Event) => void) {
triggers.forEach(trigger => {
const eventType = eventMap[trigger]
if (eventType) {
Expand Down
5 changes: 5 additions & 0 deletions packages/floating-vue/src/components/PopperWrapper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,11 @@ export default defineComponent({
type: Boolean,
default: undefined,
},
fixDiagonalSubmenuProblem: {
type: [Boolean, Number],
default: undefined,
},
},
emits: {
Expand Down

0 comments on commit 987a347

Please sign in to comment.