@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.
package/dist/index.d.mts CHANGED
@@ -2,7 +2,7 @@ export { anatomy } from './number-input.anatomy.mjs';
2
2
  export { connect } from './number-input.connect.mjs';
3
3
  export { machine } from './number-input.machine.mjs';
4
4
  export { props, splitProps } from './number-input.props.mjs';
5
- export { NumberInputApi as Api, ElementIds, FocusChangeDetails, HintValue, InputMode, IntlTranslations, NumberInputMachine as Machine, NumberInputProps as Props, NumberInputService as Service, ValidityState, ValueChangeDetails, ValueInvalidDetails } from './number-input.types.mjs';
5
+ export { NumberInputApi as Api, DecrementTriggerState, ElementIds, FocusChangeDetails, HintValue, IncrementTriggerState, InputMode, InputState, IntlTranslations, NumberInputMachine as Machine, NumberInputProps as Props, RootState, NumberInputService as Service, ValidityState, ValueChangeDetails, ValueInvalidDetails } from './number-input.types.mjs';
6
6
  import '@zag-js/anatomy';
7
7
  import '@zag-js/types';
8
8
  import '@zag-js/core';
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ export { anatomy } from './number-input.anatomy.js';
2
2
  export { connect } from './number-input.connect.js';
3
3
  export { machine } from './number-input.machine.js';
4
4
  export { props, splitProps } from './number-input.props.js';
5
- export { NumberInputApi as Api, ElementIds, FocusChangeDetails, HintValue, InputMode, IntlTranslations, NumberInputMachine as Machine, NumberInputProps as Props, NumberInputService as Service, ValidityState, ValueChangeDetails, ValueInvalidDetails } from './number-input.types.js';
5
+ export { NumberInputApi as Api, DecrementTriggerState, ElementIds, FocusChangeDetails, HintValue, IncrementTriggerState, InputMode, InputState, IntlTranslations, NumberInputMachine as Machine, NumberInputProps as Props, RootState, NumberInputService as Service, ValidityState, ValueChangeDetails, ValueInvalidDetails } from './number-input.types.js';
6
6
  import '@zag-js/anatomy';
7
7
  import '@zag-js/types';
8
8
  import '@zag-js/core';
@@ -1,6 +1,6 @@
1
1
  import * as _zag_js_anatomy from '@zag-js/anatomy';
2
2
 
3
- declare const anatomy: _zag_js_anatomy.AnatomyInstance<"root" | "label" | "input" | "control" | "valueText" | "incrementTrigger" | "decrementTrigger" | "scrubber">;
4
- declare const parts: Record<"root" | "label" | "input" | "control" | "valueText" | "incrementTrigger" | "decrementTrigger" | "scrubber", _zag_js_anatomy.AnatomyPart>;
3
+ declare const anatomy: _zag_js_anatomy.AnatomyInstance<"root" | "label" | "input" | "control" | "valueText" | "incrementTrigger" | "decrementTrigger" | "scrubber" | "scrubberCursor">;
4
+ declare const parts: Record<"root" | "label" | "input" | "control" | "valueText" | "incrementTrigger" | "decrementTrigger" | "scrubber" | "scrubberCursor", _zag_js_anatomy.AnatomyPart>;
5
5
 
6
6
  export { anatomy, parts };
@@ -1,6 +1,6 @@
1
1
  import * as _zag_js_anatomy from '@zag-js/anatomy';
2
2
 
3
- declare const anatomy: _zag_js_anatomy.AnatomyInstance<"root" | "label" | "input" | "control" | "valueText" | "incrementTrigger" | "decrementTrigger" | "scrubber">;
4
- declare const parts: Record<"root" | "label" | "input" | "control" | "valueText" | "incrementTrigger" | "decrementTrigger" | "scrubber", _zag_js_anatomy.AnatomyPart>;
3
+ declare const anatomy: _zag_js_anatomy.AnatomyInstance<"root" | "label" | "input" | "control" | "valueText" | "incrementTrigger" | "decrementTrigger" | "scrubber" | "scrubberCursor">;
4
+ declare const parts: Record<"root" | "label" | "input" | "control" | "valueText" | "incrementTrigger" | "decrementTrigger" | "scrubber" | "scrubberCursor", _zag_js_anatomy.AnatomyPart>;
5
5
 
