@zag-js/number-input 0.16.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +64 -64
- package/dist/index.d.ts +64 -64
- package/dist/index.js +48 -46
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +48 -46
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -10
- package/src/index.ts +1 -1
- package/src/number-input.connect.ts +2 -2
- package/src/number-input.machine.ts +53 -46
- package/src/number-input.types.ts +62 -62
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zag-js/number-input",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "Core logic for the number-input widget implemented as a state machine",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"js",
|
|
@@ -27,15 +27,15 @@
|
|
|
27
27
|
"url": "https://github.com/chakra-ui/zag/issues"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@zag-js/anatomy": "0.
|
|
31
|
-
"@zag-js/core": "0.
|
|
32
|
-
"@zag-js/dom-query": "0.
|
|
33
|
-
"@zag-js/dom-event": "0.
|
|
34
|
-
"@zag-js/form-utils": "0.
|
|
35
|
-
"@zag-js/mutation-observer": "0.
|
|
36
|
-
"@zag-js/number-utils": "0.
|
|
37
|
-
"@zag-js/utils": "0.
|
|
38
|
-
"@zag-js/types": "0.
|
|
30
|
+
"@zag-js/anatomy": "0.17.0",
|
|
31
|
+
"@zag-js/core": "0.17.0",
|
|
32
|
+
"@zag-js/dom-query": "0.17.0",
|
|
33
|
+
"@zag-js/dom-event": "0.17.0",
|
|
34
|
+
"@zag-js/form-utils": "0.17.0",
|
|
35
|
+
"@zag-js/mutation-observer": "0.17.0",
|
|
36
|
+
"@zag-js/number-utils": "0.17.0",
|
|
37
|
+
"@zag-js/utils": "0.17.0",
|
|
38
|
+
"@zag-js/types": "0.17.0"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"clean-package": "2.2.0"
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { anatomy } from "./number-input.anatomy"
|
|
2
2
|
export { connect } from "./number-input.connect"
|
|
3
3
|
export { machine } from "./number-input.machine"
|
|
4
|
-
export type { UserDefinedContext as Context,
|
|
4
|
+
export type { UserDefinedContext as Context, MachineApi as Api } from "./number-input.types"
|
|
@@ -4,10 +4,10 @@ import { roundToDevicePixel } from "@zag-js/number-utils"
|
|
|
4
4
|
import type { NormalizeProps, PropTypes } from "@zag-js/types"
|
|
5
5
|
import { parts } from "./number-input.anatomy"
|
|
6
6
|
import { dom } from "./number-input.dom"
|
|
7
|
-
import type {
|
|
7
|
+
import type { MachineApi, Send, State } from "./number-input.types"
|
|
8
8
|
import { utils } from "./number-input.utils"
|
|
9
9
|
|
|
10
|
-
export function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>):
|
|
10
|
+
export function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): MachineApi<T> {
|
|
11
11
|
const isFocused = state.hasTag("focus")
|
|
12
12
|
const isInvalid = state.context.isOutOfRange || !!state.context.invalid
|
|
13
13
|
|
|
@@ -54,7 +54,7 @@ export function machine(userContext: UserDefinedContext) {
|
|
|
54
54
|
},
|
|
55
55
|
|
|
56
56
|
watch: {
|
|
57
|
-
value: ["
|
|
57
|
+
value: ["syncInputElement"],
|
|
58
58
|
isOutOfRange: ["invokeOnInvalid"],
|
|
59
59
|
scrubberCursorPoint: ["setVirtualCursorPosition"],
|
|
60
60
|
},
|
|
@@ -62,15 +62,9 @@ export function machine(userContext: UserDefinedContext) {
|
|
|
62
62
|
entry: ["syncInputValue"],
|
|
63
63
|
|
|
64
64
|
on: {
|
|
65
|
-
SET_VALUE:
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
actions: ["setValue", "clampValue", "setHintToSet"],
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
actions: ["setValue", "setHintToSet"],
|
|
72
|
-
},
|
|
73
|
-
],
|
|
65
|
+
SET_VALUE: {
|
|
66
|
+
actions: ["setValue", "clampValue", "setHintToSet"],
|
|
67
|
+
},
|
|
74
68
|
CLEAR_VALUE: {
|
|
75
69
|
actions: ["clearValue"],
|
|
76
70
|
},
|
|
@@ -84,17 +78,19 @@ export function machine(userContext: UserDefinedContext) {
|
|
|
84
78
|
|
|
85
79
|
states: {
|
|
86
80
|
idle: {
|
|
87
|
-
exit: "invokeOnFocus",
|
|
88
81
|
on: {
|
|
89
82
|
PRESS_DOWN: {
|
|
90
83
|
target: "before:spin",
|
|
91
|
-
actions: ["focusInput", "setHint"],
|
|
84
|
+
actions: ["focusInput", "invokeOnFocus", "setHint"],
|
|
92
85
|
},
|
|
93
86
|
PRESS_DOWN_SCRUBBER: {
|
|
94
87
|
target: "scrubbing",
|
|
95
|
-
actions: ["focusInput", "setHint", "setCursorPoint"],
|
|
88
|
+
actions: ["focusInput", "invokeOnFocus", "setHint", "setCursorPoint"],
|
|
89
|
+
},
|
|
90
|
+
FOCUS: {
|
|
91
|
+
target: "focused",
|
|
92
|
+
actions: ["focusInput", "invokeOnFocus"],
|
|
96
93
|
},
|
|
97
|
-
FOCUS: "focused",
|
|
98
94
|
},
|
|
99
95
|
},
|
|
100
96
|
|
|
@@ -290,35 +286,37 @@ export function machine(userContext: UserDefinedContext) {
|
|
|
290
286
|
actions: {
|
|
291
287
|
focusInput(ctx) {
|
|
292
288
|
if (!ctx.focusInputOnChange) return
|
|
293
|
-
const
|
|
294
|
-
raf(() =>
|
|
289
|
+
const inputEl = dom.getInputEl(ctx)
|
|
290
|
+
raf(() => {
|
|
291
|
+
inputEl?.focus()
|
|
292
|
+
})
|
|
295
293
|
},
|
|
296
294
|
increment(ctx, evt) {
|
|
297
|
-
|
|
295
|
+
set.value(ctx, utils.increment(ctx, evt.step))
|
|
298
296
|
},
|
|
299
297
|
decrement(ctx, evt) {
|
|
300
|
-
|
|
298
|
+
set.value(ctx, utils.decrement(ctx, evt.step))
|
|
301
299
|
},
|
|
302
300
|
clampValue(ctx) {
|
|
303
|
-
|
|
301
|
+
set.value(ctx, utils.clamp(ctx))
|
|
304
302
|
},
|
|
305
303
|
roundValue(ctx) {
|
|
306
|
-
if (ctx.value
|
|
307
|
-
|
|
308
|
-
}
|
|
304
|
+
if (ctx.value === "") return
|
|
305
|
+
set.value(ctx, utils.round(ctx))
|
|
309
306
|
},
|
|
310
307
|
setValue(ctx, evt) {
|
|
311
|
-
|
|
312
|
-
|
|
308
|
+
let value = evt.target?.value ?? evt.value
|
|
309
|
+
value = utils.sanitize(ctx, utils.parse(ctx, value.toString()))
|
|
310
|
+
set.value(ctx, value)
|
|
313
311
|
},
|
|
314
312
|
clearValue(ctx) {
|
|
315
|
-
|
|
313
|
+
set.value(ctx, "")
|
|
316
314
|
},
|
|
317
315
|
setToMax(ctx) {
|
|
318
|
-
|
|
316
|
+
set.value(ctx, ctx.max.toString())
|
|
319
317
|
},
|
|
320
318
|
setToMin(ctx) {
|
|
321
|
-
|
|
319
|
+
set.value(ctx, ctx.min.toString())
|
|
322
320
|
},
|
|
323
321
|
setHint(ctx, evt) {
|
|
324
322
|
ctx.hint = evt.hint
|
|
@@ -329,12 +327,6 @@ export function machine(userContext: UserDefinedContext) {
|
|
|
329
327
|
setHintToSet(ctx) {
|
|
330
328
|
ctx.hint = "set"
|
|
331
329
|
},
|
|
332
|
-
invokeOnChange(ctx) {
|
|
333
|
-
ctx.onChange?.({
|
|
334
|
-
value: ctx.value,
|
|
335
|
-
valueAsNumber: ctx.valueAsNumber,
|
|
336
|
-
})
|
|
337
|
-
},
|
|
338
330
|
invokeOnFocus(ctx, evt) {
|
|
339
331
|
let srcElement: HTMLElement | null = null
|
|
340
332
|
|
|
@@ -353,10 +345,7 @@ export function machine(userContext: UserDefinedContext) {
|
|
|
353
345
|
})
|
|
354
346
|
},
|
|
355
347
|
invokeOnBlur(ctx) {
|
|
356
|
-
ctx.onBlur?.({
|
|
357
|
-
value: ctx.value,
|
|
358
|
-
valueAsNumber: ctx.valueAsNumber,
|
|
359
|
-
})
|
|
348
|
+
ctx.onBlur?.({ value: ctx.value, valueAsNumber: ctx.valueAsNumber })
|
|
360
349
|
},
|
|
361
350
|
invokeOnInvalid(ctx) {
|
|
362
351
|
if (!ctx.isOutOfRange) return
|
|
@@ -367,12 +356,16 @@ export function machine(userContext: UserDefinedContext) {
|
|
|
367
356
|
valueAsNumber: ctx.valueAsNumber,
|
|
368
357
|
})
|
|
369
358
|
},
|
|
370
|
-
|
|
359
|
+
syncInputElement(ctx) {
|
|
360
|
+
const inputEl = dom.getInputEl(ctx)
|
|
361
|
+
dom.setValue(inputEl, ctx.formattedValue)
|
|
362
|
+
},
|
|
371
363
|
syncInputValue(ctx) {
|
|
372
|
-
const
|
|
373
|
-
if (!
|
|
374
|
-
|
|
375
|
-
|
|
364
|
+
const inputEl = dom.getInputEl(ctx)
|
|
365
|
+
if (!inputEl || inputEl.value == ctx.value) return
|
|
366
|
+
|
|
367
|
+
const value = utils.parse(ctx, inputEl.value)
|
|
368
|
+
set.value(ctx, utils.sanitize(ctx, value))
|
|
376
369
|
},
|
|
377
370
|
setCursorPoint(ctx, evt) {
|
|
378
371
|
ctx.scrubberCursorPoint = evt.point
|
|
@@ -386,11 +379,25 @@ export function machine(userContext: UserDefinedContext) {
|
|
|
386
379
|
const { x, y } = ctx.scrubberCursorPoint
|
|
387
380
|
cursor.style.transform = `translate3d(${x}px, ${y}px, 0px)`
|
|
388
381
|
},
|
|
389
|
-
dispatchChangeEvent(ctx) {
|
|
390
|
-
const inputEl = dom.getInputEl(ctx)
|
|
391
|
-
dispatchInputValueEvent(inputEl, { value: ctx.formattedValue })
|
|
392
|
-
},
|
|
393
382
|
},
|
|
394
383
|
},
|
|
395
384
|
)
|
|
396
385
|
}
|
|
386
|
+
|
|
387
|
+
const invoke = {
|
|
388
|
+
onChange: (ctx: MachineContext) => {
|
|
389
|
+
// invoke callback
|
|
390
|
+
ctx.onChange?.({ value: ctx.value, valueAsNumber: ctx.valueAsNumber })
|
|
391
|
+
|
|
392
|
+
// form event
|
|
393
|
+
const inputEl = dom.getInputEl(ctx)
|
|
394
|
+
dispatchInputValueEvent(inputEl, { value: ctx.formattedValue })
|
|
395
|
+
},
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
const set = {
|
|
399
|
+
value: (ctx: MachineContext, value: string) => {
|
|
400
|
+
ctx.value = value
|
|
401
|
+
invoke.onChange(ctx)
|
|
402
|
+
},
|
|
403
|
+
}
|
|
@@ -154,68 +154,6 @@ type PublicContext = DirectionProperty &
|
|
|
154
154
|
spinOnPress?: boolean
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
export type PublicApi<T extends PropTypes = PropTypes> = {
|
|
158
|
-
/**
|
|
159
|
-
* Whether the input is focused.
|
|
160
|
-
*/
|
|
161
|
-
isFocused: boolean
|
|
162
|
-
/**
|
|
163
|
-
* Whether the input is invalid.
|
|
164
|
-
*/
|
|
165
|
-
isInvalid: boolean
|
|
166
|
-
/**
|
|
167
|
-
* Whether the input value is empty.
|
|
168
|
-
*/
|
|
169
|
-
isValueEmpty: boolean
|
|
170
|
-
/**
|
|
171
|
-
* The formatted value of the input.
|
|
172
|
-
*/
|
|
173
|
-
value: string
|
|
174
|
-
/**
|
|
175
|
-
* The value of the input as a number.
|
|
176
|
-
*/
|
|
177
|
-
valueAsNumber: number
|
|
178
|
-
/**
|
|
179
|
-
* Function to set the value of the input.
|
|
180
|
-
*/
|
|
181
|
-
setValue(value: string | number): void
|
|
182
|
-
/**
|
|
183
|
-
* Function to clear the value of the input.
|
|
184
|
-
*/
|
|
185
|
-
clearValue(): void
|
|
186
|
-
/**
|
|
187
|
-
* Function to increment the value of the input by the step.
|
|
188
|
-
*/
|
|
189
|
-
increment(): void
|
|
190
|
-
/**
|
|
191
|
-
* Function to decrement the value of the input by the step.
|
|
192
|
-
*/
|
|
193
|
-
decrement(): void
|
|
194
|
-
/**
|
|
195
|
-
* Function to set the value of the input to the max.
|
|
196
|
-
*/
|
|
197
|
-
setToMax(): void
|
|
198
|
-
/**
|
|
199
|
-
* Function to set the value of the input to the min.
|
|
200
|
-
*/
|
|
201
|
-
setToMin(): void
|
|
202
|
-
/**
|
|
203
|
-
* Function to focus the input.
|
|
204
|
-
*/
|
|
205
|
-
focus(): void
|
|
206
|
-
/**
|
|
207
|
-
* Function to blur the input.
|
|
208
|
-
*/
|
|
209
|
-
blur(): void
|
|
210
|
-
rootProps: T["element"]
|
|
211
|
-
labelProps: T["label"]
|
|
212
|
-
controlProps: T["element"]
|
|
213
|
-
inputProps: T["input"]
|
|
214
|
-
decrementTriggerProps: T["button"]
|
|
215
|
-
incrementTriggerProps: T["button"]
|
|
216
|
-
scrubberProps: T["element"]
|
|
217
|
-
}
|
|
218
|
-
|
|
219
157
|
export type UserDefinedContext = RequiredBy<PublicContext, "id">
|
|
220
158
|
|
|
221
159
|
type ComputedContext = Readonly<{
|
|
@@ -294,3 +232,65 @@ export type MachineState = {
|
|
|
294
232
|
export type State = S.State<MachineContext, MachineState>
|
|
295
233
|
|
|
296
234
|
export type Send = S.Send<S.AnyEventObject>
|
|
235
|
+
|
|
236
|
+
export type MachineApi<T extends PropTypes = PropTypes> = {
|
|
237
|
+
/**
|
|
238
|
+
* Whether the input is focused.
|
|
239
|
+
*/
|
|
240
|
+
isFocused: boolean
|
|
241
|
+
/**
|
|
242
|
+
* Whether the input is invalid.
|
|
243
|
+
*/
|
|
244
|
+
isInvalid: boolean
|
|
245
|
+
/**
|
|
246
|
+
* Whether the input value is empty.
|
|
247
|
+
*/
|
|
248
|
+
isValueEmpty: boolean
|
|
249
|
+
/**
|
|
250
|
+
* The formatted value of the input.
|
|
251
|
+
*/
|
|
252
|
+
value: string
|
|
253
|
+
/**
|
|
254
|
+
* The value of the input as a number.
|
|
255
|
+
*/
|
|
256
|
+
valueAsNumber: number
|
|
257
|
+
/**
|
|
258
|
+
* Function to set the value of the input.
|
|
259
|
+
*/
|
|
260
|
+
setValue(value: string | number): void
|
|
261
|
+
/**
|
|
262
|
+
* Function to clear the value of the input.
|
|
263
|
+
*/
|
|
264
|
+
clearValue(): void
|
|
265
|
+
/**
|
|
266
|
+
* Function to increment the value of the input by the step.
|
|
267
|
+
*/
|
|
268
|
+
increment(): void
|
|
269
|
+
/**
|
|
270
|
+
* Function to decrement the value of the input by the step.
|
|
271
|
+
*/
|
|
272
|
+
decrement(): void
|
|
273
|
+
/**
|
|
274
|
+
* Function to set the value of the input to the max.
|
|
275
|
+
*/
|
|
276
|
+
setToMax(): void
|
|
277
|
+
/**
|
|
278
|
+
* Function to set the value of the input to the min.
|
|
279
|
+
*/
|
|
280
|
+
setToMin(): void
|
|
281
|
+
/**
|
|
282
|
+
* Function to focus the input.
|
|
283
|
+
*/
|
|
284
|
+
focus(): void
|
|
285
|
+
/**
|
|
286
|
+
* Function to blur the input.
|
|
287
|
+
*/
|
|
288
|
+
blur(): void
|
|
289
|
+
rootProps: T["element"]
|
|
290
|
+
labelProps: T["label"]
|
|
291
|
+
controlProps: T["element"]
|
|
292
|
+
inputProps: T["input"]
|
|
293
|
+
decrementTriggerProps: T["button"]
|
|
294
|
+
incrementTriggerProps: T["button"]
|
|
295
|
+
scrubberProps: T["element"]
|
|
296
|
+
}
|