@aurodesignsystem-dev/auro-datetime 0.0.0-pr112.3 → 0.0.0-pr112.4

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.
@@ -109,7 +109,7 @@
109
109
  }
110
110
  }
111
111
  ],
112
- "description": "Creates a Date that shows the given wall-clock time when displayed in\nthe given IANA time zone. `_resolveInputDate` uses it when `value` has\nno offset and `timezone` is set, so the time is read as already being\nin that zone rather than the viewer's.\n\nIt parses the wall-clock time as if it were UTC, asks `Intl` what that\nmoment looks like in the target zone, and uses the difference between\nthe two to find the real moment.",
112
+ "description": "Creates a Date that shows the given wall-clock time when displayed in\nthe given IANA time zone. `_resolveInputDate` uses it when `value` has\nno offset and `timezone` is set, so the time is read as already being\nin that zone rather than the viewer's.\n\nOn a daylight saving change, a time the clocks skip moves forward by\nthe gap, and a time the clocks repeat resolves to its first occurrence.\nThis is the same rule JavaScript uses for local times.",
113
113
  "privacy": "private",
114
114
  "return": {
115
115
  "type": {
@@ -117,6 +117,33 @@
117
117
  }
118
118
  }
119
119
  },
120
+ {
121
+ "kind": "method",
122
+ "name": "_zoneOffsetMs",
123
+ "parameters": [
124
+ {
125
+ "name": "utcMs",
126
+ "description": "The moment, in milliseconds since the epoch.",
127
+ "type": {
128
+ "text": "number"
129
+ }
130
+ },
131
+ {
132
+ "name": "timeZone",
133
+ "description": "The IANA time zone name, such as `America/New_York`.",
134
+ "type": {
135
+ "text": "string"
136
+ }
137
+ }
138
+ ],
139
+ "description": "Gets the time zone's offset from UTC at a moment, in milliseconds, such as `-14400000` for New York in summer.",
140
+ "privacy": "private",
141
+ "return": {
142
+ "type": {
143
+ "text": "number"
144
+ }
145
+ }
146
+ },
120
147
  {
121
148
  "kind": "method",
122
149
  "name": "humanDate",
@@ -217,7 +244,7 @@
217
244
  "type": {
218
245
  "text": "string"
219
246
  },
220
- "description": "Sets the time zone to show the date or time in, such as `America/Los_Angeles` or `UTC` (an IANA time zone name). When `value` has an offset or `Z`, the element converts that moment into this zone; when it has none, the element reads `value` as a time already in this zone. Without it, or with an invalid name, which logs a console warning, the element shows the date and time in `value` as written, or the current date and time in the viewer's own time zone when `value` isn't set.",
247
+ "description": "Sets the time zone to show the date or time in, such as `America/Los_Angeles` or `UTC` (an IANA time zone name). When `value` has an offset or `Z`, the element converts that moment into this zone; when it has none, the element reads `value` as a time already in this zone. Without it, or with an invalid name, which logs a console warning, the element shows the date and time in `value` as written, or the current date and time in the viewer's own time zone when `value` isn't set. When a `value` with no offset names a time the clocks skip when they spring forward, it shows later by the length of the skip, usually one hour, so `2022-03-13T02:30:00` in `America/New_York` shows \"3:30 am\".",
221
248
  "attribute": "timezone",
222
249
  "category": "behavior"
223
250
  },
@@ -293,7 +320,7 @@
293
320
  "type": {
294
321
  "text": "string"
295
322
  },
296
- "description": "Sets the time zone to show the date or time in, such as `America/Los_Angeles` or `UTC` (an IANA time zone name). When `value` has an offset or `Z`, the element converts that moment into this zone; when it has none, the element reads `value` as a time already in this zone. Without it, or with an invalid name, which logs a console warning, the element shows the date and time in `value` as written, or the current date and time in the viewer's own time zone when `value` isn't set.",
323
+ "description": "Sets the time zone to show the date or time in, such as `America/Los_Angeles` or `UTC` (an IANA time zone name). When `value` has an offset or `Z`, the element converts that moment into this zone; when it has none, the element reads `value` as a time already in this zone. Without it, or with an invalid name, which logs a console warning, the element shows the date and time in `value` as written, or the current date and time in the viewer's own time zone when `value` isn't set. When a `value` with no offset names a time the clocks skip when they spring forward, it shows later by the length of the skip, usually one hour, so `2022-03-13T02:30:00` in `America/New_York` shows \"3:30 am\".",
297
324
  "fieldName": "timezone",
298
325
  "category": "behavior"
299
326
  },
@@ -369,5 +396,5 @@
369
396
  "exports": []
370
397
  }
371
398
  ],
372
- "package": "@aurodesignsystem-dev/auro-datetime@0.0.0-pr112.3"
399
+ "package": "@aurodesignsystem-dev/auro-datetime@0.0.0-pr112.4"
373
400
  }
package/demo/api.md CHANGED
@@ -17,14 +17,14 @@ Shows a date or time as text, formatted for a language and region you choose and
17
17
 
18
18
  ### Properties and attributes
19
19
 
