@linear_non/stellar-libs 1.4.2 → 1.4.3

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 CHANGED
@@ -150,6 +150,7 @@ const slider = new Slider({
150
150
  speed: 0.1,
151
151
  snap: true,
152
152
  infinite: false,
153
+ activeBelow: 'mediumUp', // only active below the mediumUp breakpoint; mobileOnly:true is an alias
153
154
  prevEl: document.querySelector(".prev"),
154
155
  nextEl: document.querySelector(".next"),
155
156
  progressEl: document.querySelector(".progress-fill"),
@@ -169,6 +170,16 @@ const slider = new Slider({
169
170
 
170
171
  ---
171
172
 
173
+ ## Roadmap
174
+
175
+ - [ ] TypeScript definitions (`.d.ts` for all 8 libraries)
176
+ - [ ] Unit test suite (per-library Jest tests)
177
+ - [ ] Accessibility — ARIA attributes + keyboard support (Slider, Marquee, CursorTracker)
178
+ - [ ] Animation presets — exportable GSAP timeline builders per library
179
+ - [ ] Performance monitoring — FPS tracking integrated with stellar-kit `?debug`
180
+ - [ ] Storybook interactive docs
181
+ - [ ] Plugin system — `.use(plugin)` extension API
182
+
172
183
  ## Lifecycle
173
184
 
174
185
  All libraries follow a consistent class-based lifecycle: `init() → on() → tick() → resize() → off() → destroy()`
@@ -177,4 +188,4 @@ Always call `destroy()` on page navigation to clean up event listeners, animatio
177
188
 
178
189
  ---
179
190
 
180
- Made with love by [Non-Linear Studio](https://non-linear.studio)
191
+ Made with ❤️ by [Non-Linear Studio](https://non-linear.studio)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linear_non/stellar-libs",
3
- "version": "1.4.2",
3
+ "version": "1.4.3",
4
4
  "description": "Reusable JavaScript libraries for Non-Linear Studio projects.",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -10,10 +10,6 @@
10
10
  "files": [
11
11
  "src"
12
12
  ],
13
- "scripts": {
14
- "dev": "vite",
15
- "build": "vite build"
16
- },
17
13
  "keywords": [
18
14
  "non-linear",
19
15
  "frontend",
@@ -25,10 +21,14 @@
25
21
  "author": "Non-Linear Studio",
26
22
  "license": "MIT",
27
23
  "dependencies": {
28
- "@linear_non/stellar-kit": "*"
24
+ "@linear_non/stellar-kit": "3.0.12"
29
25
  },
30
26
  "devDependencies": {
31
27
  "@linear_non/prettier-config": "^1.0.6",
32
28
  "vite": "^6.3.5"
29
+ },
30
+ "scripts": {
31
+ "dev": "vite",
32
+ "build": "vite build"
33
33
  }
34
- }
34
+ }
@@ -1,6 +1,7 @@
1
- import { lerp, bounds, sniffer } from "@linear_non/stellar-kit/utils"
1
+ import { lerp, bounds } from "@linear_non/stellar-kit/utils"
2
2
  import { gsap } from "@linear_non/stellar-kit/gsap"
3
3
  import { emitter, EVENTS } from "@linear_non/stellar-kit/events"
4
+ import { kitStore } from "@linear_non/stellar-kit"
4
5
 
5
6
  export default class Slider {
6
7
  constructor({
@@ -9,6 +10,10 @@ export default class Slider {
9
10
  speed = 0.1,
10
11
  snap = true,
11
12
  infinite = false,
13
+ // activeBelow: a kitStore.breakpoints key (e.g. 'mediumUp', 'smallUp').
14
+ // Slider is active when kitStore.breakpoints[activeBelow] is falsy (i.e. we are below that breakpoint).
15
+ // mobileOnly: true is kept as a backward-compat alias for activeBelow: 'mediumUp'.
16
+ activeBelow = null,
12
17
  mobileOnly = false,
13
18
  prevEl = null,
14
19
  nextEl = null,
@@ -20,7 +25,8 @@ export default class Slider {
20
25
  this.speed = speed
21
26
  this.snap = infinite ? true : snap // infinite always snaps
22
27
  this.infinite = infinite
23
- this.mobileOnly = mobileOnly
28
+ // Resolve activeBelow: explicit prop wins; mobileOnly:true falls back to 'mediumUp'
29
+ this.activeBelow = activeBelow || (mobileOnly ? 'mediumUp' : null)
24
30
  this.prevEl = prevEl
25
31
  this.nextEl = nextEl
26
32
  this.progressEl = progressEl
@@ -48,7 +54,9 @@ export default class Slider {
48
54
  // ─── Setup ────────────────────────────────────────────────────────────────
49
55
 
50
56
  _shouldActivate() {
51
- return !this.mobileOnly || sniffer.isDevice
57
+ if (!this.activeBelow) return true
58
+ // Active when the named breakpoint flag is falsy (i.e. we are below that breakpoint)
59
+ return !kitStore.breakpoints[this.activeBelow]
52
60
  }
53
61
 
54
62
  setup() {
@@ -63,6 +71,7 @@ export default class Slider {
63
71
  this.target = this.index * this.slideWidth
64
72
  this.current = this.target
65
73
  this._draw(this.current)
74
+ this._updateProgress()
66
75
  }
67
76
  }
68
77
 
@@ -144,10 +153,14 @@ export default class Slider {
144
153
  }
145
154
 
146
155
  _updateProgress() {
147
- if (!this.progressEl || this.infinite) return
148
- const progress = this.limit > 0 ? this.current / this.limit : 0
156
+ if (!this.progressEl || this.infinite || !this.total) return
157
+ // Position-based so the bar reaches 100% exactly when current hits limit.
158
+ // Floor at 1/total so the bar is never empty on the first slide.
159
+ const min = 1 / this.total
160
+ const pos = this.limit > 0 ? this.current / this.limit : 1
161
+ const progress = Math.max(min, Math.min(1, pos))
149
162
  this.progressEl.style.transformOrigin = "left center"
150
- this.progressEl.style.transform = `scaleX(${gsap.utils.clamp(0, 1, progress)})`
163
+ this.progressEl.style.transform = `scaleX(${progress})`
151
164
  }
152
165
 
153
166
  // ─── Tick ─────────────────────────────────────────────────────────────────
@@ -199,6 +212,7 @@ export default class Slider {
199
212
  }
200
213
 
201
214
  _fireChange() {
215
+ this._updateProgress()
202
216
  if (!this.onSlideChange) return
203
217
  this.onSlideChange({ index: this.index, total: this.total })
204
218
  }
@@ -300,7 +314,6 @@ export default class Slider {
300
314
  if (this.nextEl) this.nextEl.addEventListener("click", this.next)
301
315
 
302
316
  emitter.on(EVENTS.APP_TICK, this.tick)
303
- emitter.on(EVENTS.APP_RESIZE, this.resize)
304
317
  }
305
318
 
306
319
  off() {
@@ -315,7 +328,6 @@ export default class Slider {
315
328
  if (this.nextEl) this.nextEl.removeEventListener("click", this.next)
316
329
 
317
330
  emitter.off(EVENTS.APP_TICK, this.tick)
318
- emitter.off(EVENTS.APP_RESIZE, this.resize)
319
331
  }
320
332
 
321
333
  resize = () => {
@@ -364,6 +376,7 @@ export default class Slider {
364
376
  destroy() {
365
377
  this.off()
366
378
  this._reset()
379
+ emitter.off(EVENTS.APP_RESIZE, this.resize)
367
380
  this.container = null
368
381
  this.el = null
369
382
  }
@@ -371,5 +384,8 @@ export default class Slider {
371
384
  init() {
372
385
  this.setup()
373
386
  this.on()
387
+ // APP_RESIZE is always registered so the slider can transition
388
+ // between active/inactive states when the breakpoint changes.
389
+ emitter.on(EVENTS.APP_RESIZE, this.resize)
374
390
  }
375
391
  }