@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.
@@ -22,13 +22,13 @@ jobs:
22
22
  runs-on: ubuntu-latest
23
23
  steps:
24
24
  - name: Checkout
25
- uses: actions/checkout@v3
25
+ uses: actions/checkout@v4
26
26
  - name: Setup Node.js
27
- uses: actions/setup-node@v3
27
+ uses: actions/setup-node@v4
28
28
  with:
29
- node-version: 14
29
+ node-version: 22 # Required for the latest semantic-release plugins
30
30
  - name: Semantic Release
31
- uses: cycjimmy/semantic-release-action@v3
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.GITHUB }}"
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.0",
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
- // Convert special string '$now' to current date
207
+ const inputType = (element.getAttribute("type") || element.type || "").toLowerCase();
208
+ let date;
201
209
  if (value === "$now") {
202
- value = new Date();
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
- // Initialize a new Date from the string or object
205
- value = new Date(value);
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
- value = new Date();
230
+ console.warn("Provided date is invalid:", value);
231
+ return "";
208
232
  }
209
233
 
210
- // Check if value is a valid date
211
- if (value instanceof Date && !isNaN(value.getTime())) {
212
- // Default behavior if no specific valueType provided
213
- if (!valueType) {
214
- value = value.toISOString();
215
- }
216
-
217
- // Format for 'time' type elements
218
- if (element.type === "time" && !valueType) {
219
- value = value.substring(11, 19) + "Z";
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
- if (valueType) {
223
- switch (valueType) {
224
- case "getDayName":
225
- const days = [
226
- "Sunday",
227
- "Monday",
228
- "Tuesday",
229
- "Wednesday",
230
- "Thursday",
231
- "Friday",
232
- "Saturday"
233
- ];
234
- value = days[value.getDay()];
235
- break;
236
- case "getMonthName":
237
- const months = [
238
- "January",
239
- "February",
240
- "March",
241
- "April",
242
- "May",
243
- "June",
244
- "July",
245
- "August",
246
- "September",
247
- "October",
248
- "November",
249
- "December"
250
- ];
251
- value = months[value.getMonth()];
252
- break;
253
- case "toUnixTimestamp":
254
- value = Math.floor(value.getTime() / 1000);
255
- break;
256
- case "toLocaleString":
257
- let locale = element.getAttribute("locale") || "en-US";
258
- value = value.toLocaleString(locale);
259
- break;
260
- case "addDays":
261
- // Add days to the current date
262
- const addDays = parseInt(element.getAttribute("add-days") || 0, 10);
263
- value.setDate(value.getDate() + addDays);
264
- value = value.toISOString();
265
- break;
266
- case "subtractDays":
267
- // Subtract days from the current date
268
- const subtractDays = parseInt(element.getAttribute("subtract-days") || 0, 10);
269
- value.setDate(value.getDate() - subtractDays);
270
- value = value.toISOString();
271
- break;
272
- case "startOfDay":
273
- // Get the start of the current day (12:00 midnight)
274
- const startOfDay = new Date(value);
275
- startOfDay.setHours(0, 0, 0, 0); // Set time to midnight
276
- value = startOfDay.toISOString();
277
- break;
278
- case "startOfWeek":
279
- // Get the start of the current week (Sunday by default)
280
- const startOfWeekOffset = parseInt(element.getAttribute("week-start-day") || 0, 10); // Default to Sunday (0)
281
- const startOfWeek = new Date(value);
282
- startOfWeek.setDate(value.getDate() - value.getDay() + startOfWeekOffset);
283
- startOfWeek.setHours(0, 0, 0, 0); // Set to midnight
284
- value = startOfWeek.toISOString();
285
- break;
286
- case "endOfWeek":
287
- // Get the end of the current week (Saturday by default)
288
- const endOfWeekOffset = parseInt(element.getAttribute("week-start-day") || 0, 10); // Default to Sunday (0)
289
- const endOfWeek = new Date(value);
290
- endOfWeek.setDate(value.getDate() - value.getDay() + 6 + endOfWeekOffset);
291
- endOfWeek.setHours(23, 59, 59, 999); // Set to the end of the day
292
- value = endOfWeek.toISOString();
293
- break;
294
- case "startOfMonth":
295
- // Get the start of the month
296
- value = new Date(value.getFullYear(), value.getMonth(), 1).toISOString();
297
- break;
298
- case "endOfMonth":
299
- // Get the end of the month
300
- value = new Date(value.getFullYear(), value.getMonth() + 1, 0).toISOString();
301
- break;
302
- case "startOfYear":
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
- default:
313
- if (typeof value[valueType] === "function") {
314
- value = value[valueType]();
315
- } else {
316
- console.warn(
317
- `The method ${valueType} is not a function of Date object.`
318
- );
319
- }
320
- break;
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
- if (value) {
23
- const date = new Date(value);
24
- if (el.type === "time") {
25
- // Format time as "HH:MM"
26
- const hours = String(date.getHours()).padStart(2, "0");
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, "");