@zag-js/number-input 1.43.0 → 2.0.0-next.1

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.
@@ -8,27 +8,29 @@ declare const getInputId: (ctx: Scope) => any;
8
8
  declare const getIncrementTriggerId: (ctx: Scope) => any;
9
9
  declare const getDecrementTriggerId: (ctx: Scope) => any;
10
10
  declare const getScrubberId: (ctx: Scope) => any;
11
- declare const getCursorId: (ctx: Scope) => string;
11
+ declare const getScrubberCursorId: (ctx: Scope) => any;
12
12
  declare const getLabelId: (ctx: Scope) => any;
13
13
  declare const getInputEl: (ctx: Scope) => HTMLInputElement | null;
14
14
  declare const getIncrementTriggerEl: (ctx: Scope) => HTMLButtonElement | null;
15
15
  declare const getDecrementTriggerEl: (ctx: Scope) => HTMLButtonElement | null;
16
16
  declare const getScrubberEl: (ctx: Scope) => HTMLElement | null;
17
- declare const getCursorEl: (ctx: Scope) => HTMLElement | null;
17
+ declare const getScrubberCursorEl: (ctx: Scope) => HTMLElement | null;
18
18
  declare const getPressedTriggerEl: (ctx: Scope, hint: HintValue | null) => HTMLButtonElement | null;
