@zag-js/number-input 0.2.6 → 0.2.8

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.
@@ -0,0 +1,246 @@
1
+ import {
2
+ parts
3
+ } from "./chunk-XHRILSH3.mjs";
4
+ import {
5
+ dom
6
+ } from "./chunk-EUVYGWZ6.mjs";
7
+ import {
8
+ utils
9
+ } from "./chunk-HP6F2HUY.mjs";
10
+ import {
11
+ getNativeEvent,
12
+ isLeftClick,
13
+ isTouchEvent,
14
+ roundToDevicePixel
15
+ } from "./chunk-VCZUWKJT.mjs";
16
+
17
+ // ../../utilities/dom/src/attrs.ts
18
+ var dataAttr = (guard) => {
19
+ return guard ? "" : void 0;
20
+ };
21
+ var ariaAttr = (guard) => {
22
+ return guard ? "true" : void 0;
23
+ };
24
+
25
+ // ../../utilities/dom/src/get-event-point.ts
26
+ var fallback = {
27
+ pageX: 0,
28
+ pageY: 0,
29
+ clientX: 0,
30
+ clientY: 0
31
+ };
32
+ function getEventPoint(event, type = "page") {
33
+ var _a, _b;
34
+ const point = isTouchEvent(event) ? (_b = (_a = event.touches[0]) != null ? _a : event.changedTouches[0]) != null ? _b : fallback : event;
35
+ return { x: point[`${type}X`], y: point[`${type}Y`] };
36
+ }
37
+
38
+ // ../../utilities/dom/src/keyboard-event.ts
39
+ var PAGE_KEYS = /* @__PURE__ */ new Set(["PageUp", "PageDown"]);
40
+ var ARROW_KEYS = /* @__PURE__ */ new Set(["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"]);
41
+ function getEventStep(event) {
42
+ if (event.ctrlKey || event.metaKey) {
43
+ return 0.1;
44
+ } else {
45
+ const isPageKey = PAGE_KEYS.has(event.key);
46
+ const isSkipKey = isPageKey || event.shiftKey && ARROW_KEYS.has(event.key);
47
+ return isSkipKey ? 10 : 1;
48
+ }
49
+ }
50
+
51
+ // src/number-input.connect.ts
52
+ function connect(state, send, normalize) {
53
+ const isFocused = state.hasTag("focus");
54
+ const isInvalid = state.context.isOutOfRange || !!state.context.invalid;
55
+ const isDisabled = !!state.context.disabled;
56
+ const isValueEmpty = state.context.isValueEmpty;
57
+ const isIncrementDisabled = isDisabled || !state.context.canIncrement;
58
+ const isDecrementDisabled = isDisabled || !state.context.canDecrement;
59
+ const translations = state.context.translations;
60
+ return {
61
+ isFocused,
62
+ isInvalid,
63
+ isValueEmpty,
64
+ value: state.context.formattedValue,
65
+ valueAsNumber: state.context.valueAsNumber,
66
+ setValue(value) {
67
+ send({ type: "SET_VALUE", value: value.toString() });
68
+ },
69
+ clearValue() {
70
+ send("CLEAR_VALUE");
71
+ },
72
+ increment() {
73
+ send("INCREMENT");
74
+ },
75
+ decrement() {
76
+ send("DECREMENT");
77
+ },
78
+ setToMax() {
79
+ send({ type: "SET_VALUE", value: state.context.max });
80
+ },
81
+ setToMin() {
82
+ send({ type: "SET_VALUE", value: state.context.min });
83
+ },
84
+ focus() {
85
+ var _a;
86
+ (_a = dom.getInputEl(state.context)) == null ? void 0 : _a.focus();
87
+ },
88
+ blur() {
89
+ var _a;
90
+ (_a = dom.getInputEl(state.context)) == null ? void 0 : _a.blur();
91
+ },
92
+ rootProps: normalize.element({
93
+ id: dom.getRootId(state.context),
94
+ ...parts.root.attrs,
95
+ "data-disabled": dataAttr(isDisabled)
96
+ }),
97
+ labelProps: normalize.label({
98
+ ...parts.label.attrs,
99
+ "data-disabled": dataAttr(isDisabled),
100
+ "data-invalid": dataAttr(isInvalid),
101
+ id: dom.getLabelId(state.context),
102
+ htmlFor: dom.getInputId(state.context)
103
+ }),
104
+ controlProps: normalize.element({
105
+ ...parts.control.attrs,
106
+ role: "group",
107
+ "aria-disabled": isDisabled,
108
+ "data-disabled": dataAttr(isDisabled),
109
+ "data-invalid": dataAttr(isInvalid),
110
+ "aria-invalid": ariaAttr(state.context.invalid)
111
+ }),
112
+ inputProps: normalize.input({
113
+ ...parts.input.attrs,
114
+ name: state.context.name,
115
+ form: state.context.form,
116
+ id: dom.getInputId(state.context),
117
+ role: "spinbutton",
118
+ defaultValue: state.context.formattedValue,
119
+ pattern: state.context.pattern,
120
+ inputMode: state.context.inputMode,
121
+ "aria-invalid": isInvalid || void 0,
122
+ "data-invalid": dataAttr(isInvalid),
123
+ disabled: isDisabled,
124
+ "data-disabled": dataAttr(isDisabled),
125
+ readOnly: !!state.context.readOnly,
126
+ autoComplete: "off",
127
+ autoCorrect: "off",
128
+ spellCheck: "false",
129
+ type: "text",
130
+ "aria-roledescription": "numberfield",
131
+ "aria-valuemin": state.context.min,
132
+ "aria-valuemax": state.context.max,
133
+ "aria-valuenow": isNaN(state.context.valueAsNumber) ? void 0 : state.context.valueAsNumber,
134
+ "aria-valuetext": state.context.valueText,
135
+ onFocus() {
136
+ send("FOCUS");
137
+ },
138
+ onBlur() {
139
+ send("BLUR");
140
+ },
141
+ onChange(event) {
142
+ const evt = getNativeEvent(event);
143
+ if (evt.isComposing)
144
+ return;
145
+ send({ type: "CHANGE", target: event.currentTarget, hint: "set" });
146
+ },
147
+ onKeyDown(event) {
148
+ const evt = getNativeEvent(event);
149
+ if (evt.isComposing)
150
+ return;
151
+ if (!utils.isValidNumericEvent(state.context, event)) {
152
+ event.preventDefault();
153
+ }
154
+ const step = getEventStep(event) * state.context.step;
155
+ const keyMap = {
156
+ ArrowUp() {
157
+ send({ type: "ARROW_UP", step });
158
+ },
159
+ ArrowDown() {
160
+ send({ type: "ARROW_DOWN", step });
161
+ },
162
+ Home() {
163
+ send("HOME");
164
+ },
165
+ End() {
166
+ send("END");
167
+ }
168
+ };
169
+ const exec = keyMap[event.key];
170
+ if (exec) {
171
+ exec(event);
172
+ event.preventDefault();
173
+ }
174
+ }
175
+ }),
176
+ decrementTriggerProps: normalize.button({
177
+ ...parts.decrementTrigger.attrs,
178
+ id: dom.getDecrementTriggerId(state.context),
179
+ disabled: isDecrementDisabled,
180
+ "data-disabled": dataAttr(isDecrementDisabled),
181
+ "aria-label": translations.decrementLabel,
182
+ type: "button",
183
+ tabIndex: -1,
184
+ "aria-controls": dom.getInputId(state.context),
185
+ onPointerDown(event) {
186
+ if (isDecrementDisabled)
187
+ return;
188
+ send(isLeftClick(event) ? { type: "PRESS_DOWN", hint: "decrement" } : { type: "FOCUS" });
189
+ event.preventDefault();
190
+ },
191
+ onPointerUp() {
192
+ send({ type: "PRESS_UP", hint: "decrement" });
193
+ },
194
+ onPointerLeave() {
195
+ if (isDecrementDisabled)
196
+ return;
197
+ send({ type: "PRESS_UP", hint: "decrement" });
198
+ }
199
+ }),
200
+ incrementTriggerProps: normalize.button({
201
+ ...parts.incrementTrigger.attrs,
202
+ id: dom.getIncrementTriggerId(state.context),
203
+ disabled: isIncrementDisabled,
204
+ "data-disabled": dataAttr(isIncrementDisabled),
205
+ "aria-label": translations.incrementLabel,
206
+ type: "button",
207
+ tabIndex: -1,
208
+ "aria-controls": dom.getInputId(state.context),
209
+ onPointerDown(event) {
210
+ if (isIncrementDisabled)
211
+ return;
212
+ send(isLeftClick(event) ? { type: "PRESS_DOWN", hint: "increment" } : { type: "FOCUS" });
213
+ event.preventDefault();
214
+ },
215
+ onPointerUp() {
216
+ send({ type: "PRESS_UP", hint: "increment" });
217
+ },
218
+ onPointerLeave() {
219
+ send({ type: "PRESS_UP", hint: "increment" });
220
+ }
221
+ }),
222
+ scrubberProps: normalize.element({
223
+ ...parts.scrubber.attrs,
224
+ "data-disabled": dataAttr(isDisabled),
225
+ id: dom.getScrubberId(state.context),
226
+ role: "presentation",
227
+ onMouseDown(event) {
228
+ if (isDisabled)
229
+ return;
230
+ const evt = getNativeEvent(event);
231
+ event.preventDefault();
232
+ const point = getEventPoint(evt);
233
+ point.x = point.x - roundToDevicePixel(7.5);
234
+ point.y = point.y - roundToDevicePixel(7.5);
235
+ send({ type: "PRESS_DOWN_SCRUBBER", point });
236
+ },
237
+ style: {
238
+ cursor: isDisabled ? void 0 : "ew-resize"
239
+ }
240
+ })
241
+ };
242
+ }
243
+
244
+ export {
245
+ connect
246
+ };
@@ -0,0 +1,129 @@
1
+ import {
2
+ defineDomHelpers,
3
+ isSafari,
4
+ roundToDevicePixel,
5
+ supportsPointerEvent,
6
+ wrap
7
+ } from "./chunk-VCZUWKJT.mjs";
8
+
9
+ // ../../utilities/dom/src/constants.ts
10
+ var MAX_Z_INDEX = 2147483647;
11
+
12
+ // src/number-input.dom.ts
13
+ var dom = defineDomHelpers({
14
+ getRootId: (ctx) => {
15
+ var _a, _b;
16
+ return (_b = (_a = ctx.ids) == null ? void 0 : _a.root) != null ? _b : `number-input:${ctx.id}`;
17
+ },
18
+ getInputId: (ctx) => {
19
+ var _a, _b;
20
+ return (_b = (_a = ctx.ids) == null ? void 0 : _a.input) != null ? _b : `number-input:${ctx.id}:input`;
21
+ },
22
+ getIncrementTriggerId: (ctx) => {
23
+ var _a, _b;
24
+ return (_b = (_a = ctx.ids) == null ? void 0 : _a.incrementTrigger) != null ? _b : `number-input:${ctx.id}:inc`;
25
+ },
26
+ getDecrementTriggerId: (ctx) => {
27
+ var _a, _b;
28
+ return (_b = (_a = ctx.ids) == null ? void 0 : _a.decrementTrigger) != null ? _b : `number-input:${ctx.id}:dec`;
29
+ },
30
+ getScrubberId: (ctx) => {
31
+ var _a, _b;
32
+ return (_b = (_a = ctx.ids) == null ? void 0 : _a.scrubber) != null ? _b : `number-input:${ctx.id}:scrubber`;
33
+ },
34
+ getCursorId: (ctx) => `number-input:${ctx.id}:cursor`,
35
+ getLabelId: (ctx) => {
36
+ var _a, _b;
37
+ return (_b = (_a = ctx.ids) == null ? void 0 : _a.label) != null ? _b : `number-input:${ctx.id}:label`;
38
+ },
39
+ getInputEl: (ctx) => dom.getById(ctx, dom.getInputId(ctx)),
40
+ getIncrementTriggerEl: (ctx) => dom.getById(ctx, dom.getIncrementTriggerId(ctx)),
41
+ getDecrementTriggerEl: (ctx) => dom.getById(ctx, dom.getDecrementTriggerId(ctx)),
42
+ getScrubberEl: (ctx) => dom.getById(ctx, dom.getScrubberId(ctx)),
43
+ getCursorEl: (ctx) => dom.getDoc(ctx).getElementById(dom.getCursorId(ctx)),
44
+ getPressedTriggerEl: (ctx, hint = ctx.hint) => {
45
+ let btnEl = null;
46
+ if (hint === "increment") {
47
+ btnEl = dom.getIncrementTriggerEl(ctx);
48
+ }
49
+ if (hint === "decrement") {
50
+ btnEl = dom.getDecrementTriggerEl(ctx);
51
+ }
52
+ return btnEl;
53
+ },
54
+ setupVirtualCursor(ctx) {
55
+ if (isSafari() || !supportsPointerEvent())
56
+ return;
57
+ dom.createVirtualCursor(ctx);
58
+ return () => {
59
+ var _a;
60
+ (_a = dom.getCursorEl(ctx)) == null ? void 0 : _a.remove();
61
+ };
62
+ },
63
+ preventTextSelection(ctx) {
64
+ const doc = dom.getDoc(ctx);
65
+ const html = doc.documentElement;
66
+ const body = doc.body;
67
+ body.style.pointerEvents = "none";
68
+ html.style.userSelect = "none";
69
+ html.style.cursor = "ew-resize";
70
+ return () => {
71
+ body.style.pointerEvents = "";
72
+ html.style.userSelect = "";
73
+ html.style.cursor = "";
74
+ if (!html.style.length) {
75
+ html.removeAttribute("style");
76
+ }
77
+ if (!body.style.length) {
78
+ body.removeAttribute("style");
79
+ }
80
+ };
81
+ },
82
+ getMousementValue(ctx, event) {
83
+ const x = roundToDevicePixel(event.movementX);
84
+ const y = roundToDevicePixel(event.movementY);
85
+ let hint = x > 0 ? "increment" : x < 0 ? "decrement" : null;
86
+ if (ctx.isRtl && hint === "increment")
87
+ hint = "decrement";
88
+ if (ctx.isRtl && hint === "decrement")
89
+ hint = "increment";
90
+ const point = {
91
+ x: ctx.scrubberCursorPoint.x + x,
92
+ y: ctx.scrubberCursorPoint.y + y
93
+ };
94
+ const win = dom.getWin(ctx);
95
+ const width = win.innerWidth;
96
+ const half = roundToDevicePixel(7.5);
97
+ point.x = wrap(point.x + half, width) - half;
98
+ return { hint, point };
99
+ },
100
+ createVirtualCursor(ctx) {
101
+ const doc = dom.getDoc(ctx);
102
+ const el = doc.createElement("div");
103
+ el.className = "scrubber--cursor";
104
+ el.id = dom.getCursorId(ctx);
105
+ Object.assign(el.style, {
106
+ width: "15px",
107
+ height: "15px",
108
+ position: "fixed",
109
+ pointerEvents: "none",
110
+ left: "0px",
111
+ top: "0px",
112
+ zIndex: MAX_Z_INDEX,
113
+ transform: ctx.scrubberCursorPoint ? `translate3d(${ctx.scrubberCursorPoint.x}px, ${ctx.scrubberCursorPoint.y}px, 0px)` : void 0,
114
+ willChange: "transform"
115
+ });
116
+ el.innerHTML = `
117
+ <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);">
118
+ <g transform="translate(2 3)">
119
+ <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>
120
+ <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>
121
+ </g>
122
+ </svg>`;
123
+ doc.body.appendChild(el);
124
+ }
125
+ });
126
+
127
+ export {
128
+ dom
129
+ };
@@ -0,0 +1,53 @@
1
+ import {
2
+ clamp,
3
+ decrement,
4
+ formatDecimal,
5
+ increment,
6
+ isModifiedEvent
7
+ } from "./chunk-VCZUWKJT.mjs";
8
+
9
+ // src/number-input.utils.ts
10
+ var utils = {
11
+ isValidNumericEvent: (ctx, event) => {
12
+ var _a, _b;
13
+ if (event.key == null)
14
+ return true;
15
+ const isModifier = isModifiedEvent(event);
16
+ const isSingleKey = event.key.length === 1;
17
+ if (isModifier || !isSingleKey)
18
+ return true;
19
+ return (_b = (_a = ctx.validateCharacter) == null ? void 0 : _a.call(ctx, event.key)) != null ? _b : utils.isFloatingPoint(event.key);
20
+ },
21
+ isFloatingPoint: (v) => /^[0-9+\-.]$/.test(v),
22
+ sanitize: (ctx, value) => {
23
+ var _a;
24
+ return value.split("").filter((_a = ctx.validateCharacter) != null ? _a : utils.isFloatingPoint).join("");
25
+ },
26
+ increment: (ctx, step) => {
27
+ const value = increment(ctx.value, step != null ? step : ctx.step);
28
+ return formatDecimal(clamp(value, ctx), ctx);
29
+ },
30
+ decrement: (ctx, step) => {
31
+ const value = decrement(ctx.value, step != null ? step : ctx.step);
32
+ return formatDecimal(clamp(value, ctx), ctx);
33
+ },
34
+ clamp: (ctx) => {
35
+ return formatDecimal(clamp(ctx.value, ctx), ctx);
36
+ },
37
+ parse: (ctx, value) => {
38
+ var _a, _b;
39
+ return (_b = (_a = ctx.parse) == null ? void 0 : _a.call(ctx, value)) != null ? _b : value;
40
+ },
41
+ format: (ctx, value) => {
42
+ var _a, _b;
43
+ const _val = value.toString();
44
+ return (_b = (_a = ctx.format) == null ? void 0 : _a.call(ctx, _val)) != null ? _b : _val;
45
+ },
46
+ round: (ctx) => {
47
+ return formatDecimal(ctx.value, ctx);
48
+ }
49
+ };
50
+
51
+ export {
52
+ utils
53
+ };