jattac.libs.web.zest-textbox 0.2.0 → 0.2.2
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/README.md +325 -47
- package/dist/components/CharacterCounter.d.ts +9 -0
- package/dist/components/HelperTextDisplay.d.ts +7 -0
- package/dist/components/PasswordToggleButton.d.ts +8 -0
- package/dist/components/ProgressBar.d.ts +9 -0
- package/dist/contexts/ZestTextboxConfigContext.d.ts +12 -0
- package/dist/hooks/useCharacterCounter.d.ts +6 -0
- package/dist/hooks/useHelperText.d.ts +3 -0
- package/dist/hooks/useParsedAndValidatedInput.d.ts +13 -0
- package/dist/hooks/usePasswordVisibility.d.ts +4 -0
- package/dist/hooks/useThemeDetector.d.ts +2 -0
- package/dist/hooks/useZestTextboxConfig.d.ts +2 -0
- package/dist/index.d.ts +155 -1
- package/dist/index.esm.js +331 -59
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +335 -58
- package/dist/index.js.map +1 -1
- package/dist/{ZestTextbox.d.ts → types.d.ts} +33 -40
- package/dist/utils/numericInputFilter.d.ts +1 -0
- package/package.json +1 -1
- package/dist/IconEyeOpen.d.ts +0 -2
- package/dist/IconEyeSlashed.d.ts +0 -2
package/dist/index.js
CHANGED
|
@@ -43,6 +43,44 @@ function __rest(s, e) {
|
|
|
43
43
|
return t;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
47
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
48
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
49
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
50
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
51
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
52
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function __generator(thisArg, body) {
|
|
57
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
58
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
59
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
60
|
+
function step(op) {
|
|
61
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
62
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
63
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
64
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
65
|
+
switch (op[0]) {
|
|
66
|
+
case 0: case 1: t = op; break;
|
|
67
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
68
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
69
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
70
|
+
default:
|
|
71
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
72
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
73
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
74
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
75
|
+
if (t[2]) _.ops.pop();
|
|
76
|
+
_.trys.pop(); continue;
|
|
77
|
+
}
|
|
78
|
+
op = body.call(thisArg, _);
|
|
79
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
80
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
46
84
|
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
47
85
|
var e = new Error(message);
|
|
48
86
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
@@ -75,24 +113,82 @@ function styleInject(css, ref) {
|
|
|
75
113
|
}
|
|
76
114
|
}
|
|
77
115
|
|
|
78
|
-
var css_248z = "/* === Base Textbox Styles (input & textarea) === */\n.ZestTextbox-module_textbox__0M5Wq {\n font-family: \"Segoe UI\", Roboto, sans-serif;\n font-weight: 500;\n line-height: 1.25;\n border: 1px solid #ccc;\n border-radius: 0.5rem; /* 8px */\n color: #111827;\n background-color: #ffffff;\n transition: border-color 0.2s ease, box-shadow 0.2s ease;\n display: inline-block;\n width: auto;\n box-sizing: border-box;\n resize: none;\n font-size: 1rem; /* 16px */\n padding-bottom:
|
|
79
|
-
var styles = {"textbox":"ZestTextbox-module_textbox__0M5Wq","pulse-light":"ZestTextbox-module_pulse-light__CKfhA","sm":"ZestTextbox-module_sm__yyxXO","md":"ZestTextbox-module_md__fvL10","lg":"ZestTextbox-module_lg__fU93-","fullWidth":"ZestTextbox-module_fullWidth__xn4fT","wrapper":"ZestTextbox-module_wrapper__0ok2A","counter":"ZestTextbox-module_counter__waqIT","pulse-dark":"ZestTextbox-module_pulse-dark__L9PYJ","passwordToggle":"ZestTextbox-module_passwordToggle__I2s4O","eyeIcon":"ZestTextbox-module_eyeIcon__rKiBL","rotate":"ZestTextbox-module_rotate__Ajx19","tooltip":"ZestTextbox-module_tooltip__etRdj","progressBarContainer":"ZestTextbox-module_progressBarContainer__0qFKf","progressBar":"ZestTextbox-module_progressBar__vwttj","counterYellow":"ZestTextbox-module_counterYellow__uYGfs","counterOrange":"ZestTextbox-module_counterOrange__b9baX","helperText":"ZestTextbox-module_helperText__4twSg","fade-slide-in":"ZestTextbox-module_fade-slide-in__re-Ln"};
|
|
116
|
+
var css_248z = "/* === Base Textbox Styles (input & textarea) === */\n.ZestTextbox-module_textbox__0M5Wq {\n font-family: \"Segoe UI\", Roboto, sans-serif;\n font-weight: 500;\n line-height: 1.25;\n border: 1px solid #ccc;\n border-radius: 0.5rem; /* 8px */\n color: #111827;\n background-color: #ffffff;\n transition: border-color 0.2s ease, box-shadow 0.2s ease;\n display: inline-block;\n width: auto;\n box-sizing: border-box;\n resize: none;\n font-size: 1rem; /* 16px */\n padding-bottom: 0.5rem; /* Reduced padding to make space for progress bar */\n}\n\n.ZestTextbox-module_textbox__0M5Wq:focus {\n outline: none;\n border-color: #8B5CF6;\n box-shadow: 0 0 0 0.125rem rgba(139, 92, 246, 0.25); /* 2px */\n animation: ZestTextbox-module_pulse-light__CKfhA 0.5s 1;\n}\n\n/* === Error State === */\n.ZestTextbox-module_error__5RoCP {\n border-color: #ef4444; /* Red-500 */\n box-shadow: 0 0 0 0.125rem rgba(239, 68, 68, 0.25); /* Red-500 with 25% opacity */\n}\n\n.ZestTextbox-module_error__5RoCP:focus {\n border-color: #ef4444;\n box-shadow: 0 0 0 0.125rem rgba(239, 68, 68, 0.35);\n}\n\n/* === Sizes === */\n.ZestTextbox-module_sm__yyxXO {\n padding: 0.5rem 0.75rem; /* 8px 12px */\n font-size: 0.875rem; /* 14px */\n}\n\n.ZestTextbox-module_md__fvL10 {\n padding: 0.625rem 0.875rem; /* 10px 14px */\n font-size: 1rem; /* 16px */\n}\n\n.ZestTextbox-module_lg__fU93- {\n padding: 0.75rem 1rem; /* 12px 16px */\n font-size: 1.125rem; /* 18px */\n}\n\n/* === Full Width === */\n.ZestTextbox-module_fullWidth__xn4fT {\n width: 100%;\n}\n\n/* === Disabled State === */\n.ZestTextbox-module_textbox__0M5Wq:disabled {\n background-color: #f3f4f6;\n color: #9ca3af;\n cursor: not-allowed;\n pointer-events: none;\n border-color: #d1d5db;\n}\n\n/* === Multiline (textarea) specific enhancements === */\ntextarea.ZestTextbox-module_textbox__0M5Wq {\n min-height: 6.25rem; /* 100px */\n line-height: 1.5;\n resize: vertical;\n}\n\n.ZestTextbox-module_wrapper__0ok2A {\n position: relative;\n display: inline-block;\n}\n\n.ZestTextbox-module_counter__waqIT {\n position: absolute;\n right: 0.625rem; /* 10px */\n bottom: 0.375rem; /* 6px */\n font-size: 0.75rem;\n color: #6b7280;\n pointer-events: none;\n user-select: none;\n}\n\n/* === Dark Mode Support === */\n.dark .ZestTextbox-module_textbox__0M5Wq {\n background-color: #1f2937;\n border-color: #374151;\n color: #f3f4f6;\n}\n\n.dark .ZestTextbox-module_textbox__0M5Wq:focus {\n border-color: #A78BFA;\n box-shadow: 0 0 0 0.125rem rgba(167, 139, 250, 0.35); /* 2px */\n animation: ZestTextbox-module_pulse-dark__L9PYJ 0.5s 1;\n}\n\n.dark .ZestTextbox-module_textbox__0M5Wq:disabled {\n background-color: #374151;\n color: #9ca3af;\n border-color: #4b5563;\n}\n\n.dark .ZestTextbox-module_counter__waqIT {\n color: #9ca3af;\n}\n\n.dark .ZestTextbox-module_error__5RoCP {\n border-color: #f87171; /* Red-400 for dark mode */\n box-shadow: 0 0 0 0.125rem rgba(248, 113, 113, 0.35);\n}\n\n.dark .ZestTextbox-module_error__5RoCP:focus {\n border-color: #f87171;\n box-shadow: 0 0 0 0.125rem rgba(248, 113, 113, 0.45);\n}\n\n/* === Password Toggle === */\n.ZestTextbox-module_passwordToggle__I2s4O {\n position: absolute;\n right: 0.625rem; /* 10px */\n top: 50%;\n transform: translateY(-50%);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #6b7280;\n}\n\n.ZestTextbox-module_eyeIcon__rKiBL {\n width: 1.25em;\n height: 1.25em;\n transition: transform 0.2s ease-in-out;\n}\n\n.ZestTextbox-module_rotate__Ajx19 {\n transform: rotate(180deg);\n}\n\n.ZestTextbox-module_tooltip__etRdj {\n position: absolute;\n right: 100%;\n top: 50%;\n transform: translateY(-50%);\n background-color: #333;\n color: #fff;\n padding: 0.25rem 0.5rem; /* 4px 8px */\n border-radius: 0.25rem; /* 4px */\n font-size: 0.75rem;\n white-space: nowrap;\n margin-right: 0.5rem; /* 8px */\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.2s ease, visibility 0.2s ease;\n}\n\n.ZestTextbox-module_passwordToggle__I2s4O:hover .ZestTextbox-module_tooltip__etRdj {\n opacity: 1;\n visibility: visible;\n}\n\n.dark .ZestTextbox-module_passwordToggle__I2s4O {\n color: #9ca3af;\n}\n\n.dark .ZestTextbox-module_tooltip__etRdj {\n background-color: #4b5563;\n color: #f3f4f6;\n}\n\n/* === Progress Bar === */\n.ZestTextbox-module_progressBarContainer__0qFKf {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n height: 0.1875rem; /* 3px */\n background-color: #e5e7eb;\n border-bottom-left-radius: 0.5rem; /* 8px */\n border-bottom-right-radius: 0.5rem; /* 8px */\n overflow: hidden;\n}\n\n.ZestTextbox-module_progressBar__vwttj {\n height: 100%;\n background-color: #8B5CF6;\n transition: width 0.2s ease, background-color 0.3s ease;\n}\n\n/* === Animated Counter Colors === */\n.ZestTextbox-module_counterYellow__uYGfs {\n color: #A78BFA;\n}\n\n.ZestTextbox-module_counterOrange__b9baX {\n color: #8B5CF6;\n}\n\n.dark .ZestTextbox-module_progressBarContainer__0qFKf {\n background-color: #374151;\n}\n\n.dark .ZestTextbox-module_progressBar__vwttj {\n background-color: #A78BFA;\n}\n\n.dark .ZestTextbox-module_counterYellow__uYGfs {\n color: #C4B5FD;\n}\n\n.dark .ZestTextbox-module_counterOrange__b9baX {\n color: #A78BFA;\n}\n\n@keyframes ZestTextbox-module_pulse-light__CKfhA {\n 0% {\n box-shadow: 0 0 0 0.125rem rgba(139, 92, 246, 0.25); /* 2px */\n }\n 50% {\n box-shadow: 0 0 0 0.25rem rgba(139, 92, 246, 0.35); /* 4px */\n }\n 100% {\n box-shadow: 0 0 0 0.125rem rgba(139, 92, 246, 0.25); /* 2px */\n }\n}\n\n@keyframes ZestTextbox-module_pulse-dark__L9PYJ {\n 0% {\n box-shadow: 0 0 0 0.125rem rgba(167, 139, 250, 0.35); /* 2px */\n }\n 50% {\n box-shadow: 0 0 0 0.25rem rgba(167, 139, 250, 0.45); /* 4px */\n }\n 100% {\n box-shadow: 0 0 0 0.125rem rgba(167, 139, 250, 0.35); /* 2px */\n }\n}\n\n/* === Media Queries for Responsive Design === */\n@media (min-width: 48rem) { /* 768px */\n /* Tablet */\n .ZestTextbox-module_sm__yyxXO {\n font-size: 0.875rem; /* 14px */\n }\n .ZestTextbox-module_md__fvL10 {\n font-size: 1rem; /* 16px */\n }\n .ZestTextbox-module_lg__fU93- {\n font-size: 1.125rem; /* 18px */\n }\n}\n\n@media (min-width: 64rem) { /* 1024px */\n /* Desktop */\n .ZestTextbox-module_sm__yyxXO {\n padding: 0.375rem 0.625rem; /* 6px 10px */\n font-size: 0.875rem; /* 14px */\n }\n .ZestTextbox-module_md__fvL10 {\n padding: 0.625rem 0.875rem; /* 10px 14px */\n font-size: 1rem; /* 16px */\n }\n .ZestTextbox-module_lg__fU93- {\n padding: 0.75rem 1rem; /* 12px 16px */\n font-size: 1.125rem; /* 18px */\n }\n}\n\n/* === Helper Text === */\n.ZestTextbox-module_helperText__4twSg {\n font-size: 0.875rem; /* 14px */\n color: #6b7280;\n margin-top: 0.25rem; /* 4px */\n animation: ZestTextbox-module_fade-slide-in__re-Ln 0.3s ease-out forwards;\n}\n\n.dark .ZestTextbox-module_helperText__4twSg {\n color: #9ca3af;\n}\n\n@keyframes ZestTextbox-module_fade-slide-in__re-Ln {\n from {\n opacity: 0;\n transform: translateY(5px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}";
|
|
117
|
+
var styles = {"textbox":"ZestTextbox-module_textbox__0M5Wq","pulse-light":"ZestTextbox-module_pulse-light__CKfhA","error":"ZestTextbox-module_error__5RoCP","sm":"ZestTextbox-module_sm__yyxXO","md":"ZestTextbox-module_md__fvL10","lg":"ZestTextbox-module_lg__fU93-","fullWidth":"ZestTextbox-module_fullWidth__xn4fT","wrapper":"ZestTextbox-module_wrapper__0ok2A","counter":"ZestTextbox-module_counter__waqIT","pulse-dark":"ZestTextbox-module_pulse-dark__L9PYJ","passwordToggle":"ZestTextbox-module_passwordToggle__I2s4O","eyeIcon":"ZestTextbox-module_eyeIcon__rKiBL","rotate":"ZestTextbox-module_rotate__Ajx19","tooltip":"ZestTextbox-module_tooltip__etRdj","progressBarContainer":"ZestTextbox-module_progressBarContainer__0qFKf","progressBar":"ZestTextbox-module_progressBar__vwttj","counterYellow":"ZestTextbox-module_counterYellow__uYGfs","counterOrange":"ZestTextbox-module_counterOrange__b9baX","helperText":"ZestTextbox-module_helperText__4twSg","fade-slide-in":"ZestTextbox-module_fade-slide-in__re-Ln"};
|
|
80
118
|
styleInject(css_248z);
|
|
81
119
|
|
|
82
|
-
var
|
|
120
|
+
var filterNumericInput = function (value) {
|
|
121
|
+
// Allow digits, a single leading hyphen, and a single decimal point
|
|
122
|
+
var parts = value.split('.');
|
|
123
|
+
var integerPart = parts[0].replace(/[^0-9-]/g, '');
|
|
124
|
+
var decimalPart = parts.length > 1 ? '.' + parts[1].replace(/[^0-9]/g, '') : '';
|
|
125
|
+
// Ensure only one leading hyphen
|
|
126
|
+
if (integerPart.startsWith('-')) {
|
|
127
|
+
integerPart = '-' + integerPart.substring(1).replace(/-/g, '');
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
integerPart = integerPart.replace(/-/g, '');
|
|
131
|
+
}
|
|
132
|
+
var newValue = integerPart + decimalPart;
|
|
133
|
+
// Prevent multiple decimal points
|
|
134
|
+
if (newValue.indexOf('.') !== -1 && newValue.indexOf('.') !== newValue.lastIndexOf('.')) {
|
|
135
|
+
newValue = newValue.substring(0, newValue.lastIndexOf('.'));
|
|
136
|
+
}
|
|
137
|
+
return newValue;
|
|
138
|
+
};
|
|
83
139
|
|
|
84
|
-
var
|
|
140
|
+
var useThemeDetector = function (theme) {
|
|
141
|
+
if (theme === void 0) { theme = "system"; }
|
|
142
|
+
var _a = react.useState(false), isDark = _a[0], setIsDark = _a[1];
|
|
143
|
+
react.useEffect(function () {
|
|
144
|
+
if (theme === "dark") {
|
|
145
|
+
setIsDark(true);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (theme === "light") {
|
|
149
|
+
setIsDark(false);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
// System theme
|
|
153
|
+
var mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
154
|
+
var handleChange = function () { return setIsDark(mediaQuery.matches); };
|
|
155
|
+
handleChange(); // Set initial theme
|
|
156
|
+
mediaQuery.addEventListener("change", handleChange);
|
|
157
|
+
return function () { return mediaQuery.removeEventListener("change", handleChange); };
|
|
158
|
+
}, [theme]);
|
|
159
|
+
return isDark;
|
|
160
|
+
};
|
|
85
161
|
|
|
86
|
-
var
|
|
87
|
-
var _a =
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
162
|
+
var usePasswordVisibility = function (isPasswordType) {
|
|
163
|
+
var _a = react.useState(false), isPasswordVisible = _a[0], setIsPasswordVisible = _a[1];
|
|
164
|
+
var togglePasswordVisibility = function () {
|
|
165
|
+
if (isPasswordType) {
|
|
166
|
+
setIsPasswordVisible(function (prev) { return !prev; });
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
return { isPasswordVisible: isPasswordVisible, togglePasswordVisibility: togglePasswordVisibility };
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
var useCharacterCounter = function (value, maxLength, animatedCounter) {
|
|
173
|
+
var currentLength = value.length;
|
|
174
|
+
var showCounter = typeof maxLength === "number";
|
|
175
|
+
var charPercentage = showCounter ? (currentLength / maxLength) * 100 : 0;
|
|
176
|
+
var counterColorClass = react.useMemo(function () {
|
|
177
|
+
if (!animatedCounter || !showCounter)
|
|
178
|
+
return "";
|
|
179
|
+
if (charPercentage > 90) {
|
|
180
|
+
return styles.counterOrange;
|
|
181
|
+
}
|
|
182
|
+
else if (charPercentage > 70) {
|
|
183
|
+
return styles.counterYellow;
|
|
184
|
+
}
|
|
185
|
+
return "";
|
|
186
|
+
}, [animatedCounter, showCounter, charPercentage]);
|
|
187
|
+
return { currentLength: currentLength, charPercentage: charPercentage, counterColorClass: counterColorClass, showCounter: showCounter };
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
var useHelperText = function (value, helperTextConfig) {
|
|
191
|
+
var _a = react.useState(null), helperTextNode = _a[0], setHelperTextNode = _a[1];
|
|
96
192
|
react.useEffect(function () {
|
|
97
193
|
if (!helperTextConfig) {
|
|
98
194
|
setHelperTextNode(null);
|
|
@@ -106,76 +202,257 @@ var ZestTextbox = function (props) {
|
|
|
106
202
|
: formatted;
|
|
107
203
|
setHelperTextNode(finalNode);
|
|
108
204
|
}, [value, helperTextConfig]);
|
|
109
|
-
|
|
205
|
+
return helperTextNode;
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
var IconEyeOpen = function (props) { return (jsxRuntime.jsxs("svg", __assign({ xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", fill: "currentColor", viewBox: "0 0 16 16" }, props, { children: [jsxRuntime.jsx("path", { d: "M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8M1.173 8a13 13 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5s3.879 1.168 5.168 2.457A13 13 0 0 1 14.828 8q-.086.13-.195.288c-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5s-3.879-1.168-5.168-2.457A13 13 0 0 1 1.172 8z" }), jsxRuntime.jsx("path", { d: "M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5M4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0" })] }))); };
|
|
209
|
+
|
|
210
|
+
var IconEyeSlashed = function (props) { return (jsxRuntime.jsxs("svg", __assign({ xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", fill: "currentColor", viewBox: "0 0 16 16" }, props, { children: [jsxRuntime.jsx("path", { d: "M13.359 11.238C15.06 9.72 16 8 16 8s-3-5.5-8-5.5a7.028 7.028 0 0 0-2.79.588l.77.771A5.944 5.944 0 0 1 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.134 13.134 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755-.165.165-.337.328-.517.486l.708.709z" }), jsxRuntime.jsx("path", { d: "M11.297 9.176a3.5 3.5 0 0 0-4.474-4.474l.823.823a2.5 2.5 0 0 1 2.829 2.829l.822.822zm-2.943 1.288.822.822.073.073.026.026a3.5 3.5 0 0 1-4.474-4.474l.823.823a2.5 2.5 0 0 0 2.829 2.829l.822.822zm-2.943-1.288.822.822.073.073.026.026a3.5 3.5 0 0 1-4.474-4.474l.823.823a2.5 2.5 0 0 0 2.829 2.829l.822.822z" }), jsxRuntime.jsx("path", { d: "M3.35 5.47c-.18.16-.353.322-.518.487A13.134 13.134 0 0 0 1.172 8l.195.288c.335.48.83 1.12 1.465 1.755C4.121 11.332 5.88 12.5 8 12.5c.716 0 1.39-.133 2.02-.36l.77.772A7.029 7.029 0 0 1 8 13.5C3 13.5 0 8 0 8s.939-1.721 2.641-3.238l.708.709zm10.296 6.854-12-12 .708-.708 12 12-.708.708z" })] }))); };
|
|
211
|
+
|
|
212
|
+
var PasswordToggleButton = function (_a) {
|
|
213
|
+
var isPassword = _a.isPassword, isPasswordVisible = _a.isPasswordVisible, onToggle = _a.onToggle;
|
|
214
|
+
if (!isPassword)
|
|
215
|
+
return null;
|
|
216
|
+
return (jsxRuntime.jsxs("div", { className: styles.passwordToggle, onClick: onToggle, children: [jsxRuntime.jsx("div", { className: styles.tooltip, children: isPasswordVisible ? "Hide password" : "Show password" }), isPasswordVisible ? (jsxRuntime.jsx(IconEyeOpen, { className: styles.eyeIcon })) : (jsxRuntime.jsx(IconEyeSlashed, { className: styles.eyeIcon }))] }));
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
var CharacterCounter = function (_a) {
|
|
220
|
+
var showCounter = _a.showCounter, currentLength = _a.currentLength, maxLength = _a.maxLength, counterColorClass = _a.counterColorClass;
|
|
221
|
+
if (!showCounter)
|
|
222
|
+
return null;
|
|
223
|
+
return (jsxRuntime.jsxs("div", { className: "".concat(styles.counter, " ").concat(counterColorClass), children: [currentLength, " / ", maxLength] }));
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
var ProgressBar = function (_a) {
|
|
227
|
+
var showProgressBar = _a.showProgressBar, showCounter = _a.showCounter, charPercentage = _a.charPercentage, counterColorClass = _a.counterColorClass;
|
|
228
|
+
if (!showProgressBar || !showCounter)
|
|
229
|
+
return null;
|
|
230
|
+
return (jsxRuntime.jsx("div", { className: styles.progressBarContainer, children: jsxRuntime.jsx("div", { className: "".concat(styles.progressBar, " ").concat(counterColorClass), style: { width: "".concat(charPercentage, "%") } }) }));
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
var HelperTextDisplay = function (_a) {
|
|
234
|
+
var helperTextNode = _a.helperTextNode, className = _a.className;
|
|
235
|
+
if (!helperTextNode)
|
|
236
|
+
return null;
|
|
237
|
+
return (jsxRuntime.jsx("div", { className: "".concat(styles.helperText, " ").concat(className || ""), children: helperTextNode }, String(helperTextNode)));
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
// Create the context with a default empty object
|
|
241
|
+
var ZestTextboxConfigContext = react.createContext(undefined);
|
|
242
|
+
var ZestTextboxConfigProvider = function (_a) {
|
|
243
|
+
var children = _a.children, _b = _a.value, value = _b === void 0 ? {} : _b;
|
|
244
|
+
return (jsxRuntime.jsx(ZestTextboxConfigContext.Provider, { value: { defaultZestProps: value }, children: children }));
|
|
245
|
+
};
|
|
246
|
+
// Custom hook to use the ZestTextboxConfigContext
|
|
247
|
+
var useZestTextboxConfig$1 = function () {
|
|
248
|
+
var context = react.useContext(ZestTextboxConfigContext);
|
|
249
|
+
if (context === undefined) {
|
|
250
|
+
// This error will be caught by the useZestTextboxConfig hook in ZestTextbox.tsx
|
|
251
|
+
// if the component is used outside of a provider.
|
|
252
|
+
return { defaultZestProps: {} };
|
|
253
|
+
}
|
|
254
|
+
return context;
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
// Helper function to resolve a ZestConfigValue
|
|
258
|
+
function resolveZestConfigValue(configValue, defaultValue) {
|
|
259
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
260
|
+
var result, _a;
|
|
261
|
+
return __generator(this, function (_b) {
|
|
262
|
+
switch (_b.label) {
|
|
263
|
+
case 0:
|
|
264
|
+
if (configValue === undefined) {
|
|
265
|
+
return [2 /*return*/, defaultValue];
|
|
266
|
+
}
|
|
267
|
+
if (!(typeof configValue === "function")) return [3 /*break*/, 4];
|
|
268
|
+
result = configValue();
|
|
269
|
+
if (!(result instanceof Promise)) return [3 /*break*/, 2];
|
|
270
|
+
return [4 /*yield*/, result];
|
|
271
|
+
case 1:
|
|
272
|
+
_a = _b.sent();
|
|
273
|
+
return [3 /*break*/, 3];
|
|
274
|
+
case 2:
|
|
275
|
+
_a = result;
|
|
276
|
+
_b.label = 3;
|
|
277
|
+
case 3: return [2 /*return*/, _a];
|
|
278
|
+
case 4: return [2 /*return*/, configValue];
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
var defaultResolvedZestProps = {
|
|
284
|
+
zSize: "md",
|
|
285
|
+
stretch: false,
|
|
286
|
+
showProgressBar: false,
|
|
287
|
+
animatedCounter: false,
|
|
288
|
+
theme: "system",
|
|
289
|
+
isMultiline: false,
|
|
290
|
+
onTextChanged: undefined,
|
|
291
|
+
helperTextConfig: undefined,
|
|
292
|
+
parser: undefined,
|
|
293
|
+
validator: undefined,
|
|
294
|
+
};
|
|
295
|
+
var useZestTextboxConfig = function (componentZestProps) {
|
|
296
|
+
var contextDefaultZestProps = useZestTextboxConfig$1().defaultZestProps;
|
|
297
|
+
var _a = react.useState(defaultResolvedZestProps), resolvedZestProps = _a[0], setResolvedZestProps = _a[1];
|
|
298
|
+
// Memoize the merged props to avoid unnecessary re-renders
|
|
299
|
+
var mergedZestProps = react.useMemo(function () {
|
|
300
|
+
// Component props take precedence over context default props, which take precedence over hardcoded defaults
|
|
301
|
+
return __assign(__assign(__assign({}, defaultResolvedZestProps), contextDefaultZestProps), componentZestProps);
|
|
302
|
+
}, [contextDefaultZestProps, componentZestProps]);
|
|
110
303
|
react.useEffect(function () {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
return
|
|
304
|
+
var resolveProps = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
305
|
+
var newResolvedProps, _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
306
|
+
return __generator(this, function (_k) {
|
|
307
|
+
switch (_k.label) {
|
|
308
|
+
case 0:
|
|
309
|
+
newResolvedProps = __assign({}, defaultResolvedZestProps);
|
|
310
|
+
// Resolve each property that can be a ZestConfigValue
|
|
311
|
+
_a = newResolvedProps;
|
|
312
|
+
return [4 /*yield*/, resolveZestConfigValue(mergedZestProps.zSize, defaultResolvedZestProps.zSize)];
|
|
313
|
+
case 1:
|
|
314
|
+
// Resolve each property that can be a ZestConfigValue
|
|
315
|
+
_a.zSize = _k.sent();
|
|
316
|
+
_b = newResolvedProps;
|
|
317
|
+
return [4 /*yield*/, resolveZestConfigValue(mergedZestProps.stretch, defaultResolvedZestProps.stretch)];
|
|
318
|
+
case 2:
|
|
319
|
+
_b.stretch = _k.sent();
|
|
320
|
+
_c = newResolvedProps;
|
|
321
|
+
return [4 /*yield*/, resolveZestConfigValue(mergedZestProps.showProgressBar, defaultResolvedZestProps.showProgressBar)];
|
|
322
|
+
case 3:
|
|
323
|
+
_c.showProgressBar = _k.sent();
|
|
324
|
+
_d = newResolvedProps;
|
|
325
|
+
return [4 /*yield*/, resolveZestConfigValue(mergedZestProps.animatedCounter, defaultResolvedZestProps.animatedCounter)];
|
|
326
|
+
case 4:
|
|
327
|
+
_d.animatedCounter = _k.sent();
|
|
328
|
+
_e = newResolvedProps;
|
|
329
|
+
return [4 /*yield*/, resolveZestConfigValue(mergedZestProps.theme, defaultResolvedZestProps.theme)];
|
|
330
|
+
case 5:
|
|
331
|
+
_e.theme = _k.sent();
|
|
332
|
+
_f = newResolvedProps;
|
|
333
|
+
return [4 /*yield*/, resolveZestConfigValue(mergedZestProps.isMultiline, defaultResolvedZestProps.isMultiline)];
|
|
334
|
+
case 6:
|
|
335
|
+
_f.isMultiline = _k.sent();
|
|
336
|
+
// onTextChanged is no longer a ZestConfigValue, so it's directly assigned
|
|
337
|
+
newResolvedProps.onTextChanged = mergedZestProps.onTextChanged;
|
|
338
|
+
_g = newResolvedProps;
|
|
339
|
+
return [4 /*yield*/, resolveZestConfigValue(mergedZestProps.helperTextConfig, defaultResolvedZestProps.helperTextConfig)];
|
|
340
|
+
case 7:
|
|
341
|
+
_g.helperTextConfig = _k.sent();
|
|
342
|
+
_h = newResolvedProps;
|
|
343
|
+
return [4 /*yield*/, resolveZestConfigValue(mergedZestProps.parser, defaultResolvedZestProps.parser)];
|
|
344
|
+
case 8:
|
|
345
|
+
_h.parser = _k.sent();
|
|
346
|
+
_j = newResolvedProps;
|
|
347
|
+
return [4 /*yield*/, resolveZestConfigValue(mergedZestProps.validator, defaultResolvedZestProps.validator)];
|
|
348
|
+
case 9:
|
|
349
|
+
_j.validator = _k.sent();
|
|
350
|
+
setResolvedZestProps(newResolvedProps);
|
|
351
|
+
return [2 /*return*/];
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
}); };
|
|
355
|
+
resolveProps();
|
|
356
|
+
}, [mergedZestProps]); // Re-run effect if merged props change
|
|
357
|
+
return resolvedZestProps;
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
var useParsedAndValidatedInput = function (_a) {
|
|
361
|
+
var rawValue = _a.rawValue, parser = _a.parser, validator = _a.validator, onParsedAndValidatedChange = _a.onParsedAndValidatedChange;
|
|
362
|
+
var _b = react.useState(undefined), parsedValue = _b[0], setParsedValue = _b[1];
|
|
363
|
+
var _c = react.useState(true), isValid = _c[0], setIsValid = _c[1];
|
|
364
|
+
var _d = react.useState(undefined), validationMessage = _d[0], setValidationMessage = _d[1];
|
|
365
|
+
react.useEffect(function () {
|
|
366
|
+
var currentParsedValue = undefined;
|
|
367
|
+
var currentIsValid = true;
|
|
368
|
+
var currentValidationMessage = undefined;
|
|
369
|
+
// 1. Parse the raw value
|
|
370
|
+
if (parser) {
|
|
371
|
+
currentParsedValue = parser(rawValue);
|
|
114
372
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
373
|
+
else {
|
|
374
|
+
// If no parser, treat rawValue as the parsed value (e.g., for text inputs)
|
|
375
|
+
currentParsedValue = rawValue;
|
|
118
376
|
}
|
|
119
|
-
//
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
377
|
+
// 2. Validate the parsed value
|
|
378
|
+
if (validator) {
|
|
379
|
+
var validationResult = validator(currentParsedValue);
|
|
380
|
+
if (typeof validationResult === "string") {
|
|
381
|
+
currentIsValid = false;
|
|
382
|
+
currentValidationMessage = validationResult;
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
currentIsValid = validationResult;
|
|
386
|
+
if (!currentIsValid) {
|
|
387
|
+
currentValidationMessage = "Invalid input."; // Generic message if validator returns false
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
setParsedValue(currentParsedValue);
|
|
392
|
+
setIsValid(currentIsValid);
|
|
393
|
+
setValidationMessage(currentValidationMessage);
|
|
394
|
+
// 3. Call the consumer's callback with the parsed and validated value
|
|
395
|
+
// Only call if a callback is provided and the input is valid
|
|
396
|
+
if (onParsedAndValidatedChange && currentIsValid) {
|
|
397
|
+
onParsedAndValidatedChange(currentParsedValue);
|
|
398
|
+
}
|
|
399
|
+
}, [rawValue, parser, validator, onParsedAndValidatedChange]);
|
|
400
|
+
return { parsedValue: parsedValue, isValid: isValid, validationMessage: validationMessage };
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
// ... other imports
|
|
404
|
+
var ZestTextbox = function (props) {
|
|
405
|
+
var _a = props.className, className = _a === void 0 ? "" : _a, maxLength = props.maxLength, onChange = props.onChange, type = props.type, zest = props.zest, // Destructure the new zest prop
|
|
406
|
+
rest = __rest(props, ["className", "maxLength", "onChange", "type", "zest"]);
|
|
407
|
+
var resolvedZestProps = useZestTextboxConfig(zest);
|
|
408
|
+
var zSize = resolvedZestProps.zSize, fullWidth = resolvedZestProps.stretch, showProgressBar = resolvedZestProps.showProgressBar, animatedCounter = resolvedZestProps.animatedCounter, theme = resolvedZestProps.theme, helperTextConfig = resolvedZestProps.helperTextConfig, onTextChanged = resolvedZestProps.onTextChanged, isMultiline = resolvedZestProps.isMultiline, parser = resolvedZestProps.parser, validator = resolvedZestProps.validator;
|
|
409
|
+
var _b = react.useState(""), value = _b[0], setValue = _b[1];
|
|
410
|
+
var isDark = useThemeDetector(theme);
|
|
411
|
+
var isPassword = type === "password";
|
|
412
|
+
var _c = usePasswordVisibility(isPassword), isPasswordVisible = _c.isPasswordVisible, togglePasswordVisibility = _c.togglePasswordVisibility;
|
|
413
|
+
var _d = useCharacterCounter(value, maxLength, animatedCounter), currentLength = _d.currentLength, charPercentage = _d.charPercentage, counterColorClass = _d.counterColorClass, showCounter = _d.showCounter;
|
|
414
|
+
var _e = useParsedAndValidatedInput({
|
|
415
|
+
rawValue: value,
|
|
416
|
+
parser: parser,
|
|
417
|
+
validator: validator,
|
|
418
|
+
onParsedAndValidatedChange: onTextChanged,
|
|
419
|
+
}), isValid = _e.isValid, validationMessage = _e.validationMessage;
|
|
420
|
+
// Prioritize validation message over regular helper text
|
|
421
|
+
var finalHelperTextNode = validationMessage ? (jsxRuntime.jsx("span", { style: { color: "red" }, children: validationMessage })) : useHelperText(value, helperTextConfig);
|
|
126
422
|
var classList = [
|
|
127
423
|
styles.textbox,
|
|
128
424
|
styles[zSize],
|
|
129
425
|
fullWidth ? styles.fullWidth : "",
|
|
130
426
|
className,
|
|
131
427
|
isDark ? styles.dark : "",
|
|
428
|
+
!isValid ? styles.error : "", // Add error class if not valid
|
|
132
429
|
]
|
|
133
430
|
.filter(Boolean)
|
|
134
431
|
.join(" ");
|
|
135
432
|
var handleInputChange = function (e) {
|
|
136
433
|
var newValue = e.target.value;
|
|
434
|
+
var isNumeric = type === "number" || type === "tel";
|
|
137
435
|
if (isNumeric) {
|
|
138
|
-
|
|
139
|
-
var parts = newValue.split('.');
|
|
140
|
-
var integerPart = parts[0].replace(/[^0-9-]/g, '');
|
|
141
|
-
var decimalPart = parts.length > 1 ? '.' + parts[1].replace(/[^0-9]/g, '') : '';
|
|
142
|
-
// Ensure only one leading hyphen
|
|
143
|
-
if (integerPart.startsWith('-')) {
|
|
144
|
-
integerPart = '-' + integerPart.substring(1).replace(/-/g, '');
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
integerPart = integerPart.replace(/-/g, '');
|
|
148
|
-
}
|
|
149
|
-
newValue = integerPart + decimalPart;
|
|
150
|
-
// Prevent multiple decimal points
|
|
151
|
-
if (newValue.indexOf('.') !== newValue.lastIndexOf('.')) {
|
|
152
|
-
newValue = newValue.substring(0, newValue.lastIndexOf('.'));
|
|
153
|
-
}
|
|
436
|
+
newValue = filterNumericInput(newValue);
|
|
154
437
|
}
|
|
155
438
|
if (maxLength !== undefined && newValue.length > maxLength)
|
|
156
439
|
return;
|
|
157
440
|
setValue(newValue);
|
|
158
441
|
if (onChange)
|
|
159
442
|
onChange(e);
|
|
160
|
-
|
|
161
|
-
onTextChanged(newValue);
|
|
443
|
+
// onTextChanged is now handled by useParsedAndValidatedInput
|
|
162
444
|
};
|
|
163
|
-
var isPassword = type === "password";
|
|
164
445
|
var isNumeric = type === "number" || type === "tel";
|
|
165
446
|
var inputType = isPassword && isPasswordVisible ? "text" : isNumeric ? "tel" : type;
|
|
166
447
|
var commonProps = __assign({ className: classList, maxLength: maxLength, onChange: handleInputChange, value: value, type: inputType }, rest);
|
|
167
|
-
var showCounter = typeof maxLength === "number";
|
|
168
|
-
var charPercentage = showCounter ? (value.length / maxLength) * 100 : 0;
|
|
169
|
-
var counterColorClass = animatedCounter
|
|
170
|
-
? charPercentage > 90
|
|
171
|
-
? styles.counterOrange
|
|
172
|
-
: charPercentage > 70
|
|
173
|
-
? styles.counterYellow
|
|
174
|
-
: ""
|
|
175
|
-
: "";
|
|
176
448
|
return (jsxRuntime.jsxs("div", { className: styles.wrapper, children: [isMultiline ? ( // Use isMultiline from zest
|
|
177
|
-
jsxRuntime.jsx("textarea", __assign({}, commonProps))) : (jsxRuntime.jsx("input", __assign({}, commonProps))),
|
|
449
|
+
jsxRuntime.jsx("textarea", __assign({}, commonProps))) : (jsxRuntime.jsx("input", __assign({}, commonProps))), jsxRuntime.jsx(HelperTextDisplay, { helperTextNode: finalHelperTextNode, className: (helperTextConfig === null || helperTextConfig === void 0 ? void 0 : helperTextConfig.className) || '' }), jsxRuntime.jsx(CharacterCounter, { showCounter: showCounter, currentLength: currentLength, maxLength: maxLength, counterColorClass: counterColorClass }), jsxRuntime.jsx(PasswordToggleButton, { isPassword: isPassword, isPasswordVisible: isPasswordVisible, onToggle: togglePasswordVisibility }), jsxRuntime.jsx(ProgressBar, { showProgressBar: showProgressBar, showCounter: showCounter, charPercentage: charPercentage, counterColorClass: counterColorClass })] }));
|
|
178
450
|
};
|
|
179
451
|
|
|
180
|
-
|
|
452
|
+
exports.CharacterCounter = CharacterCounter;
|
|
453
|
+
exports.HelperTextDisplay = HelperTextDisplay;
|
|
454
|
+
exports.PasswordToggleButton = PasswordToggleButton;
|
|
455
|
+
exports.ProgressBar = ProgressBar;
|
|
456
|
+
exports.ZestTextbox = ZestTextbox;
|
|
457
|
+
exports.ZestTextboxConfigProvider = ZestTextboxConfigProvider;
|
|
181
458
|
//# sourceMappingURL=index.js.map
|