@cocreate/element-prototype 1.31.0 → 1.31.1
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/.github/workflows/automated.yml +5 -6
- package/CHANGELOG.md +8 -0
- package/package.json +1 -1
- package/src/getValue.js +159 -118
- package/src/setValue.js +36 -21
|
@@ -22,13 +22,13 @@ jobs:
|
|
|
22
22
|
runs-on: ubuntu-latest
|
|
23
23
|
steps:
|
|
24
24
|
- name: Checkout
|
|
25
|
-
uses: actions/checkout@
|
|
25
|
+
uses: actions/checkout@v4
|
|
26
26
|
- name: Setup Node.js
|
|
27
|
-
uses: actions/setup-node@
|
|
27
|
+
uses: actions/setup-node@v4
|
|
28
28
|
with:
|
|
29
|
-
node-version:
|
|
29
|
+
node-version: 22 # Required for the latest semantic-release plugins
|
|
30
30
|
- name: Semantic Release
|
|
31
|
-
uses: cycjimmy/semantic-release-action@
|
|
31
|
+
uses: cycjimmy/semantic-release-action@v4 # Update to v4 for better Node 20+ support
|
|
32
32
|
id: semantic
|
|
33
33
|
with:
|
|
34
34
|
extra_plugins: |
|
|
@@ -36,9 +36,8 @@ jobs:
|
|
|
36
36
|
@semantic-release/git
|
|
37
37
|
@semantic-release/github
|
|
38
38
|
env:
|
|
39
|
-
GITHUB_TOKEN: "${{ secrets.
|
|
39
|
+
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" # Use the built-in token if possible
|
|
40
40
|
NPM_TOKEN: "${{ secrets.NPM_TOKEN }}"
|
|
41
41
|
outputs:
|
|
42
42
|
new_release_published: "${{ steps.semantic.outputs.new_release_published }}"
|
|
43
43
|
new_release_version: "${{ steps.semantic.outputs.new_release_version }}"
|
|
44
|
-
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## [1.31.1](https://github.com/CoCreate-app/CoCreate-element-prototype/compare/v1.31.0...v1.31.1) (2026-01-18)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* improved handling of type ([afd4027](https://github.com/CoCreate-app/CoCreate-element-prototype/commit/afd40271d6c299736ed13ff90a3ca1f98b5f0449))
|
|
7
|
+
* update worklow ([636b355](https://github.com/CoCreate-app/CoCreate-element-prototype/commit/636b35571bb11a30ba0310c65e3ecaf07e977476))
|
|
8
|
+
|
|
1
9
|
# [1.31.0](https://github.com/CoCreate-app/CoCreate-element-prototype/compare/v1.30.0...v1.31.0) (2025-11-16)
|
|
2
10
|
|
|
3
11
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cocreate/element-prototype",
|
|
3
|
-
"version": "1.31.
|
|
3
|
+
"version": "1.31.1",
|
|
4
4
|
"description": "A simple element-prototype component in vanilla javascript. Easily configured using HTML5 data-attributes and/or JavaScript API.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"element-prototype",
|
package/src/getValue.js
CHANGED
|
@@ -43,7 +43,8 @@ const getValue = (element, valueType) => {
|
|
|
43
43
|
let suffix = element.getAttribute("value-suffix") || "";
|
|
44
44
|
|
|
45
45
|
// Determine elementType using type first, fallback to tagName (both lowercase and uppercase respectively)
|
|
46
|
-
const elementType = element.type ? element.type.toLowerCase() : null;
|
|
46
|
+
// const elementType = element.type ? element.type.toLowerCase() : null;
|
|
47
|
+
const elementType = element.getAttribute("type") || element.type
|
|
47
48
|
const tagName = element.tagName.toUpperCase();
|
|
48
49
|
|
|
49
50
|
// Switch statement to handle different element types and tagNames
|
|
@@ -196,134 +197,174 @@ const handleCheckbox = (element, prefix = "", suffix = "") => {
|
|
|
196
197
|
* @param {string} valueType - Specifies the type of transformation to apply to the date/time value.
|
|
197
198
|
* @returns {any} - The transformed or processed date/time value.
|
|
198
199
|
*/
|
|
200
|
+
/**
|
|
201
|
+
* Handles and transforms a date/time value with a 3-step pipeline:
|
|
202
|
+
* 1. SNAP: Adjusts date to start/end of periods (Month, Week, Year).
|
|
203
|
+
* 2. MATH: Adds/Subtracts Years, Months, Weeks, Days, Hours, Minutes, Seconds.
|
|
204
|
+
* 3. FORMAT: Returns the final string/number representation.
|
|
205
|
+
*/
|
|
199
206
|
const handleDateTime = (element, value, valueType) => {
|
|
200
|
-
|
|
207
|
+
const inputType = (element.getAttribute("type") || element.type || "").toLowerCase();
|
|
208
|
+
let date;
|
|
201
209
|
if (value === "$now") {
|
|
202
|
-
|
|
210
|
+
date = new Date();
|
|
211
|
+
} else if (value instanceof Date) {
|
|
212
|
+
// If it's already a date object, clone it to avoid mutating references
|
|
213
|
+
date = new Date(value.getTime());
|
|
203
214
|
} else if (value) {
|
|
204
|
-
|
|
205
|
-
|
|
215
|
+
if (
|
|
216
|
+
typeof value === "string" &&
|
|
217
|
+
/^\d{4}-\d{2}-\d{2}(?:[ T]\d{2}:\d{2}(?::\d{2}(?:\.\d{3})?)?(?:Z|[+-]\d{2}:?\d{2})?)?$/.test(
|
|
218
|
+
value
|
|
219
|
+
)
|
|
220
|
+
) {
|
|
221
|
+
// Normalize datetime-local only when seconds are absent; preserve provided seconds.
|
|
222
|
+
if (inputType === "datetime-local" && /^[0-9T:-]{16}$/.test(value)) {
|
|
223
|
+
value = `${value}:00`;
|
|
224
|
+
}
|
|
225
|
+
date = new Date(value);
|
|
226
|
+
} else {
|
|
227
|
+
date = new Date(value);
|
|
228
|
+
}
|
|
206
229
|
} else {
|
|
207
|
-
|
|
230
|
+
console.warn("Provided date is invalid:", value);
|
|
231
|
+
return "";
|
|
208
232
|
}
|
|
209
233
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
234
|
+
if (date instanceof Date && !isNaN(date.getTime())) {
|
|
235
|
+
// These operations "floor" or "ceil" the date to a specific boundary.
|
|
236
|
+
switch (valueType) {
|
|
237
|
+
case "startOfDay":
|
|
238
|
+
date.setHours(0, 0, 0, 0);
|
|
239
|
+
break;
|
|
240
|
+
case "startOfWeek":
|
|
241
|
+
const startWkOff = parseInt(
|
|
242
|
+
element.getAttribute("week-start-day") || 0,
|
|
243
|
+
10
|
|
244
|
+
);
|
|
245
|
+
date.setDate(date.getDate() - date.getDay() + startWkOff);
|
|
246
|
+
date.setHours(0, 0, 0, 0);
|
|
247
|
+
break;
|
|
248
|
+
case "endOfWeek":
|
|
249
|
+
const endWkOff = parseInt(
|
|
250
|
+
element.getAttribute("week-start-day") || 0,
|
|
251
|
+
10
|
|
252
|
+
);
|
|
253
|
+
date.setDate(date.getDate() - date.getDay() + 6 + endWkOff);
|
|
254
|
+
date.setHours(23, 59, 59, 999);
|
|
255
|
+
break;
|
|
256
|
+
case "startOfMonth":
|
|
257
|
+
date.setDate(1);
|
|
258
|
+
date.setHours(0, 0, 0, 0);
|
|
259
|
+
break;
|
|
260
|
+
case "endOfMonth":
|
|
261
|
+
date.setMonth(date.getMonth() + 1, 0);
|
|
262
|
+
date.setHours(23, 59, 59, 999);
|
|
263
|
+
break;
|
|
264
|
+
case "startOfYear":
|
|
265
|
+
date.setMonth(0, 1);
|
|
266
|
+
date.setHours(0, 0, 0, 0);
|
|
267
|
+
break;
|
|
268
|
+
case "endOfYear":
|
|
269
|
+
date.setMonth(11, 31);
|
|
270
|
+
date.setHours(23, 59, 59, 999);
|
|
271
|
+
break;
|
|
220
272
|
}
|
|
221
273
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
// Get the start of the year
|
|
304
|
-
value = new Date(value.getFullYear(), 0, 1).toISOString();
|
|
305
|
-
break;
|
|
306
|
-
case "endOfYear":
|
|
307
|
-
// Get the end of the year
|
|
308
|
-
value = new Date(value.getFullYear(), 11, 31).toISOString();
|
|
309
|
-
break;
|
|
310
|
-
|
|
274
|
+
// --- PHASE 3: MATH (Modify the Date)
|
|
275
|
+
// Helper to get integer value from attribute safely
|
|
276
|
+
const getVal = (attr) =>
|
|
277
|
+
parseInt(element.getAttribute(attr) || "0", 10);
|
|
278
|
+
|
|
279
|
+
// 1. Years
|
|
280
|
+
const addYears = getVal("add-years") - getVal("subtract-years");
|
|
281
|
+
if (addYears) date.setFullYear(date.getFullYear() + addYears);
|
|
282
|
+
|
|
283
|
+
// 2. Months
|
|
284
|
+
const addMonths = getVal("add-months") - getVal("subtract-months");
|
|
285
|
+
if (addMonths) date.setMonth(date.getMonth() + addMonths);
|
|
286
|
+
|
|
287
|
+
// 3. Weeks
|
|
288
|
+
const addWeeks = getVal("add-weeks") - getVal("subtract-weeks");
|
|
289
|
+
if (addWeeks) date.setDate(date.getDate() + addWeeks * 7);
|
|
290
|
+
|
|
291
|
+
// 4. Days
|
|
292
|
+
const addDays = getVal("add-days") - getVal("subtract-days");
|
|
293
|
+
if (addDays) date.setDate(date.getDate() + addDays);
|
|
294
|
+
|
|
295
|
+
// 5. Hours
|
|
296
|
+
const addHours = getVal("add-hours") - getVal("subtract-hours");
|
|
297
|
+
if (addHours) date.setHours(date.getHours() + addHours);
|
|
298
|
+
|
|
299
|
+
// 6. Minutes
|
|
300
|
+
const addMinutes = getVal("add-minutes") - getVal("subtract-minutes");
|
|
301
|
+
if (addMinutes) date.setMinutes(date.getMinutes() + addMinutes);
|
|
302
|
+
|
|
303
|
+
// 7. Seconds
|
|
304
|
+
const addSeconds = getVal("add-seconds") - getVal("subtract-seconds");
|
|
305
|
+
if (addSeconds) date.setSeconds(date.getSeconds() + addSeconds);
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
// --- PHASE 4: FORMATTING (Output the Result) ---
|
|
309
|
+
switch (valueType) {
|
|
310
|
+
case "getDayName":
|
|
311
|
+
const days = [
|
|
312
|
+
"Sunday",
|
|
313
|
+
"Monday",
|
|
314
|
+
"Tuesday",
|
|
315
|
+
"Wednesday",
|
|
316
|
+
"Thursday",
|
|
317
|
+
"Friday",
|
|
318
|
+
"Saturday",
|
|
319
|
+
];
|
|
320
|
+
return days[date.getDay()];
|
|
321
|
+
|
|
322
|
+
case "getMonthName":
|
|
323
|
+
const months = [
|
|
324
|
+
"January",
|
|
325
|
+
"February",
|
|
326
|
+
"March",
|
|
327
|
+
"April",
|
|
328
|
+
"May",
|
|
329
|
+
"June",
|
|
330
|
+
"July",
|
|
331
|
+
"August",
|
|
332
|
+
"September",
|
|
333
|
+
"October",
|
|
334
|
+
"November",
|
|
335
|
+
"December",
|
|
336
|
+
];
|
|
337
|
+
return months[date.getMonth()];
|
|
338
|
+
|
|
339
|
+
case "getYear":
|
|
340
|
+
case "getFullYear":
|
|
341
|
+
return date.getFullYear();
|
|
342
|
+
|
|
343
|
+
case "toUnixTimestamp":
|
|
344
|
+
return Math.floor(date.getTime() / 1000);
|
|
345
|
+
|
|
346
|
+
case "toLocaleString":
|
|
347
|
+
const locale = element.getAttribute("locale") || "en-US";
|
|
348
|
+
return date.toLocaleString(locale);
|
|
349
|
+
|
|
350
|
+
default:
|
|
351
|
+
// Handle generic methods if specified
|
|
352
|
+
if (valueType && typeof date[valueType] === "function") {
|
|
353
|
+
return date[valueType]();
|
|
354
|
+
}
|
|
311
355
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
)
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
|
|
356
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
357
|
+
if (inputType === "datetime-local") {
|
|
358
|
+
// Return a datetime-local compatible string with seconds to avoid invalid values
|
|
359
|
+
return `${date.getFullYear()}-${pad(
|
|
360
|
+
date.getMonth() + 1
|
|
361
|
+
)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(
|
|
362
|
+
date.getMinutes()
|
|
363
|
+
)}:${pad(date.getSeconds())}`;
|
|
364
|
+
}
|
|
365
|
+
return date.toISOString();
|
|
322
366
|
}
|
|
323
|
-
} else {
|
|
324
|
-
console.warn("Provided date is invalid or could not be parsed:", value);
|
|
325
367
|
}
|
|
326
|
-
return value;
|
|
327
368
|
};
|
|
328
369
|
|
|
329
370
|
/**
|
package/src/setValue.js
CHANGED
|
@@ -18,29 +18,44 @@ const setValue = (el, value, dispatch) => {
|
|
|
18
18
|
return storage.set(el, value);
|
|
19
19
|
else if (typeof value === "object") value = JSON.stringify(value, null, 2);
|
|
20
20
|
|
|
21
|
-
if (["time", "datetime", "datetime-local"].includes(el.type)) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
28
|
-
el.value = `${hours}:${minutes}`;
|
|
29
|
-
} else if (el.type === "datetime-local") {
|
|
30
|
-
// Format datetime-local as "YYYY-MM-DDTHH:MM"
|
|
31
|
-
const year = date.getFullYear();
|
|
32
|
-
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
33
|
-
const day = String(date.getDate()).padStart(2, "0");
|
|
34
|
-
const hours = String(date.getHours()).padStart(2, "0");
|
|
35
|
-
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
36
|
-
el.value = `${year}-${month}-${day}T${hours}:${minutes}`;
|
|
21
|
+
if (["date", "time", "datetime", "datetime-local"].includes(el.getAttribute("type") || el.type )) {
|
|
22
|
+
if (value) {
|
|
23
|
+
const date = new Date(value);
|
|
24
|
+
// If 'use-utc' is present, we shift the time forward by the timezone offset.
|
|
25
|
+
if (el.hasAttribute("use-utc")) {
|
|
26
|
+
date.setMinutes(date.getMinutes() + date.getTimezoneOffset());
|
|
37
27
|
}
|
|
38
|
-
} else {
|
|
39
|
-
el.value = "";
|
|
40
|
-
}
|
|
41
|
-
return dispatchEvents(el, bubbles, dispatch);
|
|
42
|
-
}
|
|
43
28
|
|
|
29
|
+
if (el.tagName === "INPUT") {
|
|
30
|
+
if (!isNaN(date.getTime())) {
|
|
31
|
+
// We no longer need ternary operators or if/else blocks here.
|
|
32
|
+
const year = date.getFullYear();
|
|
33
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
34
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
35
|
+
const hours = String(date.getHours()).padStart(2, "0");
|
|
36
|
+
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
37
|
+
|
|
38
|
+
// 5. Set Value
|
|
39
|
+
if (el.type === "time") {
|
|
40
|
+
el.value = `${hours}:${minutes}`;
|
|
41
|
+
} else if (el.type === "date") {
|
|
42
|
+
el.value = `${year}-${month}-${day}`;
|
|
43
|
+
} else {
|
|
44
|
+
el.value = `${year}-${month}-${day}T${hours}:${minutes}`;
|
|
45
|
+
}
|
|
46
|
+
} else {
|
|
47
|
+
console.warn(`Invalid date for input ${el.name}:`, value);
|
|
48
|
+
el.value = "";
|
|
49
|
+
}
|
|
50
|
+
return dispatchEvents(el, bubbles, dispatch);
|
|
51
|
+
} else if (!isNaN(date.getTime())) {
|
|
52
|
+
value = date.toLocaleString()
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
el.value = "";
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
44
59
|
let valueType = el.getAttribute("value-type");
|
|
45
60
|
let prefix = el.getAttribute("value-prefix") || "";
|
|
46
61
|
if (prefix) value = value.toString().replace(prefix, "");
|