@agentero/design-system 0.34.1 → 0.35.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/mcp/manifests/components.html +368 -78
- package/mcp/manifests/components.json +197 -9
- package/package.json +5 -1
- package/src/combobox/combobox.d.ts +39 -10
- package/src/combobox/combobox.js +113 -87
- package/src/combobox/index.d.ts +3 -3
- package/src/input-tel/index.d.ts +2 -0
- package/src/input-tel/index.js +2 -0
- package/src/input-tel/input-tel.d.ts +42 -0
- package/src/input-tel/input-tel.js +46 -0
- package/src/input-tel/mask.d.ts +51 -0
- package/src/input-tel/mask.js +39 -0
package/src/combobox/combobox.js
CHANGED
|
@@ -8,11 +8,11 @@ import { InputGroup as a } from "../input-group/index.js";
|
|
|
8
8
|
import { InputSearch as o } from "../input-search/input-search.js";
|
|
9
9
|
import { IconCancel as s, IconCheck as c, IconKeyboardArrowDown as l, IconSearch as u } from "./icons.js";
|
|
10
10
|
import { tv as d } from "tailwind-variants";
|
|
11
|
-
import { createContext as f, use as p,
|
|
12
|
-
import { jsx as
|
|
13
|
-
import { Combobox as
|
|
11
|
+
import { createContext as f, use as p, useEffect as m, useRef as h, useState as g } from "react";
|
|
12
|
+
import { jsx as _, jsxs as v } from "react/jsx-runtime";
|
|
13
|
+
import { Combobox as y } from "@base-ui/react/combobox";
|
|
14
14
|
//#region src/combobox/combobox.tsx
|
|
15
|
-
var
|
|
15
|
+
var b = d({ slots: {
|
|
16
16
|
action: [
|
|
17
17
|
"flex size-6 shrink-0 cursor-pointer items-center justify-center self-center rounded-sm",
|
|
18
18
|
"[&>svg>path]:fill-icon-input-default hover:[&>svg>path]:fill-icon-default-base-primary",
|
|
@@ -48,144 +48,170 @@ var y = d({ slots: {
|
|
|
48
48
|
"group-data-disabled/item:data-selected:bg-bg-checkbox-disabled"
|
|
49
49
|
],
|
|
50
50
|
message: ["mx-2 my-px px-3 py-2 text-sm text-text-default-base-tertiary", "empty:m-0 empty:p-0"]
|
|
51
|
-
} }),
|
|
52
|
-
let
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
} }), x = b(), S = f(!1), C = f(void 0), w = 500, T = (e, t) => {
|
|
52
|
+
let [n, r] = g(!1);
|
|
53
|
+
return m(() => {
|
|
54
|
+
if (!e) return;
|
|
55
|
+
let t = setTimeout(() => r(!0), w);
|
|
56
|
+
return () => {
|
|
57
|
+
clearTimeout(t), r(!1);
|
|
58
|
+
};
|
|
59
|
+
}, [e]), e && n ? t : null;
|
|
60
|
+
}, E = ({ minInputLength: e = 0, loading: t, loadingLabel: n = "Loading…", open: r, defaultOpen: i = !1, onOpenChange: a, onOpenChangeComplete: o, onInputValueChange: s, children: c, ...l }) => {
|
|
61
|
+
let u = !!l.multiple, [d, f] = g(i), p = h(String(l.inputValue ?? l.defaultInputValue ?? ""));
|
|
62
|
+
l.inputValue !== void 0 && (p.current = String(l.inputValue));
|
|
63
|
+
let m = (t) => t.trim().length < e, b = h(!1), x = h(!1), w = (e, t) => {
|
|
64
|
+
if (e && m(p.current)) {
|
|
56
65
|
t.cancel();
|
|
57
66
|
return;
|
|
58
67
|
}
|
|
59
|
-
|
|
60
|
-
},
|
|
61
|
-
|
|
62
|
-
},
|
|
63
|
-
if (
|
|
64
|
-
|
|
68
|
+
b.current = !1, a?.(e, t), u && !e && t.reason === "item-press" && t.cancel(), t.isCanceled || f(e);
|
|
69
|
+
}, E = (e) => {
|
|
70
|
+
o?.(e), !e && b.current && (b.current = !1, x.current = !0, queueMicrotask(() => x.current = !1));
|
|
71
|
+
}, D = (e, t) => {
|
|
72
|
+
if (x.current) {
|
|
73
|
+
x.current = !1, t.cancel();
|
|
65
74
|
return;
|
|
66
75
|
}
|
|
67
|
-
|
|
68
|
-
},
|
|
69
|
-
return /* @__PURE__ */
|
|
70
|
-
value:
|
|
71
|
-
children: /* @__PURE__ */
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
p.current = e, s?.(e, t), m(e) && r === void 0 && d && (b.current = !0, f(!1));
|
|
77
|
+
}, O = r ?? (e > 0 ? d : void 0), k = T(!!t && (r ?? d), n);
|
|
78
|
+
return /* @__PURE__ */ _(S, {
|
|
79
|
+
value: u,
|
|
80
|
+
children: /* @__PURE__ */ _(C, {
|
|
81
|
+
value: t,
|
|
82
|
+
children: /* @__PURE__ */ v(y.Root, {
|
|
83
|
+
open: O,
|
|
84
|
+
defaultOpen: i,
|
|
85
|
+
onOpenChange: w,
|
|
86
|
+
onOpenChangeComplete: E,
|
|
87
|
+
onInputValueChange: D,
|
|
88
|
+
...l,
|
|
89
|
+
children: [c, t !== void 0 && /* @__PURE__ */ _(y.Status, {
|
|
90
|
+
"data-slot": "combobox-loading",
|
|
91
|
+
className: "sr-only",
|
|
92
|
+
children: k
|
|
93
|
+
})]
|
|
94
|
+
})
|
|
78
95
|
})
|
|
79
96
|
});
|
|
80
97
|
};
|
|
81
|
-
|
|
82
|
-
var
|
|
98
|
+
E.displayName = "Combobox.Root";
|
|
99
|
+
var D = /* @__PURE__ */ new Set([
|
|
83
100
|
"value",
|
|
84
101
|
"defaultValue",
|
|
85
102
|
"onChange"
|
|
86
|
-
]),
|
|
87
|
-
let i = p(r), a = n(), o = i ? Object.fromEntries(Object.entries(i).filter(([e]) => !
|
|
103
|
+
]), O = (e) => {
|
|
104
|
+
let i = p(r), a = n(), o = i ? Object.fromEntries(Object.entries(i).filter(([e]) => !D.has(e))) : null, s = !("aria-label" in e || "aria-labelledby" in e) && a ? { "aria-labelledby": a.labelId } : null;
|
|
88
105
|
return t({
|
|
89
106
|
...o,
|
|
90
107
|
...s
|
|
91
108
|
}, e);
|
|
92
|
-
},
|
|
93
|
-
let { className: m, size: h = "md", ...
|
|
94
|
-
return t === "search" && n && !
|
|
95
|
-
render: /* @__PURE__ */
|
|
109
|
+
}, k = ({ variant: t = "search", showClear: n = t === "search", clearLabel: c = "Clear", triggerLabel: d = "Show options", ...f }) => {
|
|
110
|
+
let { className: m, size: h = "md", ...g } = O(f), b = p(S);
|
|
111
|
+
return t === "search" && n && !b ? /* @__PURE__ */ _(y.InputGroup, {
|
|
112
|
+
render: /* @__PURE__ */ _("div", {}),
|
|
96
113
|
"data-slot": "combobox-field",
|
|
97
|
-
children: /* @__PURE__ */
|
|
114
|
+
children: /* @__PURE__ */ _(r, {
|
|
98
115
|
value: null,
|
|
99
|
-
children: /* @__PURE__ */
|
|
116
|
+
children: /* @__PURE__ */ _(y.Input, {
|
|
100
117
|
"data-slot": "combobox-input",
|
|
101
118
|
className: m,
|
|
102
|
-
...
|
|
103
|
-
render: (e) => /* @__PURE__ */
|
|
119
|
+
...g,
|
|
120
|
+
render: (e) => /* @__PURE__ */ _(o, {
|
|
104
121
|
...e,
|
|
105
122
|
size: h,
|
|
106
123
|
clearLabel: c
|
|
107
124
|
})
|
|
108
125
|
})
|
|
109
126
|
})
|
|
110
|
-
}) : /* @__PURE__ */
|
|
111
|
-
render: /* @__PURE__ */
|
|
127
|
+
}) : /* @__PURE__ */ v(y.InputGroup, {
|
|
128
|
+
render: /* @__PURE__ */ _(a.Root, {}),
|
|
112
129
|
"data-slot": "combobox-field",
|
|
113
130
|
className: t === "plain" ? "px-4" : void 0,
|
|
114
131
|
children: [
|
|
115
|
-
t === "search" && /* @__PURE__ */
|
|
116
|
-
/* @__PURE__ */
|
|
132
|
+
t === "search" && /* @__PURE__ */ _(a.Addon, { children: /* @__PURE__ */ _(u, {}) }),
|
|
133
|
+
/* @__PURE__ */ _(y.Input, {
|
|
117
134
|
"data-slot": "combobox-input",
|
|
118
135
|
"data-size": h,
|
|
119
136
|
className: e(i({ size: h }), m),
|
|
120
|
-
...
|
|
137
|
+
...g
|
|
121
138
|
}),
|
|
122
|
-
n && !
|
|
139
|
+
n && !b && /* @__PURE__ */ _(y.Clear, {
|
|
123
140
|
"data-slot": "combobox-clear",
|
|
124
141
|
"aria-label": c,
|
|
125
|
-
className:
|
|
126
|
-
children: /* @__PURE__ */
|
|
142
|
+
className: x.action(),
|
|
143
|
+
children: /* @__PURE__ */ _(s, {})
|
|
127
144
|
}),
|
|
128
|
-
t === "select" && !
|
|
145
|
+
t === "select" && !b && /* @__PURE__ */ _(y.Trigger, {
|
|
129
146
|
"data-slot": "combobox-trigger",
|
|
130
147
|
"aria-label": d,
|
|
131
|
-
className: e(
|
|
132
|
-
children: /* @__PURE__ */
|
|
148
|
+
className: e(x.action(), x.trigger(), n && x.triggerReplaced()),
|
|
149
|
+
children: /* @__PURE__ */ _(l, {})
|
|
133
150
|
})
|
|
134
151
|
]
|
|
135
152
|
});
|
|
136
153
|
};
|
|
137
|
-
|
|
138
|
-
var
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
+
k.displayName = "Combobox.Input";
|
|
155
|
+
var A = ({ className: t, side: n = "bottom", align: r = "start", sideOffset: i = 12, alignOffset: a, anchor: o, collisionPadding: s = 8, children: c, ...l }) => {
|
|
156
|
+
let u = p(C);
|
|
157
|
+
return /* @__PURE__ */ _(y.Portal, { children: /* @__PURE__ */ _(y.Positioner, {
|
|
158
|
+
side: n,
|
|
159
|
+
align: r,
|
|
160
|
+
sideOffset: i,
|
|
161
|
+
alignOffset: a,
|
|
162
|
+
anchor: o,
|
|
163
|
+
collisionPadding: s,
|
|
164
|
+
className: "isolate z-(--z-index-top-layer) pointer-events-auto",
|
|
165
|
+
children: /* @__PURE__ */ _(y.Popup, {
|
|
166
|
+
"data-slot": "combobox-content",
|
|
167
|
+
"aria-busy": u || void 0,
|
|
168
|
+
className: e(x.content(), t),
|
|
169
|
+
...l,
|
|
170
|
+
children: c
|
|
171
|
+
})
|
|
172
|
+
}) });
|
|
173
|
+
};
|
|
174
|
+
A.displayName = "Combobox.Content";
|
|
175
|
+
var j = ({ className: t, ...n }) => {
|
|
154
176
|
let r = "aria-label" in n || "aria-labelledby" in n;
|
|
155
|
-
return /* @__PURE__ */
|
|
177
|
+
return /* @__PURE__ */ _(y.List, {
|
|
156
178
|
"data-slot": "combobox-list",
|
|
157
179
|
"aria-label": r ? void 0 : "Suggestions",
|
|
158
|
-
className: e(
|
|
180
|
+
className: e(x.list(), t),
|
|
159
181
|
...n
|
|
160
182
|
});
|
|
161
183
|
};
|
|
162
|
-
|
|
163
|
-
var
|
|
164
|
-
let i = p(
|
|
165
|
-
return /* @__PURE__ */
|
|
184
|
+
j.displayName = "Combobox.List";
|
|
185
|
+
var M = ({ className: t, children: n, ...r }) => {
|
|
186
|
+
let i = p(S);
|
|
187
|
+
return /* @__PURE__ */ v(y.Item, {
|
|
166
188
|
"data-slot": "combobox-item",
|
|
167
|
-
className: e(
|
|
189
|
+
className: e(x.item(), t),
|
|
168
190
|
...r,
|
|
169
|
-
children: [i && /* @__PURE__ */
|
|
191
|
+
children: [i && /* @__PURE__ */ _(y.ItemIndicator, {
|
|
170
192
|
keepMounted: !0,
|
|
171
193
|
"data-slot": "combobox-item-indicator",
|
|
172
|
-
className:
|
|
173
|
-
children: /* @__PURE__ */
|
|
194
|
+
className: x.indicator(),
|
|
195
|
+
children: /* @__PURE__ */ _(c, { className: "size-3.5" })
|
|
174
196
|
}), n]
|
|
175
197
|
});
|
|
176
198
|
};
|
|
177
|
-
|
|
178
|
-
var
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
199
|
+
M.displayName = "Combobox.Item";
|
|
200
|
+
var N = ({ className: t, children: n, ...r }) => {
|
|
201
|
+
let i = p(C);
|
|
202
|
+
return /* @__PURE__ */ _(y.Empty, {
|
|
203
|
+
"data-slot": "combobox-empty",
|
|
204
|
+
className: e(x.message(), t),
|
|
205
|
+
...r,
|
|
206
|
+
children: i ? null : n
|
|
207
|
+
});
|
|
208
|
+
};
|
|
209
|
+
N.displayName = "Combobox.Empty";
|
|
210
|
+
var P = ({ className: t, ...n }) => /* @__PURE__ */ _(y.Status, {
|
|
185
211
|
"data-slot": "combobox-status",
|
|
186
|
-
className: e(
|
|
212
|
+
className: e(x.message(), t),
|
|
187
213
|
...n
|
|
188
214
|
});
|
|
189
|
-
|
|
215
|
+
P.displayName = "Combobox.Status";
|
|
190
216
|
//#endregion
|
|
191
|
-
export {
|
|
217
|
+
export { A as Content, N as Empty, k as Input, M as Item, j as List, E as Root, P as Status, b as comboboxRecipe };
|
package/src/combobox/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export { comboboxRecipe } from './combobox';
|
|
|
2
2
|
export type { ComboboxRootProps } from './combobox';
|
|
3
3
|
export declare const Combobox: {
|
|
4
4
|
Root: {
|
|
5
|
-
<Value, Multiple extends boolean | undefined = false, Item = Value>({ minInputLength, open: openProp, defaultOpen, onOpenChange, onOpenChangeComplete, onInputValueChange, ...props }: import('./combobox').ComboboxRootProps<Value, Multiple, Item>): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
<Value, Multiple extends boolean | undefined = false, Item = Value>({ minInputLength, loading, loadingLabel, open: openProp, defaultOpen, onOpenChange, onOpenChangeComplete, onInputValueChange, children, ...props }: import('./combobox').ComboboxRootProps<Value, Multiple, Item>): import("react/jsx-runtime").JSX.Element;
|
|
6
6
|
displayName: string;
|
|
7
7
|
};
|
|
8
8
|
Input: {
|
|
@@ -16,7 +16,7 @@ export declare const Combobox: {
|
|
|
16
16
|
displayName: string;
|
|
17
17
|
};
|
|
18
18
|
Content: {
|
|
19
|
-
({ className, side, align, sideOffset, alignOffset, anchor, collisionPadding, ...props }: Omit<import('@base-ui/react/combobox').ComboboxPopupProps, "ref"> & import('react').RefAttributes<HTMLDivElement> & Pick<Omit<import('@base-ui/react/combobox').ComboboxPositionerProps, "ref"> & import('react').RefAttributes<HTMLDivElement>, "anchor" | "align" | "side" | "sideOffset" | "alignOffset" | "collisionPadding">): import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
({ className, side, align, sideOffset, alignOffset, anchor, collisionPadding, children, ...props }: Omit<import('@base-ui/react/combobox').ComboboxPopupProps, "ref"> & import('react').RefAttributes<HTMLDivElement> & Pick<Omit<import('@base-ui/react/combobox').ComboboxPositionerProps, "ref"> & import('react').RefAttributes<HTMLDivElement>, "anchor" | "align" | "side" | "sideOffset" | "alignOffset" | "collisionPadding">): import("react/jsx-runtime").JSX.Element;
|
|
20
20
|
displayName: string;
|
|
21
21
|
};
|
|
22
22
|
List: {
|
|
@@ -28,7 +28,7 @@ export declare const Combobox: {
|
|
|
28
28
|
displayName: string;
|
|
29
29
|
};
|
|
30
30
|
Empty: {
|
|
31
|
-
({ className, ...props }: Omit<import('@base-ui/react/combobox').ComboboxEmptyProps, "ref"> & import('react').RefAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
({ className, children, ...props }: Omit<import('@base-ui/react/combobox').ComboboxEmptyProps, "ref"> & import('react').RefAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
|
|
32
32
|
displayName: string;
|
|
33
33
|
};
|
|
34
34
|
Status: {
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { InputProps } from '../input';
|
|
2
|
+
export type InputTelProps = Omit<InputProps, 'type'>;
|
|
3
|
+
/**
|
|
4
|
+
* InputTel is a US phone number field that masks as you type: the digits the
|
|
5
|
+
* user enters are laid out as `(555) 123-4567` while typing, pasting or
|
|
6
|
+
* deleting, anything that is not a digit is dropped, and the caret stays next
|
|
7
|
+
* to the digit just edited instead of jumping to the end. A leading `+1`
|
|
8
|
+
* country code, as pasted or filled in by the browser's autofill, is dropped
|
|
9
|
+
* too; past that, the eleventh digit and beyond are ignored. `onChange`
|
|
10
|
+
* receives the native change event with the masked text already in
|
|
11
|
+
* `event.target.value`, so a controlled field, an uncontrolled one and one
|
|
12
|
+
* registered with react-hook-form all store `(555) 123-4567`, never the bare
|
|
13
|
+
* digits.
|
|
14
|
+
*
|
|
15
|
+
* It is an [Input](?path=/docs/components-input--docs) of `type="tel"` inside
|
|
16
|
+
* an [InputGroup](?path=/docs/components-inputgroup--docs) frame that always
|
|
17
|
+
* shows a `+1` prefix in front of the number. The prefix is part of the frame,
|
|
18
|
+
* not of the value. `className` styles the frame. Every other prop goes to the
|
|
19
|
+
* `<input>`: the `ref`, `id`, `name`, `value`, `onChange`, `aria-*` and every
|
|
20
|
+
* other standard attribute, such as `placeholder`, `autoComplete` or
|
|
21
|
+
* `required`. Only `type` is not accepted. Inside a `FieldText` the input
|
|
22
|
+
* takes its label, messages and states from the field as a plain `Input` does.
|
|
23
|
+
* The invalid state comes from `aria-invalid`, and the frame paints the
|
|
24
|
+
* destructive border.
|
|
25
|
+
*
|
|
26
|
+
* Do not use it for international numbers or extensions; the mask only knows
|
|
27
|
+
* the ten-digit US format. For free-form text that happens to hold a number,
|
|
28
|
+
* use `Input`.
|
|
29
|
+
*
|
|
30
|
+
* @summary US phone input with a +1 prefix that masks as you type
|
|
31
|
+
* @dataAttribute {string} data-slot - Always set to "input-tel" on the frame
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* <FieldText>
|
|
35
|
+
* <Label>Phone number</Label>
|
|
36
|
+
* <InputTel name="phone" autoComplete="tel-national" placeholder="(555) 000-0000" />
|
|
37
|
+
* </FieldText>
|
|
38
|
+
*/
|
|
39
|
+
export declare const InputTel: {
|
|
40
|
+
(props: InputTelProps): import("react/jsx-runtime").JSX.Element;
|
|
41
|
+
displayName: string;
|
|
42
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { mergeRefs as e } from "../../lib/merge-props.js";
|
|
3
|
+
import { InputContext as t, useInputContext as n } from "../input/context.js";
|
|
4
|
+
import { Input as r } from "../input/input.js";
|
|
5
|
+
import { InputGroup as i } from "../input-group/index.js";
|
|
6
|
+
import { US_PHONE_MASK as a, applyMask as o, getCursorPosition as s, getDeletionType as c, toNationalDigits as l } from "./mask.js";
|
|
7
|
+
import { useMemo as u, useRef as d } from "react";
|
|
8
|
+
import { jsx as f, jsxs as p } from "react/jsx-runtime";
|
|
9
|
+
//#region src/input-tel/input-tel.tsx
|
|
10
|
+
var m = (m) => {
|
|
11
|
+
let { className: h, onChange: g, ref: _, ...v } = n(m), y = d(null), b = u(() => e(y, _), [_]), x = (e) => {
|
|
12
|
+
let t = c(e.nativeEvent.inputType), { value: n, selectionStart: r } = e.target, i = o({
|
|
13
|
+
value: l(n),
|
|
14
|
+
mask: a,
|
|
15
|
+
maskSymbol: ".",
|
|
16
|
+
trimNonMaskCharsLeftover: t === "backward"
|
|
17
|
+
}), u = s({
|
|
18
|
+
cursorPositionAfterInput: r ?? 0,
|
|
19
|
+
phoneAfterInput: n,
|
|
20
|
+
phoneAfterFormatted: i,
|
|
21
|
+
deletion: t
|
|
22
|
+
});
|
|
23
|
+
e.target.value = i;
|
|
24
|
+
let d = () => {
|
|
25
|
+
let e = y.current;
|
|
26
|
+
e && e === document.activeElement && e.setSelectionRange(u, u);
|
|
27
|
+
};
|
|
28
|
+
g ? (g(e), Promise.resolve().then(d)) : d();
|
|
29
|
+
};
|
|
30
|
+
return /* @__PURE__ */ p(i.Root, {
|
|
31
|
+
"data-slot": "input-tel",
|
|
32
|
+
className: h,
|
|
33
|
+
children: [/* @__PURE__ */ f(i.Text, { children: "+1" }), /* @__PURE__ */ f(t, {
|
|
34
|
+
value: null,
|
|
35
|
+
children: /* @__PURE__ */ f(r, {
|
|
36
|
+
...v,
|
|
37
|
+
type: "tel",
|
|
38
|
+
ref: b,
|
|
39
|
+
onChange: x
|
|
40
|
+
})
|
|
41
|
+
})]
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
m.displayName = "InputTel";
|
|
45
|
+
//#endregion
|
|
46
|
+
export { m as InputTel };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/** The US phone mask InputTel applies: three groups of 3, 3 and 4 digits. */
|
|
2
|
+
export declare const US_PHONE_MASK = "(...) ...-....";
|
|
3
|
+
/** The character that marks a digit slot in a mask. */
|
|
4
|
+
export declare const MASK_SYMBOL = ".";
|
|
5
|
+
/**
|
|
6
|
+
* Reduces a phone number in any format to its national digits: drops
|
|
7
|
+
* everything that is not a digit and, past ten digits, the leading `1` of the
|
|
8
|
+
* `+1` country code. No US area code starts with `1`, so a national number is
|
|
9
|
+
* never cut.
|
|
10
|
+
*/
|
|
11
|
+
export declare const toNationalDigits: (value: string) => string;
|
|
12
|
+
type ApplyMaskArgs = {
|
|
13
|
+
value: string;
|
|
14
|
+
mask: string;
|
|
15
|
+
maskSymbol: string;
|
|
16
|
+
/**
|
|
17
|
+
* @description Removes all non-maskSymbol chars from the result's ending if the value is shorter than the mask
|
|
18
|
+
* @example
|
|
19
|
+
* value: "1234"
|
|
20
|
+
* mask: "(....) ...."
|
|
21
|
+
* if true -> "(1234"
|
|
22
|
+
* if false -> "(1234) "
|
|
23
|
+
*/
|
|
24
|
+
trimNonMaskCharsLeftover?: boolean;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Places each character of `value` in the next `maskSymbol` slot of `mask`,
|
|
28
|
+
* keeping the mask's own characters in between. A value longer than the mask
|
|
29
|
+
* is cut; a shorter one stops at its last character, followed by the
|
|
30
|
+
* separators up to the next slot unless `trimNonMaskCharsLeftover` is set.
|
|
31
|
+
*/
|
|
32
|
+
export declare const applyMask: ({ value, mask, maskSymbol, trimNonMaskCharsLeftover }: ApplyMaskArgs) => string;
|
|
33
|
+
export declare const isNumeric: (str?: string) => boolean;
|
|
34
|
+
type GetCursorPositionProps = {
|
|
35
|
+
phoneAfterInput: string;
|
|
36
|
+
phoneAfterFormatted: string;
|
|
37
|
+
cursorPositionAfterInput: number;
|
|
38
|
+
deletion?: 'forward' | 'backward' | undefined;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Finds where the caret should sit in the formatted phone after an edit, so
|
|
42
|
+
* that it stays after the digit the user just typed or removed instead of
|
|
43
|
+
* jumping to the end when the mask characters move around it.
|
|
44
|
+
*/
|
|
45
|
+
export declare const getCursorPosition: ({ phoneAfterInput, phoneAfterFormatted, cursorPositionAfterInput, deletion }: GetCursorPositionProps) => number;
|
|
46
|
+
/**
|
|
47
|
+
* Reads the `inputType` of a native `input` event and tells whether the edit
|
|
48
|
+
* removed characters, and in which direction. `undefined` for an insertion.
|
|
49
|
+
*/
|
|
50
|
+
export declare const getDeletionType: (inputType?: string) => "forward" | "backward" | undefined;
|
|
51
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//#region src/input-tel/mask.ts
|
|
2
|
+
var e = "(...) ...-....", t = (e) => {
|
|
3
|
+
let t = e.replace(/\D/g, "");
|
|
4
|
+
return t.length > 10 && t.startsWith("1") ? t.slice(1) : t;
|
|
5
|
+
}, n = ({ value: e, mask: t, maskSymbol: n, trimNonMaskCharsLeftover: r = !1 }) => {
|
|
6
|
+
if (!e) return "";
|
|
7
|
+
let i = "", a = 0;
|
|
8
|
+
for (let o of t.split("")) {
|
|
9
|
+
if (a >= e.length) {
|
|
10
|
+
if (!r && o !== n) {
|
|
11
|
+
i += o;
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
break;
|
|
15
|
+
}
|
|
16
|
+
o === n ? (i += e[a], a += 1) : i += o;
|
|
17
|
+
}
|
|
18
|
+
return i;
|
|
19
|
+
}, r = (e) => e ? /^\d+$/.test(e) : !1, i = ({ phoneAfterInput: e, phoneAfterFormatted: t, cursorPositionAfterInput: n, deletion: i }) => {
|
|
20
|
+
let a = null;
|
|
21
|
+
for (let t = n - 1; t >= 0; --t) if (r(e[t])) {
|
|
22
|
+
a = t;
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
if (a === null) {
|
|
26
|
+
for (let n = 0; n < e.length; n += 1) if (r(t[n])) return n;
|
|
27
|
+
return e.length;
|
|
28
|
+
}
|
|
29
|
+
let o = 0;
|
|
30
|
+
for (let t = 0; t < a; t += 1) r(e[t]) && (o += 1);
|
|
31
|
+
let s = 0, c = 0;
|
|
32
|
+
for (let e = 0; e < t.length && (s += 1, r(t[e]) && (c += 1), !(c >= o + 1)); e += 1);
|
|
33
|
+
if (i !== "backward") for (; !r(t[s]) && s < t.length;) s += 1;
|
|
34
|
+
return s;
|
|
35
|
+
}, a = (e) => {
|
|
36
|
+
if (e?.toLocaleLowerCase().includes("delete") ?? !1) return e?.toLocaleLowerCase().includes("forward") ? "forward" : "backward";
|
|
37
|
+
};
|
|
38
|
+
//#endregion
|
|
39
|
+
export { e as US_PHONE_MASK, n as applyMask, i as getCursorPosition, a as getDeletionType, r as isNumeric, t as toNationalDigits };
|