@zag-js/pin-input 0.1.8 → 0.1.11
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/LICENSE +21 -0
- package/dist/index.d.ts +136 -3
- package/dist/index.js +139 -99
- package/dist/index.mjs +135 -104
- package/package.json +14 -11
- package/dist/pin-input.connect.d.ts +0 -15
- package/dist/pin-input.dom.d.ts +0 -11
- package/dist/pin-input.machine.d.ts +0 -2
- package/dist/pin-input.types.d.ts +0 -113
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 Chakra UI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,136 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { RequiredBy, DirectionProperty, CommonProperties, Context, PropTypes, NormalizeProps } from '@zag-js/types';
|
|
2
|
+
import * as _zag_js_core from '@zag-js/core';
|
|
3
|
+
import { StateMachine } from '@zag-js/core';
|
|
4
|
+
|
|
5
|
+
declare type IntlMessages = {
|
|
6
|
+
inputLabel: (index: number, length: number) => string;
|
|
7
|
+
};
|
|
8
|
+
declare type ElementIds = Partial<{
|
|
9
|
+
root: string;
|
|
10
|
+
hiddenInput: string;
|
|
11
|
+
input(id: string): string;
|
|
12
|
+
}>;
|
|
13
|
+
declare type PublicContext = DirectionProperty & CommonProperties & {
|
|
14
|
+
/**
|
|
15
|
+
* The name of the input element. Useful for form submission.
|
|
16
|
+
*/
|
|
17
|
+
name?: string;
|
|
18
|
+
/**
|
|
19
|
+
* The regular expression that the user-entered input value is checked against.
|
|
20
|
+
*/
|
|
21
|
+
pattern?: string;
|
|
22
|
+
/**
|
|
23
|
+
* The ids of the elements in the pin input. Useful for composition.
|
|
24
|
+
*/
|
|
25
|
+
ids?: ElementIds;
|
|
26
|
+
/**
|
|
27
|
+
* Whether the inputs are disabled
|
|
28
|
+
*/
|
|
29
|
+
disabled?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* The placeholder text for the input
|
|
32
|
+
*/
|
|
33
|
+
placeholder?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Whether to auto-focus the first input.
|
|
36
|
+
*/
|
|
37
|
+
autoFocus?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Whether the pin input is in the invalid state
|
|
40
|
+
*/
|
|
41
|
+
invalid?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* If `true`, the pin input component signals to its fields that they should
|
|
44
|
+
* use `autocomplete="one-time-code"`.
|
|
45
|
+
*/
|
|
46
|
+
otp?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* The value of the the pin input.
|
|
49
|
+
*/
|
|
50
|
+
value: string[];
|
|
51
|
+
/**
|
|
52
|
+
* The type of value the pin-input should allow
|
|
53
|
+
*/
|
|
54
|
+
type?: "alphanumeric" | "numeric" | "alphabetic";
|
|
55
|
+
/**
|
|
56
|
+
* Function called when all inputs have valid values
|
|
57
|
+
*/
|
|
58
|
+
onComplete?: (details: {
|
|
59
|
+
value: string[];
|
|
60
|
+
valueAsString: string;
|
|
61
|
+
}) => void;
|
|
62
|
+
/**
|
|
63
|
+
* Function called on input change
|
|
64
|
+
*/
|
|
65
|
+
onChange?: (details: {
|
|
66
|
+
value: string[];
|
|
67
|
+
}) => void;
|
|
68
|
+
/**
|
|
69
|
+
* Function called when an invalid value is entered
|
|
70
|
+
*/
|
|
71
|
+
onInvalid?: (details: {
|
|
72
|
+
value: string;
|
|
73
|
+
index: number;
|
|
74
|
+
}) => void;
|
|
75
|
+
/**
|
|
76
|
+
* If `true`, the input's value will be masked just like `type=password`
|
|
77
|
+
*/
|
|
78
|
+
mask?: boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Whether to blur the input when the value is complete
|
|
81
|
+
*/
|
|
82
|
+
blurOnComplete?: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Specifies the localized strings that identifies the accessibility elements and their states
|
|
85
|
+
*/
|
|
86
|
+
messages: IntlMessages;
|
|
87
|
+
};
|
|
88
|
+
declare type UserDefinedContext = RequiredBy<PublicContext, "id">;
|
|
89
|
+
declare type ComputedContext = Readonly<{
|
|
90
|
+
/**
|
|
91
|
+
* @computed
|
|
92
|
+
* The number of inputs
|
|
93
|
+
*/
|
|
94
|
+
valueLength: number;
|
|
95
|
+
/**
|
|
96
|
+
* @computed
|
|
97
|
+
* The number of inputs that are not empty
|
|
98
|
+
*/
|
|
99
|
+
filledValueLength: number;
|
|
100
|
+
/**
|
|
101
|
+
* @computed
|
|
102
|
+
* Whether all input values are valid
|
|
103
|
+
*/
|
|
104
|
+
isValueComplete: boolean;
|
|
105
|
+
/**
|
|
106
|
+
* @computed
|
|
107
|
+
* The string representation of the input values
|
|
108
|
+
*/
|
|
109
|
+
valueAsString: string;
|
|
110
|
+
}>;
|
|
111
|
+
declare type PrivateContext = Context<{}>;
|
|
112
|
+
declare type MachineContext = PublicContext & PrivateContext & ComputedContext;
|
|
113
|
+
declare type MachineState = {
|
|
114
|
+
value: "unknown" | "idle" | "focused";
|
|
115
|
+
};
|
|
116
|
+
declare type State = StateMachine.State<MachineContext, MachineState>;
|
|
117
|
+
declare type Send = StateMachine.Send<StateMachine.AnyEventObject>;
|
|
118
|
+
|
|
119
|
+
declare function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): {
|
|
120
|
+
value: string[];
|
|
121
|
+
valueAsString: string;
|
|
122
|
+
isValueComplete: boolean;
|
|
123
|
+
setValue(value: string[]): void;
|
|
124
|
+
clearValue(): void;
|
|
125
|
+
setValueAtIndex(index: number, value: string): void;
|
|
126
|
+
focus(): void;
|
|
127
|
+
rootProps: T["element"];
|
|
128
|
+
hiddenInputProps: T["input"];
|
|
129
|
+
getInputProps({ index }: {
|
|
130
|
+
index: number;
|
|
131
|
+
}): T["input"];
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
declare function machine(ctx: UserDefinedContext): _zag_js_core.Machine<MachineContext, MachineState, _zag_js_core.StateMachine.AnyEventObject>;
|
|
135
|
+
|
|
136
|
+
export { UserDefinedContext as Context, connect, machine };
|
package/dist/index.js
CHANGED
|
@@ -1,25 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
|
-
var __defProps = Object.defineProperties;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
6
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
8
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
10
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
11
|
-
var __spreadValues = (a, b) => {
|
|
12
|
-
for (var prop in b || (b = {}))
|
|
13
|
-
if (__hasOwnProp.call(b, prop))
|
|
14
|
-
__defNormalProp(a, prop, b[prop]);
|
|
15
|
-
if (__getOwnPropSymbols)
|
|
16
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
17
|
-
if (__propIsEnum.call(b, prop))
|
|
18
|
-
__defNormalProp(a, prop, b[prop]);
|
|
19
|
-
}
|
|
20
|
-
return a;
|
|
21
|
-
};
|
|
22
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
23
6
|
var __export = (target, all) => {
|
|
24
7
|
for (var name in all)
|
|
25
8
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -49,28 +32,58 @@ var dataAttr = (guard) => {
|
|
|
49
32
|
var ariaAttr = (guard) => {
|
|
50
33
|
return guard ? "true" : void 0;
|
|
51
34
|
};
|
|
52
|
-
function
|
|
53
|
-
|
|
54
|
-
function raf2(fn2) {
|
|
55
|
-
const id = globalThis.requestAnimationFrame(fn2);
|
|
56
|
-
set.add(() => globalThis.cancelAnimationFrame(id));
|
|
57
|
-
}
|
|
58
|
-
raf2(() => raf2(fn));
|
|
59
|
-
return function cleanup() {
|
|
60
|
-
set.forEach(function(fn2) {
|
|
61
|
-
fn2();
|
|
62
|
-
});
|
|
63
|
-
};
|
|
35
|
+
function isDocument(el) {
|
|
36
|
+
return el.nodeType === Node.DOCUMENT_NODE;
|
|
64
37
|
}
|
|
65
|
-
function
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
38
|
+
function isWindow(value) {
|
|
39
|
+
return (value == null ? void 0 : value.toString()) === "[object Window]";
|
|
40
|
+
}
|
|
41
|
+
function getDocument(el) {
|
|
42
|
+
if (isWindow(el))
|
|
43
|
+
return el.document;
|
|
44
|
+
if (isDocument(el))
|
|
45
|
+
return el;
|
|
46
|
+
return (el == null ? void 0 : el.ownerDocument) ?? document;
|
|
47
|
+
}
|
|
48
|
+
function getWindow(el) {
|
|
49
|
+
return (el == null ? void 0 : el.ownerDocument.defaultView) ?? window;
|
|
50
|
+
}
|
|
51
|
+
function defineDomHelpers(helpers) {
|
|
52
|
+
const dom2 = {
|
|
53
|
+
getRootNode: (ctx) => {
|
|
54
|
+
var _a;
|
|
55
|
+
return ((_a = ctx.getRootNode) == null ? void 0 : _a.call(ctx)) ?? document;
|
|
56
|
+
},
|
|
57
|
+
getDoc: (ctx) => getDocument(dom2.getRootNode(ctx)),
|
|
58
|
+
getWin: (ctx) => dom2.getDoc(ctx).defaultView ?? window,
|
|
59
|
+
getActiveElement: (ctx) => dom2.getDoc(ctx).activeElement,
|
|
60
|
+
getById: (ctx, id) => dom2.getRootNode(ctx).getElementById(id)
|
|
61
|
+
};
|
|
62
|
+
return {
|
|
63
|
+
...dom2,
|
|
64
|
+
...helpers
|
|
69
65
|
};
|
|
70
66
|
}
|
|
71
67
|
function getNativeEvent(e) {
|
|
68
|
+
return e.nativeEvent ?? e;
|
|
69
|
+
}
|
|
70
|
+
var isModifiedEvent = (v) => v.ctrlKey || v.altKey || v.metaKey;
|
|
71
|
+
function getDescriptor(el, options) {
|
|
72
|
+
const { type, property } = options;
|
|
73
|
+
const proto = getWindow(el)[type].prototype;
|
|
74
|
+
return Object.getOwnPropertyDescriptor(proto, property) ?? {};
|
|
75
|
+
}
|
|
76
|
+
function dispatchInputValueEvent(el, value) {
|
|
72
77
|
var _a;
|
|
73
|
-
|
|
78
|
+
if (!el)
|
|
79
|
+
return;
|
|
80
|
+
const win = getWindow(el);
|
|
81
|
+
if (!(el instanceof win.HTMLInputElement))
|
|
82
|
+
return;
|
|
83
|
+
const desc = getDescriptor(el, { type: "HTMLInputElement", property: "value" });
|
|
84
|
+
(_a = desc.set) == null ? void 0 : _a.call(el, value);
|
|
85
|
+
const event = new win.Event("input", { bubbles: true });
|
|
86
|
+
el.dispatchEvent(event);
|
|
74
87
|
}
|
|
75
88
|
var rtlKeyMap = {
|
|
76
89
|
ArrowLeft: "ArrowRight",
|
|
@@ -88,72 +101,73 @@ var sameKeyMap = {
|
|
|
88
101
|
Right: "ArrowRight"
|
|
89
102
|
};
|
|
90
103
|
function getEventKey(event, options = {}) {
|
|
91
|
-
var _a;
|
|
92
104
|
const { dir = "ltr", orientation = "horizontal" } = options;
|
|
93
105
|
let { key } = event;
|
|
94
|
-
key =
|
|
106
|
+
key = sameKeyMap[key] ?? key;
|
|
95
107
|
const isRtl = dir === "rtl" && orientation === "horizontal";
|
|
96
108
|
if (isRtl && key in rtlKeyMap) {
|
|
97
109
|
key = rtlKeyMap[key];
|
|
98
110
|
}
|
|
99
111
|
return key;
|
|
100
112
|
}
|
|
101
|
-
function
|
|
102
|
-
|
|
103
|
-
return
|
|
113
|
+
function raf(fn) {
|
|
114
|
+
const id = globalThis.requestAnimationFrame(fn);
|
|
115
|
+
return function cleanup() {
|
|
116
|
+
globalThis.cancelAnimationFrame(id);
|
|
117
|
+
};
|
|
104
118
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
function createNormalizer(fn) {
|
|
108
|
-
return new Proxy({}, {
|
|
109
|
-
get() {
|
|
110
|
-
return fn;
|
|
111
|
-
}
|
|
112
|
-
});
|
|
119
|
+
function queryAll(root, selector) {
|
|
120
|
+
return Array.from((root == null ? void 0 : root.querySelectorAll(selector)) ?? []);
|
|
113
121
|
}
|
|
114
|
-
var
|
|
122
|
+
var visuallyHiddenStyle = {
|
|
123
|
+
border: "0",
|
|
124
|
+
clip: "rect(0 0 0 0)",
|
|
125
|
+
height: "1px",
|
|
126
|
+
margin: "-1px",
|
|
127
|
+
overflow: "hidden",
|
|
128
|
+
padding: "0",
|
|
129
|
+
position: "absolute",
|
|
130
|
+
width: "1px",
|
|
131
|
+
whiteSpace: "nowrap",
|
|
132
|
+
wordWrap: "normal"
|
|
133
|
+
};
|
|
115
134
|
|
|
116
135
|
// ../../utilities/core/dist/index.mjs
|
|
117
|
-
var fromLength = (length) => Array.from(Array(length).keys());
|
|
118
|
-
var isModifiedEvent = (v) => v.ctrlKey || v.altKey || v.metaKey;
|
|
119
136
|
function invariant(...a) {
|
|
120
137
|
const m = a.length === 1 ? a[0] : a[1];
|
|
121
138
|
const c = a.length === 2 ? a[0] : true;
|
|
122
|
-
if (c &&
|
|
139
|
+
if (c && process.env.NODE_ENV !== "production") {
|
|
123
140
|
throw new Error(m);
|
|
124
141
|
}
|
|
125
142
|
}
|
|
126
143
|
|
|
127
144
|
// src/pin-input.dom.ts
|
|
128
|
-
var dom = {
|
|
129
|
-
|
|
130
|
-
var _a;
|
|
131
|
-
return (_a = ctx.doc) != null ? _a : document;
|
|
132
|
-
},
|
|
133
|
-
getRootNode: (ctx) => {
|
|
145
|
+
var dom = defineDomHelpers({
|
|
146
|
+
getRootId: (ctx) => {
|
|
134
147
|
var _a;
|
|
135
|
-
return (_a = ctx.
|
|
148
|
+
return ((_a = ctx.ids) == null ? void 0 : _a.root) ?? `pin-input:${ctx.id}`;
|
|
136
149
|
},
|
|
137
|
-
|
|
150
|
+
getInputId: (ctx, id) => {
|
|
138
151
|
var _a, _b;
|
|
139
|
-
return (_b = (_a = ctx.ids) == null ? void 0 : _a.
|
|
152
|
+
return ((_b = (_a = ctx.ids) == null ? void 0 : _a.input) == null ? void 0 : _b.call(_a, id)) ?? `pin-input:${ctx.id}:${id}`;
|
|
140
153
|
},
|
|
141
|
-
|
|
142
|
-
var _a
|
|
143
|
-
return (
|
|
154
|
+
getHiddenInputId: (ctx) => {
|
|
155
|
+
var _a;
|
|
156
|
+
return ((_a = ctx.ids) == null ? void 0 : _a.hiddenInput) ?? `pin-input:${ctx.id}:hidden`;
|
|
144
157
|
},
|
|
145
|
-
getRootEl: (ctx) => dom.
|
|
158
|
+
getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
|
|
146
159
|
getElements: (ctx) => {
|
|
147
160
|
const ownerId = CSS.escape(dom.getRootId(ctx));
|
|
148
161
|
const selector = `input[data-ownedby=${ownerId}]`;
|
|
149
162
|
return queryAll(dom.getRootEl(ctx), selector);
|
|
150
163
|
},
|
|
151
164
|
getFocusedEl: (ctx) => dom.getElements(ctx)[ctx.focusedIndex],
|
|
152
|
-
getFirstInputEl: (ctx) => dom.getElements(ctx)[0]
|
|
153
|
-
|
|
165
|
+
getFirstInputEl: (ctx) => dom.getElements(ctx)[0],
|
|
166
|
+
getHiddenInputEl: (ctx) => dom.getById(ctx, dom.getHiddenInputId(ctx))
|
|
167
|
+
});
|
|
154
168
|
|
|
155
169
|
// src/pin-input.connect.ts
|
|
156
|
-
function connect(state, send, normalize
|
|
170
|
+
function connect(state, send, normalize) {
|
|
157
171
|
const isValueComplete = state.context.isValueComplete;
|
|
158
172
|
const isInvalid = state.context.invalid;
|
|
159
173
|
const focusedIndex = state.context.focusedIndex;
|
|
@@ -186,6 +200,16 @@ function connect(state, send, normalize = normalizeProp) {
|
|
|
186
200
|
"data-disabled": dataAttr(state.context.disabled),
|
|
187
201
|
"data-complete": dataAttr(isValueComplete)
|
|
188
202
|
}),
|
|
203
|
+
hiddenInputProps: normalize.input({
|
|
204
|
+
"aria-hidden": true,
|
|
205
|
+
type: "text",
|
|
206
|
+
tabIndex: -1,
|
|
207
|
+
id: dom.getHiddenInputId(state.context),
|
|
208
|
+
name: state.context.name,
|
|
209
|
+
style: visuallyHiddenStyle,
|
|
210
|
+
maxLength: state.context.valueLength,
|
|
211
|
+
defaultValue: state.context.valueAsString
|
|
212
|
+
}),
|
|
189
213
|
getInputProps({ index }) {
|
|
190
214
|
const inputType = state.context.type === "numeric" ? "tel" : "text";
|
|
191
215
|
return normalize.input({
|
|
@@ -234,6 +258,9 @@ function connect(state, send, normalize = normalizeProp) {
|
|
|
234
258
|
},
|
|
235
259
|
ArrowRight() {
|
|
236
260
|
send("ARROW_RIGHT");
|
|
261
|
+
},
|
|
262
|
+
Enter() {
|
|
263
|
+
send("ENTER");
|
|
237
264
|
}
|
|
238
265
|
};
|
|
239
266
|
const key = getEventKey(event, { dir: state.context.dir });
|
|
@@ -259,22 +286,22 @@ function connect(state, send, normalize = normalizeProp) {
|
|
|
259
286
|
// src/pin-input.machine.ts
|
|
260
287
|
var import_core = require("@zag-js/core");
|
|
261
288
|
var { and, not } = import_core.guards;
|
|
262
|
-
function machine(ctx
|
|
289
|
+
function machine(ctx) {
|
|
263
290
|
return (0, import_core.createMachine)({
|
|
264
291
|
id: "pin-input",
|
|
265
292
|
initial: "unknown",
|
|
266
|
-
context:
|
|
267
|
-
uid: "pin-input",
|
|
293
|
+
context: {
|
|
268
294
|
value: [],
|
|
269
295
|
focusedIndex: -1,
|
|
270
296
|
placeholder: "\u25CB",
|
|
271
297
|
otp: false,
|
|
272
|
-
type: "numeric"
|
|
273
|
-
|
|
274
|
-
messages:
|
|
275
|
-
inputLabel: (index, length) => `pin code ${index + 1} of ${length}
|
|
276
|
-
|
|
277
|
-
|
|
298
|
+
type: "numeric",
|
|
299
|
+
...ctx,
|
|
300
|
+
messages: {
|
|
301
|
+
inputLabel: (index, length) => `pin code ${index + 1} of ${length}`,
|
|
302
|
+
...ctx.messages
|
|
303
|
+
}
|
|
304
|
+
},
|
|
278
305
|
computed: {
|
|
279
306
|
valueLength: (ctx2) => ctx2.value.length,
|
|
280
307
|
filledValueLength: (ctx2) => ctx2.value.filter((v) => (v == null ? void 0 : v.trim()) !== "").length,
|
|
@@ -284,7 +311,7 @@ function machine(ctx = {}) {
|
|
|
284
311
|
watch: {
|
|
285
312
|
focusedIndex: "focusInput",
|
|
286
313
|
value: "invokeOnChange",
|
|
287
|
-
isValueComplete: ["
|
|
314
|
+
isValueComplete: ["invokeOnComplete", "blurFocusedInputIfNeeded"]
|
|
288
315
|
},
|
|
289
316
|
on: {
|
|
290
317
|
SET_VALUE: [
|
|
@@ -311,11 +338,11 @@ function machine(ctx = {}) {
|
|
|
311
338
|
{
|
|
312
339
|
guard: "autoFocus",
|
|
313
340
|
target: "focused",
|
|
314
|
-
actions: ["
|
|
341
|
+
actions: ["setupValue", "setFocusIndexToFirst"]
|
|
315
342
|
},
|
|
316
343
|
{
|
|
317
344
|
target: "idle",
|
|
318
|
-
actions:
|
|
345
|
+
actions: "setupValue"
|
|
319
346
|
}
|
|
320
347
|
]
|
|
321
348
|
}
|
|
@@ -367,6 +394,10 @@ function machine(ctx = {}) {
|
|
|
367
394
|
actions: ["setPrevFocusedIndex", "clearFocusedValue"]
|
|
368
395
|
}
|
|
369
396
|
],
|
|
397
|
+
ENTER: {
|
|
398
|
+
guard: "isValueComplete",
|
|
399
|
+
actions: "requestFormSubmit"
|
|
400
|
+
},
|
|
370
401
|
KEY_DOWN: {
|
|
371
402
|
guard: not("isValidValue"),
|
|
372
403
|
actions: ["preventDefault", "invokeOnInvalid"]
|
|
@@ -380,7 +411,12 @@ function machine(ctx = {}) {
|
|
|
380
411
|
isValueEmpty: (_ctx, evt) => evt.value === "",
|
|
381
412
|
hasValue: (ctx2) => ctx2.value[ctx2.focusedIndex] !== "",
|
|
382
413
|
isValueComplete: (ctx2) => ctx2.isValueComplete,
|
|
383
|
-
isValidValue: (ctx2, evt) =>
|
|
414
|
+
isValidValue: (ctx2, evt) => {
|
|
415
|
+
if (!ctx2.pattern)
|
|
416
|
+
return isValidType(evt.value, ctx2.type);
|
|
417
|
+
const regex = new RegExp(ctx2.pattern, "g");
|
|
418
|
+
return regex.test(evt.value);
|
|
419
|
+
},
|
|
384
420
|
isFinalValue: (ctx2) => {
|
|
385
421
|
return ctx2.filledValueLength + 1 === ctx2.valueLength && ctx2.value.findIndex((v) => v.trim() === "") === ctx2.focusedIndex;
|
|
386
422
|
},
|
|
@@ -389,19 +425,10 @@ function machine(ctx = {}) {
|
|
|
389
425
|
isDisabled: (ctx2) => !!ctx2.disabled
|
|
390
426
|
},
|
|
391
427
|
actions: {
|
|
392
|
-
setupDocument: (ctx2, evt) => {
|
|
393
|
-
if (evt.doc)
|
|
394
|
-
ctx2.doc = (0, import_core.ref)(evt.doc);
|
|
395
|
-
if (evt.root)
|
|
396
|
-
ctx2.rootNode = (0, import_core.ref)(evt.root);
|
|
397
|
-
ctx2.uid = evt.id;
|
|
398
|
-
},
|
|
399
428
|
setupValue: (ctx2) => {
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
ctx2.value = Object.assign(empty, ctx2.value);
|
|
404
|
-
});
|
|
429
|
+
const inputs = dom.getElements(ctx2);
|
|
430
|
+
const empty = Array.from({ length: inputs.length }).map(() => "");
|
|
431
|
+
ctx2.value = Object.assign(empty, ctx2.value);
|
|
405
432
|
},
|
|
406
433
|
focusInput: (ctx2) => {
|
|
407
434
|
raf(() => {
|
|
@@ -411,17 +438,18 @@ function machine(ctx = {}) {
|
|
|
411
438
|
(_a = dom.getFocusedEl(ctx2)) == null ? void 0 : _a.focus();
|
|
412
439
|
});
|
|
413
440
|
},
|
|
414
|
-
|
|
441
|
+
invokeOnComplete: (ctx2) => {
|
|
415
442
|
var _a;
|
|
416
|
-
if (ctx2.isValueComplete)
|
|
417
|
-
|
|
418
|
-
}
|
|
443
|
+
if (!ctx2.isValueComplete)
|
|
444
|
+
return;
|
|
445
|
+
(_a = ctx2.onComplete) == null ? void 0 : _a.call(ctx2, { value: Array.from(ctx2.value), valueAsString: ctx2.valueAsString });
|
|
419
446
|
},
|
|
420
447
|
invokeOnChange: (ctx2, evt) => {
|
|
421
448
|
var _a;
|
|
422
|
-
if (evt.type
|
|
423
|
-
|
|
424
|
-
}
|
|
449
|
+
if (evt.type === "SETUP")
|
|
450
|
+
return;
|
|
451
|
+
(_a = ctx2.onChange) == null ? void 0 : _a.call(ctx2, { value: Array.from(ctx2.value) });
|
|
452
|
+
dispatchInputValueEvent(dom.getHiddenInputEl(ctx2), ctx2.valueAsString);
|
|
425
453
|
},
|
|
426
454
|
invokeOnInvalid: (ctx2, evt) => {
|
|
427
455
|
var _a;
|
|
@@ -478,6 +506,13 @@ function machine(ctx = {}) {
|
|
|
478
506
|
var _a;
|
|
479
507
|
(_a = dom.getFocusedEl(ctx2)) == null ? void 0 : _a.blur();
|
|
480
508
|
});
|
|
509
|
+
},
|
|
510
|
+
requestFormSubmit(ctx2) {
|
|
511
|
+
var _a;
|
|
512
|
+
if (!ctx2.name)
|
|
513
|
+
return;
|
|
514
|
+
const input = dom.getHiddenInputEl(ctx2);
|
|
515
|
+
(_a = input == null ? void 0 : input.form) == null ? void 0 : _a.requestSubmit();
|
|
481
516
|
}
|
|
482
517
|
}
|
|
483
518
|
});
|
|
@@ -508,3 +543,8 @@ function assign(ctx, value) {
|
|
|
508
543
|
function lastChar(value) {
|
|
509
544
|
return value.charAt(value.length - 1);
|
|
510
545
|
}
|
|
546
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
547
|
+
0 && (module.exports = {
|
|
548
|
+
connect,
|
|
549
|
+
machine
|
|
550
|
+
});
|
package/dist/index.mjs
CHANGED
|
@@ -1,24 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __defProps = Object.defineProperties;
|
|
4
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
5
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
8
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
9
|
-
var __spreadValues = (a, b) => {
|
|
10
|
-
for (var prop in b || (b = {}))
|
|
11
|
-
if (__hasOwnProp.call(b, prop))
|
|
12
|
-
__defNormalProp(a, prop, b[prop]);
|
|
13
|
-
if (__getOwnPropSymbols)
|
|
14
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
15
|
-
if (__propIsEnum.call(b, prop))
|
|
16
|
-
__defNormalProp(a, prop, b[prop]);
|
|
17
|
-
}
|
|
18
|
-
return a;
|
|
19
|
-
};
|
|
20
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
21
|
-
|
|
22
1
|
// ../../utilities/dom/dist/index.mjs
|
|
23
2
|
var dataAttr = (guard) => {
|
|
24
3
|
return guard ? "" : void 0;
|
|
@@ -26,28 +5,58 @@ var dataAttr = (guard) => {
|
|
|
26
5
|
var ariaAttr = (guard) => {
|
|
27
6
|
return guard ? "true" : void 0;
|
|
28
7
|
};
|
|
29
|
-
function
|
|
30
|
-
|
|
31
|
-
function raf2(fn2) {
|
|
32
|
-
const id = globalThis.requestAnimationFrame(fn2);
|
|
33
|
-
set.add(() => globalThis.cancelAnimationFrame(id));
|
|
34
|
-
}
|
|
35
|
-
raf2(() => raf2(fn));
|
|
36
|
-
return function cleanup() {
|
|
37
|
-
set.forEach(function(fn2) {
|
|
38
|
-
fn2();
|
|
39
|
-
});
|
|
40
|
-
};
|
|
8
|
+
function isDocument(el) {
|
|
9
|
+
return el.nodeType === Node.DOCUMENT_NODE;
|
|
41
10
|
}
|
|
42
|
-
function
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
11
|
+
function isWindow(value) {
|
|
12
|
+
return (value == null ? void 0 : value.toString()) === "[object Window]";
|
|
13
|
+
}
|
|
14
|
+
function getDocument(el) {
|
|
15
|
+
if (isWindow(el))
|
|
16
|
+
return el.document;
|
|
17
|
+
if (isDocument(el))
|
|
18
|
+
return el;
|
|
19
|
+
return (el == null ? void 0 : el.ownerDocument) ?? document;
|
|
20
|
+
}
|
|
21
|
+
function getWindow(el) {
|
|
22
|
+
return (el == null ? void 0 : el.ownerDocument.defaultView) ?? window;
|
|
23
|
+
}
|
|
24
|
+
function defineDomHelpers(helpers) {
|
|
25
|
+
const dom2 = {
|
|
26
|
+
getRootNode: (ctx) => {
|
|
27
|
+
var _a;
|
|
28
|
+
return ((_a = ctx.getRootNode) == null ? void 0 : _a.call(ctx)) ?? document;
|
|
29
|
+
},
|
|
30
|
+
getDoc: (ctx) => getDocument(dom2.getRootNode(ctx)),
|
|
31
|
+
getWin: (ctx) => dom2.getDoc(ctx).defaultView ?? window,
|
|
32
|
+
getActiveElement: (ctx) => dom2.getDoc(ctx).activeElement,
|
|
33
|
+
getById: (ctx, id) => dom2.getRootNode(ctx).getElementById(id)
|
|
34
|
+
};
|
|
35
|
+
return {
|
|
36
|
+
...dom2,
|
|
37
|
+
...helpers
|
|
46
38
|
};
|
|
47
39
|
}
|
|
48
40
|
function getNativeEvent(e) {
|
|
41
|
+
return e.nativeEvent ?? e;
|
|
42
|
+
}
|
|
43
|
+
var isModifiedEvent = (v) => v.ctrlKey || v.altKey || v.metaKey;
|
|
44
|
+
function getDescriptor(el, options) {
|
|
45
|
+
const { type, property } = options;
|
|
46
|
+
const proto = getWindow(el)[type].prototype;
|
|
47
|
+
return Object.getOwnPropertyDescriptor(proto, property) ?? {};
|
|
48
|
+
}
|
|
49
|
+
function dispatchInputValueEvent(el, value) {
|
|
49
50
|
var _a;
|
|
50
|
-
|
|
51
|
+
if (!el)
|
|
52
|
+
return;
|
|
53
|
+
const win = getWindow(el);
|
|
54
|
+
if (!(el instanceof win.HTMLInputElement))
|
|
55
|
+
return;
|
|
56
|
+
const desc = getDescriptor(el, { type: "HTMLInputElement", property: "value" });
|
|
57
|
+
(_a = desc.set) == null ? void 0 : _a.call(el, value);
|
|
58
|
+
const event = new win.Event("input", { bubbles: true });
|
|
59
|
+
el.dispatchEvent(event);
|
|
51
60
|
}
|
|
52
61
|
var rtlKeyMap = {
|
|
53
62
|
ArrowLeft: "ArrowRight",
|
|
@@ -65,72 +74,73 @@ var sameKeyMap = {
|
|
|
65
74
|
Right: "ArrowRight"
|
|
66
75
|
};
|
|
67
76
|
function getEventKey(event, options = {}) {
|
|
68
|
-
var _a;
|
|
69
77
|
const { dir = "ltr", orientation = "horizontal" } = options;
|
|
70
78
|
let { key } = event;
|
|
71
|
-
key =
|
|
79
|
+
key = sameKeyMap[key] ?? key;
|
|
72
80
|
const isRtl = dir === "rtl" && orientation === "horizontal";
|
|
73
81
|
if (isRtl && key in rtlKeyMap) {
|
|
74
82
|
key = rtlKeyMap[key];
|
|
75
83
|
}
|
|
76
84
|
return key;
|
|
77
85
|
}
|
|
78
|
-
function
|
|
79
|
-
|
|
80
|
-
return
|
|
86
|
+
function raf(fn) {
|
|
87
|
+
const id = globalThis.requestAnimationFrame(fn);
|
|
88
|
+
return function cleanup() {
|
|
89
|
+
globalThis.cancelAnimationFrame(id);
|
|
90
|
+
};
|
|
81
91
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
function createNormalizer(fn) {
|
|
85
|
-
return new Proxy({}, {
|
|
86
|
-
get() {
|
|
87
|
-
return fn;
|
|
88
|
-
}
|
|
89
|
-
});
|
|
92
|
+
function queryAll(root, selector) {
|
|
93
|
+
return Array.from((root == null ? void 0 : root.querySelectorAll(selector)) ?? []);
|
|
90
94
|
}
|
|
91
|
-
var
|
|
95
|
+
var visuallyHiddenStyle = {
|
|
96
|
+
border: "0",
|
|
97
|
+
clip: "rect(0 0 0 0)",
|
|
98
|
+
height: "1px",
|
|
99
|
+
margin: "-1px",
|
|
100
|
+
overflow: "hidden",
|
|
101
|
+
padding: "0",
|
|
102
|
+
position: "absolute",
|
|
103
|
+
width: "1px",
|
|
104
|
+
whiteSpace: "nowrap",
|
|
105
|
+
wordWrap: "normal"
|
|
106
|
+
};
|
|
92
107
|
|
|
93
108
|
// ../../utilities/core/dist/index.mjs
|
|
94
|
-
var fromLength = (length) => Array.from(Array(length).keys());
|
|
95
|
-
var isModifiedEvent = (v) => v.ctrlKey || v.altKey || v.metaKey;
|
|
96
109
|
function invariant(...a) {
|
|
97
110
|
const m = a.length === 1 ? a[0] : a[1];
|
|
98
111
|
const c = a.length === 2 ? a[0] : true;
|
|
99
|
-
if (c &&
|
|
112
|
+
if (c && process.env.NODE_ENV !== "production") {
|
|
100
113
|
throw new Error(m);
|
|
101
114
|
}
|
|
102
115
|
}
|
|
103
116
|
|
|
104
117
|
// src/pin-input.dom.ts
|
|
105
|
-
var dom = {
|
|
106
|
-
|
|
107
|
-
var _a;
|
|
108
|
-
return (_a = ctx.doc) != null ? _a : document;
|
|
109
|
-
},
|
|
110
|
-
getRootNode: (ctx) => {
|
|
118
|
+
var dom = defineDomHelpers({
|
|
119
|
+
getRootId: (ctx) => {
|
|
111
120
|
var _a;
|
|
112
|
-
return (_a = ctx.
|
|
121
|
+
return ((_a = ctx.ids) == null ? void 0 : _a.root) ?? `pin-input:${ctx.id}`;
|
|
113
122
|
},
|
|
114
|
-
|
|
123
|
+
getInputId: (ctx, id) => {
|
|
115
124
|
var _a, _b;
|
|
116
|
-
return (_b = (_a = ctx.ids) == null ? void 0 : _a.
|
|
125
|
+
return ((_b = (_a = ctx.ids) == null ? void 0 : _a.input) == null ? void 0 : _b.call(_a, id)) ?? `pin-input:${ctx.id}:${id}`;
|
|
117
126
|
},
|
|
118
|
-
|
|
119
|
-
var _a
|
|
120
|
-
return (
|
|
127
|
+
getHiddenInputId: (ctx) => {
|
|
128
|
+
var _a;
|
|
129
|
+
return ((_a = ctx.ids) == null ? void 0 : _a.hiddenInput) ?? `pin-input:${ctx.id}:hidden`;
|
|
121
130
|
},
|
|
122
|
-
getRootEl: (ctx) => dom.
|
|
131
|
+
getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
|
|
123
132
|
getElements: (ctx) => {
|
|
124
133
|
const ownerId = CSS.escape(dom.getRootId(ctx));
|
|
125
134
|
const selector = `input[data-ownedby=${ownerId}]`;
|
|
126
135
|
return queryAll(dom.getRootEl(ctx), selector);
|
|
127
136
|
},
|
|
128
137
|
getFocusedEl: (ctx) => dom.getElements(ctx)[ctx.focusedIndex],
|
|
129
|
-
getFirstInputEl: (ctx) => dom.getElements(ctx)[0]
|
|
130
|
-
|
|
138
|
+
getFirstInputEl: (ctx) => dom.getElements(ctx)[0],
|
|
139
|
+
getHiddenInputEl: (ctx) => dom.getById(ctx, dom.getHiddenInputId(ctx))
|
|
140
|
+
});
|
|
131
141
|
|
|
132
142
|
// src/pin-input.connect.ts
|
|
133
|
-
function connect(state, send, normalize
|
|
143
|
+
function connect(state, send, normalize) {
|
|
134
144
|
const isValueComplete = state.context.isValueComplete;
|
|
135
145
|
const isInvalid = state.context.invalid;
|
|
136
146
|
const focusedIndex = state.context.focusedIndex;
|
|
@@ -163,6 +173,16 @@ function connect(state, send, normalize = normalizeProp) {
|
|
|
163
173
|
"data-disabled": dataAttr(state.context.disabled),
|
|
164
174
|
"data-complete": dataAttr(isValueComplete)
|
|
165
175
|
}),
|
|
176
|
+
hiddenInputProps: normalize.input({
|
|
177
|
+
"aria-hidden": true,
|
|
178
|
+
type: "text",
|
|
179
|
+
tabIndex: -1,
|
|
180
|
+
id: dom.getHiddenInputId(state.context),
|
|
181
|
+
name: state.context.name,
|
|
182
|
+
style: visuallyHiddenStyle,
|
|
183
|
+
maxLength: state.context.valueLength,
|
|
184
|
+
defaultValue: state.context.valueAsString
|
|
185
|
+
}),
|
|
166
186
|
getInputProps({ index }) {
|
|
167
187
|
const inputType = state.context.type === "numeric" ? "tel" : "text";
|
|
168
188
|
return normalize.input({
|
|
@@ -211,6 +231,9 @@ function connect(state, send, normalize = normalizeProp) {
|
|
|
211
231
|
},
|
|
212
232
|
ArrowRight() {
|
|
213
233
|
send("ARROW_RIGHT");
|
|
234
|
+
},
|
|
235
|
+
Enter() {
|
|
236
|
+
send("ENTER");
|
|
214
237
|
}
|
|
215
238
|
};
|
|
216
239
|
const key = getEventKey(event, { dir: state.context.dir });
|
|
@@ -234,24 +257,24 @@ function connect(state, send, normalize = normalizeProp) {
|
|
|
234
257
|
}
|
|
235
258
|
|
|
236
259
|
// src/pin-input.machine.ts
|
|
237
|
-
import { createMachine, guards
|
|
260
|
+
import { createMachine, guards } from "@zag-js/core";
|
|
238
261
|
var { and, not } = guards;
|
|
239
|
-
function machine(ctx
|
|
262
|
+
function machine(ctx) {
|
|
240
263
|
return createMachine({
|
|
241
264
|
id: "pin-input",
|
|
242
265
|
initial: "unknown",
|
|
243
|
-
context:
|
|
244
|
-
uid: "pin-input",
|
|
266
|
+
context: {
|
|
245
267
|
value: [],
|
|
246
268
|
focusedIndex: -1,
|
|
247
269
|
placeholder: "\u25CB",
|
|
248
270
|
otp: false,
|
|
249
|
-
type: "numeric"
|
|
250
|
-
|
|
251
|
-
messages:
|
|
252
|
-
inputLabel: (index, length) => `pin code ${index + 1} of ${length}
|
|
253
|
-
|
|
254
|
-
|
|
271
|
+
type: "numeric",
|
|
272
|
+
...ctx,
|
|
273
|
+
messages: {
|
|
274
|
+
inputLabel: (index, length) => `pin code ${index + 1} of ${length}`,
|
|
275
|
+
...ctx.messages
|
|
276
|
+
}
|
|
277
|
+
},
|
|
255
278
|
computed: {
|
|
256
279
|
valueLength: (ctx2) => ctx2.value.length,
|
|
257
280
|
filledValueLength: (ctx2) => ctx2.value.filter((v) => (v == null ? void 0 : v.trim()) !== "").length,
|
|
@@ -261,7 +284,7 @@ function machine(ctx = {}) {
|
|
|
261
284
|
watch: {
|
|
262
285
|
focusedIndex: "focusInput",
|
|
263
286
|
value: "invokeOnChange",
|
|
264
|
-
isValueComplete: ["
|
|
287
|
+
isValueComplete: ["invokeOnComplete", "blurFocusedInputIfNeeded"]
|
|
265
288
|
},
|
|
266
289
|
on: {
|
|
267
290
|
SET_VALUE: [
|
|
@@ -288,11 +311,11 @@ function machine(ctx = {}) {
|
|
|
288
311
|
{
|
|
289
312
|
guard: "autoFocus",
|
|
290
313
|
target: "focused",
|
|
291
|
-
actions: ["
|
|
314
|
+
actions: ["setupValue", "setFocusIndexToFirst"]
|
|
292
315
|
},
|
|
293
316
|
{
|
|
294
317
|
target: "idle",
|
|
295
|
-
actions:
|
|
318
|
+
actions: "setupValue"
|
|
296
319
|
}
|
|
297
320
|
]
|
|
298
321
|
}
|
|
@@ -344,6 +367,10 @@ function machine(ctx = {}) {
|
|
|
344
367
|
actions: ["setPrevFocusedIndex", "clearFocusedValue"]
|
|
345
368
|
}
|
|
346
369
|
],
|
|
370
|
+
ENTER: {
|
|
371
|
+
guard: "isValueComplete",
|
|
372
|
+
actions: "requestFormSubmit"
|
|
373
|
+
},
|
|
347
374
|
KEY_DOWN: {
|
|
348
375
|
guard: not("isValidValue"),
|
|
349
376
|
actions: ["preventDefault", "invokeOnInvalid"]
|
|
@@ -357,7 +384,12 @@ function machine(ctx = {}) {
|
|
|
357
384
|
isValueEmpty: (_ctx, evt) => evt.value === "",
|
|
358
385
|
hasValue: (ctx2) => ctx2.value[ctx2.focusedIndex] !== "",
|
|
359
386
|
isValueComplete: (ctx2) => ctx2.isValueComplete,
|
|
360
|
-
isValidValue: (ctx2, evt) =>
|
|
387
|
+
isValidValue: (ctx2, evt) => {
|
|
388
|
+
if (!ctx2.pattern)
|
|
389
|
+
return isValidType(evt.value, ctx2.type);
|
|
390
|
+
const regex = new RegExp(ctx2.pattern, "g");
|
|
391
|
+
return regex.test(evt.value);
|
|
392
|
+
},
|
|
361
393
|
isFinalValue: (ctx2) => {
|
|
362
394
|
return ctx2.filledValueLength + 1 === ctx2.valueLength && ctx2.value.findIndex((v) => v.trim() === "") === ctx2.focusedIndex;
|
|
363
395
|
},
|
|
@@ -366,19 +398,10 @@ function machine(ctx = {}) {
|
|
|
366
398
|
isDisabled: (ctx2) => !!ctx2.disabled
|
|
367
399
|
},
|
|
368
400
|
actions: {
|
|
369
|
-
setupDocument: (ctx2, evt) => {
|
|
370
|
-
if (evt.doc)
|
|
371
|
-
ctx2.doc = ref(evt.doc);
|
|
372
|
-
if (evt.root)
|
|
373
|
-
ctx2.rootNode = ref(evt.root);
|
|
374
|
-
ctx2.uid = evt.id;
|
|
375
|
-
},
|
|
376
401
|
setupValue: (ctx2) => {
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
ctx2.value = Object.assign(empty, ctx2.value);
|
|
381
|
-
});
|
|
402
|
+
const inputs = dom.getElements(ctx2);
|
|
403
|
+
const empty = Array.from({ length: inputs.length }).map(() => "");
|
|
404
|
+
ctx2.value = Object.assign(empty, ctx2.value);
|
|
382
405
|
},
|
|
383
406
|
focusInput: (ctx2) => {
|
|
384
407
|
raf(() => {
|
|
@@ -388,17 +411,18 @@ function machine(ctx = {}) {
|
|
|
388
411
|
(_a = dom.getFocusedEl(ctx2)) == null ? void 0 : _a.focus();
|
|
389
412
|
});
|
|
390
413
|
},
|
|
391
|
-
|
|
414
|
+
invokeOnComplete: (ctx2) => {
|
|
392
415
|
var _a;
|
|
393
|
-
if (ctx2.isValueComplete)
|
|
394
|
-
|
|
395
|
-
}
|
|
416
|
+
if (!ctx2.isValueComplete)
|
|
417
|
+
return;
|
|
418
|
+
(_a = ctx2.onComplete) == null ? void 0 : _a.call(ctx2, { value: Array.from(ctx2.value), valueAsString: ctx2.valueAsString });
|
|
396
419
|
},
|
|
397
420
|
invokeOnChange: (ctx2, evt) => {
|
|
398
421
|
var _a;
|
|
399
|
-
if (evt.type
|
|
400
|
-
|
|
401
|
-
}
|
|
422
|
+
if (evt.type === "SETUP")
|
|
423
|
+
return;
|
|
424
|
+
(_a = ctx2.onChange) == null ? void 0 : _a.call(ctx2, { value: Array.from(ctx2.value) });
|
|
425
|
+
dispatchInputValueEvent(dom.getHiddenInputEl(ctx2), ctx2.valueAsString);
|
|
402
426
|
},
|
|
403
427
|
invokeOnInvalid: (ctx2, evt) => {
|
|
404
428
|
var _a;
|
|
@@ -455,6 +479,13 @@ function machine(ctx = {}) {
|
|
|
455
479
|
var _a;
|
|
456
480
|
(_a = dom.getFocusedEl(ctx2)) == null ? void 0 : _a.blur();
|
|
457
481
|
});
|
|
482
|
+
},
|
|
483
|
+
requestFormSubmit(ctx2) {
|
|
484
|
+
var _a;
|
|
485
|
+
if (!ctx2.name)
|
|
486
|
+
return;
|
|
487
|
+
const input = dom.getHiddenInputEl(ctx2);
|
|
488
|
+
(_a = input == null ? void 0 : input.form) == null ? void 0 : _a.requestSubmit();
|
|
458
489
|
}
|
|
459
490
|
}
|
|
460
491
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zag-js/pin-input",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"description": "Core logic for the pin-input widget implemented as a state machine",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"js",
|
|
@@ -29,18 +29,21 @@
|
|
|
29
29
|
"url": "https://github.com/chakra-ui/zag/issues"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@zag-js/core": "0.1.
|
|
33
|
-
"@zag-js/
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
"@zag-js/core": "0.1.9",
|
|
33
|
+
"@zag-js/types": "0.2.3"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@zag-js/dom-utils": "0.1.8",
|
|
37
|
+
"@zag-js/utils": "0.1.3"
|
|
36
38
|
},
|
|
37
39
|
"scripts": {
|
|
38
|
-
"build
|
|
39
|
-
"start": "
|
|
40
|
-
"build": "
|
|
40
|
+
"build-fast": "tsup src/index.ts --format=esm,cjs",
|
|
41
|
+
"start": "pnpm build --watch",
|
|
42
|
+
"build": "tsup src/index.ts --format=esm,cjs --dts",
|
|
41
43
|
"test": "jest --config ../../../jest.config.js --rootDir . --passWithNoTests",
|
|
42
44
|
"lint": "eslint src --ext .ts,.tsx",
|
|
43
|
-
"test
|
|
44
|
-
"test
|
|
45
|
+
"test-ci": "pnpm test --ci --runInBand",
|
|
46
|
+
"test-watch": "pnpm test --watch -u",
|
|
47
|
+
"typecheck": "tsc --noEmit"
|
|
45
48
|
}
|
|
46
|
-
}
|
|
49
|
+
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { PropTypes, ReactPropTypes } from "@zag-js/types";
|
|
2
|
-
import { Send, State } from "./pin-input.types";
|
|
3
|
-
export declare function connect<T extends PropTypes = ReactPropTypes>(state: State, send: Send, normalize?: import("@zag-js/types").NormalizeProps): {
|
|
4
|
-
value: string[];
|
|
5
|
-
valueAsString: string;
|
|
6
|
-
isValueComplete: boolean;
|
|
7
|
-
setValue(value: string[]): void;
|
|
8
|
-
clearValue(): void;
|
|
9
|
-
setValueAtIndex(index: number, value: string): void;
|
|
10
|
-
focus(): void;
|
|
11
|
-
rootProps: T["element"];
|
|
12
|
-
getInputProps({ index }: {
|
|
13
|
-
index: number;
|
|
14
|
-
}): T["input"];
|
|
15
|
-
};
|
package/dist/pin-input.dom.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { MachineContext as Ctx } from "./pin-input.types";
|
|
2
|
-
export declare const dom: {
|
|
3
|
-
getDoc: (ctx: Ctx) => Document;
|
|
4
|
-
getRootNode: (ctx: Ctx) => Document | ShadowRoot;
|
|
5
|
-
getRootId: (ctx: Ctx) => string;
|
|
6
|
-
getInputId: (ctx: Ctx, id: string) => string;
|
|
7
|
-
getRootEl: (ctx: Ctx) => HTMLElement;
|
|
8
|
-
getElements: (ctx: Ctx) => HTMLInputElement[];
|
|
9
|
-
getFocusedEl: (ctx: Ctx) => HTMLInputElement;
|
|
10
|
-
getFirstInputEl: (ctx: Ctx) => HTMLInputElement;
|
|
11
|
-
};
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import type { StateMachine as S } from "@zag-js/core";
|
|
2
|
-
import type { Context, DirectionProperty } from "@zag-js/types";
|
|
3
|
-
declare type IntlMessages = {
|
|
4
|
-
inputLabel: (index: number, length: number) => string;
|
|
5
|
-
};
|
|
6
|
-
declare type ElementIds = Partial<{
|
|
7
|
-
root: string;
|
|
8
|
-
input(id: string): string;
|
|
9
|
-
}>;
|
|
10
|
-
declare type PublicContext = DirectionProperty & {
|
|
11
|
-
/**
|
|
12
|
-
* The ids of the elements in the pin input. Useful for composition.
|
|
13
|
-
*/
|
|
14
|
-
ids?: ElementIds;
|
|
15
|
-
/**
|
|
16
|
-
* Whether the inputs are disabled
|
|
17
|
-
*/
|
|
18
|
-
disabled?: boolean;
|
|
19
|
-
/**
|
|
20
|
-
* The placeholder text for the input
|
|
21
|
-
*/
|
|
22
|
-
placeholder?: string;
|
|
23
|
-
/**
|
|
24
|
-
* Whether to auto-focus the first input.
|
|
25
|
-
*/
|
|
26
|
-
autoFocus?: boolean;
|
|
27
|
-
/**
|
|
28
|
-
* Whether the pin input is in the invalid state
|
|
29
|
-
*/
|
|
30
|
-
invalid?: boolean;
|
|
31
|
-
/**
|
|
32
|
-
* If `true`, the pin input component signals to its fields that they should
|
|
33
|
-
* use `autocomplete="one-time-code"`.
|
|
34
|
-
*/
|
|
35
|
-
otp?: boolean;
|
|
36
|
-
/**
|
|
37
|
-
* The value of the the pin input.
|
|
38
|
-
*/
|
|
39
|
-
value: string[];
|
|
40
|
-
/**
|
|
41
|
-
* The type of value the pin-input should allow
|
|
42
|
-
*/
|
|
43
|
-
type?: "alphanumeric" | "numeric" | "alphabetic";
|
|
44
|
-
/**
|
|
45
|
-
* Function called when all inputs have valid values
|
|
46
|
-
*/
|
|
47
|
-
onComplete?: (details: {
|
|
48
|
-
value: string[];
|
|
49
|
-
valueAsString: string;
|
|
50
|
-
}) => void;
|
|
51
|
-
/**
|
|
52
|
-
* Function called on input change
|
|
53
|
-
*/
|
|
54
|
-
onChange?: (details: {
|
|
55
|
-
value: string[];
|
|
56
|
-
}) => void;
|
|
57
|
-
/**
|
|
58
|
-
* Function called when an invalid value is entered
|
|
59
|
-
*/
|
|
60
|
-
onInvalid?: (details: {
|
|
61
|
-
value: string;
|
|
62
|
-
index: number;
|
|
63
|
-
}) => void;
|
|
64
|
-
/**
|
|
65
|
-
* If `true`, the input's value will be masked just like `type=password`
|
|
66
|
-
*/
|
|
67
|
-
mask?: boolean;
|
|
68
|
-
/**
|
|
69
|
-
* Whether to blur the input when the value is complete
|
|
70
|
-
*/
|
|
71
|
-
blurOnComplete?: boolean;
|
|
72
|
-
/**
|
|
73
|
-
* Specifies the localized strings that identifies the accessibility elements and their states
|
|
74
|
-
*/
|
|
75
|
-
messages: IntlMessages;
|
|
76
|
-
};
|
|
77
|
-
export declare type UserDefinedContext = Partial<PublicContext>;
|
|
78
|
-
declare type ComputedContext = Readonly<{
|
|
79
|
-
/**
|
|
80
|
-
* @computed
|
|
81
|
-
* The number of inputs
|
|
82
|
-
*/
|
|
83
|
-
valueLength: number;
|
|
84
|
-
/**
|
|
85
|
-
* @computed
|
|
86
|
-
* The number of inputs that are not empty
|
|
87
|
-
*/
|
|
88
|
-
filledValueLength: number;
|
|
89
|
-
/**
|
|
90
|
-
* @computed
|
|
91
|
-
* Whether all input values are valid
|
|
92
|
-
*/
|
|
93
|
-
isValueComplete: boolean;
|
|
94
|
-
/**
|
|
95
|
-
* @computed
|
|
96
|
-
* The string representation of the input values
|
|
97
|
-
*/
|
|
98
|
-
valueAsString: string;
|
|
99
|
-
}>;
|
|
100
|
-
declare type PrivateContext = Context<{
|
|
101
|
-
/**
|
|
102
|
-
* @internal
|
|
103
|
-
* The index of the input field that has focus
|
|
104
|
-
*/
|
|
105
|
-
focusedIndex: number;
|
|
106
|
-
}>;
|
|
107
|
-
export declare type MachineContext = PublicContext & PrivateContext & ComputedContext;
|
|
108
|
-
export declare type MachineState = {
|
|
109
|
-
value: "unknown" | "idle" | "focused";
|
|
110
|
-
};
|
|
111
|
-
export declare type State = S.State<MachineContext, MachineState>;
|
|
112
|
-
export declare type Send = S.Send<S.AnyEventObject>;
|
|
113
|
-
export {};
|