@t007/input 0.0.23 → 0.0.24
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 +64 -2
- package/dist/index.css +6 -4
- package/dist/index.d.ts +20 -51
- package/dist/index.global.js +141 -155
- package/dist/index.js +96 -124
- package/dist/react.d.ts +139 -0
- package/dist/react.js +255 -0
- package/package.json +22 -2
package/dist/index.global.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
(() => {
|
|
3
|
-
//
|
|
3
|
+
// ../../../sia-reactor/dist/chunk-RVYL3OLW.js
|
|
4
4
|
function createEl(tag, props, dataset, styles, el = tag ? document?.createElement(tag) : null) {
|
|
5
5
|
return assignEl(el, props, dataset, styles), el;
|
|
6
6
|
}
|
|
@@ -17,7 +17,21 @@
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
//
|
|
20
|
+
// ../../../sia-reactor/dist/chunk-EZ4VRGYI.js
|
|
21
|
+
var CTX = {
|
|
22
|
+
/** Flag indicating whether the application is running in development mode. */
|
|
23
|
+
isDevEnv: "undefined" !== typeof process ? process.env.NODE_ENV !== "production" : true,
|
|
24
|
+
/** Flag indicating whether a cascade is currently ongoing so reactors can allow all writes. */
|
|
25
|
+
isCascading: false,
|
|
26
|
+
/** Active `Autotracker` instance, override for automatic dependency collection on `Reactor` traps. */
|
|
27
|
+
autotracker: null
|
|
28
|
+
};
|
|
29
|
+
var RTR_BATCH = "undefined" !== typeof window ? ("undefined" !== typeof queueMicrotask ? queueMicrotask : setTimeout).bind(window) : "undefined" !== typeof process && process.nextTick ? process.nextTick : setTimeout;
|
|
30
|
+
var RTR_LOG = console.log.bind(console, "[S.I.A Reactor]");
|
|
31
|
+
var NIL = Object.freeze({});
|
|
32
|
+
|
|
33
|
+
// ../utils/dist/chunk-XVFFZZJA.js
|
|
34
|
+
var INTERACTIVE_SELECTOR = 'button,[href],input,label,select,textarea,details>summary,[contenteditable],iframe,audio[controls],video[controls],[tabindex]:not([tabindex="-1"])';
|
|
21
35
|
var VIRTUAL_RESOURCE = /* @__PURE__ */ Symbol.for("T007_VIRTUAL_RESOURCE");
|
|
22
36
|
function loadResource(req, type = "style", { module, media, crossOrigin, integrity, referrerPolicy, nonce, fetchPriority, attempts = 3, retryKey = false } = {}, w = window) {
|
|
23
37
|
w.t007 ??= {}, w.t007._resourceCache ??= {};
|
|
@@ -64,9 +78,28 @@
|
|
|
64
78
|
return src1.replace(/\\/g, "/").split("?")[0].trim() === src2.replace(/\\/g, "/").split("?")[0].trim();
|
|
65
79
|
}
|
|
66
80
|
}
|
|
67
|
-
function
|
|
68
|
-
|
|
69
|
-
|
|
81
|
+
function formatSize(bytes, decimals = 3, base = 1e3) {
|
|
82
|
+
if (bytes < base) return `${bytes} byte${bytes == 1 ? "" : "s"}`;
|
|
83
|
+
const units = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"], exponent = Math.min(Math.floor(Math.log(bytes) / Math.log(base)), units.length - 1);
|
|
84
|
+
return `${(bytes / Math.pow(base, exponent)).toFixed(decimals).replace(/\.0+$/, "")} ${units[exponent]}`;
|
|
85
|
+
}
|
|
86
|
+
if ("undefined" !== typeof window) {
|
|
87
|
+
(window.t007 ??= {}).VIRTUAL_RESOURCE = VIRTUAL_RESOURCE;
|
|
88
|
+
window.T007_TOAST_JS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/toast@latest`;
|
|
89
|
+
window.T007_INPUT_JS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/input@latest`;
|
|
90
|
+
window.T007_DIALOG_JS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/dialog@latest`;
|
|
91
|
+
window.T007_TOAST_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/toast@latest/dist/index.min.css`;
|
|
92
|
+
window.T007_INPUT_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/input@latest/dist/index.min.css`;
|
|
93
|
+
window.T007_DIALOG_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/dialog@latest/dist/index.min.css`;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// ../utils/dist/hooks/vanilla.js
|
|
97
|
+
function initScrollAssist(el, { pxPerSecond = 80, assistClassName = "t007-scroll-assist", vertical = true, horizontal = true } = NIL) {
|
|
98
|
+
const parent = el?.parentElement, existing = (t007._scrollers ??= /* @__PURE__ */ new WeakMap()).get(el);
|
|
99
|
+
if (!parent || existing) return existing ? existing : void 0;
|
|
100
|
+
t007._scroller_r_observer ??= new ResizeObserver((entries) => {
|
|
101
|
+
for (const { target } of entries) t007._scrollers.get(target)?.update();
|
|
102
|
+
});
|
|
70
103
|
t007._scroller_m_observer ??= new MutationObserver((entries) => {
|
|
71
104
|
const els = /* @__PURE__ */ new Set();
|
|
72
105
|
for (const entry of entries) {
|
|
@@ -76,12 +109,10 @@
|
|
|
76
109
|
}
|
|
77
110
|
for (const el2 of els) t007._scrollers.get(el2)?.update();
|
|
78
111
|
});
|
|
79
|
-
const parent = el?.parentElement;
|
|
80
|
-
if (!parent || t007._scrollers.has(el)) return;
|
|
81
112
|
const assist = {};
|
|
82
113
|
let scrollId = null, last = performance.now(), assistWidth = 20, assistHeight = 20;
|
|
83
114
|
const update = () => {
|
|
84
|
-
const hasInteractive = !!parent.querySelector(
|
|
115
|
+
const hasInteractive = !!parent.querySelector(INTERACTIVE_SELECTOR);
|
|
85
116
|
if (horizontal) {
|
|
86
117
|
const w = assist.left?.offsetWidth || assistWidth, check = hasInteractive ? el.clientWidth < w * 2 : false;
|
|
87
118
|
assist.left.style.display = check ? "none" : el.scrollLeft > 0 ? "block" : "none";
|
|
@@ -113,93 +144,92 @@
|
|
|
113
144
|
const addAssist = (dir) => {
|
|
114
145
|
const div = createEl("div", { className: assistClassName }, { scrollDirection: dir }, { display: "none" });
|
|
115
146
|
if (!div) return;
|
|
116
|
-
["pointerenter", "dragenter"]
|
|
117
|
-
["pointerleave", "pointerup", "pointercancel", "dragleave", "dragend"]
|
|
147
|
+
for (const evt of ["pointerenter", "dragenter"]) div.addEventListener(evt, () => scroll(dir));
|
|
148
|
+
for (const evt of ["pointerleave", "pointerup", "pointercancel", "dragleave", "dragend"]) div.addEventListener(evt, stop);
|
|
118
149
|
dir === "left" || dir === "up" ? parent.insertBefore(div, el) : parent.append(div);
|
|
119
150
|
assist[dir] = div;
|
|
120
151
|
};
|
|
121
|
-
if (horizontal) ["left", "right"]
|
|
122
|
-
if (vertical) ["up", "down"]
|
|
123
|
-
|
|
124
|
-
t007._scroller_r_observer.observe(el);
|
|
125
|
-
t007._scroller_m_observer.observe(el, { childList: true, subtree: true, characterData: true });
|
|
126
|
-
t007._scrollers.set(el, {
|
|
152
|
+
if (horizontal) for (const dir of ["left", "right"]) addAssist(dir);
|
|
153
|
+
if (vertical) for (const dir of ["up", "down"]) addAssist(dir);
|
|
154
|
+
const handle = {
|
|
127
155
|
update,
|
|
128
156
|
destroy() {
|
|
129
|
-
stop();
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
t007._scrollers.delete(el);
|
|
133
|
-
Object.values(assist).forEach((a) => a.remove());
|
|
157
|
+
stop(), el.removeEventListener("scroll", update);
|
|
158
|
+
t007._scroller_r_observer.unobserve(el), t007._scrollers.delete(el);
|
|
159
|
+
for (const a of Object.values(assist)) a.remove();
|
|
134
160
|
}
|
|
135
|
-
}
|
|
136
|
-
|
|
161
|
+
};
|
|
162
|
+
update(), el.addEventListener("scroll", update);
|
|
163
|
+
t007._scroller_r_observer.observe(el), t007._scroller_m_observer.observe(el, { childList: true, subtree: true, characterData: true });
|
|
164
|
+
return t007._scrollers.set(el, handle), handle;
|
|
137
165
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
166
|
+
|
|
167
|
+
// src/ts/utils/consts.ts
|
|
168
|
+
var violationKeys = ["valueMissing", "typeMismatch", "patternMismatch", "stepMismatch", "tooShort", "tooLong", "rangeUnderflow", "rangeOverflow", "badInput", "customError"];
|
|
169
|
+
var dateTypes = ["date", "time", "datetime-local", "month"];
|
|
170
|
+
var nativeIconTypes = [...dateTypes];
|
|
171
|
+
|
|
172
|
+
// src/ts/utils/fn.ts
|
|
173
|
+
function getStrengthLevel(value, minLength = 0) {
|
|
174
|
+
value = value.trim();
|
|
175
|
+
let level = 0;
|
|
176
|
+
if (value.length < minLength) level = 1;
|
|
177
|
+
else {
|
|
178
|
+
if (/[a-z]/.test(value)) level++;
|
|
179
|
+
if (/[A-Z]/.test(value)) level++;
|
|
180
|
+
if (/[0-9]/.test(value)) level++;
|
|
181
|
+
if (/[\W_]/.test(value)) level++;
|
|
182
|
+
}
|
|
183
|
+
return Math.min(level, 4);
|
|
184
|
+
}
|
|
185
|
+
function getFilesHelper(files, opts) {
|
|
186
|
+
if (!files || !files.length) return { violation: null, message: "" };
|
|
187
|
+
const totalFiles = files.length;
|
|
188
|
+
let totalSize = 0, currFiles = 0;
|
|
189
|
+
const setMaxError = (size, max, n = 0) => ({ violation: "rangeOverflow", message: n ? `File ${files.length > 1 ? n : ""} size of ${formatSize(size)} exceeds the per file maximum of ${formatSize(max)}` : `Total files size of ${formatSize(size)} exceeds the total maximum of ${formatSize(max)}` });
|
|
190
|
+
const setMinError = (size, min, n = 0) => ({ violation: "rangeUnderflow", message: n ? `File ${files.length > 1 ? n : ""} size of ${formatSize(size)} is less than the per file minimum of ${formatSize(min)}` : `Total files size of ${formatSize(size)} is less than the total minimum of ${formatSize(min)}` });
|
|
191
|
+
for (const file of files) {
|
|
192
|
+
currFiles++;
|
|
193
|
+
totalSize += file.size;
|
|
194
|
+
if (opts.accept) {
|
|
195
|
+
const acceptedTypes = opts.accept.split(",").map((type) => type.trim().replace(/^[*\.]+|[*\.]+$/g, "")).filter(Boolean) || [];
|
|
196
|
+
if (!acceptedTypes.some((type) => file.type.includes(type))) return { violation: "typeMismatch", message: `File${currFiles > 1 ? currFiles : ""} type of '${file.type}' is not accepted.` };
|
|
197
|
+
}
|
|
198
|
+
if (opts.maxSize && file.size > opts.maxSize) return setMaxError(file.size, opts.maxSize, currFiles);
|
|
199
|
+
if (opts.minSize && file.size < opts.minSize) return setMinError(file.size, opts.minSize, currFiles);
|
|
200
|
+
if (opts.multiple) {
|
|
201
|
+
if (opts.maxTotalSize && totalSize > opts.maxTotalSize) return setMaxError(totalSize, opts.maxTotalSize);
|
|
202
|
+
if (opts.minTotalSize && totalSize < opts.minTotalSize) return setMinError(totalSize, opts.minTotalSize);
|
|
203
|
+
if (opts.maxLength && totalFiles > opts.maxLength) return { violation: "tooLong", message: `Selected ${totalFiles} files exceeds the maximum of ${opts.maxLength} allowed file${opts.maxLength == 1 ? "" : "s"}` };
|
|
204
|
+
if (opts.minLength && totalFiles < opts.minLength) return { violation: "tooShort", message: `Selected ${totalFiles} files is less than the minimum of ${opts.minLength} allowed file${opts.minLength == 1 ? "" : "s"}` };
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return { violation: null, message: "" };
|
|
147
208
|
}
|
|
148
209
|
|
|
149
|
-
// src/index.js
|
|
210
|
+
// src/js/index.js
|
|
150
211
|
var formManager = {
|
|
151
212
|
forms: document.getElementsByClassName("t007-input-form"),
|
|
152
|
-
violationKeys
|
|
213
|
+
violationKeys,
|
|
153
214
|
init() {
|
|
154
|
-
t007.FM.observeDOMForFields();
|
|
155
|
-
Array.from(t007.FM.forms).forEach(t007.FM.handleFormValidation);
|
|
215
|
+
t007.FM.observeDOMForFields(), Array.prototype.forEach.call(t007.FM.forms, t007.FM.handleFormValidation);
|
|
156
216
|
},
|
|
157
217
|
observeDOMForFields() {
|
|
158
218
|
new MutationObserver((mutations) => {
|
|
159
|
-
for (const mutation of mutations)
|
|
219
|
+
for (const mutation of mutations)
|
|
160
220
|
for (const node of mutation.addedNodes) {
|
|
161
|
-
if (!node.tagName || !(node
|
|
221
|
+
if (!node.tagName || !(node.classList.contains("t007-input-field") || node.querySelector(".t007-input-field"))) continue;
|
|
162
222
|
for (const field2 of [...node.querySelector(".t007-input-field") ? node.querySelectorAll(".t007-input-field") : [node]]) t007.FM.setUpField(field2);
|
|
163
223
|
}
|
|
164
|
-
}
|
|
165
224
|
}).observe(document.body, { childList: true, subtree: true });
|
|
166
225
|
},
|
|
167
|
-
getFilesHelper(files, opts)
|
|
168
|
-
|
|
169
|
-
const totalFiles = files.length;
|
|
170
|
-
let totalSize = 0;
|
|
171
|
-
let currFiles = 0;
|
|
172
|
-
const setMaxError = (size, max, n = 0) => ({ violation: "rangeOverflow", message: n ? `File ${files.length > 1 ? n : ""} size of ${t007.FM.formatSize(size)} exceeds the per file maximum of ${t007.FM.formatSize(max)}` : `Total files size of ${t007.FM.formatSize(size)} exceeds the total maximum of ${t007.FM.formatSize(max)}` });
|
|
173
|
-
const setMinError = (size, min, n = 0) => ({ violation: "rangeUnderflow", message: n ? `File ${files.length > 1 ? n : ""} size of ${t007.FM.formatSize(size)} is less than the per file minimum of ${t007.FM.formatSize(min)}` : `Total files size of ${t007.FM.formatSize(size)} is less than the total minimum of ${t007.FM.formatSize(min)}` });
|
|
174
|
-
for (const file of files) {
|
|
175
|
-
currFiles++;
|
|
176
|
-
totalSize += file.size;
|
|
177
|
-
if (opts.accept) {
|
|
178
|
-
const acceptedTypes = opts.accept.split(",").map((type) => type.trim().replace(/^[*\.]+|[*\.]+$/g, "")).filter(Boolean) || [];
|
|
179
|
-
if (!acceptedTypes.some((type) => file.type.includes(type))) return { violation: "typeMismatch", message: `File${currFiles > 1 ? currFiles : ""} type of '${file.type}' is not accepted.` };
|
|
180
|
-
}
|
|
181
|
-
if (opts.maxSize && file.size > opts.maxSize) return setMaxError(file.size, opts.maxSize, currFiles);
|
|
182
|
-
if (opts.minSize && file.size < opts.minSize) return setMinError(file.size, opts.minSize, currFiles);
|
|
183
|
-
if (opts.multiple) {
|
|
184
|
-
if (opts.maxTotalSize && totalSize > opts.maxTotalSize) return setMaxError(totalSize, opts.maxTotalSize);
|
|
185
|
-
if (opts.minTotalSize && totalSize < opts.minTotalSize) return setMinError(totalSize, opts.minTotalSize);
|
|
186
|
-
if (opts.maxLength && totalFiles > opts.maxLength) return { violation: "tooLong", message: `Selected ${totalFiles} files exceeds the maximum of ${opts.maxLength} allowed file${opts.maxLength == 1 ? "" : "s"}` };
|
|
187
|
-
if (opts.minLength && totalFiles < opts.minLength) return { violation: "tooShort", message: `Selected ${totalFiles} files is less than the minimum of ${opts.minLength} allowed file${opts.minLength == 1 ? "" : "s"}` };
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
return { violation: null, message: "" };
|
|
191
|
-
},
|
|
192
|
-
formatSize(size, decimals = 3, base = 1e3) {
|
|
193
|
-
if (size < base) return `${size} byte${size == 1 ? "" : "s"}`;
|
|
194
|
-
const units = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"], exponent = Math.min(Math.floor(Math.log(size) / Math.log(base)), units.length - 1);
|
|
195
|
-
return `${(size / Math.pow(base, exponent)).toFixed(decimals).replace(/\.0+$/, "")} ${units[exponent]}`;
|
|
196
|
-
},
|
|
226
|
+
getFilesHelper: (files, opts) => getFilesHelper(files, opts),
|
|
227
|
+
formatSize: (size, decimals = 3, base = 1e3) => formatSize(size, decimals, base),
|
|
197
228
|
togglePasswordType: (input) => input.type = input.type === "password" ? "text" : "password",
|
|
198
229
|
toggleFilled: (input) => input?.toggleAttribute("data-filled", input.type === "checkbox" || input.type === "radio" ? input.checked : input.value !== "" || input.files?.length > 0),
|
|
199
230
|
setFallbackHelper(field2) {
|
|
200
231
|
const helperTextWrapper = field2?.querySelector(".t007-input-helper-text-wrapper");
|
|
201
|
-
|
|
202
|
-
helperTextWrapper.append(createEl("p", { className: "t007-input-helper-text" }, { violation: "auto" }));
|
|
232
|
+
!helperTextWrapper?.querySelector(".t007-input-helper-text[data-violation='auto']") && helperTextWrapper?.append(createEl("p", { className: "t007-input-helper-text" }, { violation: "auto" }));
|
|
203
233
|
},
|
|
204
234
|
setFieldListeners(field2) {
|
|
205
235
|
if (!field2) return;
|
|
@@ -207,36 +237,22 @@
|
|
|
207
237
|
if (input.type === "file")
|
|
208
238
|
input.addEventListener("input", async () => {
|
|
209
239
|
const file = input.files?.[0], img = new Image();
|
|
210
|
-
img.onload = () => {
|
|
211
|
-
|
|
212
|
-
input.classList.add("t007-input-image-selected");
|
|
213
|
-
setTimeout(() => URL.revokeObjectURL(src), 1e3);
|
|
214
|
-
};
|
|
215
|
-
img.onerror = () => {
|
|
216
|
-
input.style.removeProperty("--t007-input-image-src");
|
|
217
|
-
input.classList.remove("t007-input-image-selected");
|
|
218
|
-
URL.revokeObjectURL(src);
|
|
219
|
-
};
|
|
240
|
+
img.onload = () => (input.style.setProperty("--t007-input-image-src", `url(${src})`), input.classList.add("t007-input-image-selected"), setTimeout(() => URL.revokeObjectURL(src), 1e3));
|
|
241
|
+
img.onerror = () => (input.style.removeProperty("--t007-input-image-src"), input.classList.remove("t007-input-image-selected"), URL.revokeObjectURL(src));
|
|
220
242
|
let src;
|
|
221
243
|
if (file?.type?.startsWith("image")) src = URL.createObjectURL(file);
|
|
222
|
-
else if (file?.type?.startsWith("video"))
|
|
244
|
+
else if (file?.type?.startsWith("video"))
|
|
223
245
|
src = await new Promise((resolve) => {
|
|
224
246
|
let video = createEl("video"), canvas = createEl("canvas"), context = canvas.getContext("2d");
|
|
225
247
|
video.ontimeupdate = () => {
|
|
226
248
|
context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
|
|
227
|
-
canvas.toBlob((blob) => resolve(URL.createObjectURL(blob)));
|
|
228
|
-
URL.revokeObjectURL(video.src);
|
|
249
|
+
canvas.toBlob((blob) => resolve(URL.createObjectURL(blob))), URL.revokeObjectURL(video.src);
|
|
229
250
|
video = video.src = video.onloadedmetadata = video.ontimeupdate = null;
|
|
230
251
|
};
|
|
231
252
|
video.onloadeddata = () => video.currentTime = 3;
|
|
232
253
|
video.src = URL.createObjectURL(file);
|
|
233
254
|
});
|
|
234
|
-
|
|
235
|
-
if (!src) {
|
|
236
|
-
input.style.removeProperty("--t007-input-image-src");
|
|
237
|
-
input.classList.remove("t007-input-image-selected");
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
255
|
+
if (!src) return input.style.removeProperty("--t007-input-image-src"), input.classList.remove("t007-input-image-selected");
|
|
240
256
|
img.src = src;
|
|
241
257
|
});
|
|
242
258
|
if (floatingLabel) floatingLabel.ontransitionend = () => floatingLabel.classList.remove("t007-input-shake");
|
|
@@ -245,9 +261,7 @@
|
|
|
245
261
|
},
|
|
246
262
|
setUpField(field2) {
|
|
247
263
|
if (field2.dataset.setUp) return;
|
|
248
|
-
t007.FM.toggleFilled(field2.querySelector(".t007-input"));
|
|
249
|
-
t007.FM.setFallbackHelper(field2);
|
|
250
|
-
t007.FM.setFieldListeners(field2);
|
|
264
|
+
t007.FM.toggleFilled(field2.querySelector(".t007-input")), t007.FM.setFallbackHelper(field2), t007.FM.setFieldListeners(field2);
|
|
251
265
|
field2.dataset.setUp = "true";
|
|
252
266
|
},
|
|
253
267
|
field({ isWrapper = false, label = "", type = "text", placeholder = "", custom = "", minSize, maxSize, minTotalSize, maxTotalSize, options = [], indeterminate = false, eyeToggler = true, passwordMeter = true, helperText = {}, className = "", fieldClassName = "", children, startIcon = "", endIcon = "", nativeIcon = "", passwordVisibleIcon = "", passwordHiddenIcon = "", ...otherProps }) {
|
|
@@ -281,19 +295,18 @@
|
|
|
281
295
|
if (maxTotalSize) inputEl.setAttribute("maxtotalsize", maxTotalSize);
|
|
282
296
|
Object.keys(otherProps).forEach((key) => inputEl[key] = otherProps[key]);
|
|
283
297
|
labelEl.append(!isWrapper ? inputEl : children);
|
|
284
|
-
|
|
285
|
-
if (nativeTypes.includes(type) && nativeIcon) labelEl.append(createEl("i", { className: "t007-input-icon t007-input-native-icon", innerHTML: nativeIcon }));
|
|
298
|
+
if (nativeIconTypes.includes(type) && nativeIcon) labelEl.append(createEl("i", { className: "t007-input-icon t007-input-native-icon", innerHTML: nativeIcon }));
|
|
286
299
|
else if (endIcon) labelEl.append(createEl("i", { className: "t007-input-icon", innerHTML: endIcon }));
|
|
287
|
-
if (type === "password" && eyeToggler)
|
|
288
|
-
labelEl.append(
|
|
289
|
-
|
|
290
|
-
|
|
300
|
+
if (type === "password" && eyeToggler)
|
|
301
|
+
labelEl.append(
|
|
302
|
+
createEl("i", { role: "button", ariaLabel: "Show password", className: "t007-input-icon t007-input-password-visible-icon", innerHTML: passwordVisibleIcon || `<svg width="24" height="24"><path fill="rgba(0,0,0,.54)" d="M12 16q1.875 0 3.188-1.312Q16.5 13.375 16.5 11.5q0-1.875-1.312-3.188Q13.875 7 12 7q-1.875 0-3.188 1.312Q7.5 9.625 7.5 11.5q0 1.875 1.312 3.188Q10.125 16 12 16Zm0-1.8q-1.125 0-1.912-.788Q9.3 12.625 9.3 11.5t.788-1.913Q10.875 8.8 12 8.8t1.913.787q.787.788.787 1.913t-.787 1.912q-.788.788-1.913.788Zm0 4.8q-3.65 0-6.65-2.038-3-2.037-4.35-5.462 1.35-3.425 4.35-5.463Q8.35 4 12 4q3.65 0 6.65 2.037 3 2.038 4.35 5.463-1.35 3.425-4.35 5.462Q15.65 19 12 19Z"/></svg>` }),
|
|
303
|
+
createEl("i", { role: "button", ariaLabel: "Hide password", className: "t007-input-icon t007-input-password-hidden-icon", innerHTML: passwordHiddenIcon || `<svg width="24" height="24"><path fill="rgba(0,0,0,.54)" d="m19.8 22.6-4.2-4.15q-.875.275-1.762.413Q12.95 19 12 19q-3.775 0-6.725-2.087Q2.325 14.825 1 11.5q.525-1.325 1.325-2.463Q3.125 7.9 4.15 7L1.4 4.2l1.4-1.4 18.4 18.4ZM12 16q.275 0 .512-.025.238-.025.513-.1l-5.4-5.4q-.075.275-.1.513-.025.237-.025.512 0 1.875 1.312 3.188Q10.125 16 12 16Zm7.3.45-3.175-3.15q.175-.425.275-.862.1-.438.1-.938 0-1.875-1.312-3.188Q13.875 7 12 7q-.5 0-.938.1-.437.1-.862.3L7.65 4.85q1.025-.425 2.1-.638Q10.825 4 12 4q3.775 0 6.725 2.087Q21.675 8.175 23 11.5q-.575 1.475-1.512 2.738Q20.55 15.5 19.3 16.45Zm-4.625-4.6-3-3q.7-.125 1.288.112.587.238 1.012.688.425.45.613 1.038.187.587.087 1.162Z"/></svg>` })
|
|
304
|
+
);
|
|
291
305
|
if (helperText !== false) {
|
|
292
306
|
const helperLine = createEl("div", { className: "t007-input-helper-line" }), helperWrapper = createEl("div", { className: "t007-input-helper-text-wrapper", tabIndex: "-1" });
|
|
293
307
|
if (helperText.info) helperWrapper.append(createEl("p", { className: "t007-input-helper-text", textContent: helperText.info }, { violation: "none" }));
|
|
294
|
-
t007.FM
|
|
295
|
-
helperLine.append(helperWrapper);
|
|
296
|
-
field2.append(helperLine);
|
|
308
|
+
t007.FM.violationKeys?.forEach((key) => helperText[key] && helperWrapper.append(createEl("p", { className: "t007-input-helper-text", textContent: helperText[key] }, { violation: key })));
|
|
309
|
+
helperLine.append(helperWrapper), field2.append(helperLine);
|
|
297
310
|
}
|
|
298
311
|
if (passwordMeter && type === "password") {
|
|
299
312
|
const meter = createEl("div", { className: "t007-input-password-meter" }, { strengthLevel: "1" });
|
|
@@ -315,36 +328,26 @@
|
|
|
315
328
|
form.validateOnClient = validateFormOnClient;
|
|
316
329
|
form.toggleGlobalError = toggleFormGlobalError;
|
|
317
330
|
const fields = form.getElementsByClassName("t007-input-field"), inputs = form.getElementsByClassName("t007-input");
|
|
318
|
-
Array.
|
|
319
|
-
form.addEventListener("input", ({ target }) =>
|
|
320
|
-
t007.FM.toggleFilled(target);
|
|
321
|
-
validateInput(target);
|
|
322
|
-
});
|
|
331
|
+
Array.prototype.forEach.call(fields, t007.FM.setUpField);
|
|
332
|
+
form.addEventListener("input", ({ target }) => (t007.FM.toggleFilled(target), validateInput(target)));
|
|
323
333
|
form.addEventListener("focusout", ({ target }) => validateInput(target, true));
|
|
324
334
|
form.addEventListener("submit", async (e) => {
|
|
325
|
-
|
|
335
|
+
form.classList.toggle("t007-input-submit-loading", true);
|
|
326
336
|
try {
|
|
327
337
|
e.preventDefault();
|
|
328
338
|
if (!validateFormOnClient()) return;
|
|
329
|
-
if (form.validateOnServer && !await form.validateOnServer()) {
|
|
330
|
-
|
|
331
|
-
form.addEventListener("input", () => toggleFormGlobalError(false), { once: true, useCapture: true });
|
|
332
|
-
return;
|
|
333
|
-
}
|
|
334
|
-
form.onSubmit ? form.onSubmit() : form.submit();
|
|
339
|
+
if (form.validateOnServer && !await form.validateOnServer()) return toggleFormGlobalError(true), form.addEventListener("input", () => toggleFormGlobalError(false), { once: true, useCapture: true });
|
|
340
|
+
form.onSubmit ? form.onSubmit(e) : form.submit();
|
|
335
341
|
} catch (error) {
|
|
336
342
|
console.error(error);
|
|
337
343
|
}
|
|
338
|
-
|
|
344
|
+
form.classList.toggle("t007-input-submit-loading", false);
|
|
339
345
|
});
|
|
340
|
-
function toggleSubmitLoader(bool) {
|
|
341
|
-
form.classList.toggle("t007-input-submit-loading", bool);
|
|
342
|
-
}
|
|
343
346
|
function toggleError(input, bool, flag = false) {
|
|
344
347
|
const field2 = input.closest(".t007-input-field"), floatingLabel = field2.querySelector(".t007-input-floating-label");
|
|
345
348
|
if (bool && flag) {
|
|
346
349
|
input.setAttribute("data-error", "");
|
|
347
|
-
floatingLabel?.classList.add("t007-input-shake");
|
|
350
|
+
floatingLabel?.classList.add("t007-input-shake"), setTimeout(() => floatingLabel?.classList.remove("t007-input-shake"), 520);
|
|
348
351
|
} else if (!bool) input.removeAttribute("data-error");
|
|
349
352
|
toggleHelper(input, input.hasAttribute("data-error"));
|
|
350
353
|
}
|
|
@@ -352,28 +355,11 @@
|
|
|
352
355
|
const field2 = input.closest(".t007-input-field"), violation = t007.FM.violationKeys.find((violation2) => input.Validity?.[violation2] || input.validity[violation2]) ?? "", helper = field2.querySelector(`.t007-input-helper-text[data-violation="${violation}"]`), fallbackHelper = field2.querySelector(`.t007-input-helper-text[data-violation="auto"]`);
|
|
353
356
|
input.closest(".t007-input-field").querySelectorAll(`.t007-input-helper-text:not([data-violation="${violation}"])`).forEach((helper2) => helper2?.classList.remove("t007-input-show"));
|
|
354
357
|
if (helper) helper.classList.toggle("t007-input-show", bool);
|
|
355
|
-
else if (fallbackHelper)
|
|
356
|
-
fallbackHelper.textContent = input.validationMessage;
|
|
357
|
-
fallbackHelper.classList.toggle("t007-input-show", bool);
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
function forceRevalidate(input) {
|
|
361
|
-
input.checkValidity();
|
|
362
|
-
input.dispatchEvent(new Event("input"));
|
|
358
|
+
else if (fallbackHelper) fallbackHelper.textContent = input.validationMessage, fallbackHelper.classList.toggle("t007-input-show", bool);
|
|
363
359
|
}
|
|
364
360
|
function updatePasswordMeter(input) {
|
|
365
361
|
const passwordMeter = input.closest(".t007-input-field").querySelector(".t007-input-password-meter");
|
|
366
|
-
if (
|
|
367
|
-
const value = input.value?.trim();
|
|
368
|
-
let strengthLevel = 0;
|
|
369
|
-
if (value.length < Number(input.minLength ?? 0)) strengthLevel = 1;
|
|
370
|
-
else {
|
|
371
|
-
if (/[a-z]/.test(value)) strengthLevel++;
|
|
372
|
-
if (/[A-Z]/.test(value)) strengthLevel++;
|
|
373
|
-
if (/[0-9]/.test(value)) strengthLevel++;
|
|
374
|
-
if (/[\W_]/.test(value)) strengthLevel++;
|
|
375
|
-
}
|
|
376
|
-
passwordMeter.dataset.strengthLevel = strengthLevel;
|
|
362
|
+
if (passwordMeter) passwordMeter.dataset.strengthLevel = `${getStrengthLevel(input.value, Number(input.minLength ?? 0))}`;
|
|
377
363
|
}
|
|
378
364
|
function validateInput(input, flag = false) {
|
|
379
365
|
if (form.dataset.globalError || !input?.classList.contains("t007-input")) return;
|
|
@@ -383,7 +369,7 @@
|
|
|
383
369
|
case "password":
|
|
384
370
|
value = input.value?.trim();
|
|
385
371
|
if (value === "") break;
|
|
386
|
-
const confirmPasswordInput = Array.
|
|
372
|
+
const confirmPasswordInput = Array.prototype.find.call(inputs, (input2) => (input2.custom ?? input2.getAttribute("custom")) === "confirm-password");
|
|
387
373
|
if (!confirmPasswordInput) break;
|
|
388
374
|
const confirmPasswordValue = confirmPasswordInput.value?.trim();
|
|
389
375
|
confirmPasswordInput.setCustomValidity(value !== confirmPasswordValue ? "Both passwords do not match" : "");
|
|
@@ -392,7 +378,7 @@
|
|
|
392
378
|
case "confirm_password":
|
|
393
379
|
value = input.value?.trim();
|
|
394
380
|
if (value === "") break;
|
|
395
|
-
const passwordInput = Array.
|
|
381
|
+
const passwordInput = Array.prototype.find.call(inputs, (input2) => (input2.custom ?? input2.getAttribute("custom")) === "password");
|
|
396
382
|
if (!passwordInput) break;
|
|
397
383
|
const passwordValue = passwordInput.value?.trim();
|
|
398
384
|
errorBool = value !== passwordValue;
|
|
@@ -401,21 +387,17 @@
|
|
|
401
387
|
case "onward_date":
|
|
402
388
|
if (input.min) break;
|
|
403
389
|
input.min = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
404
|
-
|
|
390
|
+
input.checkValidity(), input.dispatchEvent(new Event("input"));
|
|
391
|
+
break;
|
|
392
|
+
case "past_date":
|
|
393
|
+
if (input.max) break;
|
|
394
|
+
input.max = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
395
|
+
input.checkValidity(), input.dispatchEvent(new Event("input"));
|
|
405
396
|
break;
|
|
406
397
|
}
|
|
407
398
|
if (input.type === "file") {
|
|
408
399
|
input.Validity = {};
|
|
409
|
-
const { violation, message } = t007.FM.getFilesHelper(input.files ?? [], {
|
|
410
|
-
accept: input.accept,
|
|
411
|
-
multiple: input.multiple,
|
|
412
|
-
maxSize: input.maxSize ?? Number(input.getAttribute("maxsize")),
|
|
413
|
-
minSize: input.minSize ?? Number(input.getAttribute("minsize")),
|
|
414
|
-
maxTotalSize: input.maxTotalSize ?? Number(input.getAttribute("maxtotalsize")),
|
|
415
|
-
minTotalSize: input.minTotalSize ?? Number(input.getAttribute("mintotalsize")),
|
|
416
|
-
maxLength: input.maxLength ?? Number(input.getAttribute("maxlength")),
|
|
417
|
-
minLength: input.minLength ?? Number(input.getAttribute("minLength"))
|
|
418
|
-
});
|
|
400
|
+
const { violation, message } = t007.FM.getFilesHelper(input.files ?? [], { accept: input.accept, multiple: input.multiple, maxSize: input.maxSize ?? Number(input.getAttribute("maxsize")), minSize: input.minSize ?? Number(input.getAttribute("minsize")), maxTotalSize: input.maxTotalSize ?? Number(input.getAttribute("maxtotalsize")), minTotalSize: input.minTotalSize ?? Number(input.getAttribute("mintotalsize")), maxLength: input.maxLength ?? Number(input.getAttribute("maxlength")), minLength: input.minLength ?? Number(input.getAttribute("minLength")) });
|
|
419
401
|
errorBool = !!message;
|
|
420
402
|
input.setCustomValidity(message);
|
|
421
403
|
if (violation) input.Validity[violation] = true;
|
|
@@ -424,18 +406,22 @@
|
|
|
424
406
|
toggleError(input, errorBool, flag);
|
|
425
407
|
if (errorBool) return;
|
|
426
408
|
if (input.type === "radio")
|
|
427
|
-
Array.
|
|
409
|
+
Array.prototype.forEach.call(
|
|
410
|
+
Array.prototype.filter.call(inputs, (i) => i.name == input.name),
|
|
411
|
+
(radio) => toggleError(radio, errorBool, flag)
|
|
412
|
+
);
|
|
428
413
|
}
|
|
429
414
|
function validateFormOnClient() {
|
|
430
|
-
Array.
|
|
415
|
+
Array.prototype.forEach.call(inputs, (input) => validateInput(input, true));
|
|
431
416
|
form.querySelector("input:invalid")?.focus();
|
|
432
|
-
return Array.
|
|
417
|
+
return Array.prototype.every.call(inputs, (input) => input.checkValidity());
|
|
433
418
|
}
|
|
434
419
|
function toggleFormGlobalError(bool) {
|
|
435
420
|
form.toggleAttribute("data-global-error", bool);
|
|
436
421
|
form.querySelectorAll(".t007-input-field").forEach((field2) => {
|
|
437
422
|
field2.querySelector(".t007-input")?.toggleAttribute("data-error", bool);
|
|
438
|
-
|
|
423
|
+
const floatingLabel = field2.querySelector(".t007-input-floating-label");
|
|
424
|
+
floatingLabel?.classList.toggle("t007-input-shake", bool), bool && setTimeout(() => floatingLabel?.classList.remove("t007-input-shake"), 520);
|
|
439
425
|
});
|
|
440
426
|
}
|
|
441
427
|
}
|