@rtstic.dev/pulse 0.0.54 → 0.0.56
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/form/book-a-demo.js +679 -2
- package/dist/form/index.js +962 -2
- package/dist/form/index.js.map +2 -2
- package/dist/form/pricing.css +2 -0
- package/dist/form/pricing.js +790 -2
- package/dist/form/styles.css +140 -1
- package/dist/global/accordions-v2.js +262 -1
- package/dist/global/accordions.js +237 -1
- package/dist/global/faqs.js +116 -1
- package/dist/global/loader.js +76 -1
- package/dist/global/styles.css +252 -1
- package/dist/home/depth.js +243 -3
- package/dist/home/hero-animation/loader.js +67810 -1397
- package/dist/home/hero-animation/scroll.js +401 -1
- package/dist/home/hero-animation/styles.css +233 -1
- package/dist/home/hero-animation/torch.js +62 -1
- package/dist/home/horizontal-scroll.css +49 -1
- package/dist/home/horizontal-scroll.js +140 -1
- package/dist/home/tabs-v2.js +134 -1
- package/dist/home/tabs.js +163 -1
- package/dist/lever/styles.css +31 -1
- package/dist/marquee/index.js +557 -2
- package/dist/marquee/styles.css +26 -1
- package/dist/slider/freescroll-cards.js +51 -1
- package/dist/slider/freescroll-slider.js +31 -1
- package/dist/slider/testimonial.js +30 -1
- package/package.json +3 -3
package/dist/marquee/index.js
CHANGED
|
@@ -1,2 +1,557 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
(() => {
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
10
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
11
|
+
}) : x)(function(x) {
|
|
12
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
13
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
14
|
+
});
|
|
15
|
+
var __copyProps = (to, from, except, desc) => {
|
|
16
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
17
|
+
for (let key of __getOwnPropNames(from))
|
|
18
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
19
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
24
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
25
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
26
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
27
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
28
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
29
|
+
mod
|
|
30
|
+
));
|
|
31
|
+
|
|
32
|
+
// src/marquee/index.ts
|
|
33
|
+
console.log("Book a demo form script loaded");
|
|
34
|
+
var VALID_BLOCK_TYPES = [
|
|
35
|
+
"text",
|
|
36
|
+
"email",
|
|
37
|
+
"phone",
|
|
38
|
+
"checkbox",
|
|
39
|
+
"radio",
|
|
40
|
+
"select",
|
|
41
|
+
"legal"
|
|
42
|
+
];
|
|
43
|
+
var VALID_REQUIRED_VALUES = [
|
|
44
|
+
"true",
|
|
45
|
+
"atleast-one",
|
|
46
|
+
"only-one"
|
|
47
|
+
];
|
|
48
|
+
var ERROR_CODES = {
|
|
49
|
+
REQUIRED_INPUT: "ERR_REQUIRED",
|
|
50
|
+
REQUIRED_LEGAL: "ERR_LEGAL_REQUIRED",
|
|
51
|
+
REQUIRED_SELECT: "ERR_SELECT_REQUIRED",
|
|
52
|
+
ATLEAST_ONE: "ERR_ATLEAST_ONE",
|
|
53
|
+
ONLY_ONE_NONE: "ERR_ONLY_ONE_NONE",
|
|
54
|
+
ONLY_ONE_EXCEEDED: "ERR_ONLY_ONE_EXCEEDED",
|
|
55
|
+
INVALID_EMAIL: "ERR_INVALID_EMAIL",
|
|
56
|
+
INVALID_PHONE: "ERR_INVALID_PHONE",
|
|
57
|
+
PHONE_TOO_SHORT: "ERR_PHONE_TOO_SHORT",
|
|
58
|
+
PHONE_TOO_LONG: "ERR_PHONE_TOO_LONG",
|
|
59
|
+
PHONE_INVALID_COUNTRY: "ERR_PHONE_INVALID_COUNTRY"
|
|
60
|
+
};
|
|
61
|
+
var ERROR_MESSAGES = {
|
|
62
|
+
[ERROR_CODES.REQUIRED_INPUT]: "This field is required.",
|
|
63
|
+
[ERROR_CODES.REQUIRED_LEGAL]: "You must accept this to continue.",
|
|
64
|
+
[ERROR_CODES.REQUIRED_SELECT]: "Please select an option.",
|
|
65
|
+
[ERROR_CODES.ATLEAST_ONE]: "Please select at least one option.",
|
|
66
|
+
[ERROR_CODES.ONLY_ONE_NONE]: "Please select one option.",
|
|
67
|
+
[ERROR_CODES.ONLY_ONE_EXCEEDED]: "Only one option can be selected.",
|
|
68
|
+
[ERROR_CODES.INVALID_EMAIL]: "Please enter a valid email address.",
|
|
69
|
+
[ERROR_CODES.INVALID_PHONE]: "Please enter a valid phone number.",
|
|
70
|
+
[ERROR_CODES.PHONE_TOO_SHORT]: "Phone number is too short.",
|
|
71
|
+
[ERROR_CODES.PHONE_TOO_LONG]: "Phone number is too long.",
|
|
72
|
+
[ERROR_CODES.PHONE_INVALID_COUNTRY]: "Invalid country code."
|
|
73
|
+
};
|
|
74
|
+
var ERROR_SPAN_CLASS = "pulse-form-error";
|
|
75
|
+
var itiInstances = /* @__PURE__ */ new Map();
|
|
76
|
+
function fillCountryCodeInput(iti) {
|
|
77
|
+
try {
|
|
78
|
+
const countryData = iti.getSelectedCountryData?.();
|
|
79
|
+
if (!countryData?.dialCode) return;
|
|
80
|
+
const inputs = document.querySelectorAll(
|
|
81
|
+
'input[pulse-form-field="country-code"]'
|
|
82
|
+
);
|
|
83
|
+
inputs.forEach((input) => {
|
|
84
|
+
input.value = `+${countryData.dialCode}`;
|
|
85
|
+
});
|
|
86
|
+
} catch (err) {
|
|
87
|
+
console.warn("[PulseForm] Error filling country code:", err);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function initIntlTelInput() {
|
|
91
|
+
const intlTelInput = window.intlTelInput;
|
|
92
|
+
if (!intlTelInput) {
|
|
93
|
+
console.warn(
|
|
94
|
+
'[PulseForm] intlTelInput not found on window. Make sure you include the intl-tel-input script before this script.\ne.g. <script src="https://cdn.jsdelivr.net/npm/intl-tel-input@25/build/js/intlTelInput.min.js"><\/script>'
|
|
95
|
+
);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const phoneInputs = document.querySelectorAll(
|
|
99
|
+
'[pulse-form-block="phone"] input[type="tel"]'
|
|
100
|
+
);
|
|
101
|
+
phoneInputs.forEach((input) => {
|
|
102
|
+
try {
|
|
103
|
+
const iti = intlTelInput(input, {
|
|
104
|
+
initialCountry: "us",
|
|
105
|
+
separateDialCode: true,
|
|
106
|
+
strictMode: false,
|
|
107
|
+
// @ts-ignore — runtime CDN import, not a TS module
|
|
108
|
+
loadUtils: () => import("https://cdn.jsdelivr.net/npm/intl-tel-input@25/build/js/utils.js")
|
|
109
|
+
});
|
|
110
|
+
itiInstances.set(input, iti);
|
|
111
|
+
fillCountryCodeInput(iti);
|
|
112
|
+
input.addEventListener("countrychange", () => {
|
|
113
|
+
fillCountryCodeInput(iti);
|
|
114
|
+
});
|
|
115
|
+
console.log(
|
|
116
|
+
`[PulseForm] intl-tel-input initialized for "${input.closest("[pulse-form-block]")?.getAttribute("pulse-field-name") || "unknown"}"`
|
|
117
|
+
);
|
|
118
|
+
} catch (err) {
|
|
119
|
+
console.warn("[PulseForm] Failed to init intl-tel-input:", err);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
var PHONE_ITI_ERROR_MAP = {
|
|
124
|
+
0: ERROR_CODES.INVALID_PHONE,
|
|
125
|
+
1: ERROR_CODES.PHONE_INVALID_COUNTRY,
|
|
126
|
+
2: ERROR_CODES.PHONE_TOO_SHORT,
|
|
127
|
+
3: ERROR_CODES.PHONE_TOO_LONG,
|
|
128
|
+
4: ERROR_CODES.INVALID_PHONE
|
|
129
|
+
};
|
|
130
|
+
function validateEmail(value) {
|
|
131
|
+
if (!value) return null;
|
|
132
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
133
|
+
if (!emailRegex.test(value)) {
|
|
134
|
+
return { code: ERROR_CODES.INVALID_EMAIL, message: ERROR_MESSAGES[ERROR_CODES.INVALID_EMAIL] };
|
|
135
|
+
}
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
function validatePhone(input) {
|
|
139
|
+
const value = input.value.trim();
|
|
140
|
+
if (!value) return null;
|
|
141
|
+
const iti = itiInstances.get(input);
|
|
142
|
+
if (iti) {
|
|
143
|
+
try {
|
|
144
|
+
if (iti.isValidNumber()) return null;
|
|
145
|
+
const errorCode = iti.getValidationError?.() ?? 0;
|
|
146
|
+
const code = PHONE_ITI_ERROR_MAP[errorCode] || ERROR_CODES.INVALID_PHONE;
|
|
147
|
+
return { code, message: ERROR_MESSAGES[code] };
|
|
148
|
+
} catch {
|
|
149
|
+
return { code: ERROR_CODES.INVALID_PHONE, message: ERROR_MESSAGES[ERROR_CODES.INVALID_PHONE] };
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
const digits = value.replace(/\D/g, "");
|
|
153
|
+
if (digits.length < 7)
|
|
154
|
+
return { code: ERROR_CODES.PHONE_TOO_SHORT, message: ERROR_MESSAGES[ERROR_CODES.PHONE_TOO_SHORT] };
|
|
155
|
+
if (digits.length > 15)
|
|
156
|
+
return { code: ERROR_CODES.PHONE_TOO_LONG, message: ERROR_MESSAGES[ERROR_CODES.PHONE_TOO_LONG] };
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
function extractTextValue(wrapper) {
|
|
160
|
+
const input = wrapper.querySelector(
|
|
161
|
+
"input, textarea"
|
|
162
|
+
);
|
|
163
|
+
if (!input) return null;
|
|
164
|
+
return input.value.trim();
|
|
165
|
+
}
|
|
166
|
+
function extractEmailValue(wrapper) {
|
|
167
|
+
const input = wrapper.querySelector('input[type="email"]');
|
|
168
|
+
if (!input) return null;
|
|
169
|
+
return input.value.trim();
|
|
170
|
+
}
|
|
171
|
+
function extractPhoneValue(wrapper) {
|
|
172
|
+
const input = wrapper.querySelector('input[type="tel"]');
|
|
173
|
+
if (!input) return null;
|
|
174
|
+
return input.value.trim();
|
|
175
|
+
}
|
|
176
|
+
function extractCheckboxValues(wrapper) {
|
|
177
|
+
const checkboxes = wrapper.querySelectorAll(
|
|
178
|
+
'input[type="checkbox"]'
|
|
179
|
+
);
|
|
180
|
+
const values = [];
|
|
181
|
+
checkboxes.forEach((cb) => {
|
|
182
|
+
if (cb.checked) {
|
|
183
|
+
const name = cb.getAttribute("data-name")?.trim();
|
|
184
|
+
values.push(name || cb.value || "on");
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
return values;
|
|
188
|
+
}
|
|
189
|
+
function extractRadioValue(wrapper) {
|
|
190
|
+
const radios = wrapper.querySelectorAll(
|
|
191
|
+
'input[type="radio"]'
|
|
192
|
+
);
|
|
193
|
+
for (const radio of radios) {
|
|
194
|
+
if (radio.checked) {
|
|
195
|
+
const label = radio.closest("label")?.textContent?.trim();
|
|
196
|
+
return label || radio.value || "on";
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
function extractSelectValue(wrapper) {
|
|
202
|
+
const select = wrapper.querySelector("select");
|
|
203
|
+
if (!select) return null;
|
|
204
|
+
const val = select.value.trim();
|
|
205
|
+
if (!val || select.selectedIndex === 0) return null;
|
|
206
|
+
return val;
|
|
207
|
+
}
|
|
208
|
+
function extractLegalValue(wrapper) {
|
|
209
|
+
const checkbox = wrapper.querySelector(
|
|
210
|
+
'input[type="checkbox"]'
|
|
211
|
+
);
|
|
212
|
+
if (!checkbox) return false;
|
|
213
|
+
return checkbox.checked;
|
|
214
|
+
}
|
|
215
|
+
function extractValue(type, wrapper) {
|
|
216
|
+
switch (type) {
|
|
217
|
+
case "text":
|
|
218
|
+
return extractTextValue(wrapper);
|
|
219
|
+
case "email":
|
|
220
|
+
return extractEmailValue(wrapper);
|
|
221
|
+
case "phone":
|
|
222
|
+
return extractPhoneValue(wrapper);
|
|
223
|
+
case "checkbox":
|
|
224
|
+
return extractCheckboxValues(wrapper);
|
|
225
|
+
case "radio":
|
|
226
|
+
return extractRadioValue(wrapper);
|
|
227
|
+
case "select":
|
|
228
|
+
return extractSelectValue(wrapper);
|
|
229
|
+
case "legal":
|
|
230
|
+
return extractLegalValue(wrapper);
|
|
231
|
+
default:
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
function parseRequired(wrapper) {
|
|
236
|
+
const raw = wrapper.getAttribute("required-selection")?.trim().toLowerCase();
|
|
237
|
+
if (!raw || !VALID_REQUIRED_VALUES.includes(raw))
|
|
238
|
+
return null;
|
|
239
|
+
return raw;
|
|
240
|
+
}
|
|
241
|
+
function parseMirrorValue(wrapper) {
|
|
242
|
+
return wrapper.getAttribute("mirror-value")?.trim().toLowerCase() === "true";
|
|
243
|
+
}
|
|
244
|
+
function getFieldError(type, required, value, wrapper) {
|
|
245
|
+
if (required) {
|
|
246
|
+
switch (required) {
|
|
247
|
+
case "true": {
|
|
248
|
+
if (type === "legal" && value !== true)
|
|
249
|
+
return { code: ERROR_CODES.REQUIRED_LEGAL, message: ERROR_MESSAGES[ERROR_CODES.REQUIRED_LEGAL] };
|
|
250
|
+
if (type === "select" && !value)
|
|
251
|
+
return { code: ERROR_CODES.REQUIRED_SELECT, message: ERROR_MESSAGES[ERROR_CODES.REQUIRED_SELECT] };
|
|
252
|
+
if ((type === "text" || type === "email" || type === "phone") && (!value || typeof value === "string" && value === ""))
|
|
253
|
+
return { code: ERROR_CODES.REQUIRED_INPUT, message: ERROR_MESSAGES[ERROR_CODES.REQUIRED_INPUT] };
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
case "atleast-one": {
|
|
257
|
+
const empty = Array.isArray(value) ? value.length === 0 : !value;
|
|
258
|
+
if (empty)
|
|
259
|
+
return { code: ERROR_CODES.ATLEAST_ONE, message: ERROR_MESSAGES[ERROR_CODES.ATLEAST_ONE] };
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
262
|
+
case "only-one": {
|
|
263
|
+
if (Array.isArray(value)) {
|
|
264
|
+
if (value.length === 0)
|
|
265
|
+
return { code: ERROR_CODES.ONLY_ONE_NONE, message: ERROR_MESSAGES[ERROR_CODES.ONLY_ONE_NONE] };
|
|
266
|
+
if (value.length > 1)
|
|
267
|
+
return { code: ERROR_CODES.ONLY_ONE_EXCEEDED, message: ERROR_MESSAGES[ERROR_CODES.ONLY_ONE_EXCEEDED] };
|
|
268
|
+
} else if (!value) {
|
|
269
|
+
return { code: ERROR_CODES.ONLY_ONE_NONE, message: ERROR_MESSAGES[ERROR_CODES.ONLY_ONE_NONE] };
|
|
270
|
+
}
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
if (type === "email" && typeof value === "string" && value) {
|
|
276
|
+
const emailError = validateEmail(value);
|
|
277
|
+
if (emailError) return emailError;
|
|
278
|
+
}
|
|
279
|
+
if (type === "phone" && typeof value === "string" && value) {
|
|
280
|
+
const phoneInput = wrapper.querySelector('input[type="tel"]');
|
|
281
|
+
if (phoneInput) {
|
|
282
|
+
const phoneError = validatePhone(phoneInput);
|
|
283
|
+
if (phoneError) return phoneError;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
function collectFormFields(withValidation) {
|
|
289
|
+
const wrappers = document.querySelectorAll("[pulse-form-block]");
|
|
290
|
+
const fields = [];
|
|
291
|
+
wrappers.forEach((wrapper) => {
|
|
292
|
+
const rawType = wrapper.getAttribute("pulse-form-block")?.trim().toLowerCase();
|
|
293
|
+
if (!rawType || !VALID_BLOCK_TYPES.includes(rawType))
|
|
294
|
+
return;
|
|
295
|
+
const blockType = rawType;
|
|
296
|
+
const fieldName = wrapper.getAttribute("pulse-field-name")?.trim();
|
|
297
|
+
if (!fieldName) return;
|
|
298
|
+
const required = parseRequired(wrapper);
|
|
299
|
+
const mirrorValue = parseMirrorValue(wrapper);
|
|
300
|
+
const value = extractValue(blockType, wrapper);
|
|
301
|
+
const error = withValidation ? getFieldError(blockType, required, value, wrapper) : null;
|
|
302
|
+
fields.push({
|
|
303
|
+
"form-block": blockType,
|
|
304
|
+
"field-name": fieldName,
|
|
305
|
+
value,
|
|
306
|
+
required,
|
|
307
|
+
"mirror-value": mirrorValue,
|
|
308
|
+
error
|
|
309
|
+
});
|
|
310
|
+
});
|
|
311
|
+
return fields;
|
|
312
|
+
}
|
|
313
|
+
function clearAllErrors() {
|
|
314
|
+
document.querySelectorAll(`.${ERROR_SPAN_CLASS}`).forEach((el) => el.remove());
|
|
315
|
+
document.querySelectorAll("[pulse-form-block]").forEach((el) => el.classList.remove("has-error"));
|
|
316
|
+
}
|
|
317
|
+
function clearErrorOnWrapper(wrapper) {
|
|
318
|
+
const span = wrapper.querySelector(`.${ERROR_SPAN_CLASS}`);
|
|
319
|
+
if (span) span.remove();
|
|
320
|
+
wrapper.classList.remove("has-error");
|
|
321
|
+
}
|
|
322
|
+
function showErrorOnWrapper(wrapper, error) {
|
|
323
|
+
const existing = wrapper.querySelector(`.${ERROR_SPAN_CLASS}`);
|
|
324
|
+
if (existing) existing.remove();
|
|
325
|
+
const span = document.createElement("span");
|
|
326
|
+
span.className = ERROR_SPAN_CLASS;
|
|
327
|
+
span.textContent = error.message;
|
|
328
|
+
span.setAttribute("data-error-code", error.code);
|
|
329
|
+
span.setAttribute(
|
|
330
|
+
"data-field-name",
|
|
331
|
+
wrapper.getAttribute("pulse-field-name")?.trim() || ""
|
|
332
|
+
);
|
|
333
|
+
wrapper.classList.add("has-error");
|
|
334
|
+
wrapper.appendChild(span);
|
|
335
|
+
}
|
|
336
|
+
function renderErrors(fields) {
|
|
337
|
+
clearAllErrors();
|
|
338
|
+
const wrappers = document.querySelectorAll("[pulse-form-block]");
|
|
339
|
+
wrappers.forEach((wrapper) => {
|
|
340
|
+
const fieldName = wrapper.getAttribute("pulse-field-name")?.trim();
|
|
341
|
+
if (!fieldName) return;
|
|
342
|
+
const field = fields.find((f) => f["field-name"] === fieldName);
|
|
343
|
+
if (!field || !field.error) return;
|
|
344
|
+
showErrorOnWrapper(wrapper, field.error);
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
function focusFirstError() {
|
|
348
|
+
const first = document.querySelector(
|
|
349
|
+
`[pulse-form-block].has-error`
|
|
350
|
+
);
|
|
351
|
+
if (!first) return;
|
|
352
|
+
first.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
353
|
+
const focusable = first.querySelector(
|
|
354
|
+
"input, textarea, select"
|
|
355
|
+
);
|
|
356
|
+
if (focusable) setTimeout(() => focusable.focus(), 400);
|
|
357
|
+
}
|
|
358
|
+
function fillMirrorValues() {
|
|
359
|
+
const mirrorFields = _currentFields.filter((f) => f["mirror-value"] === true);
|
|
360
|
+
if (mirrorFields.length === 0) return;
|
|
361
|
+
const mirrorTargets = document.querySelectorAll("[pulse-form-block-mirror]");
|
|
362
|
+
mirrorFields.forEach((field) => {
|
|
363
|
+
const fieldName = field["field-name"];
|
|
364
|
+
let found = false;
|
|
365
|
+
mirrorTargets.forEach((target) => {
|
|
366
|
+
const mirrorAttr = target.getAttribute("pulse-form-block-mirror")?.trim();
|
|
367
|
+
if (mirrorAttr !== fieldName) return;
|
|
368
|
+
found = true;
|
|
369
|
+
const input = target.querySelector(
|
|
370
|
+
"input, textarea, select"
|
|
371
|
+
);
|
|
372
|
+
if (!input) {
|
|
373
|
+
console.warn(
|
|
374
|
+
`[PulseForm] Mirror target for "${fieldName}" found, but no input element inside it.`
|
|
375
|
+
);
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
const value = field.value;
|
|
379
|
+
if (typeof value === "string") {
|
|
380
|
+
input.value = value;
|
|
381
|
+
} else if (typeof value === "boolean") {
|
|
382
|
+
if (input instanceof HTMLInputElement && input.type === "checkbox") {
|
|
383
|
+
input.checked = value;
|
|
384
|
+
} else {
|
|
385
|
+
input.value = String(value);
|
|
386
|
+
}
|
|
387
|
+
} else if (Array.isArray(value)) {
|
|
388
|
+
input.value = value.join(", ");
|
|
389
|
+
} else {
|
|
390
|
+
input.value = "";
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
if (!found) {
|
|
394
|
+
console.warn(
|
|
395
|
+
`[PulseForm] No mirror target found for field "${fieldName}". Add an element with attribute pulse-form-block-mirror="${fieldName}" to mirror this value.`
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
var INDUSTRY_CALENDER_MAP = {
|
|
401
|
+
"Financial Services": "david",
|
|
402
|
+
"Sports": "steven",
|
|
403
|
+
"Beauty": "albany",
|
|
404
|
+
"Music": "steven",
|
|
405
|
+
"Customer Packaged Goods": "david",
|
|
406
|
+
"Other": "david"
|
|
407
|
+
};
|
|
408
|
+
function setWhiteGloveCalender() {
|
|
409
|
+
const industryField = _currentFields.find((f) => f["field-name"] === "industry");
|
|
410
|
+
if (!industryField || typeof industryField.value !== "string" || !industryField.value) return;
|
|
411
|
+
const activePerson = INDUSTRY_CALENDER_MAP[industryField.value];
|
|
412
|
+
const calenderElements = document.querySelectorAll("[hs-calender]");
|
|
413
|
+
calenderElements.forEach((el) => {
|
|
414
|
+
const elCalenderValue = el.getAttribute("hs-calender")?.trim();
|
|
415
|
+
if (activePerson && elCalenderValue === activePerson) {
|
|
416
|
+
el.setAttribute("hs-calender-active", "true");
|
|
417
|
+
} else {
|
|
418
|
+
el.setAttribute("hs-calender-active", "false");
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
function updateFlowType() {
|
|
423
|
+
const flowField = _currentFields.find((f) => f["field-name"] === "flow-type");
|
|
424
|
+
if (!flowField) return;
|
|
425
|
+
const flowValue = flowField.value;
|
|
426
|
+
const flowElements = document.querySelectorAll("[form-flow]");
|
|
427
|
+
flowElements.forEach((el) => {
|
|
428
|
+
const elFlowValue = el.getAttribute("form-flow")?.trim();
|
|
429
|
+
if (elFlowValue === flowValue) {
|
|
430
|
+
el.setAttribute("form-flow-active", "true");
|
|
431
|
+
} else {
|
|
432
|
+
el.setAttribute("form-flow-active", "false");
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
if (flowValue === "White Glove services") {
|
|
436
|
+
setWhiteGloveCalender();
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
var _currentFields = [];
|
|
440
|
+
function updateFieldInState(fieldName, value, error) {
|
|
441
|
+
const idx = _currentFields.findIndex((f) => f["field-name"] === fieldName);
|
|
442
|
+
if (idx === -1) return;
|
|
443
|
+
_currentFields[idx] = { ..._currentFields[idx], value, error };
|
|
444
|
+
window.PulseFormData = _currentFields;
|
|
445
|
+
fillMirrorValues();
|
|
446
|
+
updateFlowType();
|
|
447
|
+
}
|
|
448
|
+
function handleFieldChange(wrapper) {
|
|
449
|
+
const rawType = wrapper.getAttribute("pulse-form-block")?.trim().toLowerCase();
|
|
450
|
+
const fieldName = wrapper.getAttribute("pulse-field-name")?.trim();
|
|
451
|
+
if (!fieldName) return;
|
|
452
|
+
const required = parseRequired(wrapper);
|
|
453
|
+
const value = extractValue(rawType, wrapper);
|
|
454
|
+
const hasError = wrapper.classList.contains("has-error");
|
|
455
|
+
if (hasError) {
|
|
456
|
+
const error = getFieldError(rawType, required, value, wrapper);
|
|
457
|
+
if (!error) {
|
|
458
|
+
clearErrorOnWrapper(wrapper);
|
|
459
|
+
updateFieldInState(fieldName, value, null);
|
|
460
|
+
} else {
|
|
461
|
+
showErrorOnWrapper(wrapper, error);
|
|
462
|
+
updateFieldInState(fieldName, value, error);
|
|
463
|
+
}
|
|
464
|
+
} else {
|
|
465
|
+
updateFieldInState(fieldName, value, null);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
function bindChangeListeners() {
|
|
469
|
+
const wrappers = document.querySelectorAll("[pulse-form-block]");
|
|
470
|
+
wrappers.forEach((wrapper) => {
|
|
471
|
+
const type = wrapper.getAttribute("pulse-form-block")?.trim().toLowerCase();
|
|
472
|
+
if (!type || !VALID_BLOCK_TYPES.includes(type)) return;
|
|
473
|
+
const onChange = () => handleFieldChange(wrapper);
|
|
474
|
+
switch (type) {
|
|
475
|
+
case "text":
|
|
476
|
+
case "email": {
|
|
477
|
+
const input = wrapper.querySelector(
|
|
478
|
+
"input, textarea"
|
|
479
|
+
);
|
|
480
|
+
if (input) {
|
|
481
|
+
input.addEventListener("input", onChange);
|
|
482
|
+
input.addEventListener("change", onChange);
|
|
483
|
+
}
|
|
484
|
+
break;
|
|
485
|
+
}
|
|
486
|
+
case "phone": {
|
|
487
|
+
const phoneInput = wrapper.querySelector('input[type="tel"]');
|
|
488
|
+
if (phoneInput) {
|
|
489
|
+
phoneInput.addEventListener("input", onChange);
|
|
490
|
+
phoneInput.addEventListener("change", onChange);
|
|
491
|
+
phoneInput.addEventListener("keyup", onChange);
|
|
492
|
+
phoneInput.addEventListener("countrychange", onChange);
|
|
493
|
+
}
|
|
494
|
+
break;
|
|
495
|
+
}
|
|
496
|
+
case "checkbox":
|
|
497
|
+
case "legal": {
|
|
498
|
+
wrapper.querySelectorAll('input[type="checkbox"]').forEach((cb) => cb.addEventListener("change", onChange));
|
|
499
|
+
break;
|
|
500
|
+
}
|
|
501
|
+
case "radio": {
|
|
502
|
+
wrapper.querySelectorAll('input[type="radio"]').forEach((r) => r.addEventListener("change", onChange));
|
|
503
|
+
break;
|
|
504
|
+
}
|
|
505
|
+
case "select": {
|
|
506
|
+
const select = wrapper.querySelector("select");
|
|
507
|
+
if (select) select.addEventListener("change", onChange);
|
|
508
|
+
break;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
var PulseForm = {
|
|
514
|
+
get fields() {
|
|
515
|
+
return _currentFields;
|
|
516
|
+
},
|
|
517
|
+
refresh() {
|
|
518
|
+
_currentFields = collectFormFields(false);
|
|
519
|
+
window.PulseFormData = _currentFields;
|
|
520
|
+
fillMirrorValues();
|
|
521
|
+
updateFlowType();
|
|
522
|
+
return _currentFields;
|
|
523
|
+
},
|
|
524
|
+
validate() {
|
|
525
|
+
const fields = collectFormFields(true);
|
|
526
|
+
const isValid = fields.every((f) => f.error === null);
|
|
527
|
+
_currentFields = fields;
|
|
528
|
+
window.PulseFormData = _currentFields;
|
|
529
|
+
fillMirrorValues();
|
|
530
|
+
updateFlowType();
|
|
531
|
+
renderErrors(fields);
|
|
532
|
+
if (!isValid) focusFirstError();
|
|
533
|
+
return { fields, isValid };
|
|
534
|
+
},
|
|
535
|
+
clearErrors() {
|
|
536
|
+
clearAllErrors();
|
|
537
|
+
_currentFields = _currentFields.map((f) => ({ ...f, error: null }));
|
|
538
|
+
window.PulseFormData = _currentFields;
|
|
539
|
+
fillMirrorValues();
|
|
540
|
+
updateFlowType();
|
|
541
|
+
},
|
|
542
|
+
ERROR_CODES,
|
|
543
|
+
ERROR_MESSAGES
|
|
544
|
+
};
|
|
545
|
+
document.addEventListener("DOMContentLoaded", () => {
|
|
546
|
+
const count = document.querySelectorAll("[pulse-form-block]").length;
|
|
547
|
+
console.log(`[PulseForm] Initialized \u2014 found ${count} form blocks.`);
|
|
548
|
+
initIntlTelInput();
|
|
549
|
+
_currentFields = collectFormFields(false);
|
|
550
|
+
window.PulseFormData = _currentFields;
|
|
551
|
+
fillMirrorValues();
|
|
552
|
+
updateFlowType();
|
|
553
|
+
bindChangeListeners();
|
|
554
|
+
window.PulseForm = PulseForm;
|
|
555
|
+
});
|
|
556
|
+
})();
|
|
557
|
+
//# sourceMappingURL=index.js.map
|
package/dist/marquee/styles.css
CHANGED
|
@@ -1 +1,26 @@
|
|
|
1
|
-
|
|
1
|
+
/* src/marquee/styles.css */
|
|
2
|
+
[rtstic-marquee=wrapper] {
|
|
3
|
+
overflow: hidden;
|
|
4
|
+
}
|
|
5
|
+
[rtstic-marquee=list] {
|
|
6
|
+
display: flex;
|
|
7
|
+
width: max-content;
|
|
8
|
+
animation: scroll var(--duration) linear infinite;
|
|
9
|
+
will-change: transform;
|
|
10
|
+
}
|
|
11
|
+
[rtstic-marquee=item] {
|
|
12
|
+
white-space: nowrap;
|
|
13
|
+
flex-shrink: 0;
|
|
14
|
+
}
|
|
15
|
+
@keyframes scroll {
|
|
16
|
+
0% {
|
|
17
|
+
transform: translateX(0);
|
|
18
|
+
}
|
|
19
|
+
100% {
|
|
20
|
+
transform: translateX(calc(-100% / var(--multiplier)));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
[rtstic-marquee=wrapper]:hover [rtstic-marquee=list] {
|
|
24
|
+
animation-play-state: paused;
|
|
25
|
+
}
|
|
26
|
+
/*# sourceMappingURL=styles.css.map */
|
|
@@ -1 +1,51 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
(() => {
|
|
3
|
+
// src/slider/freescroll-cards.ts
|
|
4
|
+
document.addEventListener("DOMContentLoaded", () => {
|
|
5
|
+
if (typeof window === "undefined" || typeof window.Swiper === "undefined") {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
const enableFreeMode = window.innerWidth >= 992;
|
|
9
|
+
const initSlider = (selector, breakpoints) => {
|
|
10
|
+
const sliderEl = document.querySelector(selector);
|
|
11
|
+
if (!sliderEl) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
new window.Swiper(sliderEl, {
|
|
15
|
+
spaceBetween: 20,
|
|
16
|
+
loop: false,
|
|
17
|
+
freeMode: enableFreeMode,
|
|
18
|
+
mousewheel: enableFreeMode ? {
|
|
19
|
+
forceToAxis: true,
|
|
20
|
+
sensitivity: 1
|
|
21
|
+
} : false,
|
|
22
|
+
breakpoints
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
initSlider("[pulse-slider='scrolling-cards']", {
|
|
26
|
+
992: { slidesPerView: 2.5 },
|
|
27
|
+
// desktop
|
|
28
|
+
768: { slidesPerView: 1.5 },
|
|
29
|
+
// tablet
|
|
30
|
+
0: { slidesPerView: 1.2 }
|
|
31
|
+
// mobile
|
|
32
|
+
});
|
|
33
|
+
initSlider("[pulse-slider='scrolling-cards-2']", {
|
|
34
|
+
992: { slidesPerView: 3 },
|
|
35
|
+
// desktop
|
|
36
|
+
768: { slidesPerView: 2.5 },
|
|
37
|
+
// tablet
|
|
38
|
+
0: { slidesPerView: 1.2 }
|
|
39
|
+
// mobile
|
|
40
|
+
});
|
|
41
|
+
initSlider("[pulse-slider='scrolling-cards-3']", {
|
|
42
|
+
992: { slidesPerView: 4 },
|
|
43
|
+
// desktop
|
|
44
|
+
768: { slidesPerView: 3 },
|
|
45
|
+
// tablet
|
|
46
|
+
0: { slidesPerView: 2.1 }
|
|
47
|
+
// mobile
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
})();
|
|
51
|
+
//# sourceMappingURL=freescroll-cards.js.map
|