20
- | Properties | Attributes | Modifiers | Type | Default | Description |
21
- | ---------- | ---------- | --------- | ------------------------------------------------------------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
22
- | locale | locale | | string | `en-US` | Sets the language and region used to format the date or time, such as `en-GB`, `de-DE`, or `ja-JP` (a BCP 47 language tag). It changes month and weekday names, separators, and whether times use a 12- or 24-hour clock, but not the time zone. A malformed tag logs a console warning and falls back to `en-US`; a well-formed tag the browser doesn't support, such as `zz-ZZ`, uses the browser's default language instead, with no warning. |
23
- | month | month | | "short" \| "long" | `short` | Sets how the month name is written: `short`, such as "Jul", or `long`, such as "July". It applies to the full date and to `type="month"`. |
24
- | timezone | timezone | | string | | Sets the time zone to show the date or time in, such as `America/Los_Angeles` or `UTC` (an IANA time zone name). When `value` has an offset or `Z`, the element converts that moment into this zone; when it has none, the element reads `value` as a time already in this zone. Without it, or with an invalid name, which logs a console warning, the element shows the date and time in `value` as written, or the current date and time in the viewer's own time zone when `value` isn't set. |
25
- | type | type | | "date" \| "time" \| "year" \| "month" \| "weekday" \| "day" \| "numeric" | | Sets which part of the date or time to show: `date` for the full date, such as "Thu, Jul 14, 2022", `numeric` for a numeric date, such as "7/14/2022", `time` for the hour and minute, such as "8:00 am", or `year`, `month`, `weekday`, or `day` for that part alone. Without it, or with any other value, the element shows the full date. |
26
- | value | value | | string | | Sets the date or time to show, as a `YYYY-MM-DD` date or a `YYYY-MM-DDTHH:MM` date-time, with optional seconds and fractional seconds and an optional `Z` or `±HH:MM` offset, such as `2022-07-14`, `2022-07-14T08:00:00`, or `2022-07-14T08:00:00-07:00`. Without it, the element shows the current date and time from when it last rendered; it doesn't currently update as time passes. Invalid input, including an empty value or another ISO 8601 form, such as `20220714` or a `+0700` offset, logs a console warning and shows nothing. |
27
- | weekday | weekday | | "short" \| "long" | `short` | Sets how the weekday name is written: `short`, such as "Thu", or `long`, such as "Thursday". It applies to the full date and to `type="weekday"`. |
20
+ | Properties | Attributes | Modifiers | Type | Default | Description |
21
+ | ---------- | ---------- | --------- | ------------------------------------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
22
+ | locale | locale | | string | `en-US` | Sets the language and region used to format the date or time, such as `en-GB`, `de-DE`, or `ja-JP` (a BCP 47 language tag). It changes month and weekday names, separators, and whether times use a 12- or 24-hour clock, but not the time zone. A malformed tag logs a console warning and falls back to `en-US`; a well-formed tag the browser doesn't support, such as `zz-ZZ`, uses the browser's default language instead, with no warning. |
23
+ | month | month | | "short" \| "long" | `short` | Sets how the month name is written: `short`, such as "Jul", or `long`, such as "July". It applies to the full date and to `type="month"`. |
24
+ | timezone | timezone | | string | | Sets the time zone to show the date or time in, such as `America/Los_Angeles` or `UTC` (an IANA time zone name). When `value` has an offset or `Z`, the element converts that moment into this zone; when it has none, the element reads `value` as a time already in this zone. Without it, or with an invalid name, which logs a console warning, the element shows the date and time in `value` as written, or the current date and time in the viewer's own time zone when `value` isn't set. When a `value` with no offset names a time the clocks skip when they spring forward, it shows later by the length of the skip, usually one hour, so `2022-03-13T02:30:00` in `America/New_York` shows "3:30 am". |
25
+ | type | type | | "date" \| "time" \| "year" \| "month" \| "weekday" \| "day" \| "numeric" | | Sets which part of the date or time to show: `date` for the full date, such as "Thu, Jul 14, 2022", `numeric` for a numeric date, such as "7/14/2022", `time` for the hour and minute, such as "8:00 am", or `year`, `month`, `weekday`, or `day` for that part alone. Without it, or with any other value, the element shows the full date. |
26
+ | value | value | | string | | Sets the date or time to show, as a `YYYY-MM-DD` date or a `YYYY-MM-DDTHH:MM` date-time, with optional seconds and fractional seconds and an optional `Z` or `±HH:MM` offset, such as `2022-07-14`, `2022-07-14T08:00:00`, or `2022-07-14T08:00:00-07:00`. Without it, the element shows the current date and time from when it last rendered; it doesn't currently update as time passes. Invalid input, including an empty value or another ISO 8601 form, such as `20220714` or a `+0700` offset, logs a console warning and shows nothing. |
27
+ | weekday | weekday | | "short" \| "long" | `short` | Sets how the weekday name is written: `short`, such as "Thu", or `long`, such as "Thursday". It applies to the full date and to `type="weekday"`. |
28
28
 
29
29
  ### Methods
30
30
 
