@uinstinct/svelte-wheel-picker 0.1.12 → 0.1.14

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.
@@ -1,4 +1,4 @@
1
- <script lang="ts">
1
+ <script lang="ts" generics="T extends string | number">
2
2
  import { untrack } from 'svelte';
3
3
  import type { WheelPickerProps } from './types.js';
4
4
  import { WheelPhysics } from './use-wheel-physics.svelte.js';
@@ -25,7 +25,7 @@
25
25
  scrollSensitivity = DEFAULT_SCROLL_SENSITIVITY,
26
26
  infinite = false,
27
27
  cylindrical = false,
28
- }: WheelPickerProps = $props();
28
+ }: WheelPickerProps<T> = $props();
29
29
 
30
30
  // D-07: visibleCount must be odd — warn and round up if even
31
31
  const visibleCount = $derived.by(() => {
@@ -1,4 +1,25 @@
1
1
  import type { WheelPickerProps } from './types.js';
2
- declare const WheelPicker: import("svelte").Component<WheelPickerProps<string>, {}, "">;
3
- type WheelPicker = ReturnType<typeof WheelPicker>;
2
+ declare function $$render<T extends string | number>(): {
3
+ props: WheelPickerProps<T>;
4
+ exports: {};
5
+ bindings: "";
6
+ slots: {};
7
+ events: {};
8
+ };
9
+ declare class __sveltets_Render<T extends string | number> {
10
+ props(): ReturnType<typeof $$render<T>>['props'];
11
+ events(): ReturnType<typeof $$render<T>>['events'];
12
+ slots(): ReturnType<typeof $$render<T>>['slots'];
13
+ bindings(): "";
14
+ exports(): {};
15
+ }
16
+ interface $$IsomorphicComponent {
17
+ new <T extends string | number>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
18
+ $$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
19
+ } & ReturnType<__sveltets_Render<T>['exports']>;
20
+ <T extends string | number>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
21
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
22
+ }
23
+ declare const WheelPicker: $$IsomorphicComponent;
24
+ type WheelPicker<T extends string | number> = InstanceType<typeof WheelPicker<T>>;
4
25
  export default WheelPicker;
@@ -1,61 +1,42 @@
1
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
- if (kind === "m") throw new TypeError("Private method is not writable");
3
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
- };
7
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
- };
12
- var _ControllableState_internal, _ControllableState_onChange, _ControllableState_isControlled, _ControllableState_controlledValue;
13
- var ControllableState = /** @class */ (function () {
14
- function ControllableState(opts) {
15
- _ControllableState_internal.set(this, $state(undefined));
16
- _ControllableState_onChange.set(this, void 0);
17
- _ControllableState_isControlled.set(this, void 0);
18
- // $state so that reactive consumers (selectedIndex $derived) re-evaluate when prop changes
19
- _ControllableState_controlledValue.set(this, $state(undefined));
20
- __classPrivateFieldSet(this, _ControllableState_isControlled, typeof opts.onChange === 'function', "f");
21
- __classPrivateFieldSet(this, _ControllableState_onChange, opts.onChange, "f");
22
- __classPrivateFieldSet(this, _ControllableState_controlledValue, opts.value, "f");
23
- if (__classPrivateFieldGet(this, _ControllableState_isControlled, "f")) {
24
- __classPrivateFieldSet(this, _ControllableState_internal, opts.value, "f");
1
+ class ControllableState {
2
+ #internal = $state(undefined);
3
+ #onChange;
4
+ #isControlled;
5
+ // $state so that reactive consumers (selectedIndex $derived) re-evaluate when prop changes
6
+ #controlledValue = $state(undefined);
7
+ constructor(opts) {
8
+ this.#isControlled = typeof opts.onChange === 'function';
9
+ this.#onChange = opts.onChange;
10
+ this.#controlledValue = opts.value;
11
+ if (this.#isControlled) {
12
+ this.#internal = opts.value;
25
13
  }
26
14
  else {
27
- __classPrivateFieldSet(this, _ControllableState_internal, opts.defaultValue, "f");
15
+ this.#internal = opts.defaultValue;
28
16
  }
29
17
  }
30
18
  /**
31
19
  * Update the tracked controlled value when the external `value` prop changes.
32
20
  * Must be called from a $effect in the consuming component whenever `value` changes.
33
21
  */
34
- ControllableState.prototype.updateControlledValue = function (value) {
35
- __classPrivateFieldSet(this, _ControllableState_controlledValue, value, "f");
36
- };
37
- Object.defineProperty(ControllableState.prototype, "current", {
38
- get: function () {
39
- if (__classPrivateFieldGet(this, _ControllableState_isControlled, "f")) {
40
- return __classPrivateFieldGet(this, _ControllableState_controlledValue, "f");
41
- }
42
- return __classPrivateFieldGet(this, _ControllableState_internal, "f");
43
- },
44
- set: function (next) {
45
- var _a;
46
- if (__classPrivateFieldGet(this, _ControllableState_isControlled, "f")) {
47
- (_a = __classPrivateFieldGet(this, _ControllableState_onChange, "f")) === null || _a === void 0 ? void 0 : _a.call(this, next);
48
- }
49
- else {
50
- __classPrivateFieldSet(this, _ControllableState_internal, next, "f");
51
- }
52
- },
53
- enumerable: false,
54
- configurable: true
55
- });
56
- return ControllableState;
57
- }());
58
- _ControllableState_internal = new WeakMap(), _ControllableState_onChange = new WeakMap(), _ControllableState_isControlled = new WeakMap(), _ControllableState_controlledValue = new WeakMap();
22
+ updateControlledValue(value) {
23
+ this.#controlledValue = value;
24
+ }
25
+ get current() {
26
+ if (this.#isControlled) {
27
+ return this.#controlledValue;
28
+ }
29
+ return this.#internal;
30
+ }
31
+ set current(next) {
32
+ if (this.#isControlled) {
33
+ this.#onChange?.(next);
34
+ }
35
+ else {
36
+ this.#internal = next;
37
+ }
38
+ }
39
+ }
59
40
  export function useControllableState(opts) {
60
41
  return new ControllableState(opts);
61
42
  }
@@ -1,77 +1,59 @@
1
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
- };
6
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
7
- if (kind === "m") throw new TypeError("Private method is not writable");
8
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
9
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
10
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
11
- };
12
- var _TypeaheadSearch_instances, _TypeaheadSearch_buffer, _TypeaheadSearch_lastKey, _TypeaheadSearch_lastTime, _TypeaheadSearch_timer, _TypeaheadSearch_getSearchText, _TypeaheadSearch_findFirst, _TypeaheadSearch_cycleMatch;
13
- var TypeaheadSearch = /** @class */ (function () {
14
- function TypeaheadSearch() {
15
- _TypeaheadSearch_instances.add(this);
16
- _TypeaheadSearch_buffer.set(this, $state(''));
17
- _TypeaheadSearch_lastKey.set(this, $state(''));
18
- _TypeaheadSearch_lastTime.set(this, 0);
19
- _TypeaheadSearch_timer.set(this, null);
20
- }
21
- TypeaheadSearch.prototype.search = function (key, options, currentIndex) {
22
- var _this = this;
23
- var now = Date.now();
24
- var withinWindow = now - __classPrivateFieldGet(this, _TypeaheadSearch_lastTime, "f") < 500;
25
- var singleChar = key.length === 1;
1
+ class TypeaheadSearch {
2
+ #buffer = $state('');
3
+ #lastKey = $state('');
4
+ #lastTime = 0;
5
+ #timer = null;
6
+ search(key, options, currentIndex) {
7
+ const now = Date.now();
8
+ const withinWindow = now - this.#lastTime < 500;
9
+ const singleChar = key.length === 1;
26
10
  if (!singleChar)
27
11
  return -1;
28
- var lowerKey = key.toLowerCase();
29
- var isSameKey = withinWindow && lowerKey === __classPrivateFieldGet(this, _TypeaheadSearch_lastKey, "f");
30
- __classPrivateFieldSet(this, _TypeaheadSearch_lastKey, lowerKey, "f");
31
- __classPrivateFieldSet(this, _TypeaheadSearch_lastTime, now, "f");
12
+ const lowerKey = key.toLowerCase();
13
+ const isSameKey = withinWindow && lowerKey === this.#lastKey;
14
+ this.#lastKey = lowerKey;
15
+ this.#lastTime = now;
32
16
  // Reset timer
33
- if (__classPrivateFieldGet(this, _TypeaheadSearch_timer, "f"))
34
- clearTimeout(__classPrivateFieldGet(this, _TypeaheadSearch_timer, "f"));
35
- __classPrivateFieldSet(this, _TypeaheadSearch_timer, setTimeout(function () {
36
- __classPrivateFieldSet(_this, _TypeaheadSearch_buffer, '', "f");
37
- __classPrivateFieldSet(_this, _TypeaheadSearch_lastKey, '', "f");
38
- }, 500), "f");
17
+ if (this.#timer)
18
+ clearTimeout(this.#timer);
19
+ this.#timer = setTimeout(() => {
20
+ this.#buffer = '';
21
+ this.#lastKey = '';
22
+ }, 500);
39
23
  if (isSameKey) {
40
24
  // Same key cycling (D-02): find next match after currentIndex
41
- return __classPrivateFieldGet(this, _TypeaheadSearch_instances, "m", _TypeaheadSearch_cycleMatch).call(this, lowerKey, options, currentIndex);
25
+ return this.#cycleMatch(lowerKey, options, currentIndex);
42
26
  }
43
27
  else {
44
28
  // Accumulate or start fresh
45
- __classPrivateFieldSet(this, _TypeaheadSearch_buffer, withinWindow ? __classPrivateFieldGet(this, _TypeaheadSearch_buffer, "f") + lowerKey : lowerKey, "f");
46
- return __classPrivateFieldGet(this, _TypeaheadSearch_instances, "m", _TypeaheadSearch_findFirst).call(this, __classPrivateFieldGet(this, _TypeaheadSearch_buffer, "f"), options);
29
+ this.#buffer = withinWindow ? this.#buffer + lowerKey : lowerKey;
30
+ return this.#findFirst(this.#buffer, options);
47
31
  }
48
- };
49
- TypeaheadSearch.prototype.destroy = function () {
50
- if (__classPrivateFieldGet(this, _TypeaheadSearch_timer, "f")) {
51
- clearTimeout(__classPrivateFieldGet(this, _TypeaheadSearch_timer, "f"));
52
- __classPrivateFieldSet(this, _TypeaheadSearch_timer, null, "f");
32
+ }
33
+ #getSearchText(option) {
34
+ return (option.textValue ?? option.label).toLowerCase();
35
+ }
36
+ #findFirst(prefix, options) {
37
+ return options.findIndex((o) => !o.disabled && this.#getSearchText(o).startsWith(prefix));
38
+ }
39
+ #cycleMatch(key, options, fromIndex) {
40
+ const prefix = key.toLowerCase();
41
+ const matches = options
42
+ .map((o, i) => ({ i, matches: !o.disabled && this.#getSearchText(o).startsWith(prefix) }))
43
+ .filter((x) => x.matches)
44
+ .map((x) => x.i);
45
+ if (matches.length === 0)
46
+ return -1;
47
+ const afterCurrent = matches.find((i) => i > fromIndex);
48
+ return afterCurrent ?? matches[0]; // wrap around
49
+ }
50
+ destroy() {
51
+ if (this.#timer) {
52
+ clearTimeout(this.#timer);
53
+ this.#timer = null;
53
54
  }
54
- };
55
- return TypeaheadSearch;
56
- }());
57
- _TypeaheadSearch_buffer = new WeakMap(), _TypeaheadSearch_lastKey = new WeakMap(), _TypeaheadSearch_lastTime = new WeakMap(), _TypeaheadSearch_timer = new WeakMap(), _TypeaheadSearch_instances = new WeakSet(), _TypeaheadSearch_getSearchText = function _TypeaheadSearch_getSearchText(option) {
58
- var _a;
59
- return ((_a = option.textValue) !== null && _a !== void 0 ? _a : option.label).toLowerCase();
60
- }, _TypeaheadSearch_findFirst = function _TypeaheadSearch_findFirst(prefix, options) {
61
- var _this = this;
62
- return options.findIndex(function (o) { return !o.disabled && __classPrivateFieldGet(_this, _TypeaheadSearch_instances, "m", _TypeaheadSearch_getSearchText).call(_this, o).startsWith(prefix); });
63
- }, _TypeaheadSearch_cycleMatch = function _TypeaheadSearch_cycleMatch(key, options, fromIndex) {
64
- var _this = this;
65
- var prefix = key.toLowerCase();
66
- var matches = options
67
- .map(function (o, i) { return ({ i: i, matches: !o.disabled && __classPrivateFieldGet(_this, _TypeaheadSearch_instances, "m", _TypeaheadSearch_getSearchText).call(_this, o).startsWith(prefix) }); })
68
- .filter(function (x) { return x.matches; })
69
- .map(function (x) { return x.i; });
70
- if (matches.length === 0)
71
- return -1;
72
- var afterCurrent = matches.find(function (i) { return i > fromIndex; });
73
- return afterCurrent !== null && afterCurrent !== void 0 ? afterCurrent : matches[0]; // wrap around
74
- };
55
+ }
56
+ }
75
57
  export function useTypeaheadSearch() {
76
58
  return new TypeaheadSearch();
77
59
  }
@@ -10,67 +10,53 @@
10
10
  * - Boundary resistance uses RESISTANCE constant from React v1.2.2 source.
11
11
  * - Disabled options are always skipped when computing snap targets.
12
12
  */
13
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
14
- if (kind === "m") throw new TypeError("Private method is not writable");
15
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
16
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
17
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
18
- };
19
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
20
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
21
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
22
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
23
- };
24
- var _WheelPhysics_instances, _WheelPhysics_itemHeight, _WheelPhysics_visibleCount, _WheelPhysics_dragSensitivity, _WheelPhysics_scrollSensitivity, _WheelPhysics_options, _WheelPhysics_onSnap, _WheelPhysics_infinite, _WheelPhysics_rafId, _WheelPhysics_isDragging, _WheelPhysics_dragStartOffset, _WheelPhysics_dragStartY, _WheelPhysics_yList, _WheelPhysics_lastWheelTime, _WheelPhysics_animating, _WheelPhysics_cancelRaf, _WheelPhysics_indexToOffset, _WheelPhysics_offsetToIndex;
25
13
  import { easeOutCubic, indexToOffset, offsetToIndex, clampIndex, wrapIndex, snapToNearestEnabled, calculateVelocity, computeSnapTarget, computeAnimationDuration, RESISTANCE, DEFAULT_DRAG_SENSITIVITY, DEFAULT_SCROLL_SENSITIVITY, DEFAULT_ITEM_HEIGHT, DEFAULT_VISIBLE_COUNT, SNAP_BACK_DECELERATION, } from './wheel-physics-utils.js';
26
14
  // Re-export for convenience so consumers only need one import
27
15
  export { DEFAULT_DRAG_SENSITIVITY, DEFAULT_SCROLL_SENSITIVITY, DEFAULT_ITEM_HEIGHT, DEFAULT_VISIBLE_COUNT, };
28
- var WheelPhysics = /** @class */ (function () {
16
+ export class WheelPhysics {
17
+ // ---------------------------------------------------------------------------
18
+ // Public reactive state ($state) — the ONLY field bound to the DOM transform
19
+ // ---------------------------------------------------------------------------
20
+ offset = $state(0);
21
+ // ---------------------------------------------------------------------------
22
+ // Private configuration (set in constructor, may be updated by update())
23
+ // ---------------------------------------------------------------------------
24
+ #itemHeight;
25
+ #visibleCount;
26
+ #dragSensitivity;
27
+ #scrollSensitivity;
28
+ #options;
29
+ #onSnap;
30
+ #infinite;
31
+ // ---------------------------------------------------------------------------
32
+ // Private non-reactive animation/drag state (NOT $state — Pitfall 2)
33
+ // ---------------------------------------------------------------------------
34
+ /** Current RAF handle — null when no animation running */
35
+ #rafId = null;
36
+ /** True between pointerdown and pointerup */
37
+ #isDragging = false;
38
+ /** The offset value when the current drag began */
39
+ #dragStartOffset = 0;
40
+ /** clientY at the start of the current drag (used for direct delta) */
41
+ #dragStartY = 0;
42
+ /** Recent pointer positions for velocity calculation: [clientY, timestamp][] */
43
+ #yList = [];
44
+ /** Timestamp of the last wheel event (100ms debounce guard) */
45
+ #lastWheelTime = -Infinity;
46
+ /** True while a snap or inertia animation is running */
47
+ #animating = false;
29
48
  // ---------------------------------------------------------------------------
30
49
  // Constructor
31
50
  // ---------------------------------------------------------------------------
32
- function WheelPhysics(opts) {
33
- var _a, _b, _c, _d, _e;
34
- _WheelPhysics_instances.add(this);
35
- // ---------------------------------------------------------------------------
36
- // Public reactive state ($state) — the ONLY field bound to the DOM transform
37
- // ---------------------------------------------------------------------------
38
- this.offset = $state(0);
39
- // ---------------------------------------------------------------------------
40
- // Private configuration (set in constructor, may be updated by update())
41
- // ---------------------------------------------------------------------------
42
- _WheelPhysics_itemHeight.set(this, void 0);
43
- _WheelPhysics_visibleCount.set(this, void 0);
44
- _WheelPhysics_dragSensitivity.set(this, void 0);
45
- _WheelPhysics_scrollSensitivity.set(this, void 0);
46
- _WheelPhysics_options.set(this, void 0);
47
- _WheelPhysics_onSnap.set(this, void 0);
48
- _WheelPhysics_infinite.set(this, void 0);
49
- // ---------------------------------------------------------------------------
50
- // Private non-reactive animation/drag state (NOT $state — Pitfall 2)
51
- // ---------------------------------------------------------------------------
52
- /** Current RAF handle — null when no animation running */
53
- _WheelPhysics_rafId.set(this, null);
54
- /** True between pointerdown and pointerup */
55
- _WheelPhysics_isDragging.set(this, false);
56
- /** The offset value when the current drag began */
57
- _WheelPhysics_dragStartOffset.set(this, 0);
58
- /** clientY at the start of the current drag (used for direct delta) */
59
- _WheelPhysics_dragStartY.set(this, 0);
60
- /** Recent pointer positions for velocity calculation: [clientY, timestamp][] */
61
- _WheelPhysics_yList.set(this, []);
62
- /** Timestamp of the last wheel event (100ms debounce guard) */
63
- _WheelPhysics_lastWheelTime.set(this, -Infinity);
64
- /** True while a snap or inertia animation is running */
65
- _WheelPhysics_animating.set(this, false);
66
- __classPrivateFieldSet(this, _WheelPhysics_itemHeight, (_a = opts.itemHeight) !== null && _a !== void 0 ? _a : DEFAULT_ITEM_HEIGHT, "f");
67
- __classPrivateFieldSet(this, _WheelPhysics_visibleCount, (_b = opts.visibleCount) !== null && _b !== void 0 ? _b : DEFAULT_VISIBLE_COUNT, "f");
68
- __classPrivateFieldSet(this, _WheelPhysics_dragSensitivity, (_c = opts.dragSensitivity) !== null && _c !== void 0 ? _c : DEFAULT_DRAG_SENSITIVITY, "f");
69
- __classPrivateFieldSet(this, _WheelPhysics_scrollSensitivity, (_d = opts.scrollSensitivity) !== null && _d !== void 0 ? _d : DEFAULT_SCROLL_SENSITIVITY, "f");
70
- __classPrivateFieldSet(this, _WheelPhysics_infinite, (_e = opts.infinite) !== null && _e !== void 0 ? _e : false, "f");
71
- __classPrivateFieldSet(this, _WheelPhysics_options, opts.options, "f");
72
- __classPrivateFieldSet(this, _WheelPhysics_onSnap, opts.onSnap, "f");
73
- this.offset = __classPrivateFieldGet(this, _WheelPhysics_instances, "m", _WheelPhysics_indexToOffset).call(this, opts.initialIndex);
51
+ constructor(opts) {
52
+ this.#itemHeight = opts.itemHeight ?? DEFAULT_ITEM_HEIGHT;
53
+ this.#visibleCount = opts.visibleCount ?? DEFAULT_VISIBLE_COUNT;
54
+ this.#dragSensitivity = opts.dragSensitivity ?? DEFAULT_DRAG_SENSITIVITY;
55
+ this.#scrollSensitivity = opts.scrollSensitivity ?? DEFAULT_SCROLL_SENSITIVITY;
56
+ this.#infinite = opts.infinite ?? false;
57
+ this.#options = opts.options;
58
+ this.#onSnap = opts.onSnap;
59
+ this.offset = this.#indexToOffset(opts.initialIndex);
74
60
  }
75
61
  // ---------------------------------------------------------------------------
76
62
  // Configuration update (called when props change in parent component)
@@ -79,47 +65,47 @@ var WheelPhysics = /** @class */ (function () {
79
65
  * Update configuration when parent props change.
80
66
  * This does NOT re-trigger animation — it takes effect on the next interaction.
81
67
  */
82
- WheelPhysics.prototype.update = function (opts) {
68
+ update(opts) {
83
69
  if (opts.itemHeight !== undefined)
84
- __classPrivateFieldSet(this, _WheelPhysics_itemHeight, opts.itemHeight, "f");
70
+ this.#itemHeight = opts.itemHeight;
85
71
  if (opts.visibleCount !== undefined)
86
- __classPrivateFieldSet(this, _WheelPhysics_visibleCount, opts.visibleCount, "f");
72
+ this.#visibleCount = opts.visibleCount;
87
73
  if (opts.dragSensitivity !== undefined)
88
- __classPrivateFieldSet(this, _WheelPhysics_dragSensitivity, opts.dragSensitivity, "f");
74
+ this.#dragSensitivity = opts.dragSensitivity;
89
75
  if (opts.scrollSensitivity !== undefined)
90
- __classPrivateFieldSet(this, _WheelPhysics_scrollSensitivity, opts.scrollSensitivity, "f");
76
+ this.#scrollSensitivity = opts.scrollSensitivity;
91
77
  if (opts.infinite !== undefined)
92
- __classPrivateFieldSet(this, _WheelPhysics_infinite, opts.infinite, "f");
78
+ this.#infinite = opts.infinite;
93
79
  if (opts.options !== undefined)
94
- __classPrivateFieldSet(this, _WheelPhysics_options, opts.options, "f");
80
+ this.#options = opts.options;
95
81
  if (opts.onSnap !== undefined)
96
- __classPrivateFieldSet(this, _WheelPhysics_onSnap, opts.onSnap, "f");
97
- };
82
+ this.#onSnap = opts.onSnap;
83
+ }
98
84
  // ---------------------------------------------------------------------------
99
85
  // Drag handlers (pointer events)
100
86
  // ---------------------------------------------------------------------------
101
87
  /**
102
88
  * Called on pointerdown. Cancels any running animation and begins tracking.
103
89
  */
104
- WheelPhysics.prototype.startDrag = function (clientY) {
105
- __classPrivateFieldGet(this, _WheelPhysics_instances, "m", _WheelPhysics_cancelRaf).call(this);
106
- __classPrivateFieldSet(this, _WheelPhysics_isDragging, true, "f");
107
- __classPrivateFieldSet(this, _WheelPhysics_animating, false, "f");
108
- __classPrivateFieldSet(this, _WheelPhysics_dragStartOffset, this.offset, "f");
109
- __classPrivateFieldSet(this, _WheelPhysics_dragStartY, clientY, "f");
110
- __classPrivateFieldSet(this, _WheelPhysics_yList, [[clientY, performance.now()]], "f");
111
- };
90
+ startDrag(clientY) {
91
+ this.#cancelRaf();
92
+ this.#isDragging = true;
93
+ this.#animating = false;
94
+ this.#dragStartOffset = this.offset;
95
+ this.#dragStartY = clientY;
96
+ this.#yList = [[clientY, performance.now()]];
97
+ }
112
98
  /**
113
99
  * Called on pointermove. Updates offset applying boundary resistance at ends.
114
100
  */
115
- WheelPhysics.prototype.moveDrag = function (clientY) {
116
- if (!__classPrivateFieldGet(this, _WheelPhysics_isDragging, "f"))
101
+ moveDrag(clientY) {
102
+ if (!this.#isDragging)
117
103
  return;
118
- var delta = clientY - __classPrivateFieldGet(this, _WheelPhysics_dragStartY, "f");
119
- var maxOffset = __classPrivateFieldGet(this, _WheelPhysics_instances, "m", _WheelPhysics_indexToOffset).call(this, 0);
120
- var minOffset = __classPrivateFieldGet(this, _WheelPhysics_instances, "m", _WheelPhysics_indexToOffset).call(this, __classPrivateFieldGet(this, _WheelPhysics_options, "f").length - 1);
121
- var newOffset = __classPrivateFieldGet(this, _WheelPhysics_dragStartOffset, "f") + delta;
122
- if (__classPrivateFieldGet(this, _WheelPhysics_infinite, "f")) {
104
+ const delta = clientY - this.#dragStartY;
105
+ const maxOffset = this.#indexToOffset(0);
106
+ const minOffset = this.#indexToOffset(this.#options.length - 1);
107
+ let newOffset = this.#dragStartOffset + delta;
108
+ if (this.#infinite) {
123
109
  // Infinite mode: normalize offset when the drag exceeds the ghost item bounds.
124
110
  // The DOM has 3×N items (before-ghosts + real + after-ghosts), covering rawIndex
125
111
  // -N..2N-1. When the pointer is captured outside the container, the user can drag
@@ -128,18 +114,18 @@ var WheelPhysics = /** @class */ (function () {
128
114
  //
129
115
  // Applying the same shift to #dragStartOffset keeps future delta computations
130
116
  // consistent so the drag feels continuous across the normalization boundary.
131
- var loopDistance = __classPrivateFieldGet(this, _WheelPhysics_options, "f").length * __classPrivateFieldGet(this, _WheelPhysics_itemHeight, "f");
117
+ const loopDistance = this.#options.length * this.#itemHeight;
132
118
  // After-ghost overflow: newOffset went past the last after-ghost (rawIndex >= 2N)
133
- var afterGhostEnd = __classPrivateFieldGet(this, _WheelPhysics_instances, "m", _WheelPhysics_indexToOffset).call(this, 2 * __classPrivateFieldGet(this, _WheelPhysics_options, "f").length);
119
+ const afterGhostEnd = this.#indexToOffset(2 * this.#options.length);
134
120
  // Before-ghost overflow: newOffset went past the first before-ghost (rawIndex < -N)
135
- var beforeGhostEnd = __classPrivateFieldGet(this, _WheelPhysics_instances, "m", _WheelPhysics_indexToOffset).call(this, -__classPrivateFieldGet(this, _WheelPhysics_options, "f").length - 1);
121
+ const beforeGhostEnd = this.#indexToOffset(-this.#options.length - 1);
136
122
  while (newOffset < afterGhostEnd) {
137
123
  newOffset += loopDistance;
138
- __classPrivateFieldSet(this, _WheelPhysics_dragStartOffset, __classPrivateFieldGet(this, _WheelPhysics_dragStartOffset, "f") + loopDistance, "f");
124
+ this.#dragStartOffset += loopDistance;
139
125
  }
140
126
  while (newOffset > beforeGhostEnd) {
141
127
  newOffset -= loopDistance;
142
- __classPrivateFieldSet(this, _WheelPhysics_dragStartOffset, __classPrivateFieldGet(this, _WheelPhysics_dragStartOffset, "f") - loopDistance, "f");
128
+ this.#dragStartOffset -= loopDistance;
143
129
  }
144
130
  }
145
131
  else {
@@ -153,31 +139,31 @@ var WheelPhysics = /** @class */ (function () {
153
139
  }
154
140
  this.offset = newOffset;
155
141
  // Track last 5 pointer positions for velocity calculation
156
- __classPrivateFieldGet(this, _WheelPhysics_yList, "f").push([clientY, performance.now()]);
157
- if (__classPrivateFieldGet(this, _WheelPhysics_yList, "f").length > 5) {
158
- __classPrivateFieldGet(this, _WheelPhysics_yList, "f").shift();
142
+ this.#yList.push([clientY, performance.now()]);
143
+ if (this.#yList.length > 5) {
144
+ this.#yList.shift();
159
145
  }
160
- };
146
+ }
161
147
  /**
162
148
  * Called on pointerup. Computes velocity and kicks off inertia or direct snap.
163
149
  */
164
- WheelPhysics.prototype.endDrag = function () {
165
- console.log('[endDrag] called, isDragging=', __classPrivateFieldGet(this, _WheelPhysics_isDragging, "f"), 'offset=', this.offset);
166
- if (!__classPrivateFieldGet(this, _WheelPhysics_isDragging, "f"))
150
+ endDrag() {
151
+ console.log('[endDrag] called, isDragging=', this.#isDragging, 'offset=', this.offset);
152
+ if (!this.#isDragging)
167
153
  return;
168
- __classPrivateFieldSet(this, _WheelPhysics_isDragging, false, "f");
169
- var velocity = calculateVelocity(__classPrivateFieldGet(this, _WheelPhysics_yList, "f"), __classPrivateFieldGet(this, _WheelPhysics_itemHeight, "f"));
170
- var rawIndex = __classPrivateFieldGet(this, _WheelPhysics_instances, "m", _WheelPhysics_offsetToIndex).call(this, this.offset);
171
- var N = __classPrivateFieldGet(this, _WheelPhysics_options, "f").length;
172
- var currentIndex = __classPrivateFieldGet(this, _WheelPhysics_infinite, "f")
154
+ this.#isDragging = false;
155
+ const velocity = calculateVelocity(this.#yList, this.#itemHeight);
156
+ const rawIndex = this.#offsetToIndex(this.offset);
157
+ const N = this.#options.length;
158
+ const currentIndex = this.#infinite
173
159
  ? wrapIndex(rawIndex, N)
174
160
  : clampIndex(rawIndex, N);
175
- console.log('[endDrag] velocity=', velocity, 'rawIndex=', rawIndex, 'currentIndex=', currentIndex, 'infinite=', __classPrivateFieldGet(this, _WheelPhysics_infinite, "f"));
161
+ console.log('[endDrag] velocity=', velocity, 'rawIndex=', rawIndex, 'currentIndex=', currentIndex, 'infinite=', this.#infinite);
176
162
  if (Math.abs(velocity) < 0.5) {
177
163
  // Slow release — snap directly to nearest enabled option
178
- var snapIndex = snapToNearestEnabled(currentIndex, __classPrivateFieldGet(this, _WheelPhysics_options, "f"));
164
+ const snapIndex = snapToNearestEnabled(currentIndex, this.#options);
179
165
  console.log('[endDrag] slow path, snapIndex=', snapIndex);
180
- if (__classPrivateFieldGet(this, _WheelPhysics_infinite, "f")) {
166
+ if (this.#infinite) {
181
167
  // Preserve ghost-section context so the snap animation continues in the
182
168
  // same direction as the drag rather than jumping backward to real-section.
183
169
  // rawIndex is in [-N, 2N-1] (guaranteed by moveDrag normalization).
@@ -185,7 +171,7 @@ var WheelPhysics = /** @class */ (function () {
185
171
  // before-ghost (rawIndex < 0): animate to snapIndex - N
186
172
  // after-ghost (rawIndex >= N): animate to snapIndex + N
187
173
  // real section (rawIndex in [0, N-1]): animate to snapIndex directly
188
- var loopOffset = rawIndex < 0 ? -N : rawIndex >= N ? N : 0;
174
+ const loopOffset = rawIndex < 0 ? -N : rawIndex >= N ? N : 0;
189
175
  this.animateTo(snapIndex + loopOffset);
190
176
  }
191
177
  else {
@@ -196,25 +182,25 @@ var WheelPhysics = /** @class */ (function () {
196
182
  // Inertia — compute overshoot target
197
183
  // Use rawIndex (not currentIndex) so the overshoot accounts for the current
198
184
  // ghost-loop position, giving the correct item index after inertia deceleration.
199
- var rawTarget = computeSnapTarget(rawIndex, velocity, __classPrivateFieldGet(this, _WheelPhysics_dragSensitivity, "f"));
200
- if (__classPrivateFieldGet(this, _WheelPhysics_infinite, "f")) {
185
+ const rawTarget = computeSnapTarget(rawIndex, velocity, this.#dragSensitivity);
186
+ if (this.#infinite) {
201
187
  // snapIndex is the nearest enabled item to the overshoot target (in [0, N-1])
202
- var wrapped = wrapIndex(rawTarget, N);
203
- var snapIndex = snapToNearestEnabled(wrapped, __classPrivateFieldGet(this, _WheelPhysics_options, "f"));
188
+ const wrapped = wrapIndex(rawTarget, N);
189
+ const snapIndex = snapToNearestEnabled(wrapped, this.#options);
204
190
  // Animate to the ghost-section position of snapIndex matching the current
205
191
  // loop, so the animation moves in the same direction as the drag.
206
192
  // snapIndex is in [0,N-1]; loopOffset is -N, 0, or +N based on current section.
207
- var loopOffset = rawIndex < 0 ? -N : rawIndex >= N ? N : 0;
193
+ const loopOffset = rawIndex < 0 ? -N : rawIndex >= N ? N : 0;
208
194
  console.log('[endDrag] inertia path, rawTarget=', rawTarget, 'wrapped=', wrapped, 'snapIndex=', snapIndex, 'loopOffset=', loopOffset);
209
195
  this.animateTo(snapIndex + loopOffset);
210
196
  }
211
197
  else {
212
- var clamped = clampIndex(rawTarget, N);
213
- var snapIndex = snapToNearestEnabled(clamped, __classPrivateFieldGet(this, _WheelPhysics_options, "f"));
198
+ const clamped = clampIndex(rawTarget, N);
199
+ const snapIndex = snapToNearestEnabled(clamped, this.#options);
214
200
  this.animateTo(snapIndex);
215
201
  }
216
202
  }
217
- };
203
+ }
218
204
  // ---------------------------------------------------------------------------
219
205
  // Wheel event handler
220
206
  // ---------------------------------------------------------------------------
@@ -224,29 +210,29 @@ var WheelPhysics = /** @class */ (function () {
224
210
  * deltaY > 0: scroll down → move to next item (higher index)
225
211
  * deltaY < 0: scroll up → move to previous item (lower index)
226
212
  */
227
- WheelPhysics.prototype.handleWheel = function (deltaY) {
228
- var now = performance.now();
229
- if (now - __classPrivateFieldGet(this, _WheelPhysics_lastWheelTime, "f") < 100)
213
+ handleWheel(deltaY) {
214
+ const now = performance.now();
215
+ if (now - this.#lastWheelTime < 100)
230
216
  return;
231
- __classPrivateFieldSet(this, _WheelPhysics_lastWheelTime, now, "f");
232
- var rawIndex = __classPrivateFieldGet(this, _WheelPhysics_instances, "m", _WheelPhysics_offsetToIndex).call(this, this.offset);
233
- var currentIndex = __classPrivateFieldGet(this, _WheelPhysics_infinite, "f")
234
- ? wrapIndex(rawIndex, __classPrivateFieldGet(this, _WheelPhysics_options, "f").length)
235
- : clampIndex(rawIndex, __classPrivateFieldGet(this, _WheelPhysics_options, "f").length);
217
+ this.#lastWheelTime = now;
218
+ const rawIndex = this.#offsetToIndex(this.offset);
219
+ const currentIndex = this.#infinite
220
+ ? wrapIndex(rawIndex, this.#options.length)
221
+ : clampIndex(rawIndex, this.#options.length);
236
222
  // deltaY > 0 = scroll down = move to next item (increment index)
237
- var direction = deltaY > 0 ? 1 : -1;
238
- if (__classPrivateFieldGet(this, _WheelPhysics_infinite, "f")) {
239
- var next = currentIndex + direction;
240
- var wrapped = wrapIndex(next, __classPrivateFieldGet(this, _WheelPhysics_options, "f").length);
241
- var snapIndex = snapToNearestEnabled(wrapped, __classPrivateFieldGet(this, _WheelPhysics_options, "f"));
223
+ const direction = deltaY > 0 ? 1 : -1;
224
+ if (this.#infinite) {
225
+ const next = currentIndex + direction;
226
+ const wrapped = wrapIndex(next, this.#options.length);
227
+ const snapIndex = snapToNearestEnabled(wrapped, this.#options);
242
228
  this.animateTo(snapIndex);
243
229
  }
244
230
  else {
245
- var targetIndex = clampIndex(currentIndex + direction, __classPrivateFieldGet(this, _WheelPhysics_options, "f").length);
246
- var snapIndex = snapToNearestEnabled(targetIndex, __classPrivateFieldGet(this, _WheelPhysics_options, "f"));
231
+ const targetIndex = clampIndex(currentIndex + direction, this.#options.length);
232
+ const snapIndex = snapToNearestEnabled(targetIndex, this.#options);
247
233
  this.animateTo(snapIndex);
248
234
  }
249
- };
235
+ }
250
236
  // ---------------------------------------------------------------------------
251
237
  // Animation
252
238
  // ---------------------------------------------------------------------------
@@ -256,86 +242,96 @@ var WheelPhysics = /** @class */ (function () {
256
242
  *
257
243
  * Cancels any currently running animation before starting.
258
244
  */
259
- WheelPhysics.prototype.animateTo = function (targetIndex) {
260
- var _this = this;
245
+ animateTo(targetIndex) {
261
246
  console.log('[animateTo] targetIndex=', targetIndex, 'from offset=', this.offset);
262
- __classPrivateFieldGet(this, _WheelPhysics_instances, "m", _WheelPhysics_cancelRaf).call(this);
263
- __classPrivateFieldSet(this, _WheelPhysics_animating, true, "f");
264
- var startOffset = this.offset;
265
- var targetOffset = __classPrivateFieldGet(this, _WheelPhysics_instances, "m", _WheelPhysics_indexToOffset).call(this, targetIndex);
266
- var distance = Math.abs(targetIndex - __classPrivateFieldGet(this, _WheelPhysics_instances, "m", _WheelPhysics_offsetToIndex).call(this, startOffset));
267
- var durationSec = computeAnimationDuration(distance, __classPrivateFieldGet(this, _WheelPhysics_scrollSensitivity, "f"));
268
- var durationMs = durationSec * 1000;
269
- var startTime = performance.now();
270
- var tick = function (now) {
271
- if (!__classPrivateFieldGet(_this, _WheelPhysics_animating, "f"))
247
+ this.#cancelRaf();
248
+ this.#animating = true;
249
+ const startOffset = this.offset;
250
+ const targetOffset = this.#indexToOffset(targetIndex);
251
+ const distance = Math.abs(targetIndex - this.#offsetToIndex(startOffset));
252
+ const durationSec = computeAnimationDuration(distance, this.#scrollSensitivity);
253
+ const durationMs = durationSec * 1000;
254
+ const startTime = performance.now();
255
+ const tick = (now) => {
256
+ if (!this.#animating)
272
257
  return;
273
- var elapsed = now - startTime;
274
- var progress = Math.min(elapsed / durationMs, 1);
275
- var eased = easeOutCubic(progress);
276
- _this.offset = startOffset + (targetOffset - startOffset) * eased;
258
+ const elapsed = now - startTime;
259
+ const progress = Math.min(elapsed / durationMs, 1);
260
+ const eased = easeOutCubic(progress);
261
+ this.offset = startOffset + (targetOffset - startOffset) * eased;
277
262
  if (progress < 1) {
278
- __classPrivateFieldSet(_this, _WheelPhysics_rafId, requestAnimationFrame(tick), "f");
263
+ this.#rafId = requestAnimationFrame(tick);
279
264
  }
280
265
  else {
281
266
  // Snap to exact target to avoid float accumulation
282
- _this.offset = targetOffset;
283
- __classPrivateFieldSet(_this, _WheelPhysics_rafId, null, "f");
284
- __classPrivateFieldSet(_this, _WheelPhysics_animating, false, "f");
285
- __classPrivateFieldGet(_this, _WheelPhysics_onSnap, "f").call(_this, targetIndex);
267
+ this.offset = targetOffset;
268
+ this.#rafId = null;
269
+ this.#animating = false;
270
+ this.#onSnap(targetIndex);
286
271
  }
287
272
  };
288
- __classPrivateFieldSet(this, _WheelPhysics_rafId, requestAnimationFrame(tick), "f");
289
- };
290
- Object.defineProperty(WheelPhysics.prototype, "currentIndex", {
291
- /**
292
- * Returns the option index that the current offset visually corresponds to.
293
- * Used to guard against redundant animations when the wheel is already positioned correctly.
294
- */
295
- get: function () {
296
- var raw = __classPrivateFieldGet(this, _WheelPhysics_instances, "m", _WheelPhysics_offsetToIndex).call(this, this.offset);
297
- return __classPrivateFieldGet(this, _WheelPhysics_infinite, "f")
298
- ? wrapIndex(raw, __classPrivateFieldGet(this, _WheelPhysics_options, "f").length)
299
- : clampIndex(raw, __classPrivateFieldGet(this, _WheelPhysics_options, "f").length);
300
- },
301
- enumerable: false,
302
- configurable: true
303
- });
273
+ this.#rafId = requestAnimationFrame(tick);
274
+ }
275
+ /**
276
+ * Returns the option index that the current offset visually corresponds to.
277
+ * Used to guard against redundant animations when the wheel is already positioned correctly.
278
+ */
279
+ get currentIndex() {
280
+ const raw = this.#offsetToIndex(this.offset);
281
+ return this.#infinite
282
+ ? wrapIndex(raw, this.#options.length)
283
+ : clampIndex(raw, this.#options.length);
284
+ }
304
285
  /**
305
286
  * Immediately sets the offset to the position for the given index, no animation.
306
287
  * Used for initial render and controlled value updates.
307
288
  */
308
- WheelPhysics.prototype.jumpTo = function (index) {
309
- __classPrivateFieldGet(this, _WheelPhysics_instances, "m", _WheelPhysics_cancelRaf).call(this);
310
- this.offset = __classPrivateFieldGet(this, _WheelPhysics_instances, "m", _WheelPhysics_indexToOffset).call(this, index);
311
- };
289
+ jumpTo(index) {
290
+ this.#cancelRaf();
291
+ this.offset = this.#indexToOffset(index);
292
+ }
312
293
  /**
313
294
  * Cancels any in-progress animation.
314
295
  */
315
- WheelPhysics.prototype.cancelAnimation = function () {
316
- __classPrivateFieldGet(this, _WheelPhysics_instances, "m", _WheelPhysics_cancelRaf).call(this);
317
- };
296
+ cancelAnimation() {
297
+ this.#cancelRaf();
298
+ }
318
299
  /**
319
300
  * Cleans up RAF on component destroy.
320
301
  */
321
- WheelPhysics.prototype.destroy = function () {
302
+ destroy() {
322
303
  this.cancelAnimation();
323
- };
324
- return WheelPhysics;
325
- }());
326
- export { WheelPhysics };
327
- _WheelPhysics_itemHeight = new WeakMap(), _WheelPhysics_visibleCount = new WeakMap(), _WheelPhysics_dragSensitivity = new WeakMap(), _WheelPhysics_scrollSensitivity = new WeakMap(), _WheelPhysics_options = new WeakMap(), _WheelPhysics_onSnap = new WeakMap(), _WheelPhysics_infinite = new WeakMap(), _WheelPhysics_rafId = new WeakMap(), _WheelPhysics_isDragging = new WeakMap(), _WheelPhysics_dragStartOffset = new WeakMap(), _WheelPhysics_dragStartY = new WeakMap(), _WheelPhysics_yList = new WeakMap(), _WheelPhysics_lastWheelTime = new WeakMap(), _WheelPhysics_animating = new WeakMap(), _WheelPhysics_instances = new WeakSet(), _WheelPhysics_cancelRaf = function _WheelPhysics_cancelRaf() {
328
- if (__classPrivateFieldGet(this, _WheelPhysics_rafId, "f") !== null) {
329
- cancelAnimationFrame(__classPrivateFieldGet(this, _WheelPhysics_rafId, "f"));
330
- __classPrivateFieldSet(this, _WheelPhysics_rafId, null, "f");
331
304
  }
332
- __classPrivateFieldSet(this, _WheelPhysics_animating, false, "f");
333
- }, _WheelPhysics_indexToOffset = function _WheelPhysics_indexToOffset(index) {
334
- var ghostCount = __classPrivateFieldGet(this, _WheelPhysics_infinite, "f") ? __classPrivateFieldGet(this, _WheelPhysics_options, "f").length : 0;
335
- return indexToOffset(index + ghostCount, __classPrivateFieldGet(this, _WheelPhysics_itemHeight, "f"), __classPrivateFieldGet(this, _WheelPhysics_visibleCount, "f"));
336
- }, _WheelPhysics_offsetToIndex = function _WheelPhysics_offsetToIndex(offset) {
337
- var ghostCount = __classPrivateFieldGet(this, _WheelPhysics_infinite, "f") ? __classPrivateFieldGet(this, _WheelPhysics_options, "f").length : 0;
338
- return offsetToIndex(offset, __classPrivateFieldGet(this, _WheelPhysics_itemHeight, "f"), __classPrivateFieldGet(this, _WheelPhysics_visibleCount, "f")) - ghostCount;
339
- };
305
+ // ---------------------------------------------------------------------------
306
+ // Private helpers
307
+ // ---------------------------------------------------------------------------
308
+ #cancelRaf() {
309
+ if (this.#rafId !== null) {
310
+ cancelAnimationFrame(this.#rafId);
311
+ this.#rafId = null;
312
+ }
313
+ this.#animating = false;
314
+ }
315
+ /**
316
+ * Converts an option index to a translateY offset, accounting for before-ghost
317
+ * rows prepended to the DOM container in infinite mode.
318
+ *
319
+ * In infinite mode the container begins with N = options.length ghost rows, so
320
+ * real item[i] sits at DOM position (N + i) * itemHeight. The offset must be
321
+ * shifted by -N * itemHeight relative to the non-infinite formula.
322
+ */
323
+ #indexToOffset(index) {
324
+ const ghostCount = this.#infinite ? this.#options.length : 0;
325
+ return indexToOffset(index + ghostCount, this.#itemHeight, this.#visibleCount);
326
+ }
327
+ /**
328
+ * Converts a translateY offset back to an option index, accounting for the
329
+ * before-ghost prefix in infinite mode (inverse of #indexToOffset).
330
+ */
331
+ #offsetToIndex(offset) {
332
+ const ghostCount = this.#infinite ? this.#options.length : 0;
333
+ return offsetToIndex(offset, this.#itemHeight, this.#visibleCount) - ghostCount;
334
+ }
335
+ }
340
336
  // Unused export to prevent unused import warnings
341
337
  void SNAP_BACK_DECELERATION;
@@ -11,21 +11,21 @@
11
11
  // Physics constants (from React source v1.2.2)
12
12
  // ---------------------------------------------------------------------------
13
13
  /** Boundary resistance factor — how much drag is applied when pulling past the ends. */
14
- export var RESISTANCE = 0.3;
14
+ export const RESISTANCE = 0.3;
15
15
  /** Maximum scroll velocity in items/second. */
16
- export var MAX_VELOCITY = 30;
16
+ export const MAX_VELOCITY = 30;
17
17
  /** Default drag sensitivity (pointer drag delta multiplier for inertia). */
18
- export var DEFAULT_DRAG_SENSITIVITY = 3;
18
+ export const DEFAULT_DRAG_SENSITIVITY = 3;
19
19
  /** Default scroll sensitivity (wheel event multiplier for snap animation duration). */
20
- export var DEFAULT_SCROLL_SENSITIVITY = 5;
20
+ export const DEFAULT_SCROLL_SENSITIVITY = 5;
21
21
  /** Default height in pixels of each option row. */
22
- export var DEFAULT_ITEM_HEIGHT = 30;
22
+ export const DEFAULT_ITEM_HEIGHT = 30;
23
23
  /** Default number of visible option rows. */
24
- export var DEFAULT_VISIBLE_COUNT = 5;
24
+ export const DEFAULT_VISIBLE_COUNT = 5;
25
25
  /** Deceleration constant used in snap-back calculations. */
26
- export var SNAP_BACK_DECELERATION = 10;
26
+ export const SNAP_BACK_DECELERATION = 10;
27
27
  /** Minimum scaleY for cylindrical mode to prevent items collapsing to zero height. */
28
- export var MIN_CYLINDRICAL_SCALE = 0.1;
28
+ export const MIN_CYLINDRICAL_SCALE = 0.1;
29
29
  // ---------------------------------------------------------------------------
30
30
  // Pure physics functions
31
31
  // ---------------------------------------------------------------------------
@@ -99,18 +99,17 @@ export function wrapIndex(index, optionsLength) {
99
99
  * @returns The nearest enabled index
100
100
  */
101
101
  export function snapToNearestEnabled(targetIndex, options) {
102
- var _a, _b, _c;
103
- if (!((_a = options[targetIndex]) === null || _a === void 0 ? void 0 : _a.disabled)) {
102
+ if (!options[targetIndex]?.disabled) {
104
103
  return targetIndex;
105
104
  }
106
105
  // Walk outward from targetIndex to find the nearest enabled option
107
- for (var delta = 1; delta < options.length; delta++) {
108
- var lower = targetIndex - delta;
109
- var upper = targetIndex + delta;
110
- if (lower >= 0 && !((_b = options[lower]) === null || _b === void 0 ? void 0 : _b.disabled)) {
106
+ for (let delta = 1; delta < options.length; delta++) {
107
+ const lower = targetIndex - delta;
108
+ const upper = targetIndex + delta;
109
+ if (lower >= 0 && !options[lower]?.disabled) {
111
110
  return lower;
112
111
  }
113
- if (upper < options.length && !((_c = options[upper]) === null || _c === void 0 ? void 0 : _c.disabled)) {
112
+ if (upper < options.length && !options[upper]?.disabled) {
114
113
  return upper;
115
114
  }
116
115
  }
@@ -131,13 +130,13 @@ export function calculateVelocity(yList, itemHeight) {
131
130
  if (yList.length < 2) {
132
131
  return 0;
133
132
  }
134
- var _a = yList[yList.length - 2], y1 = _a[0], t1 = _a[1];
135
- var _b = yList[yList.length - 1], y2 = _b[0], t2 = _b[1];
133
+ const [y1, t1] = yList[yList.length - 2];
134
+ const [y2, t2] = yList[yList.length - 1];
136
135
  if (t2 === t1) {
137
136
  return 0;
138
137
  }
139
- var velocity = ((y2 - y1) / itemHeight) * (1000 / (t2 - t1));
140
- var clamped = Math.max(-MAX_VELOCITY, Math.min(MAX_VELOCITY, velocity));
138
+ const velocity = ((y2 - y1) / itemHeight) * (1000 / (t2 - t1));
139
+ const clamped = Math.max(-MAX_VELOCITY, Math.min(MAX_VELOCITY, velocity));
141
140
  return clamped;
142
141
  }
143
142
  /**
@@ -153,11 +152,11 @@ export function calculateVelocity(yList, itemHeight) {
153
152
  * @returns The rounded target index after inertia overshoot
154
153
  */
155
154
  export function computeSnapTarget(currentIndexFromOffset, velocity, dragSensitivity) {
156
- var baseDeceleration = dragSensitivity * 10;
157
- var overshoot = (0.5 * velocity * velocity) / baseDeceleration;
155
+ const baseDeceleration = dragSensitivity * 10;
156
+ const overshoot = (0.5 * velocity * velocity) / baseDeceleration;
158
157
  // Velocity sign is inverted relative to index direction:
159
158
  // drag down (positive velocity) increases offset → decreases index → overshoot toward lower index.
160
- var rawTarget = currentIndexFromOffset - Math.sign(velocity) * overshoot;
159
+ const rawTarget = currentIndexFromOffset - Math.sign(velocity) * overshoot;
161
160
  return Math.round(rawTarget);
162
161
  }
163
162
  /**
@@ -171,7 +170,7 @@ export function computeSnapTarget(currentIndexFromOffset, velocity, dragSensitiv
171
170
  * @returns Animation duration in seconds
172
171
  */
173
172
  export function computeAnimationDuration(distance, scrollSensitivity) {
174
- var raw = Math.sqrt(Math.abs(distance) / scrollSensitivity);
173
+ const raw = Math.sqrt(Math.abs(distance) / scrollSensitivity);
175
174
  return Math.max(0.1, Math.min(0.6, raw));
176
175
  }
177
176
  /**
@@ -193,7 +192,7 @@ export function computeAnimationDuration(distance, scrollSensitivity) {
193
192
  * @returns scaleY in range [MIN_CYLINDRICAL_SCALE, 1.0]
194
193
  */
195
194
  export function cylindricalScaleY(slotIndex, offset, itemHeight, visibleCount) {
196
- var dist = slotIndex + offset / itemHeight - Math.floor(visibleCount / 2);
197
- var angle = (dist * Math.PI) / visibleCount;
195
+ const dist = slotIndex + offset / itemHeight - Math.floor(visibleCount / 2);
196
+ const angle = (dist * Math.PI) / visibleCount;
198
197
  return Math.max(MIN_CYLINDRICAL_SCALE, Math.cos(angle));
199
198
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uinstinct/svelte-wheel-picker",
3
- "version": "0.1.12",
3
+ "version": "0.1.14",
4
4
  "type": "module",
5
5
  "description": "iOS-style wheel picker for Svelte 5 with inertia scrolling, infinite loop, and keyboard navigation",
6
6
  "license": "MIT",