@brandocms/jupiter 4.0.0-beta.1 → 4.0.0-beta.2
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/README.md +191 -2
- package/package.json +20 -18
- package/src/index.js +10 -10
- package/src/modules/Application/index.js +203 -157
- package/src/modules/Cookies/index.js +34 -55
- package/src/modules/CoverOverlay/index.js +20 -13
- package/src/modules/Dataloader/index.js +71 -24
- package/src/modules/Dataloader/url-sync.js +238 -0
- package/src/modules/Dom/index.js +18 -0
- package/src/modules/DoubleHeader/index.js +571 -0
- package/src/modules/Dropdown/index.js +101 -75
- package/src/modules/EqualHeightElements/index.js +5 -7
- package/src/modules/EqualHeightImages/index.js +7 -2
- package/src/modules/FixedHeader/index.js +60 -30
- package/src/modules/FooterReveal/index.js +3 -3
- package/src/modules/HeroSlider/index.js +207 -91
- package/src/modules/HeroVideo/index.js +15 -27
- package/src/modules/Lazyload/index.js +101 -80
- package/src/modules/Lightbox/index.js +17 -55
- package/src/modules/Links/index.js +54 -49
- package/src/modules/Looper/index.js +1737 -0
- package/src/modules/Marquee/index.js +106 -37
- package/src/modules/MobileMenu/index.js +70 -124
- package/src/modules/Moonwalk/index.js +349 -150
- package/src/modules/Popover/index.js +186 -28
- package/src/modules/Popup/index.js +27 -34
- package/src/modules/StackedBoxes/index.js +3 -3
- package/src/modules/StickyHeader/index.js +364 -155
- package/src/modules/Toggler/index.js +184 -27
- package/src/utils/motion-helpers.js +330 -0
- package/types/index.d.ts +1 -30
- package/types/modules/Application/index.d.ts +6 -6
- package/types/modules/Breakpoints/index.d.ts +2 -0
- package/types/modules/Dataloader/index.d.ts +5 -2
- package/types/modules/Dataloader/url-sync.d.ts +36 -0
- package/types/modules/Dom/index.d.ts +7 -0
- package/types/modules/DoubleHeader/index.d.ts +63 -0
- package/types/modules/Dropdown/index.d.ts +7 -30
- package/types/modules/EqualHeightImages/index.d.ts +1 -1
- package/types/modules/FixedHeader/index.d.ts +1 -1
- package/types/modules/Lazyload/index.d.ts +9 -9
- package/types/modules/Lightbox/index.d.ts +0 -5
- package/types/modules/Looper/index.d.ts +127 -0
- package/types/modules/Moonwalk/index.d.ts +6 -15
- package/types/modules/Parallax/index.d.ts +10 -32
- package/types/modules/Popover/index.d.ts +12 -0
- package/types/modules/Popup/index.d.ts +6 -19
- package/types/modules/ScrollSpy/index.d.ts +1 -1
- package/types/modules/StickyHeader/index.d.ts +171 -14
- package/types/modules/Toggler/index.d.ts +24 -2
|
@@ -1,8 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { animate } from 'motion'
|
|
2
2
|
import Dom from '../Dom'
|
|
3
3
|
import _defaultsDeep from 'lodash.defaultsdeep'
|
|
4
|
+
import * as Events from '../../events'
|
|
4
5
|
|
|
5
|
-
const DEFAULT_OPTIONS = {
|
|
6
|
+
const DEFAULT_OPTIONS = {
|
|
7
|
+
clickToggle: false,
|
|
8
|
+
allowMultiple: false,
|
|
9
|
+
followTrigger: false,
|
|
10
|
+
followSpeed: 0.3,
|
|
11
|
+
onShow: null,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Static array to track active popovers
|
|
15
|
+
const activePopovers = []
|
|
6
16
|
|
|
7
17
|
export default class Popover {
|
|
8
18
|
constructor(app, trigger, opts = {}) {
|
|
@@ -13,10 +23,17 @@ export default class Popover {
|
|
|
13
23
|
this.position = this.trigger.getAttribute('data-popover-position') || 'top'
|
|
14
24
|
this.className = 'popover'
|
|
15
25
|
this.orderedPositions = ['top', 'right', 'bottom', 'left']
|
|
26
|
+
this.currentPosition = this.position
|
|
16
27
|
|
|
17
28
|
const popoverTemplate = document.querySelector(
|
|
18
29
|
`[data-popover-template=${trigger.dataset.popoverTarget}]`
|
|
19
30
|
)
|
|
31
|
+
|
|
32
|
+
if (!popoverTemplate) {
|
|
33
|
+
console.warn(`Popover template not found for trigger: ${trigger.dataset.popoverTarget}`)
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
|
|
20
37
|
this.popover = document.createElement('div')
|
|
21
38
|
this.popover.innerHTML = popoverTemplate.innerHTML
|
|
22
39
|
|
|
@@ -24,22 +41,31 @@ export default class Popover {
|
|
|
24
41
|
position: 'fixed',
|
|
25
42
|
})
|
|
26
43
|
|
|
44
|
+
// Add base popover class
|
|
27
45
|
this.popover.classList.add(this.className)
|
|
28
46
|
|
|
47
|
+
// Add any classes from the template element
|
|
48
|
+
if (popoverTemplate.classList && popoverTemplate.classList.length > 0) {
|
|
49
|
+
popoverTemplate.classList.forEach(className => {
|
|
50
|
+
if (className !== 'popover-template') {
|
|
51
|
+
this.popover.classList.add(className)
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Bind handlers
|
|
57
|
+
this.boundHandleDocumentClick = this.handleDocumentClick.bind(this)
|
|
58
|
+
this.boundHandleScroll = this.handleScroll.bind(this)
|
|
59
|
+
|
|
29
60
|
if (!app.featureTests.results.touch) {
|
|
30
|
-
this.
|
|
31
|
-
'
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
this.handleMouseLeave.bind(this)
|
|
37
|
-
)
|
|
61
|
+
if (this.opts.clickToggle) {
|
|
62
|
+
this.trigger.addEventListener('click', this.handleClick.bind(this))
|
|
63
|
+
} else {
|
|
64
|
+
this.trigger.addEventListener('mouseenter', this.handleMouseEnter.bind(this))
|
|
65
|
+
this.trigger.addEventListener('mouseleave', this.handleMouseLeave.bind(this))
|
|
66
|
+
}
|
|
38
67
|
} else {
|
|
39
|
-
this.trigger.addEventListener(
|
|
40
|
-
'touchstart',
|
|
41
|
-
this.handleTouchStart.bind(this)
|
|
42
|
-
)
|
|
68
|
+
this.trigger.addEventListener('touchstart', this.handleTouchStart.bind(this))
|
|
43
69
|
}
|
|
44
70
|
}
|
|
45
71
|
|
|
@@ -55,19 +81,61 @@ export default class Popover {
|
|
|
55
81
|
this.toggle()
|
|
56
82
|
}
|
|
57
83
|
|
|
84
|
+
handleClick(e) {
|
|
85
|
+
e.stopPropagation()
|
|
86
|
+
this.toggle()
|
|
87
|
+
}
|
|
88
|
+
|
|
58
89
|
get isVisible() {
|
|
59
90
|
return document.body.contains(this.popover)
|
|
60
91
|
}
|
|
61
92
|
|
|
62
93
|
show() {
|
|
94
|
+
// Close other popovers if not allowing multiple
|
|
95
|
+
if (!this.opts.allowMultiple) {
|
|
96
|
+
this.closeAllExcept(this)
|
|
97
|
+
}
|
|
98
|
+
|
|
63
99
|
document.body.appendChild(this.popover)
|
|
64
100
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
101
|
+
// Add to active popovers list
|
|
102
|
+
if (!activePopovers.includes(this)) {
|
|
103
|
+
activePopovers.push(this)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Calculate initial position
|
|
107
|
+
this.updatePosition(false)
|
|
108
|
+
|
|
109
|
+
// Setup document click handler for click outside closing
|
|
110
|
+
if (this.opts.clickToggle) {
|
|
111
|
+
this.addDocumentClickHandler()
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Setup scroll handler if followTrigger is enabled
|
|
115
|
+
if (this.opts.followTrigger) {
|
|
116
|
+
// Use requestAnimationFrame to ensure the popover is fully rendered
|
|
117
|
+
requestAnimationFrame(() => {
|
|
118
|
+
this.addScrollListener()
|
|
119
|
+
})
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Call onShow callback if provided
|
|
123
|
+
if (typeof this.opts.onShow === 'function') {
|
|
124
|
+
requestAnimationFrame(() => {
|
|
125
|
+
this.opts.onShow(this)
|
|
126
|
+
})
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Update popover position based on trigger position
|
|
131
|
+
updatePosition(shouldAnimate = true) {
|
|
132
|
+
const {
|
|
133
|
+
top: triggerTop,
|
|
134
|
+
left: triggerLeft,
|
|
135
|
+
width: triggerWidth,
|
|
136
|
+
height: triggerHeight,
|
|
137
|
+
} = this.trigger.getBoundingClientRect()
|
|
138
|
+
const { offsetHeight: popoverHeight, offsetWidth: popoverWidth } = this.popover
|
|
71
139
|
|
|
72
140
|
const positionIndex = this.orderedPositions.indexOf(this.position)
|
|
73
141
|
|
|
@@ -94,31 +162,77 @@ export default class Popover {
|
|
|
94
162
|
},
|
|
95
163
|
}
|
|
96
164
|
|
|
165
|
+
// Try to find a position that keeps the popover in viewport
|
|
97
166
|
const position = this.orderedPositions
|
|
98
167
|
.slice(positionIndex)
|
|
99
168
|
.concat(this.orderedPositions.slice(0, positionIndex))
|
|
100
|
-
.map(
|
|
101
|
-
.find(
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
169
|
+
.map(pos => positions[pos])
|
|
170
|
+
.find(pos => {
|
|
171
|
+
// Temporarily set position to check viewport
|
|
172
|
+
if (!shouldAnimate) {
|
|
173
|
+
this.popover.style.top = `${pos.top}px`
|
|
174
|
+
this.popover.style.left = `${pos.left}px`
|
|
175
|
+
}
|
|
176
|
+
return Dom.inViewportStrict(this.popover)
|
|
105
177
|
})
|
|
106
178
|
|
|
107
|
-
|
|
179
|
+
// Remove previous position classes
|
|
180
|
+
this.orderedPositions.forEach(pos => {
|
|
108
181
|
this.popover.classList.remove(`${this.className}--${pos}`)
|
|
109
182
|
})
|
|
110
183
|
|
|
184
|
+
// Set position and apply appropriate class
|
|
111
185
|
if (position) {
|
|
186
|
+
if (shouldAnimate && this.isVisible) {
|
|
187
|
+
animate(this.popover, {
|
|
188
|
+
top: Math.max(0, position.top),
|
|
189
|
+
left: Math.max(0, position.left)
|
|
190
|
+
}, {
|
|
191
|
+
duration: this.opts.followSpeed,
|
|
192
|
+
ease: 'easeOut'
|
|
193
|
+
})
|
|
194
|
+
} else if (!shouldAnimate) {
|
|
195
|
+
this.popover.style.top = `${Math.max(0, position.top)}px`
|
|
196
|
+
this.popover.style.left = `${Math.max(0, position.left)}px`
|
|
197
|
+
}
|
|
112
198
|
this.popover.classList.add(`${this.className}--${position.name}`)
|
|
199
|
+
this.currentPosition = position.name
|
|
113
200
|
} else {
|
|
114
|
-
|
|
115
|
-
this.
|
|
201
|
+
// Fallback to bottom if no position works
|
|
202
|
+
if (shouldAnimate && this.isVisible) {
|
|
203
|
+
animate(this.popover, {
|
|
204
|
+
top: Math.max(0, positions.bottom.top),
|
|
205
|
+
left: Math.max(0, positions.bottom.left)
|
|
206
|
+
}, {
|
|
207
|
+
duration: this.opts.followSpeed,
|
|
208
|
+
ease: 'easeOut'
|
|
209
|
+
})
|
|
210
|
+
} else if (!shouldAnimate) {
|
|
211
|
+
this.popover.style.top = `${Math.max(0, positions.bottom.top)}px`
|
|
212
|
+
this.popover.style.left = `${Math.max(0, positions.bottom.left)}px`
|
|
213
|
+
}
|
|
116
214
|
this.popover.classList.add(`${this.className}--bottom`)
|
|
215
|
+
this.currentPosition = 'bottom'
|
|
117
216
|
}
|
|
118
217
|
}
|
|
119
218
|
|
|
120
219
|
hide() {
|
|
121
220
|
this.popover.remove()
|
|
221
|
+
|
|
222
|
+
// Remove from active popovers
|
|
223
|
+
const index = activePopovers.indexOf(this)
|
|
224
|
+
if (index !== -1) {
|
|
225
|
+
activePopovers.splice(index, 1)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Remove handlers
|
|
229
|
+
if (this.opts.clickToggle) {
|
|
230
|
+
this.removeDocumentClickHandler()
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (this.opts.followTrigger) {
|
|
234
|
+
this.removeScrollListener()
|
|
235
|
+
}
|
|
122
236
|
}
|
|
123
237
|
|
|
124
238
|
toggle() {
|
|
@@ -128,4 +242,48 @@ export default class Popover {
|
|
|
128
242
|
this.show()
|
|
129
243
|
}
|
|
130
244
|
}
|
|
245
|
+
|
|
246
|
+
// Add document click handler to close popover when clicking outside
|
|
247
|
+
addDocumentClickHandler() {
|
|
248
|
+
document.addEventListener('click', this.boundHandleDocumentClick)
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Remove document click handler
|
|
252
|
+
removeDocumentClickHandler() {
|
|
253
|
+
document.removeEventListener('click', this.boundHandleDocumentClick)
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Handle clicks on document to close popover when clicking outside
|
|
257
|
+
handleDocumentClick(e) {
|
|
258
|
+
// If click is outside the popover and the trigger, close it
|
|
259
|
+
if (this.isVisible && !this.popover.contains(e.target) && !this.trigger.contains(e.target)) {
|
|
260
|
+
this.hide()
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Close all popovers except the specified one
|
|
265
|
+
closeAllExcept(exceptPopover) {
|
|
266
|
+
activePopovers.forEach(popover => {
|
|
267
|
+
if (popover !== exceptPopover) {
|
|
268
|
+
popover.hide()
|
|
269
|
+
}
|
|
270
|
+
})
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Handle scroll events to update popover position
|
|
274
|
+
handleScroll() {
|
|
275
|
+
if (this.isVisible) {
|
|
276
|
+
this.updatePosition(true)
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Add scroll event listener using APPLICATION:SCROLL event
|
|
281
|
+
addScrollListener() {
|
|
282
|
+
window.addEventListener(Events.APPLICATION_SCROLL, this.boundHandleScroll)
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Remove scroll event listener
|
|
286
|
+
removeScrollListener() {
|
|
287
|
+
window.removeEventListener(Events.APPLICATION_SCROLL, this.boundHandleScroll)
|
|
288
|
+
}
|
|
131
289
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { animate } from 'motion'
|
|
2
|
+
import { set } from '../../utils/motion-helpers'
|
|
2
3
|
import _defaultsDeep from 'lodash.defaultsdeep'
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -36,51 +37,41 @@ const DEFAULT_OPTIONS = {
|
|
|
36
37
|
onClose: () => {},
|
|
37
38
|
|
|
38
39
|
tweenIn: (trigger, target, popup) => {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
popup.backdrop.style.display = 'block'
|
|
41
|
+
animate(popup.backdrop, { opacity: 1 }, { duration: 0.3 })
|
|
42
|
+
.finished
|
|
43
|
+
.then(() => {
|
|
44
|
+
target.style.display = 'block'
|
|
45
|
+
animate(
|
|
45
46
|
target,
|
|
46
47
|
{
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
opacity: 0,
|
|
52
|
-
display: 'block',
|
|
48
|
+
transform: [
|
|
49
|
+
'translate(calc(-50% - 5px), -50%)',
|
|
50
|
+
'translate(-50%, -50%)'
|
|
51
|
+
],
|
|
52
|
+
opacity: [0, 1]
|
|
53
53
|
},
|
|
54
|
-
{
|
|
55
|
-
duration: 0.3,
|
|
56
|
-
yPercent: -50,
|
|
57
|
-
xPercent: -50,
|
|
58
|
-
x: 0,
|
|
59
|
-
opacity: 1,
|
|
60
|
-
}
|
|
54
|
+
{ duration: 0.3, ease: [0.4, 0, 0.2, 1] }
|
|
61
55
|
)
|
|
62
|
-
}
|
|
63
|
-
})
|
|
56
|
+
})
|
|
64
57
|
},
|
|
65
58
|
|
|
66
59
|
tweenOut: (popup) => {
|
|
67
60
|
console.log('default tweenOut')
|
|
68
61
|
const popupElement = popup.currentPopup
|
|
69
62
|
if (popupElement) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
63
|
+
animate(popupElement, { opacity: 0 }, { duration: 0.3 })
|
|
64
|
+
.finished
|
|
65
|
+
.then(() => {
|
|
66
|
+
popupElement.style.display = 'none'
|
|
67
|
+
})
|
|
75
68
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
onComplete: () => {
|
|
69
|
+
animate(popup.backdrop, { opacity: 0 }, { duration: 0.3 })
|
|
70
|
+
.finished
|
|
71
|
+
.then(() => {
|
|
80
72
|
// Remove the backdrop completely instead of just hiding it
|
|
81
73
|
popup.backdrop.remove()
|
|
82
|
-
}
|
|
83
|
-
})
|
|
74
|
+
})
|
|
84
75
|
},
|
|
85
76
|
}
|
|
86
77
|
|
|
@@ -189,7 +180,9 @@ export default class Popup {
|
|
|
189
180
|
if (key) {
|
|
190
181
|
backdrop.setAttribute('data-popup-key', key)
|
|
191
182
|
}
|
|
192
|
-
|
|
183
|
+
backdrop.style.display = 'none'
|
|
184
|
+
backdrop.style.zIndex = '4999'
|
|
185
|
+
set(backdrop, { opacity: 0 })
|
|
193
186
|
|
|
194
187
|
backdrop.addEventListener('click', (e) => {
|
|
195
188
|
e.stopPropagation()
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { set } from '../../utils/motion-helpers'
|
|
2
2
|
import _defaultsDeep from 'lodash.defaultsdeep'
|
|
3
3
|
|
|
4
4
|
const DEFAULT_OPTIONS = {}
|
|
@@ -62,10 +62,10 @@ export default class StackedBoxes {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
pull(box, amnt) {
|
|
65
|
-
|
|
65
|
+
set(box, { y: amnt * -1, marginBottom: amnt * -1 })
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
size(target, src) {
|
|
69
|
-
|
|
69
|
+
set(target, { height: src.clientHeight })
|
|
70
70
|
}
|
|
71
71
|
}
|