@@ -165,6 +165,8 @@ Use `timezone` with an IANA time zone name, such as `America/Los_Angeles` or `UT
165
165
  - **`value` has no offset:** the element reads `value` as a time already in `timezone`, so every reader sees the same result. For example, `type="time" value="2022-07-14T08:00:00" timezone="America/New_York"` shows "8:00 am" wherever the reader is. Use this form when you know the zone a time belongs to but don't have its offset, such as flight times listed by airport.
166
166
  - **`value` isn't set:** the element shows the current date or time in `timezone`, as in the example below.
167
167
 
168
+ On a day the clocks change in `timezone`, a `value` with no offset still shows as written, except for a time the clocks skip when they spring forward. That time moves later by the length of the skip, usually one hour, so `2022-03-13T02:30:00` in `America/New_York` shows "3:30 am".
169
+
168
170
  <div class="exampleWrapper">
169
171
  <!-- AURO-GENERATED-CONTENT:START (FILE:src=../apiExamples/timezone.html) -->
170
172
  <!-- The below content is automatically added from ../apiExamples/timezone.html -->
package/demo/api.min.js CHANGED
@@ -267,7 +267,7 @@ class AuroDatetime extends i {
267
267
  month: { type: String },
268
268
 
269
269
  /**
270
- * Sets the time zone to show the date or time in, such as `America/Los_Angeles` or `UTC` (an IANA time zone name). When `value` has an offset or `Z`, the element converts that moment into this zone; when it has none, the element reads `value` as a time already in this zone. Without it, or with an invalid name, which logs a console warning, the element shows the date and time in `value` as written, or the current date and time in the viewer's own time zone when `value` isn't set.
270
+ * Sets the time zone to show the date or time in, such as `America/Los_Angeles` or `UTC` (an IANA time zone name). When `value` has an offset or `Z`, the element converts that moment into this zone; when it has none, the element reads `value` as a time already in this zone. Without it, or with an invalid name, which logs a console warning, the element shows the date and time in `value` as written, or the current date and time in the viewer's own time zone when `value` isn't set. When a `value` with no offset names a time the clocks skip when they spring forward, it shows later by the length of the skip, usually one hour, so `2022-03-13T02:30:00` in `America/New_York` shows "3:30 am".
271
271
  * @type {string}
272
272
  * @category behavior
273
273
  */
@@ -324,22 +324,16 @@ class AuroDatetime extends i {
324
324
  }
325
325
 
326
326
  /**
327
- * Creates a Date that shows the given wall-clock time when displayed in
328
- * the given IANA time zone. `_resolveInputDate` uses it when `value` has
329
- * no offset and `timezone` is set, so the time is read as already being
330
- * in that zone rather than the viewer's.
331
- *
332
- * It parses the wall-clock time as if it were UTC, asks `Intl` what that
333
- * moment looks like in the target zone, and uses the difference between
334
- * the two to find the real moment.
327
+ * Gets the time zone's offset from UTC at a moment, in milliseconds, such as `-14400000` for New York in summer.
335
328
  *
336
329
  * @private
337
- * @param {string} localISO - The ISO 8601 date-time with no offset, such as `2022-07-14T08:00:00`.
330
+ * @param {number} utcMs - The moment, in milliseconds since the epoch.
338
331
  * @param {string} timeZone - The IANA time zone name, such as `America/New_York`.
339
- * @returns {Date} The moment that reads as `localISO` in `timeZone`.
332
+ * @returns {number} The offset in milliseconds: the zone's wall-clock time, read as UTC, minus the moment.
340
333
  */
341
- _zonedWallClockToUtc(localISO, timeZone) {
342
- const naiveUtc = new Date(`${localISO}Z`);
334
+ _zoneOffsetMs(utcMs, timeZone) {
335
+ // formatToParts drops milliseconds, so compare whole seconds.
336
+ const wholeSeconds = Math.floor(utcMs / 1000) * 1000;
343
337
  const parts = new Intl.DateTimeFormat("en-US", {
344
338
  timeZone,
345
339
  hourCycle: "h23",
@@ -349,15 +343,60 @@ class AuroDatetime extends i {
349
343
  hour: "2-digit",
350
344
  minute: "2-digit",
351
345
  second: "2-digit",
352
- }).formatToParts(naiveUtc);
346
+ }).formatToParts(wholeSeconds);
353
347
  const lookup = Object.fromEntries(
354
348
  parts.filter((p) => p.type !== "literal").map((p) => [p.type, p.value]),
355
349
  );
356
- const seenInZone = new Date(
357
- `${lookup.year}-${lookup.month}-${lookup.day}T${lookup.hour}:${lookup.minute}:${lookup.second}Z`,
350
+ const wallClockAsUtc = Date.UTC(
351
+ Number(lookup.year),
352
+ Number(lookup.month) - 1,
353
+ Number(lookup.day),
354
+ Number(lookup.hour),
355
+ Number(lookup.minute),
356
+ Number(lookup.second),
358
357
  );
359
- const offsetMs = naiveUtc.getTime() - seenInZone.getTime();
360
- return new Date(naiveUtc.getTime() + offsetMs);
358
+ return wallClockAsUtc - wholeSeconds;
359
+ }
360
+
361
+ /**
362
+ * Creates a Date that shows the given wall-clock time when displayed in
363
+ * the given IANA time zone. `_resolveInputDate` uses it when `value` has
364
+ * no offset and `timezone` is set, so the time is read as already being
365
+ * in that zone rather than the viewer's.
366
+ *
367
+ * On a daylight saving change, a time the clocks skip moves forward by
368
+ * the gap, and a time the clocks repeat resolves to its first occurrence.
369
+ * This is the same rule JavaScript uses for local times.
370
+ *
371
+ * @private
372
+ * @param {string} localISO - The ISO 8601 date-time with no offset, such as `2022-07-14T08:00:00`.
373
+ * @param {string} timeZone - The IANA time zone name, such as `America/New_York`.
374
+ * @returns {Date} The moment that reads as `localISO` in `timeZone`.
375
+ */
376
+ _zonedWallClockToUtc(localISO, timeZone) {
377
+ const DAY_MS = 86400000;
378
+ // The wall-clock time read as if it were UTC.
379
+ const naiveMs = new Date(`${localISO}Z`).getTime();
380
+
381
+ // A zone's offset changes at most once within a couple of days, so the
382
+ // offsets a day before and a day after cover both sides of any change
383
+ // near this date. Keep each candidate moment that really reads as the
384
+ // wall-clock time in the zone.
385
+ const offsetBefore = this._zoneOffsetMs(naiveMs - DAY_MS, timeZone);
386
+ const offsetAfter = this._zoneOffsetMs(naiveMs + DAY_MS, timeZone);
387
+ const matches = [naiveMs - offsetBefore, naiveMs - offsetAfter]
388
+ .filter((ms) => ms + this._zoneOffsetMs(ms, timeZone) === naiveMs)
389
+ .sort((a, b) => a - b);
390
+
391
+ if (matches.length > 0) {
392
+ // One match for ordinary times; two for a repeated time, where the
393
+ // first occurrence wins.
394
+ return new Date(matches[0]);
395
+ }
396
+
397
+ // No match: the clocks skip this time. Reading it with the offset from
398
+ // before the change moves it forward by the gap.
399
+ return new Date(naiveMs - offsetBefore);
361
400
  }
362
401
 
363
402
  /**
package/demo/index.min.js CHANGED
@@ -267,7 +267,7 @@ class AuroDatetime extends i {
267
267
  month: { type: String },
268
268
 
269
269
  /**
270
- * Sets the time zone to show the date or time in, such as `America/Los_Angeles` or `UTC` (an IANA time zone name). When `value` has an offset or `Z`, the element converts that moment into this zone; when it has none, the element reads `value` as a time already in this zone. Without it, or with an invalid name, which logs a console warning, the element shows the date and time in `value` as written, or the current date and time in the viewer's own time zone when `value` isn't set.
270
+ * Sets the time zone to show the date or time in, such as `America/Los_Angeles` or `UTC` (an IANA time zone name). When `value` has an offset or `Z`, the element converts that moment into this zone; when it has none, the element reads `value` as a time already in this zone. Without it, or with an invalid name, which logs a console warning, the element shows the date and time in `value` as written, or the current date and time in the viewer's own time zone when `value` isn't set. When a `value` with no offset names a time the clocks skip when they spring forward, it shows later by the length of the skip, usually one hour, so `2022-03-13T02:30:00` in `America/New_York` shows "3:30 am".
271
271
  * @type {string}
272
272
  * @category behavior
273
273
  */
@@ -324,22 +324,16 @@ class AuroDatetime extends i {
324
324
  }
325
325
 
326
326
  /**
327
- * Creates a Date that shows the given wall-clock time when displayed in
328
- * the given IANA time zone. `_resolveInputDate` uses it when `value` has
329
- * no offset and `timezone` is set, so the time is read as already being
330
- * in that zone rather than the viewer's.
331
- *
332
- * It parses the wall-clock time as if it were UTC, asks `Intl` what that
333
- * moment looks like in the target zone, and uses the difference between
334
- * the two to find the real moment.
327
+ * Gets the time zone's offset from UTC at a moment, in milliseconds, such as `-14400000` for New York in summer.
335
328
  *
336
329
  * @private
337
- * @param {string} localISO - The ISO 8601 date-time with no offset, such as `2022-07-14T08:00:00`.
330
+ * @param {number} utcMs - The moment, in milliseconds since the epoch.
338
331
  * @param {string} timeZone - The IANA time zone name, such as `America/New_York`.
339
- * @returns {Date} The moment that reads as `localISO` in `timeZone`.
332
+ * @returns {number} The offset in milliseconds: the zone's wall-clock time, read as UTC, minus the moment.
340
333
  */
341
- _zonedWallClockToUtc(localISO, timeZone) {
342
- const naiveUtc = new Date(`${localISO}Z`);
334
+ _zoneOffsetMs(utcMs, timeZone) {
335
+ // formatToParts drops milliseconds, so compare whole seconds.
336
+ const wholeSeconds = Math.floor(utcMs / 1000) * 1000;
343
337
  const parts = new Intl.DateTimeFormat("en-US", {
344
338
  timeZone,
345
339
  hourCycle: "h23",
@@ -349,15 +343,60 @@ class AuroDatetime extends i {
349
343
  hour: "2-digit",
350
344
  minute: "2-digit",
351
345
  second: "2-digit",
352
- }).formatToParts(naiveUtc);
346
+ }).formatToParts(wholeSeconds);
353
347
  const lookup = Object.fromEntries(
354
348
  parts.filter((p) => p.type !== "literal").map((p) => [p.type, p.value]),
355
349
  );
356
- const seenInZone = new Date(
357
- `${lookup.year}-${lookup.month}-${lookup.day}T${lookup.hour}:${lookup.minute}:${lookup.second}Z`,
350
+ const wallClockAsUtc = Date.UTC(
351
+ Number(lookup.year),
352
+ Number(lookup.month) - 1,
353
+ Number(lookup.day),
354
+ Number(lookup.hour),
355
+ Number(lookup.minute),
356
+ Number(lookup.second),
358
357
  );
359
- const offsetMs = naiveUtc.getTime() - seenInZone.getTime();
360
- return new Date(naiveUtc.getTime() + offsetMs);
358
+ return wallClockAsUtc - wholeSeconds;
359
+ }
360
+
361
+ /**
362
+ * Creates a Date that shows the given wall-clock time when displayed in
363
+ * the given IANA time zone. `_resolveInputDate` uses it when `value` has
364
+ * no offset and `timezone` is set, so the time is read as already being
365
+ * in that zone rather than the viewer's.
366
+ *
367
+ * On a daylight saving change, a time the clocks skip moves forward by
368
+ * the gap, and a time the clocks repeat resolves to its first occurrence.
369
+ * This is the same rule JavaScript uses for local times.
370
+ *
371
+ * @private
372
+ * @param {string} localISO - The ISO 8601 date-time with no offset, such as `2022-07-14T08:00:00`.
373
+ * @param {string} timeZone - The IANA time zone name, such as `America/New_York`.
374
+ * @returns {Date} The moment that reads as `localISO` in `timeZone`.
375
+ */
376
+ _zonedWallClockToUtc(localISO, timeZone) {
377
+ const DAY_MS = 86400000;
378
+ // The wall-clock time read as if it were UTC.
379
+ const naiveMs = new Date(`${localISO}Z`).getTime();
380
+
381
+ // A zone's offset changes at most once within a couple of days, so the
382
+ // offsets a day before and a day after cover both sides of any change
383
+ // near this date. Keep each candidate moment that really reads as the
384
+ // wall-clock time in the zone.
385
+ const offsetBefore = this._zoneOffsetMs(naiveMs - DAY_MS, timeZone);
386
+ const offsetAfter = this._zoneOffsetMs(naiveMs + DAY_MS, timeZone);
387
+ const matches = [naiveMs - offsetBefore, naiveMs - offsetAfter]
388
+ .filter((ms) => ms + this._zoneOffsetMs(ms, timeZone) === naiveMs)
389
+ .sort((a, b) => a - b);
390
+
391
+ if (matches.length > 0) {
392
+ // One match for ordinary times; two for a repeated time, where the
393
+ // first occurrence wins.
394
+ return new Date(matches[0]);
395
+ }
396
+
397
+ // No match: the clocks skip this time. Reading it with the offset from
398
+ // before the change moves it forward by the gap.
399
+ return new Date(naiveMs - offsetBefore);
361
400
  }
362
401
 
363
402
  /**
@@ -0,0 +1,6 @@
1
+ import{LitElement as e,html as t}from"lit";class n{registerComponent(e,t){customElements.get(e)||customElements.define(e,class extends t{})}closestElement(e,t=this,n=(t,i=t&&t.closest(e))=>t&&t!==document&&t!==window?i||n(t.getRootNode().host):null){return n(t)}handleComponentTagRename(e,t){const n=t.toLowerCase();e.tagName.toLowerCase()!==n&&e.setAttribute(n,!0)}elementMatch(e,t){const n=t.toLowerCase();return e.tagName.toLowerCase()===n||e.hasAttribute(n)}getSlotText(e,t){const n=e.shadowRoot?.querySelector(`slot[name="${t}"]`);return(n?.assignedNodes({flatten:!0})||[]).map(e=>e.textContent?.trim()).join(" ").trim()||null}}const i=/^(\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?)?)(Z|[+-]\d{2}:\d{2})?$/u;class a extends e{constructor(){super(),this._initializeDefaults()}_initializeDefaults(){this.weekday="short",this.month="short",this.locale="en-US",this._warnedLocales=new Set,this._warnedTimeZones=new Set,this._warnedValues=new Set,this._effectiveLocale=this._resolveLocale(this.locale),this._effectiveTimeZone=this._resolveTimeZone(this.timezone),this.runtimeUtils=new n}_resolveLocale(e){if(!e)return"en-US";try{return Intl.getCanonicalLocales(e)[0]}catch{return this._warnedLocales&&!this._warnedLocales.has(e)&&(this._warnedLocales.add(e),console.warn(`auro-datetime: "${e}" is not a valid BCP 47 locale tag. Falling back to \`en-US\`.`)),"en-US"}}_resolveTimeZone(e){if(e)try{return new Intl.DateTimeFormat(void 0,{timeZone:e}),e}catch{return void(this._warnedTimeZones&&!this._warnedTimeZones.has(e)&&(this._warnedTimeZones.add(e),console.warn(`auro-datetime: "${e}" is not a valid IANA timezone. Ignoring it.`)))}}static get properties(){return{locale:{type:String},month:{type:String},timezone:{type:String},type:{type:String},value:{type:String},weekday:{type:String}}}static register(e="auro-datetime"){n.prototype.registerComponent(e,a)}willUpdate(e){e.has("locale")&&(this._effectiveLocale=this._resolveLocale(this.locale)),e.has("timezone")&&(this._effectiveTimeZone=this._resolveTimeZone(this.timezone))}firstUpdated(){this.runtimeUtils.handleComponentTagRename(this,"auro-datetime")}_zoneOffsetMs(e,t){const n=1e3*Math.floor(e/1e3),i=new Intl.DateTimeFormat("en-US",{timeZone:t,hourCycle:"h23",year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"}).formatToParts(n),a=Object.fromEntries(i.filter(e=>"literal"!==e.type).map(e=>[e.type,e.value]));return Date.UTC(Number(a.year),Number(a.month)-1,Number(a.day),Number(a.hour),Number(a.minute),Number(a.second))-n}_zonedWallClockToUtc(e,t){const n=864e5,i=new Date(`${e}Z`).getTime(),a=this._zoneOffsetMs(i-n,t),s=this._zoneOffsetMs(i+n,t),o=[i-a,i-s].filter(e=>e+this._zoneOffsetMs(e,t)===i).sort((e,t)=>e-t);return o.length>0?new Date(o[0]):new Date(i-a)}_resolveInputDate(){const e=this._effectiveTimeZone;if(null==this.value)return{date:new Date,timeZoneOption:e};const t=this.value.match(i);if(!t)return this._warnedValues.has(this.value)||(this._warnedValues.add(this.value),console.warn(`auro-datetime: "${this.value}" is not a valid ISO 8601 string.`)),{date:null,timeZoneOption:void 0};const n=t[1],a=Boolean(t[2]);if(a&&!n.includes("T"))return this._warnedValues.has(this.value)||(this._warnedValues.add(this.value),console.warn(`auro-datetime: "${this.value}" is not a valid ISO 8601 string (offset/Z requires a time component).`)),{date:null,timeZoneOption:void 0};const s=n.includes("T")?n:`${n}T00:00:00`,o=(()=>e&&!a?this._zonedWallClockToUtc(s,e):e&&a?new Date(this.value):new Date(s))();return Number.isNaN(o.getTime())?(this._warnedValues.has(this.value)||(this._warnedValues.add(this.value),console.warn(`auro-datetime: "${this.value}" is not a valid ISO 8601 date.`)),{date:null,timeZoneOption:void 0}):{date:o,timeZoneOption:e}}humanDate(){const{date:e,timeZoneOption:t}=this._resolveInputDate();if(!e)return"";const n={weekday:this.weekday||"short",year:"numeric",month:this.month||"short",day:"numeric"};return t&&(n.timeZone=t),e.toLocaleString(this._effectiveLocale,n)}humanDateConversion(){const{date:e,timeZoneOption:t}=this._resolveInputDate();if(!e)return"";const n={};switch(t&&(n.timeZone=t),this.type){case"day":n.day="numeric";break;case"month":n.month=this.month||"short";break;case"year":n.year="numeric";break;case"weekday":n.weekday=this.weekday||"short"}return e.toLocaleString(this._effectiveLocale,n)}numericDate(){const{date:e,timeZoneOption:t}=this._resolveInputDate();if(!e)return"";const n={year:"numeric",month:"numeric",day:"numeric"};return t&&(n.timeZone=t),e.toLocaleString(this._effectiveLocale,n)}humanTime(){const{date:e,timeZoneOption:t}=this._resolveInputDate();if(!e)return"";const n={hour:"2-digit",minute:"2-digit"};t&&(n.timeZone=t);const i=e.toLocaleString(this._effectiveLocale,n);return/[ap]\.?m\.?/iu.test(i)?i.replace(/^0+/u,"").toLowerCase():i}whichDate(){switch(this.type){case"date":default:return this.humanDate();case"time":return this.humanTime();case"year":case"month":case"weekday":case"day":return this.humanDateConversion();case"numeric":return this.numericDate()}}render(){return t`
2
+ <slot name="pre"></slot>
3
+ <span class="yield">${this.whichDate()}</span>
4
+ <slot name="post"></slot>
5
+ <slot></slot>
6
+ `}}export{a as A};
package/dist/index.d.ts CHANGED
@@ -81,7 +81,7 @@ export type AuroDatetimeProps = {
81
81
  locale?: AuroDatetime["locale"];
82
82
  /** Sets how the month name is written: `short`, such as "Jul", or `long`, such as "July". It applies to the full date and to `type="month"`. */
83
83
  month?: AuroDatetime["month"];
84
- /** Sets the time zone to show the date or time in, such as `America/Los_Angeles` or `UTC` (an IANA time zone name). When `value` has an offset or `Z`, the element converts that moment into this zone; when it has none, the element reads `value` as a time already in this zone. Without it, or with an invalid name, which logs a console warning, the element shows the date and time in `value` as written, or the current date and time in the viewer's own time zone when `value` isn't set. */
84
+ /** Sets the time zone to show the date or time in, such as `America/Los_Angeles` or `UTC` (an IANA time zone name). When `value` has an offset or `Z`, the element converts that moment into this zone; when it has none, the element reads `value` as a time already in this zone. Without it, or with an invalid name, which logs a console warning, the element shows the date and time in `value` as written, or the current date and time in the viewer's own time zone when `value` isn't set. When a `value` with no offset names a time the clocks skip when they spring forward, it shows later by the length of the skip, usually one hour, so `2022-03-13T02:30:00` in `America/New_York` shows "3:30 am". */
85
85
  timezone?: AuroDatetime["timezone"];
86
86
  /** Sets which part of the date or time to show: `date` for the full date, such as "Thu, Jul 14, 2022", `numeric` for a numeric date, such as "7/14/2022", `time` for the hour and minute, such as "8:00 am", or `year`, `month`, `weekday`, or `day` for that part alone. Without it, or with any other value, the element shows the full date. */
87
87
  type?: AuroDatetime["type"];
@@ -96,7 +96,7 @@ export type AuroDatetimeSolidJsProps = {
96
96
  "prop:locale"?: AuroDatetime["locale"];
97
97
  /** Sets how the month name is written: `short`, such as "Jul", or `long`, such as "July". It applies to the full date and to `type="month"`. */
98
98
  "prop:month"?: AuroDatetime["month"];
99
- /** Sets the time zone to show the date or time in, such as `America/Los_Angeles` or `UTC` (an IANA time zone name). When `value` has an offset or `Z`, the element converts that moment into this zone; when it has none, the element reads `value` as a time already in this zone. Without it, or with an invalid name, which logs a console warning, the element shows the date and time in `value` as written, or the current date and time in the viewer's own time zone when `value` isn't set. */
99
+ /** Sets the time zone to show the date or time in, such as `America/Los_Angeles` or `UTC` (an IANA time zone name). When `value` has an offset or `Z`, the element converts that moment into this zone; when it has none, the element reads `value` as a time already in this zone. Without it, or with an invalid name, which logs a console warning, the element shows the date and time in `value` as written, or the current date and time in the viewer's own time zone when `value` isn't set. When a `value` with no offset names a time the clocks skip when they spring forward, it shows later by the length of the skip, usually one hour, so `2022-03-13T02:30:00` in `America/New_York` shows "3:30 am". */
100
100
  "prop:timezone"?: AuroDatetime["timezone"];
101
101
  /** Sets which part of the date or time to show: `date` for the full date, such as "Thu, Jul 14, 2022", `numeric` for a numeric date, such as "7/14/2022", `time` for the hour and minute, such as "8:00 am", or `year`, `month`, `weekday`, or `day` for that part alone. Without it, or with any other value, the element shows the full date. */
102
102
  "prop:type"?: AuroDatetime["type"];
@@ -133,7 +133,7 @@ export type CustomElements = {
133
133
  *
134
134
  * - `locale`: Sets the language and region used to format the date or time, such as `en-GB`, `de-DE`, or `ja-JP` (a BCP 47 language tag). It changes month and weekday names, separators, and whether times use a 12- or 24-hour clock, but not the time zone. A malformed tag logs a console warning and falls back to `en-US`; a well-formed tag the browser doesn't support, such as `zz-ZZ`, uses the browser's default language instead, with no warning.
135
135
  * - `month`: Sets how the month name is written: `short`, such as "Jul", or `long`, such as "July". It applies to the full date and to `type="month"`.
136
- * - `timezone`: Sets the time zone to show the date or time in, such as `America/Los_Angeles` or `UTC` (an IANA time zone name). When `value` has an offset or `Z`, the element converts that moment into this zone; when it has none, the element reads `value` as a time already in this zone. Without it, or with an invalid name, which logs a console warning, the element shows the date and time in `value` as written, or the current date and time in the viewer's own time zone when `value` isn't set.
136
+ * - `timezone`: Sets the time zone to show the date or time in, such as `America/Los_Angeles` or `UTC` (an IANA time zone name). When `value` has an offset or `Z`, the element converts that moment into this zone; when it has none, the element reads `value` as a time already in this zone. Without it, or with an invalid name, which logs a console warning, the element shows the date and time in `value` as written, or the current date and time in the viewer's own time zone when `value` isn't set. When a `value` with no offset names a time the clocks skip when they spring forward, it shows later by the length of the skip, usually one hour, so `2022-03-13T02:30:00` in `America/New_York` shows "3:30 am".
137
137
  * - `type`: Sets which part of the date or time to show: `date` for the full date, such as "Thu, Jul 14, 2022", `numeric` for a numeric date, such as "7/14/2022", `time` for the hour and minute, such as "8:00 am", or `year`, `month`, `weekday`, or `day` for that part alone. Without it, or with any other value, the element shows the full date.
138
138
  * - `value`: Sets the date or time to show, as a `YYYY-MM-DD` date or a `YYYY-MM-DDTHH:MM` date-time, with optional seconds and fractional seconds and an optional `Z` or `±HH:MM` offset, such as `2022-07-14`, `2022-07-14T08:00:00`, or `2022-07-14T08:00:00-07:00`. Without it, the element shows the current date and time from when it last rendered; it doesn't currently update as time passes. Invalid input, including an empty value or another ISO 8601 form, such as `20220714` or a `+0700` offset, logs a console warning and shows nothing.
139
139
  * - `weekday`: Sets how the weekday name is written: `short`, such as "Thu", or `long`, such as "Thursday". It applies to the full date and to `type="weekday"`.
@@ -179,7 +179,7 @@ export type CustomElementsSolidJs = {
179
179
  *
180
180
  * - `locale`: Sets the language and region used to format the date or time, such as `en-GB`, `de-DE`, or `ja-JP` (a BCP 47 language tag). It changes month and weekday names, separators, and whether times use a 12- or 24-hour clock, but not the time zone. A malformed tag logs a console warning and falls back to `en-US`; a well-formed tag the browser doesn't support, such as `zz-ZZ`, uses the browser's default language instead, with no warning.
181
181
  * - `month`: Sets how the month name is written: `short`, such as "Jul", or `long`, such as "July". It applies to the full date and to `type="month"`.
182
- * - `timezone`: Sets the time zone to show the date or time in, such as `America/Los_Angeles` or `UTC` (an IANA time zone name). When `value` has an offset or `Z`, the element converts that moment into this zone; when it has none, the element reads `value` as a time already in this zone. Without it, or with an invalid name, which logs a console warning, the element shows the date and time in `value` as written, or the current date and time in the viewer's own time zone when `value` isn't set.
182
+ * - `timezone`: Sets the time zone to show the date or time in, such as `America/Los_Angeles` or `UTC` (an IANA time zone name). When `value` has an offset or `Z`, the element converts that moment into this zone; when it has none, the element reads `value` as a time already in this zone. Without it, or with an invalid name, which logs a console warning, the element shows the date and time in `value` as written, or the current date and time in the viewer's own time zone when `value` isn't set. When a `value` with no offset names a time the clocks skip when they spring forward, it shows later by the length of the skip, usually one hour, so `2022-03-13T02:30:00` in `America/New_York` shows "3:30 am".
183
183
  * - `type`: Sets which part of the date or time to show: `date` for the full date, such as "Thu, Jul 14, 2022", `numeric` for a numeric date, such as "7/14/2022", `time` for the hour and minute, such as "8:00 am", or `year`, `month`, `weekday`, or `day` for that part alone. Without it, or with any other value, the element shows the full date.
184
184
  * - `value`: Sets the date or time to show, as a `YYYY-MM-DD` date or a `YYYY-MM-DDTHH:MM` date-time, with optional seconds and fractional seconds and an optional `Z` or `±HH:MM` offset, such as `2022-07-14`, `2022-07-14T08:00:00`, or `2022-07-14T08:00:00-07:00`. Without it, the element shows the current date and time from when it last rendered; it doesn't currently update as time passes. Invalid input, including an empty value or another ISO 8601 form, such as `20220714` or a `+0700` offset, logs a console warning and shows nothing.
185
185
  * - `weekday`: Sets how the weekday name is written: `short`, such as "Thu", or `long`, such as "Thursday". It applies to the full date and to `type="weekday"`.
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- export{A as AuroDatetime}from"./auro-datetime-dJCvhV16.js";import"lit";
1
+ export{A as AuroDatetime}from"./auro-datetime-Cn3fy-t_.js";import"lit";
@@ -1 +1 @@
1
- import{A as r}from"./auro-datetime-dJCvhV16.js";import"lit";r.register();
1
+ import{A as r}from"./auro-datetime-Cn3fy-t_.js";import"lit";r.register();
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "================================================================================"
8
8
  ],
9
9
  "name": "@aurodesignsystem-dev/auro-datetime",
10
- "version": "0.0.0-pr112.3",
10
+ "version": "0.0.0-pr112.4",
11
11
  "description": "auro-datetime HTML custom element",
12
12
  "repository": {
13
13
  "type": "git",
@@ -1,6 +0,0 @@
1
- import{LitElement as e,html as t}from"lit";class i{registerComponent(e,t){customElements.get(e)||customElements.define(e,class extends t{})}closestElement(e,t=this,i=(t,n=t&&t.closest(e))=>t&&t!==document&&t!==window?n||i(t.getRootNode().host):null){return i(t)}handleComponentTagRename(e,t){const i=t.toLowerCase();e.tagName.toLowerCase()!==i&&e.setAttribute(i,!0)}elementMatch(e,t){const i=t.toLowerCase();return e.tagName.toLowerCase()===i||e.hasAttribute(i)}getSlotText(e,t){const i=e.shadowRoot?.querySelector(`slot[name="${t}"]`);return(i?.assignedNodes({flatten:!0})||[]).map(e=>e.textContent?.trim()).join(" ").trim()||null}}const n=/^(\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?)?)(Z|[+-]\d{2}:\d{2})?$/u;class a extends e{constructor(){super(),this._initializeDefaults()}_initializeDefaults(){this.weekday="short",this.month="short",this.locale="en-US",this._warnedLocales=new Set,this._warnedTimeZones=new Set,this._warnedValues=new Set,this._effectiveLocale=this._resolveLocale(this.locale),this._effectiveTimeZone=this._resolveTimeZone(this.timezone),this.runtimeUtils=new i}_resolveLocale(e){if(!e)return"en-US";try{return Intl.getCanonicalLocales(e)[0]}catch{return this._warnedLocales&&!this._warnedLocales.has(e)&&(this._warnedLocales.add(e),console.warn(`auro-datetime: "${e}" is not a valid BCP 47 locale tag. Falling back to \`en-US\`.`)),"en-US"}}_resolveTimeZone(e){if(e)try{return new Intl.DateTimeFormat(void 0,{timeZone:e}),e}catch{return void(this._warnedTimeZones&&!this._warnedTimeZones.has(e)&&(this._warnedTimeZones.add(e),console.warn(`auro-datetime: "${e}" is not a valid IANA timezone. Ignoring it.`)))}}static get properties(){return{locale:{type:String},month:{type:String},timezone:{type:String},type:{type:String},value:{type:String},weekday:{type:String}}}static register(e="auro-datetime"){i.prototype.registerComponent(e,a)}willUpdate(e){e.has("locale")&&(this._effectiveLocale=this._resolveLocale(this.locale)),e.has("timezone")&&(this._effectiveTimeZone=this._resolveTimeZone(this.timezone))}firstUpdated(){this.runtimeUtils.handleComponentTagRename(this,"auro-datetime")}_zonedWallClockToUtc(e,t){const i=new Date(`${e}Z`),n=new Intl.DateTimeFormat("en-US",{timeZone:t,hourCycle:"h23",year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"}).formatToParts(i),a=Object.fromEntries(n.filter(e=>"literal"!==e.type).map(e=>[e.type,e.value])),o=new Date(`${a.year}-${a.month}-${a.day}T${a.hour}:${a.minute}:${a.second}Z`),s=i.getTime()-o.getTime();return new Date(i.getTime()+s)}_resolveInputDate(){const e=this._effectiveTimeZone;if(null==this.value)return{date:new Date,timeZoneOption:e};const t=this.value.match(n);if(!t)return this._warnedValues.has(this.value)||(this._warnedValues.add(this.value),console.warn(`auro-datetime: "${this.value}" is not a valid ISO 8601 string.`)),{date:null,timeZoneOption:void 0};const i=t[1],a=Boolean(t[2]);if(a&&!i.includes("T"))return this._warnedValues.has(this.value)||(this._warnedValues.add(this.value),console.warn(`auro-datetime: "${this.value}" is not a valid ISO 8601 string (offset/Z requires a time component).`)),{date:null,timeZoneOption:void 0};const o=i.includes("T")?i:`${i}T00:00:00`,s=(()=>e&&!a?this._zonedWallClockToUtc(o,e):e&&a?new Date(this.value):new Date(o))();return Number.isNaN(s.getTime())?(this._warnedValues.has(this.value)||(this._warnedValues.add(this.value),console.warn(`auro-datetime: "${this.value}" is not a valid ISO 8601 date.`)),{date:null,timeZoneOption:void 0}):{date:s,timeZoneOption:e}}humanDate(){const{date:e,timeZoneOption:t}=this._resolveInputDate();if(!e)return"";const i={weekday:this.weekday||"short",year:"numeric",month:this.month||"short",day:"numeric"};return t&&(i.timeZone=t),e.toLocaleString(this._effectiveLocale,i)}humanDateConversion(){const{date:e,timeZoneOption:t}=this._resolveInputDate();if(!e)return"";const i={};switch(t&&(i.timeZone=t),this.type){case"day":i.day="numeric";break;case"month":i.month=this.month||"short";break;case"year":i.year="numeric";break;case"weekday":i.weekday=this.weekday||"short"}return e.toLocaleString(this._effectiveLocale,i)}numericDate(){const{date:e,timeZoneOption:t}=this._resolveInputDate();if(!e)return"";const i={year:"numeric",month:"numeric",day:"numeric"};return t&&(i.timeZone=t),e.toLocaleString(this._effectiveLocale,i)}humanTime(){const{date:e,timeZoneOption:t}=this._resolveInputDate();if(!e)return"";const i={hour:"2-digit",minute:"2-digit"};t&&(i.timeZone=t);const n=e.toLocaleString(this._effectiveLocale,i);return/[ap]\.?m\.?/iu.test(n)?n.replace(/^0+/u,"").toLowerCase():n}whichDate(){switch(this.type){case"date":default:return this.humanDate();case"time":return this.humanTime();case"year":case"month":case"weekday":case"day":return this.humanDateConversion();case"numeric":return this.numericDate()}}render(){return t`
2
- <slot name="pre"></slot>
3
- <span class="yield">${this.whichDate()}</span>
4
- <slot name="post"></slot>
5
- <slot></slot>
6
- `}}export{a as A};