19
- declare const setupVirtualCursor: (ctx: Scope, point: Point | null) => (() => void) | undefined;
20
- declare const preventTextSelection: (ctx: Scope) => () => void;
21
- declare const getMousemoveValue: (ctx: Scope, opts: {
19
+ declare const preventTextSelection: (ctx: Scope, direction: "horizontal" | "vertical") => () => void;
20
+ interface MousemoveOpts {
22
21
  point: Point | null;
23
22
  isRtl: boolean;
24
23
  event: MouseEvent;
25
- }) => {
24
+ direction: "horizontal" | "vertical";
25
+ teleportDistance?: number | undefined;
26
+ }
27
+ declare const getMousemoveValue: (ctx: Scope, opts: MousemoveOpts) => {
26
28
  hint: string | null;
27
29
  point: {
28
30
  x: number;
29
31
  y: number;
30
32
  };
33
+ delta: number;
31
34
  };
32
- declare const createVirtualCursor: (ctx: Scope, point: Point | null) => void;
33
35
 
34
- export { createVirtualCursor, getCursorEl, getCursorId, getDecrementTriggerEl, getDecrementTriggerId, getIncrementTriggerEl, getIncrementTriggerId, getInputEl, getInputId, getLabelId, getMousemoveValue, getPressedTriggerEl, getRootId, getScrubberEl, getScrubberId, preventTextSelection, setupVirtualCursor };
36
+ export { getDecrementTriggerEl, getDecrementTriggerId, getIncrementTriggerEl, getIncrementTriggerId, getInputEl, getInputId, getLabelId, getMousemoveValue, getPressedTriggerEl, getRootId, getScrubberCursorEl, getScrubberCursorId, getScrubberEl, getScrubberId, preventTextSelection };
@@ -20,9 +20,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/number-input.dom.ts
21
21
  var number_input_dom_exports = {};
22
22
  __export(number_input_dom_exports, {
23
- createVirtualCursor: () => createVirtualCursor,
24
- getCursorEl: () => getCursorEl,
25
- getCursorId: () => getCursorId,
26
23
  getDecrementTriggerEl: () => getDecrementTriggerEl,
27
24
  getDecrementTriggerId: () => getDecrementTriggerId,
28
25
  getIncrementTriggerEl: () => getIncrementTriggerEl,
@@ -33,26 +30,27 @@ __export(number_input_dom_exports, {
33
30
  getMousemoveValue: () => getMousemoveValue,
34
31
  getPressedTriggerEl: () => getPressedTriggerEl,
35
32
  getRootId: () => getRootId,
33
+ getScrubberCursorEl: () => getScrubberCursorEl,
34
+ getScrubberCursorId: () => getScrubberCursorId,
36
35
  getScrubberEl: () => getScrubberEl,
37
36
  getScrubberId: () => getScrubberId,
38
- preventTextSelection: () => preventTextSelection,
39
- setupVirtualCursor: () => setupVirtualCursor
37
+ preventTextSelection: () => preventTextSelection
40
38
  });
41
39
  module.exports = __toCommonJS(number_input_dom_exports);
42
- var import_dom_query = require("@zag-js/dom-query");
43
40
  var import_utils = require("@zag-js/utils");
44
- var getRootId = (ctx) => ctx.ids?.root ?? `number-input:${ctx.id}`;
45
- var getInputId = (ctx) => ctx.ids?.input ?? `number-input:${ctx.id}:input`;
46
- var getIncrementTriggerId = (ctx) => ctx.ids?.incrementTrigger ?? `number-input:${ctx.id}:inc`;
47
- var getDecrementTriggerId = (ctx) => ctx.ids?.decrementTrigger ?? `number-input:${ctx.id}:dec`;
48
- var getScrubberId = (ctx) => ctx.ids?.scrubber ?? `number-input:${ctx.id}:scrubber`;
49
- var getCursorId = (ctx) => `number-input:${ctx.id}:cursor`;
50
- var getLabelId = (ctx) => ctx.ids?.label ?? `number-input:${ctx.id}:label`;
51
- var getInputEl = (ctx) => ctx.getById(getInputId(ctx));
52
- var getIncrementTriggerEl = (ctx) => ctx.getById(getIncrementTriggerId(ctx));
53
- var getDecrementTriggerEl = (ctx) => ctx.getById(getDecrementTriggerId(ctx));
54
- var getScrubberEl = (ctx) => ctx.getById(getScrubberId(ctx));
55
- var getCursorEl = (ctx) => ctx.getDoc().getElementById(getCursorId(ctx));
41
+ var import_number_input = require("./number-input.anatomy.js");
42
+ var getRootId = (ctx) => ctx.ids?.root ?? `${ctx.id}`;
43
+ var getInputId = (ctx) => ctx.ids?.input ?? `${ctx.id}:input`;
44
+ var getIncrementTriggerId = (ctx) => ctx.ids?.incrementTrigger ?? `${ctx.id}:inc`;
45
+ var getDecrementTriggerId = (ctx) => ctx.ids?.decrementTrigger ?? `${ctx.id}:dec`;
46
+ var getScrubberId = (ctx) => ctx.ids?.scrubber ?? `${ctx.id}:scrubber`;
47
+ var getScrubberCursorId = (ctx) => ctx.ids?.scrubberCursor ?? `${ctx.id}:scrubber-cursor`;
48
+ var getLabelId = (ctx) => ctx.ids?.label ?? `${ctx.id}:label`;
49
+ var getInputEl = (ctx) => ctx.query(ctx.selector(import_number_input.parts.input));
50
+ var getIncrementTriggerEl = (ctx) => ctx.query(ctx.selector(import_number_input.parts.incrementTrigger));
51
+ var getDecrementTriggerEl = (ctx) => ctx.query(ctx.selector(import_number_input.parts.decrementTrigger));
52
+ var getScrubberEl = (ctx) => ctx.query(ctx.selector(import_number_input.parts.scrubber));
53
+ var getScrubberCursorEl = (ctx) => ctx.query(ctx.selector(import_number_input.parts.scrubberCursor));
56
54
  var getPressedTriggerEl = (ctx, hint) => {
57
55
  let btnEl = null;
58
56
  if (hint === "increment") {
@@ -63,20 +61,13 @@ var getPressedTriggerEl = (ctx, hint) => {
63
61
  }
64
62
  return btnEl;
65
63
  };
66
- var setupVirtualCursor = (ctx, point) => {
67
- if ((0, import_dom_query.isSafari)()) return;
68
- createVirtualCursor(ctx, point);
69
- return () => {
70
- getCursorEl(ctx)?.remove();
71
- };
72
- };
73
- var preventTextSelection = (ctx) => {
64
+ var preventTextSelection = (ctx, direction) => {
74
65
  const doc = ctx.getDoc();
75
66
  const html = doc.documentElement;
76
67
  const body = doc.body;
77
68
  body.style.pointerEvents = "none";
78
69
  html.style.userSelect = "none";
79
- html.style.cursor = "ew-resize";
70
+ html.style.cursor = direction === "vertical" ? "ns-resize" : "ew-resize";
80
71
  return () => {
81
72
  body.style.pointerEvents = "";
82
73
  html.style.userSelect = "";
@@ -90,49 +81,53 @@ var preventTextSelection = (ctx) => {
90
81
  };
91
82
  };
92
83
  var getMousemoveValue = (ctx, opts) => {
93
- const { point, isRtl, event } = opts;
84
+ const { point, isRtl, event, direction, teleportDistance } = opts;
94
85
  const win = ctx.getWin();
95
86
  const x = (0, import_utils.roundToDpr)(event.movementX, win.devicePixelRatio);
96
87
  const y = (0, import_utils.roundToDpr)(event.movementY, win.devicePixelRatio);
97
- let hint = x > 0 ? "increment" : x < 0 ? "decrement" : null;
98
- if (isRtl && hint === "increment") hint = "decrement";
99
- if (isRtl && hint === "decrement") hint = "increment";
88
+ const isVertical = direction === "vertical";
89
+ const delta = isVertical ? y : x;
90
+ let hint;
91
+ if (isVertical) {
92
+ hint = delta < 0 ? "increment" : delta > 0 ? "decrement" : null;
93
+ } else {
94
+ hint = delta > 0 ? "increment" : delta < 0 ? "decrement" : null;
95
+ }
96
+ if (!isVertical && isRtl) {
97
+ if (hint === "increment") hint = "decrement";
98
+ else if (hint === "decrement") hint = "increment";
99
+ }
100
100
  const newPoint = { x: point.x + x, y: point.y + y };
101
- const width = win.innerWidth;
102
101
  const half = (0, import_utils.roundToDpr)(7.5, win.devicePixelRatio);
103
- newPoint.x = (0, import_utils.wrap)(newPoint.x + half, width) - half;
104
- return { hint, point: newPoint };
105
- };
106
- var createVirtualCursor = (ctx, point) => {
107
- const doc = ctx.getDoc();
108
- const el = doc.createElement("div");
109
- el.className = "scrubber--cursor";
110
- el.id = getCursorId(ctx);
111
- Object.assign(el.style, {
112
- width: "15px",
113
- height: "15px",
114
- position: "fixed",
115
- pointerEvents: "none",
116
- left: "0px",
117
- top: "0px",
118
- zIndex: import_dom_query.MAX_Z_INDEX,
119
- transform: point ? `translate3d(${point.x}px, ${point.y}px, 0px)` : void 0,
120
- willChange: "transform"
121
- });
122
- el.innerHTML = `
123
- <svg width="46" height="15" style="left: -15.5px; position: absolute; top: 0; filter: drop-shadow(rgba(0, 0, 0, 0.4) 0px 1px 1.1px);">
124
- <g transform="translate(2 3)">
125
- <path fill-rule="evenodd" d="M 15 4.5L 15 2L 11.5 5.5L 15 9L 15 6.5L 31 6.5L 31 9L 34.5 5.5L 31 2L 31 4.5Z" style="stroke-width: 2px; stroke: white;"></path>
126
- <path fill-rule="evenodd" d="M 15 4.5L 15 2L 11.5 5.5L 15 9L 15 6.5L 31 6.5L 31 9L 34.5 5.5L 31 2L 31 4.5Z"></path>
127
- </g>
128
- </svg>`;
129
- doc.body.appendChild(el);
102
+ if (teleportDistance != null) {
103
+ const scrubberEl = getScrubberEl(ctx);
104
+ if (scrubberEl) {
105
+ const rect = scrubberEl.getBoundingClientRect();
106
+ if (isVertical) {
107
+ const center = rect.top + rect.height / 2;
108
+ const min = center - teleportDistance / 2;
109
+ const max = center + teleportDistance / 2;
110
+ newPoint.y = (0, import_utils.wrap)(newPoint.y + half - min, max - min) + min - half;
111
+ } else {
112
+ const center = rect.left + rect.width / 2;
113
+ const min = center - teleportDistance / 2;
114
+ const max = center + teleportDistance / 2;
115
+ newPoint.x = (0, import_utils.wrap)(newPoint.x + half - min, max - min) + min - half;
116
+ }
117
+ }
118
+ } else {
119
+ if (isVertical) {
120
+ const height = win.innerHeight;
121
+ newPoint.y = (0, import_utils.wrap)(newPoint.y + half, height) - half;
122
+ } else {
123
+ const width = win.innerWidth;
124
+ newPoint.x = (0, import_utils.wrap)(newPoint.x + half, width) - half;
125
+ }
126
+ }
127
+ return { hint, point: newPoint, delta };
130
128
  };
131
129
  // Annotate the CommonJS export names for ESM import in node:
132
130
  0 && (module.exports = {
133
- createVirtualCursor,
134
- getCursorEl,
135
- getCursorId,
136
131
  getDecrementTriggerEl,
137
132
  getDecrementTriggerId,
138
133
  getIncrementTriggerEl,
@@ -143,8 +138,9 @@ var createVirtualCursor = (ctx, point) => {
143
138
  getMousemoveValue,
144
139
  getPressedTriggerEl,
145
140
  getRootId,
141
+ getScrubberCursorEl,
142
+ getScrubberCursorId,
146
143
  getScrubberEl,
147
144
  getScrubberId,
148
- preventTextSelection,
149
- setupVirtualCursor
145
+ preventTextSelection
150
146
  });
@@ -1,18 +1,18 @@
1
1
  // src/number-input.dom.ts
2
- import { isSafari, MAX_Z_INDEX } from "@zag-js/dom-query";
3
2
  import { roundToDpr, wrap } from "@zag-js/utils";
4
- var getRootId = (ctx) => ctx.ids?.root ?? `number-input:${ctx.id}`;
5
- var getInputId = (ctx) => ctx.ids?.input ?? `number-input:${ctx.id}:input`;
6
- var getIncrementTriggerId = (ctx) => ctx.ids?.incrementTrigger ?? `number-input:${ctx.id}:inc`;
7
- var getDecrementTriggerId = (ctx) => ctx.ids?.decrementTrigger ?? `number-input:${ctx.id}:dec`;
8
- var getScrubberId = (ctx) => ctx.ids?.scrubber ?? `number-input:${ctx.id}:scrubber`;
9
- var getCursorId = (ctx) => `number-input:${ctx.id}:cursor`;
10
- var getLabelId = (ctx) => ctx.ids?.label ?? `number-input:${ctx.id}:label`;
11
- var getInputEl = (ctx) => ctx.getById(getInputId(ctx));
12
- var getIncrementTriggerEl = (ctx) => ctx.getById(getIncrementTriggerId(ctx));
13
- var getDecrementTriggerEl = (ctx) => ctx.getById(getDecrementTriggerId(ctx));
14
- var getScrubberEl = (ctx) => ctx.getById(getScrubberId(ctx));
15
- var getCursorEl = (ctx) => ctx.getDoc().getElementById(getCursorId(ctx));
3
+ import { parts } from "./number-input.anatomy.mjs";
4
+ var getRootId = (ctx) => ctx.ids?.root ?? `${ctx.id}`;
5
+ var getInputId = (ctx) => ctx.ids?.input ?? `${ctx.id}:input`;
6
+ var getIncrementTriggerId = (ctx) => ctx.ids?.incrementTrigger ?? `${ctx.id}:inc`;
7
+ var getDecrementTriggerId = (ctx) => ctx.ids?.decrementTrigger ?? `${ctx.id}:dec`;
8
+ var getScrubberId = (ctx) => ctx.ids?.scrubber ?? `${ctx.id}:scrubber`;
9
+ var getScrubberCursorId = (ctx) => ctx.ids?.scrubberCursor ?? `${ctx.id}:scrubber-cursor`;
10
+ var getLabelId = (ctx) => ctx.ids?.label ?? `${ctx.id}:label`;
11
+ var getInputEl = (ctx) => ctx.query(ctx.selector(parts.input));
12
+ var getIncrementTriggerEl = (ctx) => ctx.query(ctx.selector(parts.incrementTrigger));
13
+ var getDecrementTriggerEl = (ctx) => ctx.query(ctx.selector(parts.decrementTrigger));
14
+ var getScrubberEl = (ctx) => ctx.query(ctx.selector(parts.scrubber));
15
+ var getScrubberCursorEl = (ctx) => ctx.query(ctx.selector(parts.scrubberCursor));
16
16
  var getPressedTriggerEl = (ctx, hint) => {
17
17
  let btnEl = null;
18
18
  if (hint === "increment") {
@@ -23,20 +23,13 @@ var getPressedTriggerEl = (ctx, hint) => {
23
23
  }
24
24
  return btnEl;
25
25
  };
26
- var setupVirtualCursor = (ctx, point) => {
27
- if (isSafari()) return;
28
- createVirtualCursor(ctx, point);
29
- return () => {
30
- getCursorEl(ctx)?.remove();
31
- };
32
- };
33
- var preventTextSelection = (ctx) => {
26
+ var preventTextSelection = (ctx, direction) => {
34
27
  const doc = ctx.getDoc();
35
28
  const html = doc.documentElement;
36
29
  const body = doc.body;
37
30
  body.style.pointerEvents = "none";
38
31
  html.style.userSelect = "none";
39
- html.style.cursor = "ew-resize";
32
+ html.style.cursor = direction === "vertical" ? "ns-resize" : "ew-resize";
40
33
  return () => {
41
34
  body.style.pointerEvents = "";
42
35
  html.style.userSelect = "";
@@ -50,48 +43,52 @@ var preventTextSelection = (ctx) => {
50
43
  };
51
44
  };
52
45
  var getMousemoveValue = (ctx, opts) => {
53
- const { point, isRtl, event } = opts;
46
+ const { point, isRtl, event, direction, teleportDistance } = opts;
54
47
  const win = ctx.getWin();
55
48
  const x = roundToDpr(event.movementX, win.devicePixelRatio);
56
49
  const y = roundToDpr(event.movementY, win.devicePixelRatio);
57
- let hint = x > 0 ? "increment" : x < 0 ? "decrement" : null;
58
- if (isRtl && hint === "increment") hint = "decrement";
59
- if (isRtl && hint === "decrement") hint = "increment";
50
+ const isVertical = direction === "vertical";
51
+ const delta = isVertical ? y : x;
52
+ let hint;
53
+ if (isVertical) {
54
+ hint = delta < 0 ? "increment" : delta > 0 ? "decrement" : null;
55
+ } else {
56
+ hint = delta > 0 ? "increment" : delta < 0 ? "decrement" : null;
57
+ }
58
+ if (!isVertical && isRtl) {
59
+ if (hint === "increment") hint = "decrement";
60
+ else if (hint === "decrement") hint = "increment";
61
+ }
60
62
  const newPoint = { x: point.x + x, y: point.y + y };
61
- const width = win.innerWidth;
62
63
  const half = roundToDpr(7.5, win.devicePixelRatio);
63
- newPoint.x = wrap(newPoint.x + half, width) - half;
64
- return { hint, point: newPoint };
65
- };
66
- var createVirtualCursor = (ctx, point) => {
67
- const doc = ctx.getDoc();
68
- const el = doc.createElement("div");
69
- el.className = "scrubber--cursor";
70
- el.id = getCursorId(ctx);
71
- Object.assign(el.style, {
72
- width: "15px",
73
- height: "15px",
74
- position: "fixed",
75
- pointerEvents: "none",
76
- left: "0px",
77
- top: "0px",
78
- zIndex: MAX_Z_INDEX,
79
- transform: point ? `translate3d(${point.x}px, ${point.y}px, 0px)` : void 0,
80
- willChange: "transform"
81
- });
82
- el.innerHTML = `
83
- <svg width="46" height="15" style="left: -15.5px; position: absolute; top: 0; filter: drop-shadow(rgba(0, 0, 0, 0.4) 0px 1px 1.1px);">
84
- <g transform="translate(2 3)">
85
- <path fill-rule="evenodd" d="M 15 4.5L 15 2L 11.5 5.5L 15 9L 15 6.5L 31 6.5L 31 9L 34.5 5.5L 31 2L 31 4.5Z" style="stroke-width: 2px; stroke: white;"></path>
86
- <path fill-rule="evenodd" d="M 15 4.5L 15 2L 11.5 5.5L 15 9L 15 6.5L 31 6.5L 31 9L 34.5 5.5L 31 2L 31 4.5Z"></path>
87
- </g>
88
- </svg>`;
89
- doc.body.appendChild(el);
64
+ if (teleportDistance != null) {
65
+ const scrubberEl = getScrubberEl(ctx);
66
+ if (scrubberEl) {
67
+ const rect = scrubberEl.getBoundingClientRect();
68
+ if (isVertical) {
69
+ const center = rect.top + rect.height / 2;
70
+ const min = center - teleportDistance / 2;
71
+ const max = center + teleportDistance / 2;
72
+ newPoint.y = wrap(newPoint.y + half - min, max - min) + min - half;
73
+ } else {
74
+ const center = rect.left + rect.width / 2;
75
+ const min = center - teleportDistance / 2;
76
+ const max = center + teleportDistance / 2;
77
+ newPoint.x = wrap(newPoint.x + half - min, max - min) + min - half;
78
+ }
79
+ }
80
+ } else {
81
+ if (isVertical) {
82
+ const height = win.innerHeight;
83
+ newPoint.y = wrap(newPoint.y + half, height) - half;
84
+ } else {
85
+ const width = win.innerWidth;
86
+ newPoint.x = wrap(newPoint.x + half, width) - half;
87
+ }
88
+ }
89
+ return { hint, point: newPoint, delta };
90
90
  };
91
91
  export {
92
- createVirtualCursor,
93
- getCursorEl,
94
- getCursorId,
95
92
  getDecrementTriggerEl,
96
93
  getDecrementTriggerId,
97
94
  getIncrementTriggerEl,
@@ -102,8 +99,9 @@ export {
102
99
  getMousemoveValue,
103
100
  getPressedTriggerEl,
104
101
  getRootId,
102
+ getScrubberCursorEl,
103
+ getScrubberCursorId,
105
104
  getScrubberEl,
106
105
  getScrubberId,
107
- preventTextSelection,
108
- setupVirtualCursor
106
+ preventTextSelection
109
107
  };
@@ -57,6 +57,9 @@ var machine = createMachine({
57
57
  min: Number.MIN_SAFE_INTEGER,
58
58
  max: Number.MAX_SAFE_INTEGER,
59
59
  spinOnPress: true,
60
+ scrubberPixelSensitivity: 2,
61
+ scrubberDirection: "horizontal",
62
+ snapOnStep: false,
60
63
  ...props,
61
64
  largeStep: props.largeStep ?? 10 * step,
62
65
  smallStep: props.smallStep ?? step / 10,
@@ -88,7 +91,10 @@ var machine = createMachine({
88
91
  return value ? `x:${value.x}, y:${value.y}` : "";
89
92
  }
90
93
  })),
91
- fieldsetDisabled: bindable(() => ({ defaultValue: false }))
94
+ fieldsetDisabled: bindable(() => ({ defaultValue: false })),
95
+ cumulativeDelta: bindable(() => ({ defaultValue: 0 })),
96
+ isPointerLockSupported: bindable(() => ({ defaultValue: false })),
97
+ visualScale: bindable(() => ({ defaultValue: 1 }))
92
98
  };
93
99
  },
94
100
  computed: {
@@ -123,7 +129,7 @@ var machine = createMachine({
123
129
  action(["setVirtualCursorPosition"]);
124
130
  });
125
131
  },
126
- effects: ["trackFormControl"],
132
+ effects: ["trackFormControl", "detectPointerLock"],
127
133
  on: {
128
134
  "VALUE.SET": {
129
135
  actions: ["setRawValue"]
@@ -246,22 +252,16 @@ var machine = createMachine({
246
252
  },
247
253
  scrubbing: {
248
254
  tags: ["focus"],
249
- effects: ["activatePointerLock", "trackMousemove", "setupVirtualCursor", "preventTextSelection"],
255
+ effects: ["activatePointerLock", "trackMousemove", "preventTextSelection", "trackVisualViewport"],
256
+ entry: ["clearCumulativeDelta"],
250
257
  on: {
251
258
  "SCRUBBER.POINTER_UP": {
252
259
  target: "focused",
253
- actions: ["focusInput", "clearCursorPoint"]
260
+ actions: ["focusInput", "clearCursorPoint", "clearCumulativeDelta"]
254
261
  },
255
- "SCRUBBER.POINTER_MOVE": [
256
- {
257
- guard: "isIncrementHint",
258
- actions: ["increment", "setCursorPoint"]
259
- },
260
- {
261
- guard: "isDecrementHint",
262
- actions: ["decrement", "setCursorPoint"]
263
- }
264
- ]
262
+ "SCRUBBER.POINTER_MOVE": {
263
+ actions: ["accumulateDelta", "setCursorPoint"]
264
+ }
265
265
  }
266
266
  }
267
267
  },
@@ -288,6 +288,9 @@ var machine = createMachine({
288
288
  }, 50);
289
289
  return () => clearInterval(id);
290
290
  },
291
+ detectPointerLock({ context }) {
292
+ context.set("isPointerLockSupported", !(0, import_dom_query.isSafari)());
293
+ },
291
294
  trackFormControl({ context, scope }) {
292
295
  const inputEl = dom.getInputEl(scope);
293
296
  return (0, import_dom_query.trackFormControl)(inputEl, {
@@ -299,12 +302,8 @@ var machine = createMachine({
299
302
  }
300
303
  });
301
304
  },
302
- setupVirtualCursor({ context, scope }) {
303
- const point = context.get("scrubberCursorPoint");
304
- return dom.setupVirtualCursor(scope, point);
305
- },
306
- preventTextSelection({ scope }) {
307
- return dom.preventTextSelection(scope);
305
+ preventTextSelection({ scope, prop }) {
306
+ return dom.preventTextSelection(scope, prop("scrubberDirection"));
308
307
  },
309
308
  trackButtonDisabled({ context, scope, send }) {
310
309
  const hint = context.get("hint");
@@ -330,21 +329,39 @@ var machine = createMachine({
330
329
  }
331
330
  return (0, import_dom_query.addDomEvent)(inputEl, "wheel", onWheel, { passive: false });
332
331
  },
332
+ trackVisualViewport({ scope, context }) {
333
+ const vV = scope.getWin().visualViewport;
334
+ if (!vV) return;
335
+ function onResize() {
336
+ context.set("visualScale", vV.scale);
337
+ }
338
+ onResize();
339
+ return (0, import_dom_query.addDomEvent)(vV, "resize", onResize);
340
+ },
333
341
  activatePointerLock({ scope }) {
334
342
  if ((0, import_dom_query.isSafari)()) return;
335
- return (0, import_dom_query.requestPointerLock)(scope.getDoc());
343
+ const cleanup = (0, import_dom_query.requestPointerLock)(scope.getDoc());
344
+ return () => {
345
+ if ((0, import_dom_query.isFirefox)()) {
346
+ setTimeout(() => cleanup?.(), 20);
347
+ } else {
348
+ cleanup?.();
349
+ }
350
+ };
336
351
  },
337
- trackMousemove({ scope, send, context, computed }) {
352
+ trackMousemove({ scope, send, context, computed, prop }) {
338
353
  const doc = scope.getDoc();
339
354
  function onMousemove(event) {
340
355
  const point = context.get("scrubberCursorPoint");
341
356
  const isRtl = computed("isRtl");
342
- const value = dom.getMousemoveValue(scope, { point, isRtl, event });
343
- if (!value.hint) return;
357
+ const direction = prop("scrubberDirection");
358
+ const teleportDistance = prop("scrubberTeleportDistance");
359
+ const value = dom.getMousemoveValue(scope, { point, isRtl, event, direction, teleportDistance });
344
360
  send({
345
361
  type: "SCRUBBER.POINTER_MOVE",
346
362
  hint: value.hint,
347
- point: value.point
363
+ point: value.point,
364
+ delta: value.delta
348
365
  });
349
366
  }
350
367
  function onMouseup() {
@@ -363,11 +380,15 @@ var machine = createMachine({
363
380
  increment({ context, event, prop, computed }) {
364
381
  let nextValue = (0, import_utils.incrementValue)(computed("valueAsNumber"), event.step ?? prop("step"));
365
382
  if (!prop("allowOverflow")) nextValue = (0, import_utils.clampValue)(nextValue, prop("min"), prop("max"));
383
+ if (prop("snapOnStep"))
384
+ nextValue = (0, import_utils.snapValueToStep)(nextValue, prop("min"), prop("max"), event.step ?? prop("step"));
366
385
  context.set("value", (0, import_number_input.formatValue)(nextValue, { computed, prop }));
367
386
  },
368
387
  decrement({ context, event, prop, computed }) {
369
388
  let nextValue = (0, import_utils.decrementValue)(computed("valueAsNumber"), event.step ?? prop("step"));
370
389
  if (!prop("allowOverflow")) nextValue = (0, import_utils.clampValue)(nextValue, prop("min"), prop("max"));
390
+ if (prop("snapOnStep"))
391
+ nextValue = (0, import_utils.snapValueToStep)(nextValue, prop("min"), prop("max"), event.step ?? prop("step"));
371
392
  context.set("value", (0, import_number_input.formatValue)(nextValue, { computed, prop }));
372
393
  },
373
394
  setClampedValue({ context, prop, computed }) {
@@ -449,10 +470,31 @@ var machine = createMachine({
449
470
  context.set("scrubberCursorPoint", null);
450
471
  },
451
472
  setVirtualCursorPosition({ context, scope }) {
452
- const cursorEl = dom.getCursorEl(scope);
473
+ const scrubberEl = dom.getScrubberEl(scope);
453
474
  const point = context.get("scrubberCursorPoint");
454
- if (!cursorEl || !point) return;
455
- cursorEl.style.transform = `translate3d(${point.x}px, ${point.y}px, 0px)`;
475
+ if (!scrubberEl || !point) return;
476
+ scrubberEl.style.setProperty("--scrubber-x", `${point.x}px`);
477
+ scrubberEl.style.setProperty("--scrubber-y", `${point.y}px`);
478
+ },
479
+ accumulateDelta({ context, event, prop, send }) {
480
+ const delta = event.delta ?? 0;
481
+ const newDelta = context.get("cumulativeDelta") + delta;
482
+ const sensitivity = prop("scrubberPixelSensitivity");
483
+ if (Math.abs(newDelta) >= sensitivity) {
484
+ const step = prop("step");
485
+ const hint = event.hint;
486
+ if (hint === "increment") {
487
+ send({ type: "VALUE.INCREMENT", step });
488
+ } else if (hint === "decrement") {
489
+ send({ type: "VALUE.DECREMENT", step });
490
+ }
491
+ context.set("cumulativeDelta", newDelta % sensitivity);
492
+ } else {
493
+ context.set("cumulativeDelta", newDelta);
494
+ }
495
+ },
496
+ clearCumulativeDelta({ context }) {
497
+ context.set("cumulativeDelta", 0);
456
498
  }
457
499
  }
458
500
  }