6
6
  export { anatomy, parts };
@@ -33,7 +33,8 @@ var anatomy = (0, import_anatomy.createAnatomy)("numberInput").parts(
33
33
  "valueText",
34
34
  "incrementTrigger",
35
35
  "decrementTrigger",
36
- "scrubber"
36
+ "scrubber",
37
+ "scrubberCursor"
37
38
  );
38
39
  var parts = anatomy.build();
39
40
  // Annotate the CommonJS export names for ESM import in node:
@@ -8,7 +8,8 @@ var anatomy = createAnatomy("numberInput").parts(
8
8
  "valueText",
9
9
  "incrementTrigger",
10
10
  "decrementTrigger",
11
- "scrubber"
11
+ "scrubber",
12
+ "scrubberCursor"
12
13
  );
13
14
  var parts = anatomy.build();
14
15
  export {
@@ -39,7 +39,7 @@ var import_cursor = require("./cursor.js");
39
39
  var import_number_input = require("./number-input.anatomy.js");
40
40
  var dom = __toESM(require("./number-input.dom.js"));
41
41
  function connect(service, normalize) {
42
- const { state, send, prop, scope, computed } = service;
42
+ const { state, send, prop, scope, computed, context } = service;
43
43
  const focused = state.hasTag("focus");
44
44
  const disabled = computed("isDisabled");
45
45
  const readOnly = !!prop("readOnly");
@@ -50,8 +50,21 @@ function connect(service, normalize) {
50
50
  const isIncrementDisabled = disabled || !computed("canIncrement") || readOnly;
51
51
  const isDecrementDisabled = disabled || !computed("canDecrement") || readOnly;
52
52
  const translations = prop("translations");
53
+ function getRootState() {
54
+ return { disabled, focused, invalid, scrubbing };
55
+ }
56
+ function getInputState() {
57
+ return { disabled, invalid, readOnly, scrubbing };
58
+ }
59
+ function getIncrementTriggerState() {
60
+ return { disabled: isIncrementDisabled };
61
+ }
62
+ function getDecrementTriggerState() {
63
+ return { disabled: isDecrementDisabled };
64
+ }
53
65
  return {
54
66
  focused,
67
+ scrubbing,
55
68
  invalid,
56
69
  empty,
57
70
  value: computed("formattedValue"),
@@ -77,20 +90,21 @@ function connect(service, normalize) {
77
90
  focus() {
78
91
  dom.getInputEl(scope)?.focus();
79
92
  },
93
+ getRootState,
80
94
  getRootProps() {
95
+ const rootState = getRootState();
81
96
  return normalize.element({
82
- id: dom.getRootId(scope),
83
- ...import_number_input.parts.root.attrs,
97
+ ...import_number_input.parts.root.attrs(scope.id),
84
98
  dir: prop("dir"),
85
- "data-disabled": (0, import_dom_query.dataAttr)(disabled),
86
- "data-focus": (0, import_dom_query.dataAttr)(focused),
87
- "data-invalid": (0, import_dom_query.dataAttr)(invalid),
88
- "data-scrubbing": (0, import_dom_query.dataAttr)(scrubbing)
99
+ "data-disabled": (0, import_dom_query.dataAttr)(rootState.disabled),
100
+ "data-focus": (0, import_dom_query.dataAttr)(rootState.focused),
101
+ "data-invalid": (0, import_dom_query.dataAttr)(rootState.invalid),
102
+ "data-scrubbing": (0, import_dom_query.dataAttr)(rootState.scrubbing)
89
103
  });
90
104
  },
91
105
  getLabelProps() {
92
106
  return normalize.label({
93
- ...import_number_input.parts.label.attrs,
107
+ ...import_number_input.parts.label.attrs(scope.id),
94
108
  dir: prop("dir"),
95
109
  "data-disabled": (0, import_dom_query.dataAttr)(disabled),
96
110
  "data-focus": (0, import_dom_query.dataAttr)(focused),
@@ -108,7 +122,7 @@ function connect(service, normalize) {
108
122
  },
109
123
  getControlProps() {
110
124
  return normalize.element({
111
- ...import_number_input.parts.control.attrs,
125
+ ...import_number_input.parts.control.attrs(scope.id),
112
126
  dir: prop("dir"),
113
127
  role: "group",
114
128
  "aria-disabled": disabled,
@@ -121,7 +135,7 @@ function connect(service, normalize) {
121
135
  },
122
136
  getValueTextProps() {
123
137
  return normalize.element({
124
- ...import_number_input.parts.valueText.attrs,
138
+ ...import_number_input.parts.valueText.attrs(scope.id),
125
139
  dir: prop("dir"),
126
140
  "data-disabled": (0, import_dom_query.dataAttr)(disabled),
127
141
  "data-invalid": (0, import_dom_query.dataAttr)(invalid),
@@ -129,9 +143,11 @@ function connect(service, normalize) {
129
143
  "data-scrubbing": (0, import_dom_query.dataAttr)(scrubbing)
130
144
  });
131
145
  },
146
+ getInputState,
132
147
  getInputProps() {
148
+ const inputState = getInputState();
133
149
  return normalize.input({
134
- ...import_number_input.parts.input.attrs,
150
+ ...import_number_input.parts.input.attrs(scope.id),
135
151
  dir: prop("dir"),
136
152
  name: prop("name"),
137
153
  form: prop("form"),
@@ -140,11 +156,11 @@ function connect(service, normalize) {
140
156
  defaultValue: computed("formattedValue"),
141
157
  pattern: prop("formatOptions") ? void 0 : prop("pattern"),
142
158
  inputMode: prop("inputMode"),
143
- "aria-invalid": (0, import_dom_query.ariaAttr)(invalid),
144
- "data-invalid": (0, import_dom_query.dataAttr)(invalid),
145
- disabled,
146
- "data-disabled": (0, import_dom_query.dataAttr)(disabled),
147
- readOnly,
159
+ "aria-invalid": (0, import_dom_query.ariaAttr)(inputState.invalid),
160
+ "data-invalid": (0, import_dom_query.dataAttr)(inputState.invalid),
161
+ disabled: inputState.disabled,
162
+ "data-disabled": (0, import_dom_query.dataAttr)(inputState.disabled),
163
+ readOnly: inputState.readOnly,
148
164
  required: prop("required"),
149
165
  autoComplete: "off",
150
166
  autoCorrect: "off",
@@ -155,7 +171,7 @@ function connect(service, normalize) {
155
171
  "aria-valuemax": prop("max"),
156
172
  "aria-valuenow": Number.isNaN(computed("valueAsNumber")) ? void 0 : computed("valueAsNumber"),
157
173
  "aria-valuetext": computed("valueText"),
158
- "data-scrubbing": (0, import_dom_query.dataAttr)(scrubbing),
174
+ "data-scrubbing": (0, import_dom_query.dataAttr)(inputState.scrubbing),
159
175
  onFocus() {
160
176
  send({ type: "INPUT.FOCUS" });
161
177
  },
@@ -190,20 +206,24 @@ function connect(service, normalize) {
190
206
  ArrowUp() {
191
207
  send({ type: "INPUT.ARROW_UP", step });
192
208
  event.preventDefault();
209
+ event.stopPropagation();
193
210
  },
194
211
  ArrowDown() {
195
212
  send({ type: "INPUT.ARROW_DOWN", step });
196
213
  event.preventDefault();
214
+ event.stopPropagation();
197
215
  },
198
216
  Home() {
199
217
  if ((0, import_dom_query.isModifierKey)(event)) return;
200
218
  send({ type: "INPUT.HOME" });
201
219
  event.preventDefault();
220
+ event.stopPropagation();
202
221
  },
203
222
  End() {
204
223
  if ((0, import_dom_query.isModifierKey)(event)) return;
205
224
  send({ type: "INPUT.END" });
206
225
  event.preventDefault();
226
+ event.stopPropagation();
207
227
  },
208
228
  Enter(event2) {
209
229
  const selection = (0, import_cursor.recordCursor)(event2.currentTarget, scope);
@@ -215,20 +235,21 @@ function connect(service, normalize) {
215
235
  }
216
236
  });
217
237
  },
238
+ getDecrementTriggerState,
218
239
  getDecrementTriggerProps() {
240
+ const decrementTriggerState = getDecrementTriggerState();
219
241
  return normalize.button({
220
- ...import_number_input.parts.decrementTrigger.attrs,
242
+ ...import_number_input.parts.decrementTrigger.attrs(scope.id),
221
243
  dir: prop("dir"),
222
- id: dom.getDecrementTriggerId(scope),
223
- disabled: isDecrementDisabled,
224
- "data-disabled": (0, import_dom_query.dataAttr)(isDecrementDisabled),
244
+ disabled: decrementTriggerState.disabled,
245
+ "data-disabled": (0, import_dom_query.dataAttr)(decrementTriggerState.disabled),
225
246
  "aria-label": translations.decrementLabel,
226
247
  type: "button",
227
248
  tabIndex: -1,
228
249
  "aria-controls": dom.getInputId(scope),
229
250
  "data-scrubbing": (0, import_dom_query.dataAttr)(scrubbing),
230
251
  onPointerDown(event) {
231
- if (isDecrementDisabled) return;
252
+ if (decrementTriggerState.disabled) return;
232
253
  if (!(0, import_dom_query.isLeftClick)(event)) return;
233
254
  send({ type: "TRIGGER.PRESS_DOWN", hint: "decrement", pointerType: event.pointerType });
234
255
  if (event.pointerType === "mouse") {
@@ -242,25 +263,26 @@ function connect(service, normalize) {
242
263
  send({ type: "TRIGGER.PRESS_UP", hint: "decrement", pointerType: event.pointerType });
243
264
  },
244
265
  onPointerLeave() {
245
- if (isDecrementDisabled) return;
266
+ if (decrementTriggerState.disabled) return;
246
267
  send({ type: "TRIGGER.PRESS_UP", hint: "decrement" });
247
268
  }
248
269
  });
249
270
  },
271
+ getIncrementTriggerState,
250
272
  getIncrementTriggerProps() {
273
+ const incrementTriggerState = getIncrementTriggerState();
251
274
  return normalize.button({
252
- ...import_number_input.parts.incrementTrigger.attrs,
275
+ ...import_number_input.parts.incrementTrigger.attrs(scope.id),
253
276
  dir: prop("dir"),
254
- id: dom.getIncrementTriggerId(scope),
255
- disabled: isIncrementDisabled,
256
- "data-disabled": (0, import_dom_query.dataAttr)(isIncrementDisabled),
277
+ disabled: incrementTriggerState.disabled,
278
+ "data-disabled": (0, import_dom_query.dataAttr)(incrementTriggerState.disabled),
257
279
  "aria-label": translations.incrementLabel,
258
280
  type: "button",
259
281
  tabIndex: -1,
260
282
  "aria-controls": dom.getInputId(scope),
261
283
  "data-scrubbing": (0, import_dom_query.dataAttr)(scrubbing),
262
284
  onPointerDown(event) {
263
- if (isIncrementDisabled || !(0, import_dom_query.isLeftClick)(event)) return;
285
+ if (incrementTriggerState.disabled || !(0, import_dom_query.isLeftClick)(event)) return;
264
286
  send({ type: "TRIGGER.PRESS_DOWN", hint: "increment", pointerType: event.pointerType });
265
287
  if (event.pointerType === "mouse") {
266
288
  event.preventDefault();
@@ -278,29 +300,48 @@ function connect(service, normalize) {
278
300
  });
279
301
  },
280
302
  getScrubberProps() {
303
+ const direction = prop("scrubberDirection");
304
+ const point = context.get("scrubberCursorPoint");
281
305
  return normalize.element({
282
- ...import_number_input.parts.scrubber.attrs,
306
+ ...import_number_input.parts.scrubber.attrs(scope.id),
283
307
  dir: prop("dir"),
284
308
  "data-disabled": (0, import_dom_query.dataAttr)(disabled),
285
- id: dom.getScrubberId(scope),
286
309
  role: "presentation",
287
310
  "data-scrubbing": (0, import_dom_query.dataAttr)(scrubbing),
288
311
  onMouseDown(event) {
289
312
  if (disabled) return;
290
313
  if (!(0, import_dom_query.isLeftClick)(event)) return;
291
- const point = (0, import_dom_query.getEventPoint)(event);
314
+ const pt = (0, import_dom_query.getEventPoint)(event);
292
315
  const win = (0, import_dom_query.getWindow)(event.currentTarget);
293
316
  const dpr = win.devicePixelRatio;
294
- point.x = point.x - (0, import_utils.roundToDpr)(7.5, dpr);
295
- point.y = point.y - (0, import_utils.roundToDpr)(7.5, dpr);
296
- send({ type: "SCRUBBER.PRESS_DOWN", point });
317
+ pt.x = pt.x - (0, import_utils.roundToDpr)(7.5, dpr);
318
+ pt.y = pt.y - (0, import_utils.roundToDpr)(7.5, dpr);
319
+ send({ type: "SCRUBBER.PRESS_DOWN", point: pt });
297
320
  event.preventDefault();
298
321
  (0, import_dom_query.raf)(() => {
299
322
  (0, import_dom_query.setCaretToEnd)(dom.getInputEl(scope));
300
323
  });
301
324
  },
302
325
  style: {
303
- cursor: disabled ? void 0 : "ew-resize"
326
+ cursor: disabled ? void 0 : direction === "vertical" ? "ns-resize" : "ew-resize",
327
+ "--scrubber-x": point ? (0, import_utils.toPx)(point.x) : void 0,
328
+ "--scrubber-y": point ? (0, import_utils.toPx)(point.y) : void 0,
329
+ "--scrubber-scale": `${1 / context.get("visualScale")}`
330
+ }
331
+ });
332
+ },
333
+ getScrubberCursorProps() {
334
+ return normalize.element({
335
+ ...import_number_input.parts.scrubberCursor.attrs(scope.id),
336
+ hidden: !scrubbing || !context.get("isPointerLockSupported"),
337
+ style: {
338
+ position: "fixed",
339
+ pointerEvents: "none",
340
+ left: "0px",
341
+ top: "0px",
342
+ zIndex: import_dom_query.MAX_Z_INDEX,
343
+ transform: "translate3d(var(--scrubber-x, 0px), var(--scrubber-y, 0px), 0px) scale(var(--scrubber-scale, 1))",
344
+ willChange: "transform"
304
345
  }
305
346
  });
306
347
  }
@@ -5,18 +5,19 @@ import {
5
5
  getEventPoint,
6
6
  getEventStepValue,
7
7
  getWindow,
8
+ MAX_Z_INDEX,
8
9
  isComposingEvent,
9
10
  isLeftClick,
10
11
  isModifierKey,
11
12
  raf,
12
13
  setCaretToEnd
13
14
  } from "@zag-js/dom-query";
14
- import { roundToDpr } from "@zag-js/utils";
15
+ import { roundToDpr, toPx } from "@zag-js/utils";
15
16
  import { recordCursor } from "./cursor.mjs";
16
17
  import { parts } from "./number-input.anatomy.mjs";
17
18
  import * as dom from "./number-input.dom.mjs";
18
19
  function connect(service, normalize) {
19
- const { state, send, prop, scope, computed } = service;
20
+ const { state, send, prop, scope, computed, context } = service;
20
21
  const focused = state.hasTag("focus");
21
22
  const disabled = computed("isDisabled");
22
23
  const readOnly = !!prop("readOnly");
@@ -27,8 +28,21 @@ function connect(service, normalize) {
27
28
  const isIncrementDisabled = disabled || !computed("canIncrement") || readOnly;
28
29
  const isDecrementDisabled = disabled || !computed("canDecrement") || readOnly;
29
30
  const translations = prop("translations");
31
+ function getRootState() {
32
+ return { disabled, focused, invalid, scrubbing };
33
+ }
34
+ function getInputState() {
35
+ return { disabled, invalid, readOnly, scrubbing };
36
+ }
37
+ function getIncrementTriggerState() {
38
+ return { disabled: isIncrementDisabled };
39
+ }
40
+ function getDecrementTriggerState() {
41
+ return { disabled: isDecrementDisabled };
42
+ }
30
43
  return {
31
44
  focused,
45
+ scrubbing,
32
46
  invalid,
33
47
  empty,
34
48
  value: computed("formattedValue"),
@@ -54,20 +68,21 @@ function connect(service, normalize) {
54
68
  focus() {
55
69
  dom.getInputEl(scope)?.focus();
56
70
  },
71
+ getRootState,
57
72
  getRootProps() {
73
+ const rootState = getRootState();
58
74
  return normalize.element({
59
- id: dom.getRootId(scope),
60
- ...parts.root.attrs,
75
+ ...parts.root.attrs(scope.id),
61
76
  dir: prop("dir"),
62
- "data-disabled": dataAttr(disabled),
63
- "data-focus": dataAttr(focused),
64
- "data-invalid": dataAttr(invalid),
65
- "data-scrubbing": dataAttr(scrubbing)
77
+ "data-disabled": dataAttr(rootState.disabled),
78
+ "data-focus": dataAttr(rootState.focused),
79
+ "data-invalid": dataAttr(rootState.invalid),
80
+ "data-scrubbing": dataAttr(rootState.scrubbing)
66
81
  });
67
82
  },
68
83
  getLabelProps() {
69
84
  return normalize.label({
70
- ...parts.label.attrs,
85
+ ...parts.label.attrs(scope.id),
71
86
  dir: prop("dir"),
72
87
  "data-disabled": dataAttr(disabled),
73
88
  "data-focus": dataAttr(focused),
@@ -85,7 +100,7 @@ function connect(service, normalize) {
85
100
  },
86
101
  getControlProps() {
87
102
  return normalize.element({
88
- ...parts.control.attrs,
103
+ ...parts.control.attrs(scope.id),
89
104
  dir: prop("dir"),
90
105
  role: "group",
91
106
  "aria-disabled": disabled,
@@ -98,7 +113,7 @@ function connect(service, normalize) {
98
113
  },
99
114
  getValueTextProps() {
100
115
  return normalize.element({
101
- ...parts.valueText.attrs,
116
+ ...parts.valueText.attrs(scope.id),
102
117
  dir: prop("dir"),
103
118
  "data-disabled": dataAttr(disabled),
104
119
  "data-invalid": dataAttr(invalid),
@@ -106,9 +121,11 @@ function connect(service, normalize) {
106
121
  "data-scrubbing": dataAttr(scrubbing)
107
122
  });
108
123
  },
124
+ getInputState,
109
125
  getInputProps() {
126
+ const inputState = getInputState();
110
127
  return normalize.input({
111
- ...parts.input.attrs,
128
+ ...parts.input.attrs(scope.id),
112
129
  dir: prop("dir"),
113
130
  name: prop("name"),
114
131
  form: prop("form"),
@@ -117,11 +134,11 @@ function connect(service, normalize) {
117
134
  defaultValue: computed("formattedValue"),
118
135
  pattern: prop("formatOptions") ? void 0 : prop("pattern"),
119
136
  inputMode: prop("inputMode"),
120
- "aria-invalid": ariaAttr(invalid),
121
- "data-invalid": dataAttr(invalid),
122
- disabled,
123
- "data-disabled": dataAttr(disabled),
124
- readOnly,
137
+ "aria-invalid": ariaAttr(inputState.invalid),
138
+ "data-invalid": dataAttr(inputState.invalid),
139
+ disabled: inputState.disabled,
140
+ "data-disabled": dataAttr(inputState.disabled),
141
+ readOnly: inputState.readOnly,
125
142
  required: prop("required"),
126
143
  autoComplete: "off",
127
144
  autoCorrect: "off",
@@ -132,7 +149,7 @@ function connect(service, normalize) {
132
149
  "aria-valuemax": prop("max"),
133
150
  "aria-valuenow": Number.isNaN(computed("valueAsNumber")) ? void 0 : computed("valueAsNumber"),
134
151
  "aria-valuetext": computed("valueText"),
135
- "data-scrubbing": dataAttr(scrubbing),
152
+ "data-scrubbing": dataAttr(inputState.scrubbing),
136
153
  onFocus() {
137
154
  send({ type: "INPUT.FOCUS" });
138
155
  },
@@ -167,20 +184,24 @@ function connect(service, normalize) {
167
184
  ArrowUp() {
168
185
  send({ type: "INPUT.ARROW_UP", step });
169
186
  event.preventDefault();
187
+ event.stopPropagation();
170
188
  },
171
189
  ArrowDown() {
172
190
  send({ type: "INPUT.ARROW_DOWN", step });
173
191
  event.preventDefault();
192
+ event.stopPropagation();
174
193
  },
175
194
  Home() {
176
195
  if (isModifierKey(event)) return;
177
196
  send({ type: "INPUT.HOME" });
178
197
  event.preventDefault();
198
+ event.stopPropagation();
179
199
  },
180
200
  End() {
181
201
  if (isModifierKey(event)) return;
182
202
  send({ type: "INPUT.END" });
183
203
  event.preventDefault();
204
+ event.stopPropagation();
184
205
  },
185
206
  Enter(event2) {
186
207
  const selection = recordCursor(event2.currentTarget, scope);
@@ -192,20 +213,21 @@ function connect(service, normalize) {
192
213
  }
193
214
  });
194
215
  },
216
+ getDecrementTriggerState,
195
217
  getDecrementTriggerProps() {
218
+ const decrementTriggerState = getDecrementTriggerState();
196
219
  return normalize.button({
197
- ...parts.decrementTrigger.attrs,
220
+ ...parts.decrementTrigger.attrs(scope.id),
198
221
  dir: prop("dir"),
199
- id: dom.getDecrementTriggerId(scope),
200
- disabled: isDecrementDisabled,
201
- "data-disabled": dataAttr(isDecrementDisabled),
222
+ disabled: decrementTriggerState.disabled,
223
+ "data-disabled": dataAttr(decrementTriggerState.disabled),
202
224
  "aria-label": translations.decrementLabel,
203
225
  type: "button",
204
226
  tabIndex: -1,
205
227
  "aria-controls": dom.getInputId(scope),
206
228
  "data-scrubbing": dataAttr(scrubbing),
207
229
  onPointerDown(event) {
208
- if (isDecrementDisabled) return;
230
+ if (decrementTriggerState.disabled) return;
209
231
  if (!isLeftClick(event)) return;
210
232
  send({ type: "TRIGGER.PRESS_DOWN", hint: "decrement", pointerType: event.pointerType });
211
233
  if (event.pointerType === "mouse") {
@@ -219,25 +241,26 @@ function connect(service, normalize) {
219
241
  send({ type: "TRIGGER.PRESS_UP", hint: "decrement", pointerType: event.pointerType });
220
242
  },
221
243
  onPointerLeave() {
222
- if (isDecrementDisabled) return;
244
+ if (decrementTriggerState.disabled) return;
223
245
  send({ type: "TRIGGER.PRESS_UP", hint: "decrement" });
224
246
  }
225
247
  });
226
248
  },
249
+ getIncrementTriggerState,
227
250
  getIncrementTriggerProps() {
251
+ const incrementTriggerState = getIncrementTriggerState();
228
252
  return normalize.button({
229
- ...parts.incrementTrigger.attrs,
253
+ ...parts.incrementTrigger.attrs(scope.id),
230
254
  dir: prop("dir"),
231
- id: dom.getIncrementTriggerId(scope),
232
- disabled: isIncrementDisabled,
233
- "data-disabled": dataAttr(isIncrementDisabled),
255
+ disabled: incrementTriggerState.disabled,
256
+ "data-disabled": dataAttr(incrementTriggerState.disabled),
234
257
  "aria-label": translations.incrementLabel,
235
258
  type: "button",
236
259
  tabIndex: -1,
237
260
  "aria-controls": dom.getInputId(scope),
238
261
  "data-scrubbing": dataAttr(scrubbing),
239
262
  onPointerDown(event) {
240
- if (isIncrementDisabled || !isLeftClick(event)) return;
263
+ if (incrementTriggerState.disabled || !isLeftClick(event)) return;
241
264
  send({ type: "TRIGGER.PRESS_DOWN", hint: "increment", pointerType: event.pointerType });
242
265
  if (event.pointerType === "mouse") {
243
266
  event.preventDefault();
@@ -255,29 +278,48 @@ function connect(service, normalize) {
255
278
  });
256
279
  },
257
280
  getScrubberProps() {
281
+ const direction = prop("scrubberDirection");
282
+ const point = context.get("scrubberCursorPoint");
258
283
  return normalize.element({
259
- ...parts.scrubber.attrs,
284
+ ...parts.scrubber.attrs(scope.id),
260
285
  dir: prop("dir"),
261
286
  "data-disabled": dataAttr(disabled),
262
- id: dom.getScrubberId(scope),
263
287
  role: "presentation",
264
288
  "data-scrubbing": dataAttr(scrubbing),
265
289
  onMouseDown(event) {
266
290
  if (disabled) return;
267
291
  if (!isLeftClick(event)) return;
268
- const point = getEventPoint(event);
292
+ const pt = getEventPoint(event);
269
293
  const win = getWindow(event.currentTarget);
270
294
  const dpr = win.devicePixelRatio;
271
- point.x = point.x - roundToDpr(7.5, dpr);
272
- point.y = point.y - roundToDpr(7.5, dpr);
273
- send({ type: "SCRUBBER.PRESS_DOWN", point });
295
+ pt.x = pt.x - roundToDpr(7.5, dpr);
296
+ pt.y = pt.y - roundToDpr(7.5, dpr);
297
+ send({ type: "SCRUBBER.PRESS_DOWN", point: pt });
274
298
  event.preventDefault();
275
299
  raf(() => {
276
300
  setCaretToEnd(dom.getInputEl(scope));
277
301
  });
278
302
  },
279
303
  style: {
280
- cursor: disabled ? void 0 : "ew-resize"
304
+ cursor: disabled ? void 0 : direction === "vertical" ? "ns-resize" : "ew-resize",
305
+ "--scrubber-x": point ? toPx(point.x) : void 0,
306
+ "--scrubber-y": point ? toPx(point.y) : void 0,
307
+ "--scrubber-scale": `${1 / context.get("visualScale")}`
308
+ }
309
+ });
310
+ },
311
+ getScrubberCursorProps() {
312
+ return normalize.element({
313
+ ...parts.scrubberCursor.attrs(scope.id),
314
+ hidden: !scrubbing || !context.get("isPointerLockSupported"),
315
+ style: {
316
+ position: "fixed",
317
+ pointerEvents: "none",
318
+ left: "0px",
319
+ top: "0px",
320
+ zIndex: MAX_Z_INDEX,
321
+ transform: "translate3d(var(--scrubber-x, 0px), var(--scrubber-y, 0px), 0px) scale(var(--scrubber-scale, 1))",
322
+ willChange: "transform"
281
323
  }
282
324
  });
283
325
  }
@@ -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 };