@brandocms/jupiter 3.44.0 → 3.45.0

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/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ #### 3.45.0
2
+
3
+ - Marquee: Reveal on `APPLICATION:REVEALED`
4
+ - Add Toggler module
5
+
6
+
1
7
  #### 3.44.0
2
8
 
3
9
  - Moonwalk: Add `data-moonwalked` to walked elements. Don't run again on
package/README.md CHANGED
@@ -261,6 +261,57 @@ include images from this section. Otherwise, all lightboxed images will be inclu
261
261
  - `onPointerLeft/onPointerRight` - `function (lightbox)` - callback for when pointer direction changes
262
262
 
263
263
 
264
+ ## Toggler
265
+
266
+ #### Example
267
+
268
+ HTML
269
+ ```html
270
+ <div data-toggle>
271
+ <button data-toggle-trigger>Click to expand <span class="arrow">&darr;</span></button>
272
+ <div class="panel" data-toggle-content>
273
+ <div class="panel-content">
274
+ Content goes here
275
+ </div>
276
+ </div>
277
+ </div>
278
+ ```
279
+
280
+ CSS
281
+ ```css
282
+ [data-toggle-trigger] {
283
+ .arrow {
284
+ display: inline-block;
285
+ transform: scaleY(1);
286
+ transition: transform 250ms ease;
287
+ &.active {
288
+ transform: scaleY(-1);
289
+ }
290
+ }
291
+ }
292
+
293
+ [data-toggle-content] {
294
+ height: 0;
295
+ overflow: hidden;
296
+ opacity: 1;
297
+ position: relative;
298
+ }
299
+ ```
300
+
301
+ JS
302
+ ```es6
303
+ import { Toggler } from '@brandocms/jupiter'
304
+
305
+ app.togglers = []
306
+
307
+ const togglers = Dom.all('[data-toggle]')
308
+ togglers.forEach(toggleEl => {
309
+ app.togglers.push(new Toggler(app, toggleEl))
310
+ })
311
+ ```
312
+
313
+ #### Options
314
+
264
315
 
265
316
  ## Links
266
317
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brandocms/jupiter",
3
- "version": "3.44.0",
3
+ "version": "3.45.0",
4
4
  "description": "Frontend helpers.",
5
5
  "author": "Univers/Twined",
6
6
  "license": "UNLICENSED",
package/src/index.js CHANGED
@@ -31,6 +31,7 @@ import Popup from './modules/Popup'
31
31
  import ScrollSpy from './modules/ScrollSpy'
32
32
  import StackedBoxes from './modules/StackedBoxes'
33
33
  import StickyHeader from './modules/StickyHeader'
34
+ import Toggler from './modules/Toggler'
34
35
  import Typography from './modules/Typography'
35
36
 
36
37
  import imageIsLoaded from './utils/imageIsLoaded'
