@brandocms/jupiter 3.55.0 → 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.
Files changed (76) hide show
  1. package/README.md +509 -54
  2. package/package.json +30 -18
  3. package/src/index.js +15 -10
  4. package/src/modules/Application/index.js +236 -158
  5. package/src/modules/Breakpoints/index.js +116 -36
  6. package/src/modules/Cookies/index.js +95 -64
  7. package/src/modules/CoverOverlay/index.js +21 -14
  8. package/src/modules/Dataloader/index.js +71 -24
  9. package/src/modules/Dataloader/url-sync.js +238 -0
  10. package/src/modules/Dom/index.js +24 -0
  11. package/src/modules/DoubleHeader/index.js +571 -0
  12. package/src/modules/Dropdown/index.js +108 -73
  13. package/src/modules/EqualHeightElements/index.js +8 -8
  14. package/src/modules/EqualHeightImages/index.js +15 -7
  15. package/src/modules/FixedHeader/index.js +116 -30
  16. package/src/modules/FooterReveal/index.js +5 -5
  17. package/src/modules/HeroSlider/index.js +231 -106
  18. package/src/modules/HeroVideo/index.js +72 -44
  19. package/src/modules/Lazyload/index.js +128 -80
  20. package/src/modules/Lightbox/index.js +101 -80
  21. package/src/modules/Links/index.js +77 -51
  22. package/src/modules/Looper/index.js +1737 -0
  23. package/src/modules/Marquee/index.js +106 -37
  24. package/src/modules/MobileMenu/index.js +105 -130
  25. package/src/modules/Moonwalk/index.js +479 -153
  26. package/src/modules/Parallax/index.js +280 -57
  27. package/src/modules/Popover/index.js +187 -17
  28. package/src/modules/Popup/index.js +172 -53
  29. package/src/modules/ScrollSpy/index.js +21 -0
  30. package/src/modules/StackedBoxes/index.js +8 -6
  31. package/src/modules/StickyHeader/index.js +394 -164
  32. package/src/modules/Toggler/index.js +207 -11
  33. package/src/modules/Typography/index.js +33 -20
  34. package/src/utils/motion-helpers.js +330 -0
  35. package/types/README.md +159 -0
  36. package/types/events/index.d.ts +20 -0
  37. package/types/index.d.ts +6 -0
  38. package/types/modules/Application/index.d.ts +168 -0
  39. package/types/modules/Breakpoints/index.d.ts +40 -0
  40. package/types/modules/Cookies/index.d.ts +81 -0
  41. package/types/modules/CoverOverlay/index.d.ts +6 -0
  42. package/types/modules/Dataloader/index.d.ts +38 -0
  43. package/types/modules/Dataloader/url-sync.d.ts +36 -0
  44. package/types/modules/Dom/index.d.ts +47 -0
  45. package/types/modules/DoubleHeader/index.d.ts +63 -0
  46. package/types/modules/Dropdown/index.d.ts +15 -0
  47. package/types/modules/EqualHeightElements/index.d.ts +8 -0
  48. package/types/modules/EqualHeightImages/index.d.ts +11 -0
  49. package/types/modules/FeatureTests/index.d.ts +27 -0
  50. package/types/modules/FixedHeader/index.d.ts +219 -0
  51. package/types/modules/Fontloader/index.d.ts +5 -0
  52. package/types/modules/FooterReveal/index.d.ts +5 -0
  53. package/types/modules/HeroSlider/index.d.ts +28 -0
  54. package/types/modules/HeroVideo/index.d.ts +83 -0
  55. package/types/modules/Lazyload/index.d.ts +80 -0
  56. package/types/modules/Lightbox/index.d.ts +123 -0
  57. package/types/modules/Links/index.d.ts +55 -0
  58. package/types/modules/Looper/index.d.ts +127 -0
  59. package/types/modules/Marquee/index.d.ts +23 -0
  60. package/types/modules/MobileMenu/index.d.ts +63 -0
  61. package/types/modules/Moonwalk/index.d.ts +322 -0
  62. package/types/modules/Parallax/index.d.ts +71 -0
  63. package/types/modules/Popover/index.d.ts +29 -0
  64. package/types/modules/Popup/index.d.ts +76 -0
  65. package/types/modules/ScrollSpy/index.d.ts +29 -0
  66. package/types/modules/StackedBoxes/index.d.ts +9 -0
  67. package/types/modules/StickyHeader/index.d.ts +220 -0
  68. package/types/modules/Toggler/index.d.ts +48 -0
  69. package/types/modules/Typography/index.d.ts +77 -0
  70. package/types/utils/dispatchElementEvent.d.ts +1 -0
  71. package/types/utils/imageIsLoaded.d.ts +1 -0
  72. package/types/utils/imagesAreLoaded.d.ts +1 -0
  73. package/types/utils/loadScript.d.ts +2 -0
  74. package/types/utils/prefersReducedMotion.d.ts +4 -0
  75. package/types/utils/rafCallback.d.ts +2 -0
  76. package/types/utils/zoom.d.ts +4 -0
