@linear_non/stellar-libs 1.0.42 → 1.0.43

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linear_non/stellar-libs",
3
- "version": "1.0.42",
3
+ "version": "1.0.43",
4
4
  "description": "Reusable JavaScript libraries for Non-Linear Studio projects.",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -25,7 +25,7 @@
25
25
  "author": "Non-Linear Studio",
26
26
  "license": "MIT",
27
27
  "dependencies": {
28
- "@linear_non/stellar-kit": "^2.1.11"
28
+ "@linear_non/stellar-kit": "^2.1.17"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@linear_non/prettier-config": "^1.0.6",
@@ -1,6 +1,10 @@
1
- import { EVENTS, PRIORITY, emitter } from "@linear_non/stellar-kit/events"
1
+ import { EVENTS } from "@linear_non/stellar-kit/events"
2
2
  import { Observer, reverseSplit, splitText } from "@linear_non/stellar-kit/plugins"
3
3
 
4
+ import { EVENTS } from "../events"
5
+ import Observer from "./_Observer"
6
+ import { reverseSplit, splitText } from "./_SplitText"
7
+
4
8
  const NOOP = () => {}
5
9
 
6
10
  function normalizeTargets(splitTargets) {
@@ -13,64 +17,62 @@ function normalizeTargets(splitTargets) {
13
17
  export default class SplitonScroll {
14
18
  constructor({
15
19
  el,
16
- splitText: splitTargets,
20
+ splitText,
17
21
  isReady,
18
22
  reverse,
23
+ resize,
19
24
  start = "top bottom",
20
25
  end = "bottom top",
21
26
  scrub = false,
22
27
  once = true,
23
28
  }) {
24
29
  this.element = el
25
- this.targets = normalizeTargets(splitTargets)
30
+ this.targets = normalizeTargets(splitText)
26
31
 
27
32
  this.splits = null
28
33
  this.groups = null
29
34
 
30
35
  this.isReadyCallback = isReady || NOOP
31
36
  this.reverseCallback = reverse || NOOP
37
+ this.isResizeCallback = resize || NOOP
32
38
  this.start = start
33
39
  this.end = end
34
40
  this.scrub = scrub
35
41
  this.once = once
36
42
 
37
- this._readyNotified = false
38
- this._resolveReady = null
39
43
  this.ready = new Promise(resolve => {
40
44
  this._resolveReady = resolve
41
45
  })
42
46
 
43
- this._needsResplit = false
44
-
45
- this._onResizeStart = this._onResizeStart.bind(this)
46
- this._onSmoothResize = this._onSmoothResize.bind(this)
47
- this._offResizeStart = null
48
- this._offSmoothResize = null
47
+ this._readyFired = false
48
+ this._rebuilding = false
49
49
 
50
50
  if (!this.element || !this.targets.length) {
51
- const payload = { splits: [], groups: {} }
52
- this._notifyReadyOnce(payload)
51
+ this._notifyReadyOnce([])
53
52
  return
54
53
  }
55
54
 
55
+ this.init()
56
+ }
57
+
58
+ init() {
59
+ // Initialize observer
56
60
  this.addObserver()
57
- this.addResizeListeners()
58
61
 
62
+ // If already in view, handle immediately
59
63
  if (this.observer && (this.observer.isActive || this.observer.progress > 0)) {
60
64
  this.handleEnter()
61
65
  }
62
66
  }
63
67
 
64
- _notifyReadyOnce(payload) {
65
- if (this._readyNotified) return
66
- this._readyNotified = true
67
-
68
- this.isReadyCallback(payload.splits, payload.groups)
68
+ // Set is ready only once
69
+ _notifyReadyOnce(splits, groups) {
70
+ if (this._readyFired) return
71
+ this._readyFired = true
69
72
 
70
- if (this._resolveReady) {
71
- this._resolveReady(payload)
72
- this._resolveReady = null
73
- }
73
+ this.isReadyCallback(splits, groups)
74
+ this._resolveReady?.({ splits, groups })
75
+ this._resolveReady = null
74
76
  }
75
77
 
76
78
  addObserver() {
@@ -86,78 +88,66 @@ export default class SplitonScroll {
86
88
  this.observer.on("leave", () => this.handleLeave())
87
89
  }
88
90
 
89
- addResizeListeners() {
90
- // Raw resize start, clear split
91
- this._offResizeStart = emitter.on(EVENTS.APP_RESIZE, this._onResizeStart, PRIORITY.first)
91
+ async resize() {
92
+ // if not built yet, just build once
93
+ if (!this.splits) return
92
94
 
93
- // Smooth.update() + setScrollBounds()
94
- this._offSmoothResize = emitter.on(EVENTS.APP_SMOOTH_RESIZE, this._onSmoothResize)
95
- }
95
+ // revert then rebuild
96
+ reverseSplit(this.splits)
97
+ this.splits = null
98
+ this.groups = null
96
99
 
97
- removeResizeListeners() {
98
- if (this._offResizeStart) {
99
- this._offResizeStart()
100
- this._offResizeStart = null
101
- }
102
- if (this._offSmoothResize) {
103
- this._offSmoothResize()
104
- this._offSmoothResize = null
105
- }
100
+ // rebuild splits
101
+ await this.refreshSplits()
106
102
  }
107
103
 
108
- _onResizeStart() {
109
- if (!this.element || !this.targets || !this.targets.length) return
110
-
111
- if (this.splits) {
112
- reverseSplit(this.splits)
113
-
114
- this.splits = null
115
- this.groups = null
116
- }
104
+ async handleEnter() {
105
+ const splitEmitter = splitText(this.targets)
117
106
 
118
- this._needsResplit = true
119
- }
107
+ const { splits, groups } = await new Promise(resolve => {
108
+ const onReady = (readySplits, groupMap) => {
109
+ // Clean up listener
110
+ if (splitEmitter.off) {
111
+ splitEmitter.off(EVENTS.APP_SPLITTEXT_READY, onReady)
112
+ }
120
113
 
121
- _onSmoothResize() {
122
- if (!this._needsResplit) return
123
- if (!this.element || !this.targets || !this.targets.length) return
114
+ resolve({
115
+ splits: readySplits || [],
116
+ groups: groupMap || {},
117
+ })
118
+ }
124
119
 
125
- if (this.observer && typeof this.observer.refresh === "function") {
126
- this.observer.refresh()
127
- }
120
+ // Listen for ready event once
121
+ splitEmitter.once(EVENTS.APP_SPLITTEXT_READY, onReady)
122
+ })
128
123
 
129
- if (this.observer && (this.observer.isActive || this.observer.progress > 0)) {
130
- this.handleEnter()
131
- }
124
+ this.splits = splits
125
+ this.groups = groups
132
126
 
133
- this._needsResplit = false
127
+ this._notifyReadyOnce(splits, groups)
134
128
  }
135
129
 
136
- async handleEnter() {
137
- const splitEmitter = splitText(this.targets)
130
+ async refreshSplits() {
131
+ if (this._rebuilding) return
132
+ this._rebuilding = true
138
133
 
134
+ // (Re)build fresh splits
135
+ const emitter = splitText(this.targets)
139
136
  const { splits, groups } = await new Promise(resolve => {
140
137
  const onReady = (readySplits, groupMap) => {
141
- if (typeof splitEmitter.off === "function") {
142
- splitEmitter.off(EVENTS.APP_SPLITTEXT_READY, onReady)
143
- }
144
138
  resolve({
145
139
  splits: readySplits || [],
146
140
  groups: groupMap || {},
147
141
  })
148
142
  }
149
-
150
- if (typeof splitEmitter.once === "function") {
151
- splitEmitter.once(EVENTS.APP_SPLITTEXT_READY, onReady)
152
- } else {
153
- splitEmitter.on(EVENTS.APP_SPLITTEXT_READY, onReady)
154
- }
143
+ emitter.once(EVENTS.APP_SPLITTEXT_READY, onReady)
155
144
  })
156
145
 
157
146
  this.splits = splits
158
147
  this.groups = groups
148
+ this._rebuilding = false
159
149
 
160
- this._notifyReadyOnce({ splits, groups })
150
+ this.isResizeCallback(splits, groups)
161
151
  }
162
152
 
163
153
  handleLeave() {
@@ -179,9 +169,6 @@ export default class SplitonScroll {
179
169
  }
180
170
 
181
171
  destroy() {
182
- this.observer?.kill()
183
- this.removeResizeListeners()
184
-
185
172
  if (this.splits) {
186
173
  reverseSplit(this.splits)
187
174
  }