@linear_non/stellar-libs 1.1.8 → 1.2.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linear_non/stellar-libs",
3
- "version": "1.1.8",
3
+ "version": "1.2.0",
4
4
  "description": "Reusable JavaScript libraries for Non-Linear Studio projects.",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -1,7 +1,7 @@
1
1
  import Scrollbar from "../ScrollBar"
2
2
  import { kitStore } from "@linear_non/stellar-kit"
3
3
  import { emitter, EVENTS } from "@linear_non/stellar-kit/events"
4
- import { qs, qsa, bounds, Debug } from "@linear_non/stellar-kit/utils"
4
+ import { qs, qsa, bounds } from "@linear_non/stellar-kit/utils"
5
5
 
6
6
  export default class Smooth {
7
7
  constructor(obj) {
@@ -12,6 +12,7 @@ export default class Smooth {
12
12
  this.sections = null
13
13
  this.scrollbar = null
14
14
  this.dpr = Math.max(1, Math.round(window.devicePixelRatio || 1))
15
+ this.resizeRAF = null
15
16
 
16
17
  this.init()
17
18
  }
@@ -44,7 +45,7 @@ export default class Smooth {
44
45
  bottom,
45
46
  offset,
46
47
  speed,
47
- out: true,
48
+ out: false,
48
49
  transform: 0,
49
50
  _roundedY: 0,
50
51
  })
@@ -109,20 +110,49 @@ export default class Smooth {
109
110
  }
110
111
  }
111
112
 
113
+ resetTransforms() {
114
+ if (!this.elems) return
115
+ this.elems.forEach(el => {
116
+ el.style.transform = ""
117
+ })
118
+ }
119
+
112
120
  resize = () => {
113
121
  const { isSmooth } = kitStore.flags
114
122
 
115
123
  if (!isSmooth) return
116
124
 
117
- this.scroll?.setScrollBounds()
125
+ // Cancel any pending resize RAF
126
+ if (this.resizeRAF) {
127
+ cancelAnimationFrame(this.resizeRAF)
128
+ this.resizeRAF = null
129
+ }
118
130
 
119
- const { fh } = kitStore.sizes
120
- this.current = Math.min(Math.max(this.current, 0), fh || 0)
131
+ // Clear transforms to get accurate measurements
132
+ this.resetTransforms()
121
133
 
122
- this.getSections()
123
- emitter.emit(EVENTS.APP_SMOOTH_RESIZE)
124
- this.transformSections()
125
- this.scrollbar?.update()
134
+ // Force reflow
135
+ if (this.el) {
136
+ void this.el.offsetHeight
137
+ }
138
+
139
+ // Double RAF to ensure DOM has fully reflowed
140
+ this.resizeRAF = requestAnimationFrame(() => {
141
+ this.resizeRAF = requestAnimationFrame(() => {
142
+ this.resizeRAF = null
143
+
144
+ this.scroll?.setScrollBounds()
145
+
146
+ const { fh } = kitStore.sizes
147
+ this.current = Math.min(Math.max(this.current, 0), fh || 0)
148
+
149
+ this.getSections()
150
+
151
+ emitter.emit(EVENTS.APP_SMOOTH_RESIZE)
152
+ this.transformSections()
153
+ this.scrollbar?.update()
154
+ })
155
+ })
126
156
  }
127
157
 
128
158
  update(elems) {
@@ -152,6 +182,11 @@ export default class Smooth {
152
182
  }
153
183
 
154
184
  destroy() {
185
+ if (this.resizeRAF) {
186
+ cancelAnimationFrame(this.resizeRAF)
187
+ this.resizeRAF = null
188
+ }
189
+
155
190
  this.off()
156
191
  this.scrollbar?.destroy()
157
192
  this.clean()
@@ -43,6 +43,7 @@ export default class SplitonScroll {
43
43
  this._readyFired = false
44
44
  this._rebuilding = false
45
45
  this._entering = false
46
+ this._hasEntered = false
46
47
 
47
48
  if (!this.element || !this.targets.length) {
48
49
  this._notifyReadyOnce([])
@@ -67,7 +68,7 @@ export default class SplitonScroll {
67
68
  if (this._readyFired) return
68
69
  this._readyFired = true
69
70
 
70
- this.isReadyCallback(splits, groups)
71
+ this.isReadyCallback({ splits, groups })
71
72
  this._resolveReady?.({ splits, groups })
72
73
  this._resolveReady = null
73
74
  }
@@ -125,6 +126,7 @@ export default class SplitonScroll {
125
126
  this.splits = splits
126
127
  this.groups = groups
127
128
  this._entering = false
129
+ this._hasEntered = true
128
130
 
129
131
  this._notifyReadyOnce(splits, groups)
130
132
  }
@@ -149,16 +151,20 @@ export default class SplitonScroll {
149
151
  this.groups = groups
150
152
  this._rebuilding = false
151
153
 
152
- this.isResizeCallback(splits, groups)
154
+ this.isResizeCallback({ splits, groups })
153
155
  }
154
156
 
155
157
  handleLeave() {
158
+ // Don't reverse if we haven't fully entered yet
159
+ if (!this._hasEntered) return
160
+
156
161
  if (this.splits) {
157
162
  reverseSplit(this.splits)
158
163
  this.splits = null
159
164
  this.groups = null
160
165
  }
161
166
 
167
+ this._hasEntered = false
162
168
  this.reverseCallback()
163
169
 
164
170
  if (this.once) {