@brandocms/jupiter 3.54.2 → 3.54.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -25,15 +25,20 @@ const DEFAULT_OPTIONS = {
|
|
|
25
25
|
selectors: {
|
|
26
26
|
trigger: '[data-dropdown-trigger]',
|
|
27
27
|
menu: '[data-dropdown-menu]',
|
|
28
|
-
menuItems: '[data-dropdown-menu] > li'
|
|
28
|
+
menuItems: '[data-dropdown-menu] > li',
|
|
29
29
|
},
|
|
30
30
|
tweens: {
|
|
31
31
|
items: {
|
|
32
32
|
duration: 0.2,
|
|
33
33
|
autoAlpha: 0,
|
|
34
|
-
stagger: 0.03
|
|
35
|
-
}
|
|
36
|
-
}
|
|
34
|
+
stagger: 0.03,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
onBeforeOpen: async (dropdown) => {},
|
|
39
|
+
onAfterOpen: async (dropdown) => {},
|
|
40
|
+
onBeforeClose: async (dropdown) => {},
|
|
41
|
+
onAfterClose: async (dropdown) => {},
|
|
37
42
|
}
|
|
38
43
|
|
|
39
44
|
export default class Dropdown {
|
|
@@ -44,14 +49,25 @@ export default class Dropdown {
|
|
|
44
49
|
this.open = false
|
|
45
50
|
this.element = opts.el
|
|
46
51
|
this.timeline = gsap.timeline({ paused: true, reversed: true })
|
|
52
|
+
|
|
47
53
|
this.elements.trigger = Dom.find(this.element, this.opts.selectors.trigger)
|
|
48
54
|
if (this.elements.trigger.hasAttribute('data-dropdown-target')) {
|
|
49
|
-
const dropdownTarget = this.elements.trigger.getAttribute(
|
|
55
|
+
const dropdownTarget = this.elements.trigger.getAttribute(
|
|
56
|
+
'data-dropdown-target'
|
|
57
|
+
)
|
|
50
58
|
this.elements.menu = Dom.find(dropdownTarget)
|
|
51
59
|
} else {
|
|
52
60
|
this.elements.menu = Dom.find(this.element, this.opts.selectors.menu)
|
|
53
61
|
}
|
|
54
|
-
|
|
62
|
+
|
|
63
|
+
this.elements.menuItems = Dom.all(
|
|
64
|
+
this.elements.menu,
|
|
65
|
+
this.opts.selectors.menuItems
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
// Bind the document click handler to this instance
|
|
69
|
+
this.handleDocumentClick = this.handleDocumentClick.bind(this)
|
|
70
|
+
|
|
55
71
|
this.initialize()
|
|
56
72
|
this.checkForInitialOpen()
|
|
57
73
|
}
|
|
@@ -64,38 +80,60 @@ export default class Dropdown {
|
|
|
64
80
|
this.elements.menu,
|
|
65
81
|
{
|
|
66
82
|
className: `${this.elements.menu.className} zero-height`,
|
|
67
|
-
duration: 0.1
|
|
83
|
+
duration: 0.1,
|
|
68
84
|
},
|
|
69
|
-
|
|
70
85
|
'open'
|
|
71
86
|
)
|
|
72
87
|
.to(
|
|
73
88
|
this.elements.menu,
|
|
74
89
|
{
|
|
75
90
|
height: 'auto',
|
|
76
|
-
duration: 0.1
|
|
91
|
+
duration: 0.1,
|
|
77
92
|
},
|
|
78
93
|
'open'
|
|
79
94
|
)
|
|
80
95
|
.call(() => {
|
|
81
|
-
//
|
|
82
|
-
const
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
96
|
+
// Get current bounds and viewport dimensions
|
|
97
|
+
const menuRect = this.elements.menu.getBoundingClientRect()
|
|
98
|
+
const viewportHeight = window.innerHeight
|
|
99
|
+
const viewportWidth = window.innerWidth
|
|
100
|
+
const menuHeight = menuRect.height
|
|
101
|
+
const menuTop = menuRect.top
|
|
102
|
+
|
|
103
|
+
// Update CSS variable for height (if used in your styles)
|
|
104
|
+
Dom.setCSSVar(
|
|
105
|
+
'dropdown-menu-height',
|
|
106
|
+
`${menuHeight}px`,
|
|
107
|
+
this.elements.menu
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
// Vertical placement: if the menu overflows the bottom, set placement to "top"
|
|
111
|
+
if (menuHeight + menuTop > viewportHeight) {
|
|
91
112
|
this.elements.menu.setAttribute('data-dropdown-placement', 'top')
|
|
92
113
|
} else {
|
|
93
114
|
this.elements.menu.setAttribute('data-dropdown-placement', 'bottom')
|
|
94
115
|
}
|
|
116
|
+
|
|
117
|
+
// Horizontal check: adjust left offset if the menu is offscreen
|
|
118
|
+
const computedStyle = window.getComputedStyle(this.elements.menu)
|
|
119
|
+
let currentLeft = parseFloat(computedStyle.left) || 0
|
|
120
|
+
|
|
121
|
+
if (menuRect.left < 0) {
|
|
122
|
+
// Shift right by the amount it’s off the left edge
|
|
123
|
+
this.elements.menu.style.left = `${currentLeft - menuRect.left}px`
|
|
124
|
+
} else if (menuRect.right > viewportWidth) {
|
|
125
|
+
// Shift left by the amount it’s off the right edge
|
|
126
|
+
this.elements.menu.style.left = `${currentLeft - (menuRect.right - viewportWidth)}px`
|
|
127
|
+
}
|
|
95
128
|
})
|
|
96
129
|
.to(this.elements.menu, { opacity: 1 })
|
|
130
|
+
|
|
97
131
|
if (this.elements.menuItems.length) {
|
|
98
|
-
this.timeline.from(
|
|
132
|
+
this.timeline.from(
|
|
133
|
+
this.elements.menuItems,
|
|
134
|
+
this.opts.tweens.items,
|
|
135
|
+
'open+=.1'
|
|
136
|
+
)
|
|
99
137
|
}
|
|
100
138
|
|
|
101
139
|
if (!this.elements.trigger) {
|
|
@@ -104,18 +142,22 @@ export default class Dropdown {
|
|
|
104
142
|
this.elements.trigger.addEventListener('click', this.onClick.bind(this))
|
|
105
143
|
}
|
|
106
144
|
|
|
107
|
-
onClick(event) {
|
|
145
|
+
async onClick(event) {
|
|
108
146
|
event.preventDefault()
|
|
109
147
|
event.stopPropagation()
|
|
110
148
|
|
|
111
149
|
if (this.open) {
|
|
112
|
-
this.
|
|
150
|
+
await this.opts.onBeforeClose(this)
|
|
151
|
+
await this.closeMenu()
|
|
152
|
+
this.opts.onAfterClose(this)
|
|
113
153
|
} else {
|
|
114
|
-
this.
|
|
154
|
+
await this.opts.onBeforeOpen(this)
|
|
155
|
+
await this.openMenu()
|
|
156
|
+
this.opts.onAfterOpen(this)
|
|
115
157
|
}
|
|
116
158
|
}
|
|
117
159
|
|
|
118
|
-
openMenu() {
|
|
160
|
+
async openMenu() {
|
|
119
161
|
if (!this.opts.multipleActive) {
|
|
120
162
|
if (this.app.currentMenu) {
|
|
121
163
|
this.app.currentMenu.closeMenu()
|
|
@@ -125,22 +167,37 @@ export default class Dropdown {
|
|
|
125
167
|
this.open = true
|
|
126
168
|
this.elements.trigger.dataset.dropdownActive = ''
|
|
127
169
|
|
|
170
|
+
// Add document click listener when menu is open.
|
|
171
|
+
document.addEventListener('click', this.handleDocumentClick)
|
|
172
|
+
|
|
128
173
|
if (this.timeline.reversed()) {
|
|
129
|
-
this.timeline.play()
|
|
174
|
+
await this.timeline.play()
|
|
130
175
|
} else {
|
|
131
|
-
this.timeline.reverse()
|
|
176
|
+
await this.timeline.reverse()
|
|
132
177
|
}
|
|
133
178
|
}
|
|
134
179
|
|
|
135
|
-
closeMenu() {
|
|
180
|
+
async closeMenu() {
|
|
136
181
|
this.app.currentMenu = null
|
|
137
182
|
this.open = false
|
|
138
183
|
delete this.elements.trigger.dataset.dropdownActive
|
|
139
184
|
|
|
185
|
+
// Remove the document click listener when menu closes.
|
|
186
|
+
document.removeEventListener('click', this.handleDocumentClick)
|
|
187
|
+
|
|
140
188
|
if (this.timeline.reversed()) {
|
|
141
|
-
this.timeline.play()
|
|
189
|
+
await this.timeline.play()
|
|
142
190
|
} else {
|
|
143
|
-
this.timeline.reverse()
|
|
191
|
+
await this.timeline.reverse()
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Handler that checks if a click was outside the dropdown element.
|
|
196
|
+
handleDocumentClick(event) {
|
|
197
|
+
// If the click target is not inside the dropdown, close the menu.
|
|
198
|
+
if (!this.element.contains(event.target)) {
|
|
199
|
+
// this.closeMenu()
|
|
200
|
+
this.onClick(event)
|
|
144
201
|
}
|
|
145
202
|
}
|
|
146
203
|
|
|
@@ -52,6 +52,11 @@ const DEFAULT_OPTIONS = {
|
|
|
52
52
|
*/
|
|
53
53
|
clearMoonwalkOnAnchors: true,
|
|
54
54
|
|
|
55
|
+
/**
|
|
56
|
+
* If an element with moonwalk-run also has moonwalk-section, print a console warning
|
|
57
|
+
*/
|
|
58
|
+
warnRunWithSection: true,
|
|
59
|
+
|
|
55
60
|
/**
|
|
56
61
|
* Determines how early the IntersectionObserver triggers
|
|
57
62
|
*/
|
|
@@ -120,6 +125,17 @@ export default class Moonwalk {
|
|
|
120
125
|
.forEach((ms) => ms.removeAttribute('data-moonwalk'))
|
|
121
126
|
}
|
|
122
127
|
|
|
128
|
+
if (this.opts.warnRunWithSection) {
|
|
129
|
+
container
|
|
130
|
+
.querySelectorAll('[data-moonwalk-run][data-moonwalk-section]')
|
|
131
|
+
.forEach((ms) =>
|
|
132
|
+
console.warn(
|
|
133
|
+
'Element with moonwalk-run also has moonwalk-section. This may lead to rendering issues.',
|
|
134
|
+
ms
|
|
135
|
+
)
|
|
136
|
+
)
|
|
137
|
+
}
|
|
138
|
+
|
|
123
139
|
if (this.opts.clearMoonwalkOnAnchors) {
|
|
124
140
|
if (window.location.hash) {
|
|
125
141
|
this.walkToThisPoint(window.location.hash)
|