@brandocms/jupiter 3.55.0 → 4.0.0-beta.1
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 +318 -52
- package/package.json +26 -16
- package/src/index.js +5 -0
- package/src/modules/Application/index.js +36 -4
- package/src/modules/Breakpoints/index.js +116 -36
- package/src/modules/Cookies/index.js +67 -15
- package/src/modules/CoverOverlay/index.js +2 -2
- package/src/modules/Dom/index.js +6 -0
- package/src/modules/Dropdown/index.js +15 -6
- package/src/modules/EqualHeightElements/index.js +8 -6
- package/src/modules/EqualHeightImages/index.js +9 -6
- package/src/modules/FixedHeader/index.js +57 -1
- package/src/modules/FooterReveal/index.js +3 -3
- package/src/modules/HeroSlider/index.js +39 -30
- package/src/modules/HeroVideo/index.js +64 -24
- package/src/modules/Lazyload/index.js +27 -0
- package/src/modules/Lightbox/index.js +90 -31
- package/src/modules/Links/index.js +23 -2
- package/src/modules/MobileMenu/index.js +50 -21
- package/src/modules/Moonwalk/index.js +131 -4
- package/src/modules/Parallax/index.js +280 -57
- package/src/modules/Popover/index.js +28 -16
- package/src/modules/Popup/index.js +155 -29
- package/src/modules/ScrollSpy/index.js +21 -0
- package/src/modules/StackedBoxes/index.js +6 -4
- package/src/modules/StickyHeader/index.js +45 -24
- package/src/modules/Toggler/index.js +44 -5
- package/src/modules/Typography/index.js +33 -20
- package/types/README.md +159 -0
- package/types/events/index.d.ts +20 -0
- package/types/index.d.ts +35 -0
- package/types/modules/Application/index.d.ts +168 -0
- package/types/modules/Breakpoints/index.d.ts +38 -0
- package/types/modules/Cookies/index.d.ts +81 -0
- package/types/modules/CoverOverlay/index.d.ts +6 -0
- package/types/modules/Dataloader/index.d.ts +35 -0
- package/types/modules/Dom/index.d.ts +40 -0
- package/types/modules/Dropdown/index.d.ts +38 -0
- package/types/modules/EqualHeightElements/index.d.ts +8 -0
- package/types/modules/EqualHeightImages/index.d.ts +11 -0
- package/types/modules/FeatureTests/index.d.ts +27 -0
- package/types/modules/FixedHeader/index.d.ts +219 -0
- package/types/modules/Fontloader/index.d.ts +5 -0
- package/types/modules/FooterReveal/index.d.ts +5 -0
- package/types/modules/HeroSlider/index.d.ts +28 -0
- package/types/modules/HeroVideo/index.d.ts +83 -0
- package/types/modules/Lazyload/index.d.ts +80 -0
- package/types/modules/Lightbox/index.d.ts +128 -0
- package/types/modules/Links/index.d.ts +55 -0
- package/types/modules/Marquee/index.d.ts +23 -0
- package/types/modules/MobileMenu/index.d.ts +63 -0
- package/types/modules/Moonwalk/index.d.ts +331 -0
- package/types/modules/Parallax/index.d.ts +93 -0
- package/types/modules/Popover/index.d.ts +17 -0
- package/types/modules/Popup/index.d.ts +89 -0
- package/types/modules/ScrollSpy/index.d.ts +29 -0
- package/types/modules/StackedBoxes/index.d.ts +9 -0
- package/types/modules/StickyHeader/index.d.ts +63 -0
- package/types/modules/Toggler/index.d.ts +26 -0
- package/types/modules/Typography/index.d.ts +77 -0
- package/types/utils/dispatchElementEvent.d.ts +1 -0
- package/types/utils/imageIsLoaded.d.ts +1 -0
- package/types/utils/imagesAreLoaded.d.ts +1 -0
- package/types/utils/loadScript.d.ts +2 -0
- package/types/utils/prefersReducedMotion.d.ts +4 -0
- package/types/utils/rafCallback.d.ts +2 -0
- package/types/utils/zoom.d.ts +4 -0
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import _defaultsDeep from 'lodash.defaultsdeep'
|
|
2
2
|
import * as Events from '../../events'
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {Object} BreakpointsOptions
|
|
6
|
+
* @property {boolean} [runListenerOnInit=false] - Whether to run listener on initialization
|
|
7
|
+
* @property {string[]} [breakpoints=['xs', 'sm', 'md', 'lg']] - Breakpoint names
|
|
8
|
+
* @property {Object.<string, Function>} [listeners={}] - Listener functions for breakpoints
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** @type {BreakpointsOptions} */
|
|
4
12
|
const DEFAULT_OPTIONS = {
|
|
5
13
|
runListenerOnInit: false,
|
|
6
14
|
breakpoints: ['xs', 'sm', 'md', 'lg'],
|
|
@@ -13,14 +21,24 @@ const DEFAULT_OPTIONS = {
|
|
|
13
21
|
// // NOT XS ANYMORE
|
|
14
22
|
// }
|
|
15
23
|
// }
|
|
16
|
-
}
|
|
24
|
+
},
|
|
17
25
|
}
|
|
18
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Breakpoints module for responsive design
|
|
29
|
+
*/
|
|
19
30
|
export default class Breakpoints {
|
|
31
|
+
/**
|
|
32
|
+
* Create a new Breakpoints instance
|
|
33
|
+
* @param {Object} app - Application instance
|
|
34
|
+
* @param {BreakpointsOptions} [opts={}] - Breakpoints options
|
|
35
|
+
*/
|
|
20
36
|
constructor(app, opts = {}) {
|
|
21
37
|
this.app = app
|
|
22
38
|
this.mediaQueries = {}
|
|
23
39
|
this.opts = _defaultsDeep(opts, DEFAULT_OPTIONS)
|
|
40
|
+
this.currentBreakpoint = null
|
|
41
|
+
this.initialized = false
|
|
24
42
|
window.addEventListener(Events.APPLICATION_PRELUDIUM, () => {
|
|
25
43
|
this.initialize(false)
|
|
26
44
|
})
|
|
@@ -30,63 +48,125 @@ export default class Breakpoints {
|
|
|
30
48
|
}
|
|
31
49
|
|
|
32
50
|
initialize(reveal = false) {
|
|
33
|
-
|
|
34
|
-
this.
|
|
35
|
-
|
|
51
|
+
if (!reveal) {
|
|
52
|
+
this.opts.breakpoints.forEach((size) => {
|
|
53
|
+
this.mediaQueries[size] = this._getVal(`--breakpoint-${size}`)
|
|
54
|
+
})
|
|
36
55
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
|
|
56
|
+
const keys = Object.keys(this.mediaQueries)
|
|
57
|
+
keys.forEach((key) => {
|
|
58
|
+
let query = ''
|
|
59
|
+
const next = keys[(keys.indexOf(key) + 1) % keys.length]
|
|
60
|
+
if (
|
|
61
|
+
key === this.opts.breakpoints[0] &&
|
|
62
|
+
this.mediaQueries[key] === '0'
|
|
63
|
+
) {
|
|
64
|
+
query = `(min-width: 0px) and (max-width: ${parseInt(this.mediaQueries[next]) - 1}px)`
|
|
65
|
+
} else if (next === this.opts.breakpoints[0]) {
|
|
66
|
+
// max size
|
|
67
|
+
query = `(min-width: ${this.mediaQueries[key]})`
|
|
68
|
+
} else {
|
|
69
|
+
query = `(min-width: ${this.mediaQueries[key]}) and (max-width: ${
|
|
70
|
+
parseInt(this.mediaQueries[next]) - 1
|
|
71
|
+
}px)`
|
|
72
|
+
}
|
|
51
73
|
|
|
52
|
-
|
|
53
|
-
this.mediaQueries[key].addListener(this.defaultListener.bind(this))
|
|
74
|
+
this.mediaQueries[key] = window.matchMedia(query)
|
|
54
75
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
76
|
+
// Replace the direct listener with a combined one that handles both core and custom behavior
|
|
77
|
+
const combinedListener = (e) => {
|
|
78
|
+
if (e.matches) {
|
|
79
|
+
// Get the current breakpoint
|
|
80
|
+
const oldBreakpoint = this.currentBreakpoint
|
|
81
|
+
this.setCurrentBreakpoint()
|
|
59
82
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
83
|
+
// Only dispatch event if breakpoint actually changed
|
|
84
|
+
if (oldBreakpoint !== this.currentBreakpoint) {
|
|
85
|
+
const evt = new CustomEvent(Events.BREAKPOINT_CHANGE, {
|
|
86
|
+
detail: {
|
|
87
|
+
leaveBreakpoint: oldBreakpoint,
|
|
88
|
+
enterBreakpoint: this.currentBreakpoint,
|
|
89
|
+
},
|
|
90
|
+
})
|
|
91
|
+
window.dispatchEvent(evt)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Run any custom listener if one exists for this breakpoint
|
|
96
|
+
if (Object.prototype.hasOwnProperty.call(this.opts.listeners, key)) {
|
|
97
|
+
this.opts.listeners[key](e)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
this.mediaQueries[key].addListener(combinedListener)
|
|
102
|
+
})
|
|
65
103
|
}
|
|
66
104
|
|
|
105
|
+
// Set the current breakpoint first
|
|
67
106
|
this.setCurrentBreakpoint()
|
|
107
|
+
|
|
108
|
+
// Only fire events and run listeners for initialization if needed
|
|
109
|
+
if (reveal && this.opts.runListenerOnInit && !this.initialized) {
|
|
110
|
+
this.initialized = true
|
|
111
|
+
const result = this.getCurrentBreakpoint()
|
|
112
|
+
|
|
113
|
+
if (result && result.key && result.mq) {
|
|
114
|
+
// Create a fake event object that mimics MediaQueryListEvent
|
|
115
|
+
const fakeEvent = {
|
|
116
|
+
matches: result.mq.matches,
|
|
117
|
+
media: result.mq.media,
|
|
118
|
+
target: result.mq,
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Fire the BREAKPOINT_CHANGE event only once during initialization
|
|
122
|
+
const evt = new CustomEvent(Events.BREAKPOINT_CHANGE)
|
|
123
|
+
window.dispatchEvent(evt)
|
|
124
|
+
|
|
125
|
+
// Run any custom listener if one exists for this breakpoint
|
|
126
|
+
if (
|
|
127
|
+
Object.prototype.hasOwnProperty.call(this.opts.listeners, result.key)
|
|
128
|
+
) {
|
|
129
|
+
this.opts.listeners[result.key](fakeEvent)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
68
133
|
}
|
|
69
134
|
|
|
70
135
|
getCurrentBreakpoint() {
|
|
71
|
-
|
|
136
|
+
// First check if mediaQueries is populated
|
|
137
|
+
if (!Object.keys(this.mediaQueries).length) {
|
|
138
|
+
return null
|
|
139
|
+
}
|
|
72
140
|
|
|
73
|
-
|
|
141
|
+
const key = Object.keys(this.mediaQueries).find((q) => {
|
|
142
|
+
return this.mediaQueries[q] && this.mediaQueries[q].matches
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
// Only return if we found a matching breakpoint
|
|
146
|
+
if (key && this.mediaQueries[key]) {
|
|
147
|
+
return { key, mq: this.mediaQueries[key] }
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return null
|
|
74
151
|
}
|
|
75
152
|
|
|
76
153
|
defaultListener(e) {
|
|
77
154
|
if (e.matches) {
|
|
78
155
|
this.setCurrentBreakpoint()
|
|
79
156
|
}
|
|
80
|
-
const evt = new CustomEvent(Events.BREAKPOINT_CHANGE)
|
|
81
|
-
window.dispatchEvent(evt)
|
|
82
157
|
}
|
|
83
158
|
|
|
84
159
|
setCurrentBreakpoint() {
|
|
85
|
-
const
|
|
86
|
-
|
|
160
|
+
const result = this.getCurrentBreakpoint()
|
|
161
|
+
if (result && result.key) {
|
|
162
|
+
this.currentBreakpoint = result.key
|
|
163
|
+
this.app.breakpoint = result.key
|
|
164
|
+
}
|
|
87
165
|
}
|
|
88
166
|
|
|
89
167
|
_getVal(key) {
|
|
90
|
-
return getComputedStyle(document.documentElement)
|
|
168
|
+
return getComputedStyle(document.documentElement)
|
|
169
|
+
.getPropertyValue(key)
|
|
170
|
+
.trim()
|
|
91
171
|
}
|
|
92
172
|
}
|
|
@@ -1,9 +1,20 @@
|
|
|
1
|
-
import { gsap } from 'gsap'
|
|
1
|
+
import { gsap } from 'gsap/all'
|
|
2
2
|
import _defaultsDeep from 'lodash.defaultsdeep'
|
|
3
3
|
import * as Events from '../../events'
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {Object} CookiesOptions
|
|
7
|
+
* @property {Function} [onAccept] - Called when cookies are accepted
|
|
8
|
+
* @property {Function} [onRefuse] - Called when cookies are refused
|
|
9
|
+
* @property {Function} [alreadyConsented] - Called if user has already consented to cookies
|
|
10
|
+
* @property {Function} [alreadyRefused] - Called if user has already refused cookies
|
|
11
|
+
* @property {Function} [setCookies] - Custom function to set cookies
|
|
12
|
+
* @property {Function} [showCC] - Custom function to display cookie consent dialog
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/** @type {CookiesOptions} */
|
|
5
16
|
const DEFAULT_OPTIONS = {
|
|
6
|
-
onAccept: c => {
|
|
17
|
+
onAccept: (c) => {
|
|
7
18
|
const oneYearFromNow = new Date()
|
|
8
19
|
oneYearFromNow.setFullYear(oneYearFromNow.getFullYear() + 1)
|
|
9
20
|
|
|
@@ -17,7 +28,7 @@ const DEFAULT_OPTIONS = {
|
|
|
17
28
|
.set(c.cc, { display: 'none' })
|
|
18
29
|
},
|
|
19
30
|
|
|
20
|
-
onRefuse: c => {
|
|
31
|
+
onRefuse: (c) => {
|
|
21
32
|
const oneYearFromNow = new Date()
|
|
22
33
|
oneYearFromNow.setFullYear(oneYearFromNow.getFullYear() + 1)
|
|
23
34
|
|
|
@@ -30,17 +41,17 @@ const DEFAULT_OPTIONS = {
|
|
|
30
41
|
.set(c.cc, { display: 'none' })
|
|
31
42
|
},
|
|
32
43
|
|
|
33
|
-
alreadyConsented: c => {
|
|
44
|
+
alreadyConsented: (c) => {
|
|
34
45
|
// user has already consented to cookies. Can be used to update/load gtm etc.
|
|
35
46
|
},
|
|
36
47
|
|
|
37
|
-
alreadyRefused: c => {
|
|
48
|
+
alreadyRefused: (c) => {
|
|
38
49
|
// user has already refused cookies.
|
|
39
50
|
},
|
|
40
51
|
|
|
41
|
-
setCookies: c => {},
|
|
52
|
+
setCookies: (c) => {},
|
|
42
53
|
|
|
43
|
-
showCC: c => {
|
|
54
|
+
showCC: (c) => {
|
|
44
55
|
if (c.hasCookie('COOKIES_CONSENT_STATUS')) {
|
|
45
56
|
if (c.getCookie('COOKIES_CONSENT_STATUS') === '1') {
|
|
46
57
|
c.opts.alreadyConsented(c)
|
|
@@ -58,13 +69,13 @@ const DEFAULT_OPTIONS = {
|
|
|
58
69
|
{
|
|
59
70
|
duration: 0.5,
|
|
60
71
|
y: '120%',
|
|
61
|
-
display: 'block'
|
|
72
|
+
display: 'block',
|
|
62
73
|
},
|
|
63
74
|
{
|
|
64
75
|
duration: 0.5,
|
|
65
76
|
y: '0%',
|
|
66
77
|
delay: '0.5',
|
|
67
|
-
ease: 'power3.out'
|
|
78
|
+
ease: 'power3.out',
|
|
68
79
|
},
|
|
69
80
|
'0.5'
|
|
70
81
|
)
|
|
@@ -72,12 +83,12 @@ const DEFAULT_OPTIONS = {
|
|
|
72
83
|
c.text,
|
|
73
84
|
{
|
|
74
85
|
duration: 0.7,
|
|
75
|
-
opacity: 0
|
|
86
|
+
opacity: 0,
|
|
76
87
|
},
|
|
77
88
|
{
|
|
78
89
|
duration: 0.7,
|
|
79
90
|
opacity: 1,
|
|
80
|
-
ease: 'power3.out'
|
|
91
|
+
ease: 'power3.out',
|
|
81
92
|
},
|
|
82
93
|
'-=0.35'
|
|
83
94
|
)
|
|
@@ -85,19 +96,27 @@ const DEFAULT_OPTIONS = {
|
|
|
85
96
|
c.btns,
|
|
86
97
|
{
|
|
87
98
|
duration: 0.7,
|
|
88
|
-
opacity: 0
|
|
99
|
+
opacity: 0,
|
|
89
100
|
},
|
|
90
101
|
{
|
|
91
102
|
duration: 0.7,
|
|
92
103
|
opacity: 1,
|
|
93
|
-
ease: 'power3.out'
|
|
104
|
+
ease: 'power3.out',
|
|
94
105
|
},
|
|
95
106
|
'-=0.35'
|
|
96
107
|
)
|
|
97
|
-
}
|
|
108
|
+
},
|
|
98
109
|
}
|
|
99
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Cookies module for handling cookie consent
|
|
113
|
+
*/
|
|
100
114
|
export default class Cookies {
|
|
115
|
+
/**
|
|
116
|
+
* Create a new Cookies instance
|
|
117
|
+
* @param {Object} app - Application instance
|
|
118
|
+
* @param {CookiesOptions} [opts={}] - Cookies options
|
|
119
|
+
*/
|
|
101
120
|
constructor(app, opts = {}) {
|
|
102
121
|
this.app = app
|
|
103
122
|
this.opts = _defaultsDeep(opts, DEFAULT_OPTIONS)
|
|
@@ -127,6 +146,11 @@ export default class Cookies {
|
|
|
127
146
|
}
|
|
128
147
|
}
|
|
129
148
|
|
|
149
|
+
/**
|
|
150
|
+
* Get a cookie value by key
|
|
151
|
+
* @param {string} sKey - Cookie key
|
|
152
|
+
* @returns {string|null} Cookie value or null if not found
|
|
153
|
+
*/
|
|
130
154
|
getCookie(sKey) {
|
|
131
155
|
if (!sKey) {
|
|
132
156
|
return null
|
|
@@ -146,6 +170,16 @@ export default class Cookies {
|
|
|
146
170
|
)
|
|
147
171
|
}
|
|
148
172
|
|
|
173
|
+
/**
|
|
174
|
+
* Set a cookie
|
|
175
|
+
* @param {string} sKey - Cookie key
|
|
176
|
+
* @param {string|number} sValue - Cookie value
|
|
177
|
+
* @param {Date|string|number} vEnd - Expiration date, string date, or max age in seconds
|
|
178
|
+
* @param {string} [sPath] - Cookie path
|
|
179
|
+
* @param {string} [sDomain] - Cookie domain
|
|
180
|
+
* @param {boolean} [bSecure] - Secure flag
|
|
181
|
+
* @returns {boolean} Whether cookie was set successfully
|
|
182
|
+
*/
|
|
149
183
|
setCookie(sKey, sValue, vEnd, sPath, sDomain, bSecure) {
|
|
150
184
|
if (!sKey || /^(?:expires|max-age|path|domain|secure)$/i.test(sKey)) {
|
|
151
185
|
return false
|
|
@@ -155,7 +189,9 @@ export default class Cookies {
|
|
|
155
189
|
switch (vEnd.constructor) {
|
|
156
190
|
case Number:
|
|
157
191
|
sExpires =
|
|
158
|
-
vEnd === Infinity
|
|
192
|
+
vEnd === Infinity
|
|
193
|
+
? '; expires=Fri, 31 Dec 9999 23:59:59 GMT'
|
|
194
|
+
: `; max-age=${vEnd}`
|
|
159
195
|
break
|
|
160
196
|
case String:
|
|
161
197
|
sExpires = `; expires=${vEnd}`
|
|
@@ -173,6 +209,13 @@ export default class Cookies {
|
|
|
173
209
|
return true
|
|
174
210
|
}
|
|
175
211
|
|
|
212
|
+
/**
|
|
213
|
+
* Remove a cookie
|
|
214
|
+
* @param {string} sKey - Cookie key
|
|
215
|
+
* @param {string} [sPath] - Cookie path
|
|
216
|
+
* @param {string} [sDomain] - Cookie domain
|
|
217
|
+
* @returns {boolean} Whether cookie was removed successfully
|
|
218
|
+
*/
|
|
176
219
|
removeCookie(sKey, sPath, sDomain) {
|
|
177
220
|
if (!this.hasCookie(sKey)) {
|
|
178
221
|
return false
|
|
@@ -183,6 +226,11 @@ export default class Cookies {
|
|
|
183
226
|
return true
|
|
184
227
|
}
|
|
185
228
|
|
|
229
|
+
/**
|
|
230
|
+
* Check if a cookie exists
|
|
231
|
+
* @param {string} sKey - Cookie key
|
|
232
|
+
* @returns {boolean} Whether cookie exists
|
|
233
|
+
*/
|
|
186
234
|
hasCookie(sKey) {
|
|
187
235
|
if (!sKey || /^(?:expires|max-age|path|domain|secure)$/i.test(sKey)) {
|
|
188
236
|
return false
|
|
@@ -192,6 +240,10 @@ export default class Cookies {
|
|
|
192
240
|
).test(document.cookie)
|
|
193
241
|
}
|
|
194
242
|
|
|
243
|
+
/**
|
|
244
|
+
* Get all cookie keys
|
|
245
|
+
* @returns {string[]} Array of cookie keys
|
|
246
|
+
*/
|
|
195
247
|
keys() {
|
|
196
248
|
const aKeys = document.cookie
|
|
197
249
|
.replace(/((?:^|\s*;)[^=]+)(?=;|$)|^\s*|\s*(?:=[^;]*)?(?:\1|$)/g, '')
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { gsap } from 'gsap'
|
|
1
|
+
import { gsap } from 'gsap/all'
|
|
2
2
|
import _defaultsDeep from 'lodash.defaultsdeep'
|
|
3
3
|
|
|
4
4
|
const DEFAULT_OPTIONS = {}
|
|
@@ -13,7 +13,7 @@ export default class CoverOverlay {
|
|
|
13
13
|
initialize() {
|
|
14
14
|
const coveredModules = document.querySelectorAll('[data-cover-overlay]')
|
|
15
15
|
|
|
16
|
-
Array.from(coveredModules).forEach(v => {
|
|
16
|
+
Array.from(coveredModules).forEach((v) => {
|
|
17
17
|
let player
|
|
18
18
|
const overlay = v.querySelector('.picture-wrapper')
|
|
19
19
|
const btn = v.querySelector('[data-cover-overlay-button]')
|
package/src/modules/Dom/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { gsap } from 'gsap'
|
|
1
|
+
import { gsap } from 'gsap/all'
|
|
2
2
|
import _defaultsDeep from 'lodash.defaultsdeep'
|
|
3
3
|
import Dom from '../Dom'
|
|
4
4
|
|
|
@@ -27,6 +27,8 @@ const DEFAULT_OPTIONS = {
|
|
|
27
27
|
menu: '[data-dropdown-menu]',
|
|
28
28
|
menuItems: '[data-dropdown-menu] > li',
|
|
29
29
|
},
|
|
30
|
+
overlapTweens: true,
|
|
31
|
+
menuOpenDuration: 0.1,
|
|
30
32
|
tweens: {
|
|
31
33
|
items: {
|
|
32
34
|
duration: 0.2,
|
|
@@ -80,7 +82,7 @@ export default class Dropdown {
|
|
|
80
82
|
this.elements.menu,
|
|
81
83
|
{
|
|
82
84
|
className: `${this.elements.menu.className} zero-height`,
|
|
83
|
-
duration: 0.
|
|
85
|
+
duration: 0.05,
|
|
84
86
|
},
|
|
85
87
|
'open'
|
|
86
88
|
)
|
|
@@ -88,7 +90,7 @@ export default class Dropdown {
|
|
|
88
90
|
this.elements.menu,
|
|
89
91
|
{
|
|
90
92
|
height: 'auto',
|
|
91
|
-
duration: 0.
|
|
93
|
+
duration: 0.05,
|
|
92
94
|
},
|
|
93
95
|
'open'
|
|
94
96
|
)
|
|
@@ -126,13 +128,16 @@ export default class Dropdown {
|
|
|
126
128
|
this.elements.menu.style.left = `${currentLeft - (menuRect.right - viewportWidth)}px`
|
|
127
129
|
}
|
|
128
130
|
})
|
|
129
|
-
.to(this.elements.menu, {
|
|
131
|
+
.to(this.elements.menu, {
|
|
132
|
+
opacity: 1,
|
|
133
|
+
duration: this.opts.menuOpenDuration,
|
|
134
|
+
})
|
|
130
135
|
|
|
131
136
|
if (this.elements.menuItems.length) {
|
|
132
137
|
this.timeline.from(
|
|
133
138
|
this.elements.menuItems,
|
|
134
139
|
this.opts.tweens.items,
|
|
135
|
-
|
|
140
|
+
`open+=${this.opts.menuOpenDuration}`
|
|
136
141
|
)
|
|
137
142
|
}
|
|
138
143
|
|
|
@@ -160,7 +165,11 @@ export default class Dropdown {
|
|
|
160
165
|
async openMenu() {
|
|
161
166
|
if (!this.opts.multipleActive) {
|
|
162
167
|
if (this.app.currentMenu) {
|
|
163
|
-
this.
|
|
168
|
+
if (this.opts.overlapTweens) {
|
|
169
|
+
this.app.currentMenu.closeMenu()
|
|
170
|
+
} else {
|
|
171
|
+
await this.app.currentMenu.closeMenu()
|
|
172
|
+
}
|
|
164
173
|
}
|
|
165
174
|
this.app.currentMenu = this
|
|
166
175
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { gsap } from 'gsap'
|
|
1
|
+
import { gsap } from 'gsap/all'
|
|
2
2
|
import Dom from '../Dom'
|
|
3
3
|
import _defaultsDeep from 'lodash.defaultsdeep'
|
|
4
4
|
import * as Events from '../../events'
|
|
@@ -13,21 +13,23 @@ export default class EqualHeightElements {
|
|
|
13
13
|
this.selector = selector
|
|
14
14
|
this.initialize()
|
|
15
15
|
window.addEventListener(Events.APPLICATION_RESIZE, () => {
|
|
16
|
-
gsap.set('[data-eq-height-elements-adjusted]', {
|
|
16
|
+
gsap.set('[data-eq-height-elements-adjusted]', {
|
|
17
|
+
clearProps: 'minHeight',
|
|
18
|
+
})
|
|
17
19
|
this.initialize()
|
|
18
20
|
})
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
initialize() {
|
|
22
24
|
const canvases = Dom.all(this.container, '[data-eq-height-elements]')
|
|
23
|
-
Array.from(canvases).forEach(canvas => {
|
|
25
|
+
Array.from(canvases).forEach((canvas) => {
|
|
24
26
|
let lastTop = null
|
|
25
27
|
const actionables = []
|
|
26
28
|
let elements = []
|
|
27
29
|
let height = 0
|
|
28
30
|
const eqElements = Dom.all(canvas, this.selector)
|
|
29
31
|
|
|
30
|
-
eqElements.forEach(el => {
|
|
32
|
+
eqElements.forEach((el) => {
|
|
31
33
|
const rect = el.getBoundingClientRect()
|
|
32
34
|
|
|
33
35
|
if (lastTop === null) {
|
|
@@ -58,10 +60,10 @@ export default class EqualHeightElements {
|
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
if (actionables.length) {
|
|
61
|
-
actionables.forEach(a => {
|
|
63
|
+
actionables.forEach((a) => {
|
|
62
64
|
gsap.set(a.elements, {
|
|
63
65
|
minHeight: a.height,
|
|
64
|
-
attr: { 'data-eq-height-elements-adjusted': true }
|
|
66
|
+
attr: { 'data-eq-height-elements-adjusted': true },
|
|
65
67
|
})
|
|
66
68
|
})
|
|
67
69
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { gsap } from 'gsap'
|
|
1
|
+
import { gsap } from 'gsap/all'
|
|
2
2
|
import Dom from '../Dom'
|
|
3
3
|
import * as Events from '../../events'
|
|
4
4
|
import imagesAreLoaded from '../../utils/imagesAreLoaded'
|
|
5
5
|
import _defaultsDeep from 'lodash.defaultsdeep'
|
|
6
6
|
|
|
7
7
|
const DEFAULT_OPTIONS = {
|
|
8
|
-
listenForResize: true
|
|
8
|
+
listenForResize: true,
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export default class EqualHeightImages {
|
|
@@ -23,7 +23,7 @@ export default class EqualHeightImages {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
run() {
|
|
26
|
-
Array.from(this.canvases).forEach(canvas => {
|
|
26
|
+
Array.from(this.canvases).forEach((canvas) => {
|
|
27
27
|
let lastTop = null
|
|
28
28
|
const actionables = []
|
|
29
29
|
let elements = []
|
|
@@ -31,7 +31,7 @@ export default class EqualHeightImages {
|
|
|
31
31
|
const imgs = Dom.all(canvas, 'img')
|
|
32
32
|
|
|
33
33
|
imagesAreLoaded(imgs, false).then(() => {
|
|
34
|
-
imgs.forEach(el => {
|
|
34
|
+
imgs.forEach((el) => {
|
|
35
35
|
const rect = el.getBoundingClientRect()
|
|
36
36
|
const size = this.getImgSizeInfo(el)
|
|
37
37
|
|
|
@@ -62,7 +62,7 @@ export default class EqualHeightImages {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
if (actionables.length) {
|
|
65
|
-
actionables.forEach(a => {
|
|
65
|
+
actionables.forEach((a) => {
|
|
66
66
|
gsap.set(a.elements, { minHeight: a.height })
|
|
67
67
|
})
|
|
68
68
|
}
|
|
@@ -94,7 +94,10 @@ export default class EqualHeightImages {
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
getImgSizeInfo(img) {
|
|
97
|
-
const pos = window
|
|
97
|
+
const pos = window
|
|
98
|
+
.getComputedStyle(img)
|
|
99
|
+
.getPropertyValue('object-position')
|
|
100
|
+
.split(' ')
|
|
98
101
|
|
|
99
102
|
return this.getRenderedSize(
|
|
100
103
|
true,
|
|
@@ -23,11 +23,58 @@
|
|
|
23
23
|
*
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
import { gsap } from 'gsap'
|
|
26
|
+
import { gsap } from 'gsap/all'
|
|
27
27
|
import _defaultsDeep from 'lodash.defaultsdeep'
|
|
28
28
|
import * as Events from '../../events'
|
|
29
29
|
import Dom from '../Dom'
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* @typedef {Object} FixedHeaderEvents
|
|
33
|
+
* @property {Function} [onPin] - Called when header is pinned
|
|
34
|
+
* @property {Function} [onUnpin] - Called when header is unpinned
|
|
35
|
+
* @property {Function} [onAltBg] - Called when alternate background is applied
|
|
36
|
+
* @property {Function} [onNotAltBg] - Called when regular background is applied
|
|
37
|
+
* @property {Function} [onSmall] - Called when header becomes small
|
|
38
|
+
* @property {Function} [onNotSmall] - Called when header becomes normal size
|
|
39
|
+
* @property {Function} [onTop] - Called when page is at the top
|
|
40
|
+
* @property {Function} [onNotTop] - Called when page is not at the top
|
|
41
|
+
* @property {Function} [onBottom] - Called when page is at the bottom
|
|
42
|
+
* @property {Function} [onNotBottom] - Called when page is not at the bottom
|
|
43
|
+
* @property {Function} [onMobileMenuOpen] - Called when mobile menu opens
|
|
44
|
+
* @property {Function} [onMobileMenuClose] - Called when mobile menu closes
|
|
45
|
+
* @property {Function} [onIntersect] - Called when header intersects with an element
|
|
46
|
+
* @property {Function} [onOutline] - Called when user tabs (outline mode)
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @typedef {Object} FixedHeaderSectionOptions
|
|
51
|
+
* @property {boolean} [unPinOnResize=true] - Whether to unpin header on window resize
|
|
52
|
+
* @property {Window|HTMLElement} [canvas=window] - Scrolling element
|
|
53
|
+
* @property {string|null} [intersects=null] - Selector for elements to check intersection with
|
|
54
|
+
* @property {Function} [beforeEnter] - Called before header enters
|
|
55
|
+
* @property {Function} [enter] - Called when header enters
|
|
56
|
+
* @property {number} [enterDelay=0] - Delay before enter animation
|
|
57
|
+
* @property {number} [tolerance=3] - Scroll tolerance before triggering hide/show
|
|
58
|
+
* @property {number|string|Function} [offset=0] - Offset from top before triggering hide
|
|
59
|
+
* @property {number|string|Function} [offsetSmall=50] - Offset from top before shrinking header
|
|
60
|
+
* @property {number|string|Function} [offsetBg=200] - Offset from top before changing background color
|
|
61
|
+
* @property {string|null} [regBgColor=null] - Regular background color
|
|
62
|
+
* @property {string|null} [altBgColor=null] - Alternate background color
|
|
63
|
+
*/
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @typedef {Object} FixedHeaderOptions
|
|
67
|
+
* @property {string|HTMLElement} [el='header[data-nav]'] - Header element or selector
|
|
68
|
+
* @property {string} [on=Events.APPLICATION_REVEALED] - Event to initialize on
|
|
69
|
+
* @property {boolean} [unpinOnForcedScrollStart=true] - Whether to unpin on forced scroll start
|
|
70
|
+
* @property {boolean} [pinOnForcedScrollEnd=true] - Whether to pin on forced scroll end
|
|
71
|
+
* @property {boolean} [ignoreForcedScroll=false] - Whether to ignore forced scroll events
|
|
72
|
+
* @property {boolean} [rafScroll=true] - Whether to use requestAnimationFrame for scrolling
|
|
73
|
+
* @property {FixedHeaderSectionOptions} [default] - Default options for all sections
|
|
74
|
+
* @property {Object.<string, FixedHeaderSectionOptions>} [sections] - Section-specific options
|
|
75
|
+
*/
|
|
76
|
+
|
|
77
|
+
/** @type {FixedHeaderEvents} */
|
|
31
78
|
const DEFAULT_EVENTS = {
|
|
32
79
|
onPin: (h) => {
|
|
33
80
|
gsap.to(h.el, {
|
|
@@ -93,6 +140,7 @@ const DEFAULT_EVENTS = {
|
|
|
93
140
|
},
|
|
94
141
|
}
|
|
95
142
|
|
|
143
|
+
/** @type {FixedHeaderOptions} */
|
|
96
144
|
const DEFAULT_OPTIONS = {
|
|
97
145
|
el: 'header[data-nav]',
|
|
98
146
|
on: Events.APPLICATION_REVEALED,
|
|
@@ -134,7 +182,15 @@ const DEFAULT_OPTIONS = {
|
|
|
134
182
|
},
|
|
135
183
|
}
|
|
136
184
|
|
|
185
|
+
/**
|
|
186
|
+
* FixedHeader component for sticky navigation headers with scroll behaviors
|
|
187
|
+
*/
|
|
137
188
|
export default class FixedHeader {
|
|
189
|
+
/**
|
|
190
|
+
* Create a new FixedHeader instance
|
|
191
|
+
* @param {Object} app - Application instance
|
|
192
|
+
* @param {FixedHeaderOptions} [opts={}] - FixedHeader options
|
|
193
|
+
*/
|
|
138
194
|
constructor(app, opts = {}) {
|
|
139
195
|
this.app = app
|
|
140
196
|
this.mainOpts = _defaultsDeep(opts, DEFAULT_OPTIONS)
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { gsap } from 'gsap'
|
|
1
|
+
import { gsap } from 'gsap/all'
|
|
2
2
|
import _defaultsDeep from 'lodash.defaultsdeep'
|
|
3
3
|
|
|
4
4
|
const DEFAULT_OPTIONS = {
|
|
5
5
|
shadow: false,
|
|
6
|
-
shadowColor: 'rgba(255, 255, 255, 1)'
|
|
6
|
+
shadowColor: 'rgba(255, 255, 255, 1)',
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export default class FooterReveal {
|
|
@@ -17,7 +17,7 @@ export default class FooterReveal {
|
|
|
17
17
|
gsap.set(footer, {
|
|
18
18
|
'z-index': -100,
|
|
19
19
|
position: 'fixed',
|
|
20
|
-
bottom: 0
|
|
20
|
+
bottom: 0,
|
|
21
21
|
})
|
|
22
22
|
const footerHeight = footer.offsetHeight
|
|
23
23
|
// add height as margin
|