@@ -1,17 +1,28 @@
1
- import { gsap } from 'gsap'
2
- import { ScrollToPlugin } from 'gsap/ScrollToPlugin'
1
+ import { animate } from 'motion'
3
2
  import _defaultsDeep from 'lodash.defaultsdeep'
4
-
5
- gsap.registerPlugin(ScrollToPlugin)
6
-
3
+ import { set } from '../../utils/motion-helpers'
4
+
5
+ /**
6
+ * @typedef {Object} LinksOptions
7
+ * @property {boolean} [triggerEvents=true] - Whether to trigger events when scrolling
8
+ * @property {number} [scrollDuration=0.8] - Duration of scroll animation
9
+ * @property {boolean} [scrollOffsetNav=false] - Whether to offset scroll for nav header
10
+ * @property {number} [mobileMenuDelay=800] - Delay for mobile menu before scrolling
11
+ * @property {boolean} [openExternalInWindow=true] - Whether to open external links in new window
12
+ * @property {string} [linkQuery] - Query selector for regular links
13
+ * @property {string} [anchorQuery] - Query selector for anchor links
14
+ * @property {Function} [onAnchor] - Called when an anchor link is clicked
15
+ * @property {Function} [onTransition] - Called when transitioning between pages
16
+ */
17
+
18
+ /** @type {LinksOptions} */
7
19
  const DEFAULT_OPTIONS = {
8
20
  triggerEvents: true,
9
21
  scrollDuration: 0.8,
10
22
  scrollOffsetNav: false,
11
23
  mobileMenuDelay: 800,
12
24
  openExternalInWindow: true,
13
- linkQuery:
14
- 'a:not([href^="#"]):not([target="_blank"]):not([data-lightbox]):not(.noanim)',
25
+ linkQuery: 'a:not([href^="#"]):not([target="_blank"]):not([data-lightbox]):not(.noanim)',
15
26
  anchorQuery: 'a[href^="#"]:not(.noanim)',
16
27
 
17
28
  onAnchor: (target, links) => {
@@ -20,11 +31,7 @@ const DEFAULT_OPTIONS = {
20
31
  const headerHeight = header ? header.clientHeight : 0
21
32
  target = { y: target, offsetY: headerHeight }
22
33
  }
23
- links.app.scrollTo(
24
- target,
25
- links.opts.scrollDuration,
26
- links.opts.triggerEvents
27
- )
34
+ links.app.scrollTo(target, links.opts.scrollDuration, links.opts.triggerEvents)
28
35
  },
29
36
 
30
37
  onTransition: (href, app) => {
@@ -34,55 +41,54 @@ const DEFAULT_OPTIONS = {
34
41
  const fader = document.querySelector('#fader')
35
42
 
36
43
  if (fader) {
37
- gsap.set(fader, { display: 'block', opacity: 0 })
38
- gsap.to(main, {
39
- duration: 0.8,
40
- y: 25,
41
- ease: 'power3.out',
42
- })
44
+ set(fader, { display: 'block', opacity: 0 })
45
+
46
+ if (main) {
47
+ animate(main, { y: 25 }, { duration: 0.8, ease: 'easeOut' })
48
+ animate(main, { opacity: 0 }, { duration: 0.2 })
49
+ }
43
50
 
44
51
  if (header) {
45
- gsap.to(header, { duration: 0.2, opacity: 0 })
52
+ animate(header, { opacity: 0 }, { duration: 0.2 })
46
53
  }
47
54
 
48
55
  if (footer) {
49
- gsap.to(footer, { duration: 0.2, opacity: 0 })
56
+ animate(footer, { opacity: 0 }, { duration: 0.2 })
50
57
  }
51
58
 
52
- gsap.to(fader, {
53
- duration: 0.2,
54
- opacity: 1,
55
- onComplete: () => {
56
- window.location = href
57
- },
59
+ animate(fader, { opacity: 1 }, { duration: 0.2 }).finished.then(() => {
60
+ window.location = href
58
61
  })
59
62
  } else {
60
- gsap.to(main, {
61
- duration: 0.8,
62
- y: 25,
63
- ease: 'power3.out',
64
- })
63
+ if (main) {
64
+ animate(main, { y: 25 }, { duration: 0.8, ease: 'easeOut' })
65
+ animate(main, { opacity: 0 }, { duration: 0.2 })
66
+ }
65
67
 
66
68
  if (header) {
67
- gsap.to(header, { duration: 0.2, opacity: 0 })
69
+ animate(header, { opacity: 0 }, { duration: 0.2 })
68
70
  }
69
71
 
70
72
  if (footer) {
71
- gsap.to(footer, { duration: 0.2, opacity: 0 })
73
+ animate(footer, { opacity: 0 }, { duration: 0.2 })
72
74
  }
73
75
 
74
- gsap.to(main, {
75
- duration: 0.2,
76
- opacity: 0,
77
- onComplete: () => {
78
- window.location = href
79
- },
76
+ animate(main, { opacity: 0 }, { duration: 0.2 }).finished.then(() => {
77
+ window.location = href
80
78
  })
81
79
  }
82
80
  },
83
81
  }
84
82
 
83
+ /**
84
+ * Links handler for navigation and transitions
85
+ */
85
86
  export default class Links {
87
+ /**
88
+ * Create a new Links instance
89
+ * @param {Object} app - Application instance
90
+ * @param {LinksOptions} [opts={}] - Links options
91
+ */
86
92
  constructor(app, opts = {}) {
87
93
  this.app = app
88
94
  this.opts = _defaultsDeep(opts, DEFAULT_OPTIONS)
@@ -98,7 +104,7 @@ export default class Links {
98
104
  bindHeroLink() {
99
105
  const el = document.querySelector('[data-link-to-content]')
100
106
  if (el) {
101
- el.addEventListener('click', (e) => {
107
+ el.addEventListener('click', e => {
102
108
  const dataTarget = document.querySelector('main')
103
109
  e.preventDefault()
104
110
  if (dataTarget) {
@@ -110,8 +116,8 @@ export default class Links {
110
116
 
111
117
  bindAnchors(anchors) {
112
118
  let wait = false
113
- Array.from(anchors).forEach((anchor) => {
114
- anchor.addEventListener('click', (e) => {
119
+ Array.from(anchors).forEach(anchor => {
120
+ anchor.addEventListener('click', e => {
115
121
  e.preventDefault()
116
122
  const href = anchor.getAttribute('href')
117
123
  if (href === '#') {
@@ -166,21 +172,21 @@ export default class Links {
166
172
  bindLinks(links) {
167
173
  const loadingContainer = document.querySelector('.loading-container')
168
174
 
169
- Array.from(links).forEach((link) => {
175
+ Array.from(links).forEach(link => {
170
176
  const href = link.getAttribute('href')
171
177
  if (!href || href === '#' || href.startsWith('javascript:')) {
172
178
  return // Skip empty, anchor, or JS-based links
173
179
  }
174
180
 
175
181
  // Determine the normalized hostname of the current document.
176
- const normalizedCurrentHost = this.normalizeHostname(
177
- document.location.hostname
178
- )
182
+ const normalizedCurrentHost = this.normalizeHostname(document.location.hostname)
179
183
 
180
184
  // For absolute URLs, use the URL constructor.
181
185
  let linkHostname
186
+ let linkUrl
182
187
  try {
183
- linkHostname = new URL(href, document.location.href).hostname
188
+ linkUrl = new URL(href, document.location.href)
189
+ linkHostname = linkUrl.hostname
184
190
  } catch (error) {
185
191
  // If URL construction fails, assume it's not internal.
186
192
  console.warn(`Failed to parse URL for href "${href}":`, error) // Log errors for debugging
@@ -195,7 +201,7 @@ export default class Links {
195
201
  link.setAttribute('target', '_blank')
196
202
  }
197
203
 
198
- link.addEventListener('click', (e) => {
204
+ link.addEventListener('click', e => {
199
205
  if (e.shiftKey || e.metaKey || e.ctrlKey) {
200
206
  return
201
207
  }
@@ -204,9 +210,29 @@ export default class Links {
204
210
  loadingContainer.style.display = 'none'
205
211
  }
206
212
 
207
- if (internalLink) {
208
- e.preventDefault()
209
- this.opts.onTransition(href, this.app)
213
+ if (internalLink && linkUrl) {
214
+ // Check if we're navigating to the same page with just a different hash
215
+ const currentUrl = new URL(window.location.href)
216
+ const isSamePage = linkUrl.pathname === currentUrl.pathname &&
217
+ linkUrl.search === currentUrl.search
218
+
219
+ if (isSamePage && linkUrl.hash) {
220
+ // Same page, just different hash - treat as anchor navigation
221
+ e.preventDefault()
222
+ const target = linkUrl.hash
223
+ const element = document.querySelector(target)
224
+ if (element) {
225
+ this.opts.onAnchor(element, this)
226
+ history.pushState({}, '', href)
227
+ }
228
+ } else if (isSamePage && !linkUrl.hash && !currentUrl.hash) {
229
+ // Same exact page without hash - do nothing
230
+ e.preventDefault()
231
+ } else {
232
+ // Different page or same page with/without hash change - do transition
233
+ e.preventDefault()
234
+ this.opts.onTransition(href, this.app)
235
+ }
210
236
  }
211
237
  })
212
238
  })