@rovula/ui 0.0.77 → 0.0.78
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/cjs/bundle.css +28 -0
- package/dist/cjs/bundle.js +3 -3
- package/dist/cjs/bundle.js.map +1 -1
- package/dist/cjs/types/components/MaskedTextInput/MaskedTextInput.d.ts +75 -0
- package/dist/cjs/types/components/MaskedTextInput/MaskedTextInput.stories.d.ts +491 -0
- package/dist/cjs/types/components/MaskedTextInput/index.d.ts +3 -0
- package/dist/cjs/types/index.d.ts +2 -0
- package/dist/components/MaskedTextInput/MaskedTextInput.js +267 -0
- package/dist/components/MaskedTextInput/MaskedTextInput.stories.js +167 -0
- package/dist/components/MaskedTextInput/index.js +2 -0
- package/dist/components/Toast/Toast.styles.js +1 -1
- package/dist/esm/bundle.css +28 -0
- package/dist/esm/bundle.js +3 -3
- package/dist/esm/bundle.js.map +1 -1
- package/dist/esm/types/components/MaskedTextInput/MaskedTextInput.d.ts +75 -0
- package/dist/esm/types/components/MaskedTextInput/MaskedTextInput.stories.d.ts +491 -0
- package/dist/esm/types/components/MaskedTextInput/index.d.ts +3 -0
- package/dist/esm/types/index.d.ts +2 -0
- package/dist/index.d.ts +59 -1
- package/dist/index.js +1 -0
- package/dist/src/theme/global.css +35 -0
- package/package.json +1 -1
- package/src/components/MaskedTextInput/MaskedTextInput.stories.tsx +414 -0
- package/src/components/MaskedTextInput/MaskedTextInput.tsx +391 -0
- package/src/components/MaskedTextInput/README.md +202 -0
- package/src/components/MaskedTextInput/index.ts +3 -0
- package/src/components/Toast/Toast.styles.tsx +1 -1
- package/src/index.ts +5 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
+
import React, { forwardRef, useCallback, useImperativeHandle, useRef, useState, useEffect, } from "react";
|
|
14
|
+
import TextInput from "../TextInput/TextInput";
|
|
15
|
+
import { cn } from "@/utils/cn";
|
|
16
|
+
// Kendo UI style mask patterns
|
|
17
|
+
export const MASK_PATTERNS = {
|
|
18
|
+
PHONE: "(000) 000-0000",
|
|
19
|
+
PHONE_INTL: "+000 000 000 0000",
|
|
20
|
+
CREDIT_CARD: "0000 0000 0000 0000",
|
|
21
|
+
DATE: "00/00/0000",
|
|
22
|
+
TIME: "00:00",
|
|
23
|
+
SSN: "000-00-0000",
|
|
24
|
+
ZIP_CODE: "00000",
|
|
25
|
+
ZIP_CODE_EXT: "00000-0000",
|
|
26
|
+
CURRENCY: "$000,000.00",
|
|
27
|
+
PERCENTAGE: "000%",
|
|
28
|
+
LICENSE_PLATE: "AAA-0000",
|
|
29
|
+
PRODUCT_CODE: "AA-0000-AA",
|
|
30
|
+
ALPHANUMERIC: "AAAA-0000",
|
|
31
|
+
};
|
|
32
|
+
// Kendo UI mask rules
|
|
33
|
+
const KENDO_RULES = {
|
|
34
|
+
"0": { pattern: /[0-9]/, placeholder: "0" }, // Any digit 0-9
|
|
35
|
+
"9": { pattern: /[0-9\s]/, placeholder: "9" }, // Any digit 0-9 or space
|
|
36
|
+
"#": { pattern: /[0-9\s+\-]/, placeholder: "#" }, // Any digit, space, +, or -
|
|
37
|
+
L: { pattern: /[a-zA-Z]/, placeholder: "L" }, // Any letter
|
|
38
|
+
"?": { pattern: /[a-zA-Z\s]/, placeholder: "?" }, // Any letter or space
|
|
39
|
+
"&": { pattern: /[^\s]/, placeholder: "&" }, // Any character except space
|
|
40
|
+
C: { pattern: /./, placeholder: "C" }, // Any character including space
|
|
41
|
+
A: { pattern: /[a-zA-Z0-9]/, placeholder: "A" }, // Any alphanumeric
|
|
42
|
+
a: { pattern: /[a-zA-Z0-9\s]/, placeholder: "a" }, // Any alphanumeric or space
|
|
43
|
+
};
|
|
44
|
+
// Helper function to create mask pattern from string using Kendo UI rules
|
|
45
|
+
const createMaskPattern = (mask, customRules) => {
|
|
46
|
+
const rules = Object.assign(Object.assign({}, KENDO_RULES), customRules);
|
|
47
|
+
const pattern = [];
|
|
48
|
+
let i = 0;
|
|
49
|
+
while (i < mask.length) {
|
|
50
|
+
const char = mask[i];
|
|
51
|
+
if (char === "\\" && i + 1 < mask.length) {
|
|
52
|
+
// Escaped character - treat as literal
|
|
53
|
+
const nextChar = mask[i + 1];
|
|
54
|
+
pattern.push({
|
|
55
|
+
pattern: new RegExp(`^${nextChar}$`),
|
|
56
|
+
placeholder: nextChar,
|
|
57
|
+
isLiteral: true,
|
|
58
|
+
});
|
|
59
|
+
i += 2;
|
|
60
|
+
}
|
|
61
|
+
else if (rules[char]) {
|
|
62
|
+
// Apply Kendo rule
|
|
63
|
+
const rule = rules[char];
|
|
64
|
+
if (typeof rule === "function") {
|
|
65
|
+
pattern.push({
|
|
66
|
+
pattern: /./, // Accept any character, validate with function
|
|
67
|
+
placeholder: char,
|
|
68
|
+
validator: rule,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
else if (rule instanceof RegExp) {
|
|
72
|
+
pattern.push({
|
|
73
|
+
pattern: rule,
|
|
74
|
+
placeholder: char,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
pattern.push({
|
|
79
|
+
pattern: rule.pattern,
|
|
80
|
+
placeholder: rule.placeholder,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
i++;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
// Literal character
|
|
87
|
+
pattern.push({
|
|
88
|
+
pattern: new RegExp(`^${char.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}$`),
|
|
89
|
+
placeholder: char,
|
|
90
|
+
isLiteral: true,
|
|
91
|
+
});
|
|
92
|
+
i++;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return pattern;
|
|
96
|
+
};
|
|
97
|
+
// Helper function to apply mask to value using Kendo UI rules
|
|
98
|
+
const applyMask = (value, maskPattern, maskChar = "_", showMask = true, guide = true) => {
|
|
99
|
+
let maskedValue = "";
|
|
100
|
+
let valueIndex = 0;
|
|
101
|
+
for (let i = 0; i < maskPattern.length; i++) {
|
|
102
|
+
const rule = maskPattern[i];
|
|
103
|
+
if (rule.isLiteral) {
|
|
104
|
+
// Literal character - always add
|
|
105
|
+
maskedValue += rule.placeholder;
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
// Input character - find next valid character
|
|
109
|
+
let foundValid = false;
|
|
110
|
+
while (valueIndex < value.length) {
|
|
111
|
+
const char = value[valueIndex];
|
|
112
|
+
valueIndex++;
|
|
113
|
+
// Check with validator function first if exists
|
|
114
|
+
const isValid = rule.validator
|
|
115
|
+
? rule.validator(char)
|
|
116
|
+
: rule.pattern.test(char);
|
|
117
|
+
if (isValid) {
|
|
118
|
+
maskedValue += char;
|
|
119
|
+
foundValid = true;
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
// Skip invalid characters and continue searching
|
|
123
|
+
}
|
|
124
|
+
if (!foundValid && guide && showMask) {
|
|
125
|
+
// No valid character found, fill with placeholder
|
|
126
|
+
maskedValue += maskChar;
|
|
127
|
+
}
|
|
128
|
+
else if (!foundValid) {
|
|
129
|
+
// No placeholder needed, stop building the mask
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return maskedValue;
|
|
135
|
+
};
|
|
136
|
+
// Helper function to extract raw value from masked value
|
|
137
|
+
const extractRawValue = (maskedValue, maskPattern) => {
|
|
138
|
+
let rawValue = "";
|
|
139
|
+
for (let i = 0; i < maskedValue.length && i < maskPattern.length; i++) {
|
|
140
|
+
const rule = maskPattern[i];
|
|
141
|
+
const char = maskedValue[i];
|
|
142
|
+
if (!rule.isLiteral) {
|
|
143
|
+
// Only include non-literal characters in raw value
|
|
144
|
+
rawValue += char;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return rawValue;
|
|
148
|
+
};
|
|
149
|
+
// Helper function to get cursor position after masking
|
|
150
|
+
const getCursorPosition = (maskedValue, rawInputLength, maskPattern) => {
|
|
151
|
+
let inputCount = 0;
|
|
152
|
+
let cursorPos = 0;
|
|
153
|
+
for (let i = 0; i < maskPattern.length && i < maskedValue.length; i++) {
|
|
154
|
+
const rule = maskPattern[i];
|
|
155
|
+
const char = maskedValue[i];
|
|
156
|
+
if (rule.isLiteral) {
|
|
157
|
+
cursorPos = i + 1;
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
inputCount++;
|
|
161
|
+
cursorPos = i + 1;
|
|
162
|
+
if (inputCount >= rawInputLength) {
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return cursorPos;
|
|
168
|
+
};
|
|
169
|
+
export const MaskedTextInput = forwardRef((_a, ref) => {
|
|
170
|
+
var { mask, maskChar = "_", showMask = true, guide = true, keepCharPositions = false, rules, onMaskedChange, onChange, value, defaultValue } = _a, props = __rest(_a, ["mask", "maskChar", "showMask", "guide", "keepCharPositions", "rules", "onMaskedChange", "onChange", "value", "defaultValue"]);
|
|
171
|
+
const inputRef = useRef(null);
|
|
172
|
+
const [maskedValue, setMaskedValue] = useState("");
|
|
173
|
+
const [rawValue, setRawValue] = useState("");
|
|
174
|
+
// Parse mask pattern using Kendo UI rules
|
|
175
|
+
const maskPattern = React.useMemo(() => {
|
|
176
|
+
if (!mask)
|
|
177
|
+
return null;
|
|
178
|
+
return createMaskPattern(mask, rules);
|
|
179
|
+
}, [mask, rules]);
|
|
180
|
+
// Initialize values
|
|
181
|
+
useEffect(() => {
|
|
182
|
+
const initialValue = value || defaultValue || "";
|
|
183
|
+
if (maskPattern && initialValue) {
|
|
184
|
+
const masked = applyMask(initialValue, maskPattern, maskChar, showMask, guide);
|
|
185
|
+
const raw = extractRawValue(masked, maskPattern);
|
|
186
|
+
setMaskedValue(masked);
|
|
187
|
+
setRawValue(raw);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
setMaskedValue(initialValue);
|
|
191
|
+
setRawValue(initialValue);
|
|
192
|
+
}
|
|
193
|
+
}, [maskPattern, maskChar, showMask, guide, value, defaultValue]);
|
|
194
|
+
useImperativeHandle(ref, () => inputRef === null || inputRef === void 0 ? void 0 : inputRef.current);
|
|
195
|
+
const handleChange = useCallback((event) => {
|
|
196
|
+
const inputValue = event.target.value;
|
|
197
|
+
if (!maskPattern) {
|
|
198
|
+
setMaskedValue(inputValue);
|
|
199
|
+
setRawValue(inputValue);
|
|
200
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(event);
|
|
201
|
+
onMaskedChange === null || onMaskedChange === void 0 ? void 0 : onMaskedChange(inputValue, inputValue);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
const newMaskedValue = applyMask(inputValue, maskPattern, maskChar, showMask, guide);
|
|
205
|
+
const newRawValue = extractRawValue(newMaskedValue, maskPattern);
|
|
206
|
+
setMaskedValue(newMaskedValue);
|
|
207
|
+
setRawValue(newRawValue);
|
|
208
|
+
// Create synthetic event with masked value
|
|
209
|
+
const syntheticEvent = Object.assign(Object.assign({}, event), { target: Object.assign(Object.assign({}, event.target), { value: newMaskedValue }) });
|
|
210
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(syntheticEvent);
|
|
211
|
+
onMaskedChange === null || onMaskedChange === void 0 ? void 0 : onMaskedChange(newMaskedValue, newRawValue);
|
|
212
|
+
// Set cursor position after state update
|
|
213
|
+
setTimeout(() => {
|
|
214
|
+
if (inputRef.current) {
|
|
215
|
+
const rawLength = newRawValue.replace(/[_\s]/g, "").length;
|
|
216
|
+
const newCursorPos = getCursorPosition(newMaskedValue, rawLength, maskPattern);
|
|
217
|
+
inputRef.current.setSelectionRange(newCursorPos, newCursorPos);
|
|
218
|
+
}
|
|
219
|
+
}, 0);
|
|
220
|
+
}, [maskPattern, maskChar, showMask, guide, onChange, onMaskedChange]);
|
|
221
|
+
const handleKeyDown = useCallback((event) => {
|
|
222
|
+
var _a, _b, _c;
|
|
223
|
+
if (!maskPattern) {
|
|
224
|
+
(_a = props.onKeyDown) === null || _a === void 0 ? void 0 : _a.call(props, event);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
const { key, ctrlKey, metaKey } = event;
|
|
228
|
+
const input = event.target;
|
|
229
|
+
const cursorPos = input.selectionStart || 0;
|
|
230
|
+
// Allow navigation and editing keys
|
|
231
|
+
if (key === "Backspace" ||
|
|
232
|
+
key === "Delete" ||
|
|
233
|
+
key === "ArrowLeft" ||
|
|
234
|
+
key === "ArrowRight" ||
|
|
235
|
+
key === "Home" ||
|
|
236
|
+
key === "End" ||
|
|
237
|
+
key === "Tab" ||
|
|
238
|
+
key.length > 1 || // Allow other special keys
|
|
239
|
+
ctrlKey ||
|
|
240
|
+
metaKey) {
|
|
241
|
+
(_b = props.onKeyDown) === null || _b === void 0 ? void 0 : _b.call(props, event);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
// Find the next non-literal position from cursor
|
|
245
|
+
let targetPos = cursorPos;
|
|
246
|
+
while (targetPos < maskPattern.length &&
|
|
247
|
+
maskPattern[targetPos].isLiteral) {
|
|
248
|
+
targetPos++;
|
|
249
|
+
}
|
|
250
|
+
// Check if we have a valid position and the key matches
|
|
251
|
+
if (targetPos < maskPattern.length) {
|
|
252
|
+
const targetRule = maskPattern[targetPos];
|
|
253
|
+
// Check with validator function first if exists
|
|
254
|
+
const isValid = targetRule.validator
|
|
255
|
+
? targetRule.validator(key)
|
|
256
|
+
: targetRule.pattern.test(key);
|
|
257
|
+
if (!isValid) {
|
|
258
|
+
event.preventDefault();
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
(_c = props.onKeyDown) === null || _c === void 0 ? void 0 : _c.call(props, event);
|
|
263
|
+
}, [maskPattern, props]);
|
|
264
|
+
return (_jsx(TextInput, Object.assign({}, props, { ref: inputRef, value: maskedValue, onChange: handleChange, onKeyDown: handleKeyDown, className: cn(props.className) })));
|
|
265
|
+
});
|
|
266
|
+
MaskedTextInput.displayName = "MaskedTextInput";
|
|
267
|
+
export default MaskedTextInput;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import MaskedTextInput, { MASK_PATTERNS } from "./MaskedTextInput";
|
|
4
|
+
// More on how to set up stories at: https://storybook.js.org/docs/7.0/react/writing-stories/introduction
|
|
5
|
+
const meta = {
|
|
6
|
+
title: "Components/MaskedTextInput",
|
|
7
|
+
component: MaskedTextInput,
|
|
8
|
+
tags: ["autodocs"],
|
|
9
|
+
parameters: {
|
|
10
|
+
// More on how to position stories at: https://storybook.js.org/docs/7.0/react/configure/story-layout
|
|
11
|
+
layout: "fullscreen",
|
|
12
|
+
},
|
|
13
|
+
decorators: [
|
|
14
|
+
(Story) => (_jsx("div", { className: "p-5 flex w-full bg-[rgb(var(--base-bg-2))] ", children: _jsx(Story, {}) })),
|
|
15
|
+
],
|
|
16
|
+
};
|
|
17
|
+
export default meta;
|
|
18
|
+
export const Default = {
|
|
19
|
+
args: {
|
|
20
|
+
label: "Phone Number",
|
|
21
|
+
mask: MASK_PATTERNS.PHONE,
|
|
22
|
+
fullwidth: true,
|
|
23
|
+
},
|
|
24
|
+
render: (args) => {
|
|
25
|
+
return (_jsxs("div", { className: "flex flex-row gap-4 w-full", children: [_jsx(MaskedTextInput, Object.assign({ id: "1", size: "lg" }, args)), _jsx(MaskedTextInput, Object.assign({ id: "2", size: "md" }, args)), _jsx(MaskedTextInput, Object.assign({ id: "3", size: "sm" }, args))] }));
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
export const PhoneNumber = {
|
|
29
|
+
args: {
|
|
30
|
+
label: "Phone Number",
|
|
31
|
+
mask: MASK_PATTERNS.PHONE,
|
|
32
|
+
fullwidth: true,
|
|
33
|
+
},
|
|
34
|
+
render: (args) => {
|
|
35
|
+
return (_jsxs("div", { className: "flex flex-col gap-4 w-full max-w-md", children: [_jsx(MaskedTextInput, Object.assign({}, args)), _jsx(MaskedTextInput, Object.assign({}, args, { label: "International Phone", mask: MASK_PATTERNS.PHONE_INTL }))] }));
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
export const CreditCard = {
|
|
39
|
+
args: {
|
|
40
|
+
label: "Credit Card Number",
|
|
41
|
+
mask: MASK_PATTERNS.CREDIT_CARD,
|
|
42
|
+
fullwidth: true,
|
|
43
|
+
},
|
|
44
|
+
render: (args) => {
|
|
45
|
+
return (_jsx("div", { className: "flex flex-col gap-4 w-full max-w-md", children: _jsx(MaskedTextInput, Object.assign({}, args)) }));
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
export const DateAndTime = {
|
|
49
|
+
args: {
|
|
50
|
+
label: "Date",
|
|
51
|
+
mask: MASK_PATTERNS.DATE,
|
|
52
|
+
fullwidth: true,
|
|
53
|
+
},
|
|
54
|
+
render: (args) => {
|
|
55
|
+
return (_jsxs("div", { className: "flex flex-col gap-4 w-full max-w-md", children: [_jsx(MaskedTextInput, Object.assign({}, args)), _jsx(MaskedTextInput, Object.assign({}, args, { label: "Time", mask: MASK_PATTERNS.TIME }))] }));
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
export const SocialSecurityNumber = {
|
|
59
|
+
args: {
|
|
60
|
+
label: "Social Security Number",
|
|
61
|
+
mask: MASK_PATTERNS.SSN,
|
|
62
|
+
fullwidth: true,
|
|
63
|
+
},
|
|
64
|
+
render: (args) => {
|
|
65
|
+
return (_jsx("div", { className: "flex flex-col gap-4 w-full max-w-md", children: _jsx(MaskedTextInput, Object.assign({}, args)) }));
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
export const ZipCode = {
|
|
69
|
+
args: {
|
|
70
|
+
label: "ZIP Code",
|
|
71
|
+
mask: MASK_PATTERNS.ZIP_CODE,
|
|
72
|
+
fullwidth: true,
|
|
73
|
+
},
|
|
74
|
+
render: (args) => {
|
|
75
|
+
return (_jsxs("div", { className: "flex flex-col gap-4 w-full max-w-md", children: [_jsx(MaskedTextInput, Object.assign({}, args)), _jsx(MaskedTextInput, Object.assign({}, args, { label: "ZIP Code + 4", mask: MASK_PATTERNS.ZIP_CODE_EXT }))] }));
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
export const Currency = {
|
|
79
|
+
args: {
|
|
80
|
+
label: "Amount",
|
|
81
|
+
mask: MASK_PATTERNS.CURRENCY,
|
|
82
|
+
fullwidth: true,
|
|
83
|
+
},
|
|
84
|
+
render: (args) => {
|
|
85
|
+
return (_jsx("div", { className: "flex flex-col gap-4 w-full max-w-md", children: _jsx(MaskedTextInput, Object.assign({}, args)) }));
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
export const CustomMask = {
|
|
89
|
+
args: {
|
|
90
|
+
label: "Custom Pattern",
|
|
91
|
+
mask: "AAA-999-AAA",
|
|
92
|
+
fullwidth: true,
|
|
93
|
+
},
|
|
94
|
+
render: (args) => {
|
|
95
|
+
return (_jsxs("div", { className: "flex flex-col gap-4 w-full max-w-md", children: [_jsx(MaskedTextInput, Object.assign({}, args)), _jsx(MaskedTextInput, Object.assign({}, args, { label: "License Plate", mask: "999-AAA" })), _jsx(MaskedTextInput, Object.assign({}, args, { label: "Product Code", mask: "AA-9999-AA" })), _jsx(MaskedTextInput, Object.assign({}, args, { label: "Time", mask: "00:00:00" }))] }));
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
export const MaskOptions = {
|
|
99
|
+
args: {
|
|
100
|
+
label: "Phone with Options",
|
|
101
|
+
mask: MASK_PATTERNS.PHONE,
|
|
102
|
+
fullwidth: true,
|
|
103
|
+
},
|
|
104
|
+
render: (args) => {
|
|
105
|
+
return (_jsxs("div", { className: "flex flex-col gap-4 w-full max-w-md", children: [_jsx(MaskedTextInput, Object.assign({}, args, { label: "With Guide", guide: true, showMask: true })), _jsx(MaskedTextInput, Object.assign({}, args, { label: "Without Guide", guide: false, showMask: true })), _jsx(MaskedTextInput, Object.assign({}, args, { label: "Custom Mask Char", maskChar: "*", guide: true, showMask: true }))] }));
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
export const WithCallbacks = {
|
|
109
|
+
args: {
|
|
110
|
+
label: "Phone with Callbacks",
|
|
111
|
+
mask: MASK_PATTERNS.PHONE,
|
|
112
|
+
fullwidth: true,
|
|
113
|
+
},
|
|
114
|
+
render: (args) => {
|
|
115
|
+
const [maskedValue, setMaskedValue] = useState("");
|
|
116
|
+
const [rawValue, setRawValue] = useState("");
|
|
117
|
+
return (_jsxs("div", { className: "flex flex-col gap-4 w-full max-w-md", children: [_jsx(MaskedTextInput, Object.assign({}, args, { onChange: (e) => {
|
|
118
|
+
setMaskedValue(e.target.value);
|
|
119
|
+
setRawValue(e.target.value);
|
|
120
|
+
}, onMaskedChange: (masked, raw) => {
|
|
121
|
+
setMaskedValue(masked);
|
|
122
|
+
setRawValue(raw);
|
|
123
|
+
} })), _jsxs("div", { className: "p-4 bg-gray-100 rounded", children: [_jsxs("p", { children: [_jsx("strong", { children: "Masked Value:" }), " ", maskedValue] }), _jsxs("p", { children: [_jsx("strong", { children: "Raw Value:" }), " ", rawValue] })] })] }));
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
export const AllPatterns = {
|
|
127
|
+
args: {
|
|
128
|
+
fullwidth: true,
|
|
129
|
+
},
|
|
130
|
+
render: (args) => {
|
|
131
|
+
return (_jsxs("div", { className: "flex flex-col gap-4 w-full max-w-2xl", children: [_jsx("h3", { className: "text-lg font-semibold", children: "All Mask Patterns" }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsx(MaskedTextInput, Object.assign({}, args, { label: "Phone", mask: MASK_PATTERNS.PHONE })), _jsx(MaskedTextInput, Object.assign({}, args, { label: "International Phone", mask: MASK_PATTERNS.PHONE_INTL })), _jsx(MaskedTextInput, Object.assign({}, args, { label: "Credit Card", mask: MASK_PATTERNS.CREDIT_CARD })), _jsx(MaskedTextInput, Object.assign({}, args, { label: "Date", mask: MASK_PATTERNS.DATE })), _jsx(MaskedTextInput, Object.assign({}, args, { label: "Time", mask: MASK_PATTERNS.TIME })), _jsx(MaskedTextInput, Object.assign({}, args, { label: "SSN", mask: MASK_PATTERNS.SSN })), _jsx(MaskedTextInput, Object.assign({}, args, { label: "ZIP Code", mask: MASK_PATTERNS.ZIP_CODE })), _jsx(MaskedTextInput, Object.assign({}, args, { label: "ZIP Code + 4", mask: MASK_PATTERNS.ZIP_CODE_EXT })), _jsx(MaskedTextInput, Object.assign({}, args, { label: "Currency", mask: MASK_PATTERNS.CURRENCY })), _jsx(MaskedTextInput, Object.assign({}, args, { label: "Percentage", mask: MASK_PATTERNS.PERCENTAGE }))] })] }));
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
export const KendoRules = {
|
|
135
|
+
args: {
|
|
136
|
+
label: "Kendo UI Rules",
|
|
137
|
+
fullwidth: true,
|
|
138
|
+
},
|
|
139
|
+
render: (args) => {
|
|
140
|
+
return (_jsxs("div", { className: "flex flex-col gap-4 w-full max-w-md", children: [_jsx("h3", { className: "text-sm font-semibold text-gray-700", children: "Kendo UI Mask Rules Examples" }), _jsx(MaskedTextInput, Object.assign({}, args, { label: "Rule: 0 (Digits Only)", mask: "000-000-0000", helperText: "0 = Required digit (0-9)" })), _jsx(MaskedTextInput, Object.assign({}, args, { label: "Rule: L (Letters Only)", mask: "LLL-LLLL", helperText: "L = Required letter (a-z, A-Z)" })), _jsx(MaskedTextInput, Object.assign({}, args, { label: "Rule: A (Alphanumeric)", mask: "AAAA-0000", helperText: "A = Letter or digit" })), _jsx(MaskedTextInput, Object.assign({}, args, { label: "Rule: # (Number with sign)", mask: "###", helperText: "# = Digit, space, + or -" })), _jsx(MaskedTextInput, Object.assign({}, args, { label: "Mixed Pattern Example", mask: "(000) LLL-0000", helperText: "Format: (123) ABC-4567" }))] }));
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
export const OptionalRules = {
|
|
144
|
+
args: {
|
|
145
|
+
label: "Optional Rules (with space)",
|
|
146
|
+
fullwidth: true,
|
|
147
|
+
},
|
|
148
|
+
render: (args) => {
|
|
149
|
+
return (_jsxs("div", { className: "flex flex-col gap-4 w-full max-w-md", children: [_jsx("h3", { className: "text-sm font-semibold text-gray-700", children: "Rules that accept space (optional input)" }), _jsx("p", { className: "text-xs text-gray-500", children: "Note: These rules allow space, making the position optional" }), _jsx(MaskedTextInput, Object.assign({}, args, { label: "Rule: 9 (Digit or Space)", mask: "999-999-9999", helperText: "9 = Optional digit (press space to skip)", guide: false })), _jsx(MaskedTextInput, Object.assign({}, args, { label: "Rule: ? (Letter or Space)", mask: "???-????", helperText: "? = Optional letter (press space to skip)", guide: false })), _jsx(MaskedTextInput, Object.assign({}, args, { label: "Rule: a (Alphanumeric or Space)", mask: "aaaa-aaaa", helperText: "a = Optional alphanumeric (press space to skip)", guide: false }))] }));
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
export const CustomRules = {
|
|
153
|
+
args: {
|
|
154
|
+
label: "Custom Rules",
|
|
155
|
+
fullwidth: true,
|
|
156
|
+
},
|
|
157
|
+
render: (args) => {
|
|
158
|
+
return (_jsxs("div", { className: "flex flex-col gap-4 w-full max-w-md", children: [_jsx("h3", { className: "text-sm font-semibold text-gray-700", children: "Custom Validation Rules" }), _jsx("div", { className: "space-y-2", children: _jsx(MaskedTextInput, Object.assign({}, args, { label: "Custom Rule: Digits 3-9 only", mask: "~-~-~", rules: {
|
|
159
|
+
"~": /[3-9]/,
|
|
160
|
+
}, helperText: "Type only digits 3, 4, 5, 6, 7, 8, or 9" })) }), _jsx("div", { className: "space-y-2", children: _jsx(MaskedTextInput, Object.assign({}, args, { label: "Custom Rule: Uppercase letters only", mask: "***", rules: {
|
|
161
|
+
"*": (char) => char === char.toUpperCase() && /[A-Z]/.test(char),
|
|
162
|
+
}, helperText: "Type only uppercase letters (A-Z)" })) }), _jsx("div", { className: "space-y-2", children: _jsx(MaskedTextInput, Object.assign({}, args, { label: "Mixed Custom Rules", mask: "~*-~*", rules: {
|
|
163
|
+
"~": /[0-9]/,
|
|
164
|
+
"*": /[A-Z]/,
|
|
165
|
+
}, helperText: "Format: Digit-Letter-Digit-Letter" })) })] }));
|
|
166
|
+
},
|
|
167
|
+
};
|
|
@@ -18,7 +18,7 @@ export const toastVariants = cva([
|
|
|
18
18
|
variant: "success",
|
|
19
19
|
},
|
|
20
20
|
});
|
|
21
|
-
export const toastViewportVariants = cva(["fixed z-[
|
|
21
|
+
export const toastViewportVariants = cva(["fixed z-[1000] flex w-auto flex-col-reverse px-4"], {
|
|
22
22
|
variants: {
|
|
23
23
|
position: {
|
|
24
24
|
"top-center": "top-[40px] left-0 right-0 justify-self-center",
|
package/dist/esm/bundle.css
CHANGED
|
@@ -665,6 +665,9 @@ input[type=number] {
|
|
|
665
665
|
.z-50{
|
|
666
666
|
z-index: 50;
|
|
667
667
|
}
|
|
668
|
+
.z-\[1000\]{
|
|
669
|
+
z-index: 1000;
|
|
670
|
+
}
|
|
668
671
|
.z-\[100\]{
|
|
669
672
|
z-index: 100;
|
|
670
673
|
}
|
|
@@ -993,6 +996,9 @@ input[type=number] {
|
|
|
993
996
|
min-width: -moz-fit-content;
|
|
994
997
|
min-width: fit-content;
|
|
995
998
|
}
|
|
999
|
+
.max-w-2xl{
|
|
1000
|
+
max-width: 42rem;
|
|
1001
|
+
}
|
|
996
1002
|
.max-w-\[300px\]{
|
|
997
1003
|
max-width: 300px;
|
|
998
1004
|
}
|
|
@@ -1002,6 +1008,9 @@ input[type=number] {
|
|
|
1002
1008
|
.max-w-lg{
|
|
1003
1009
|
max-width: 32rem;
|
|
1004
1010
|
}
|
|
1011
|
+
.max-w-md{
|
|
1012
|
+
max-width: 28rem;
|
|
1013
|
+
}
|
|
1005
1014
|
.flex-1{
|
|
1006
1015
|
flex: 1 1 0%;
|
|
1007
1016
|
}
|
|
@@ -1869,6 +1878,10 @@ input[type=number] {
|
|
|
1869
1878
|
--tw-bg-opacity: 1;
|
|
1870
1879
|
background-color: color-mix(in srgb, var(--function-default-stroke) calc(100% * var(--tw-bg-opacity, 1)), transparent);
|
|
1871
1880
|
}
|
|
1881
|
+
.bg-gray-100{
|
|
1882
|
+
--tw-bg-opacity: 1;
|
|
1883
|
+
background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
|
|
1884
|
+
}
|
|
1872
1885
|
.bg-gray-200{
|
|
1873
1886
|
--tw-bg-opacity: 1;
|
|
1874
1887
|
background-color: rgb(229 231 235 / var(--tw-bg-opacity, 1));
|
|
@@ -3165,6 +3178,10 @@ input[type=number] {
|
|
|
3165
3178
|
line-height: var(--label-label2-line-height, 10px);
|
|
3166
3179
|
font-weight: var(--label-label2-weight, 400);
|
|
3167
3180
|
}
|
|
3181
|
+
.text-lg{
|
|
3182
|
+
font-size: 1.125rem;
|
|
3183
|
+
line-height: 1.75rem;
|
|
3184
|
+
}
|
|
3168
3185
|
.text-sm{
|
|
3169
3186
|
font-size: 0.875rem;
|
|
3170
3187
|
line-height: 1.25rem;
|
|
@@ -3258,6 +3275,9 @@ input[type=number] {
|
|
|
3258
3275
|
.font-medium{
|
|
3259
3276
|
font-weight: 500;
|
|
3260
3277
|
}
|
|
3278
|
+
.font-semibold{
|
|
3279
|
+
font-weight: 600;
|
|
3280
|
+
}
|
|
3261
3281
|
.uppercase{
|
|
3262
3282
|
text-transform: uppercase;
|
|
3263
3283
|
}
|
|
@@ -3458,6 +3478,10 @@ input[type=number] {
|
|
|
3458
3478
|
--tw-text-opacity: 1;
|
|
3459
3479
|
color: rgb(107 114 128 / var(--tw-text-opacity, 1));
|
|
3460
3480
|
}
|
|
3481
|
+
.text-gray-700{
|
|
3482
|
+
--tw-text-opacity: 1;
|
|
3483
|
+
color: rgb(55 65 81 / var(--tw-text-opacity, 1));
|
|
3484
|
+
}
|
|
3461
3485
|
.text-green-500{
|
|
3462
3486
|
--tw-text-opacity: 1;
|
|
3463
3487
|
color: rgb(34 197 94 / var(--tw-text-opacity, 1));
|
|
@@ -5826,6 +5850,10 @@ input[type=number] {
|
|
|
5826
5850
|
.md\:right-\[40px\]{
|
|
5827
5851
|
right: 40px;
|
|
5828
5852
|
}
|
|
5853
|
+
|
|
5854
|
+
.md\:grid-cols-2{
|
|
5855
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
5856
|
+
}
|
|
5829
5857
|
}
|
|
5830
5858
|
.\[\&\:has\(\[role\=checkbox\]\)\]\:w-4:has([role=checkbox]){
|
|
5831
5859
|
width: 1rem;
|