@@ -63,6 +64,7 @@ export {
63
64
  ScrollSpy,
64
65
  StackedBoxes,
65
66
  StickyHeader,
67
+ Toggler,
66
68
  Typography,
67
69
 
68
70
  // Export utils
@@ -223,9 +223,11 @@ export default class FixedHeader {
223
223
  window.addEventListener(Events.APPLICATION_FORCED_SCROLL_END, this.pin.bind(this), false)
224
224
  }
225
225
 
226
- window.addEventListener(Events.APPLICATION_SCROLL, this.update.bind(this), {
227
- capture: false,
228
- passive: true
226
+ window.addEventListener(Events.APPLICATION_REVEALED, e => {
227
+ window.addEventListener(Events.APPLICATION_SCROLL, this.update.bind(this), {
228
+ capture: false,
229
+ passive: true
230
+ })
229
231
  })
230
232
 
231
233
  window.addEventListener(Events.APPLICATION_READY, this.unpinIfScrolled.bind(this))
@@ -249,9 +251,11 @@ export default class FixedHeader {
249
251
  this.checkBg(true)
250
252
  this.checkTop(true)
251
253
 
252
- setTimeout(() => {
253
- this.el.setAttribute('data-header-transitions', '')
254
- }, 350)
254
+ window.addEventListener(Events.APPLICATION_REVEALED, e => {
255
+ setTimeout(() => {
256
+ this.el.setAttribute('data-header-transitions', '')
257
+ }, 350)
258
+ })
255
259
  }
256
260
 
257
261
  lock () {
@@ -6,7 +6,10 @@ const DEFAULT_OPTIONS = {
6
6
  speed: 100,
7
7
  extraHeight: 0,
8
8
  slowDownOnHover: true,
9
- paddingLeft: 0
9
+ paddingLeft: 0,
10
+ onReveal: marqueeEl => {
11
+ gsap.to(marqueeEl, { opacity: 1 })
12
+ }
10
13
  }
11
14
 
12
15
  export default class Marquee {
@@ -25,7 +28,9 @@ export default class Marquee {
25
28
  }
26
29
 
27
30
  initialize () {
31
+ gsap.set(this.elements.$marquee, { opacity: 0 })
28
32
  window.addEventListener('APPLICATION:RESIZE', this.updateMarquee.bind(this))
33
+ window.addEventListener('APPLICATION:REVEALED', this.revealMarquee.bind(this))
29
34
  this.updateMarquee()
30
35
  this.setupObserver()
31
36
  if (this.opts.slowDownOnHover) {
@@ -34,6 +39,11 @@ export default class Marquee {
34
39
  }
35
40
  }
36
41
 
42
+ revealMarquee (e) {
43
+ this.updateMarquee()
44
+ this.opts.onReveal(this.elements.$marquee)
45
+ }
46
+
37
47
  updateMarquee (e) {
38
48
  if (e) {
39
49
  // updating cause of a resize. we only care about width change
@@ -41,6 +51,7 @@ export default class Marquee {
41
51
  return
42
52
  }
43
53
  }
54
+
44
55
  this.killTweens()
45
56
  this.clearHolders()
46
57
  this.setHeight()
@@ -160,14 +171,18 @@ export default class Marquee {
160
171
  this.elements.$holder.appendChild(Dom.new('<span>&nbsp;&mdash;&nbsp;</span>')[0])
161
172
 
162
173
  const textWidth = this.elements.$item.offsetWidth
163
- const count = Math.ceil(this.app.size.width / textWidth) - 1
164
-
165
- for (let i = 0; i < count; i += 1) {
166
- this.elements.$holder.append(this.elements.$item.cloneNode(true))
167
- this.elements.$holder.appendChild(Dom.new('<span>&nbsp;&mdash;&nbsp;</p>')[0])
174
+ if (textWidth) {
175
+ const count = Math.ceil(this.app.size.width / textWidth) - 1
176
+
177
+ for (let i = 0; i < count; i += 1) {
178
+ this.elements.$holder.append(this.elements.$item.cloneNode(true))
179
+ this.elements.$holder.appendChild(Dom.new('<span>&nbsp;&mdash;&nbsp;</p>')[0])
180
+ }
181
+
182
+ this.elements.$marquee.appendChild(this.elements.$holder.cloneNode(true))
183
+ } else {
184
+ console.error('no textWidth! probably image?', this.elements.$item)
168
185
  }
169
-
170
- this.elements.$marquee.appendChild(this.elements.$holder.cloneNode(true))
171
186
  }
172
187
 
173
188
  setHeight () {
@@ -0,0 +1,46 @@
1
+ import { gsap } from 'gsap'
2
+ import Dom from '../Dom'
3
+
4
+ const DEFAULT_OPTIONS = {}
5
+
6
+ export default class Toggler {
7
+ constructor(app, el) {
8
+ this.open = false
9
+ this.app = app
10
+ this.el = el
11
+ // this.opts = _defaultsDeep(opts, DEFAULT_OPTIONS)
12
+ this.trigger = Dom.find(this.el, '[data-toggle-trigger]')
13
+ this.triggerIcon = Dom.find(this.trigger, 'span.icon')
14
+ this.content = Dom.find(this.el, '[data-toggle-content]')
15
+ this.trigger.addEventListener('click', this.onClick.bind(this))
16
+ }
17
+
18
+ onClick() {
19
+ this.toggleState()
20
+
21
+ if (this.open) {
22
+ this.triggerIcon.classList.toggle('active')
23
+ gsap.set(this.content, { height: 'auto' })
24
+ this.el.classList.toggle('open')
25
+ gsap.from(this.content, { height: 0, ease: 'power1.inOut' })
26
+ } else {
27
+ this.triggerIcon.classList.toggle('active')
28
+ gsap.to(this.content, {
29
+ duration: 0.25,
30
+ onComplete: () => {
31
+ this.el.classList.toggle('open')
32
+ }
33
+ })
34
+
35
+ gsap.to(this.content, { height: 0, ease: 'power3.out' })
36
+ }
37
+ }
38
+
39
+ toggleState() {
40
+ if (this.open) {
41
+ this.open = false
42
+ } else {
43
+ this.open = true
44
+ }
45
+ }
46
+ }