@aurodesignsystem-dev/auro-datetime 0.0.0-pr82.4 → 0.0.0-pr82.6
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/demo/api.md +104 -82
- package/demo/auro-datetime.min.js +265 -130
- package/dist/auro-datetime-Cml4cDmu.js +6 -0
- package/dist/index.d.ts +46 -22
- package/dist/index.js +1 -1
- package/dist/registered.js +1 -1
- package/package.json +1 -1
- package/dist/auro-datetime-BwaHVIh8.js +0 -6
package/demo/api.md
CHANGED
|
@@ -7,16 +7,14 @@ The `auro-datetime` element is for the purposes of providing an easy to use date
|
|
|
7
7
|
|
|
8
8
|
### Properties & Attributes
|
|
9
9
|
|
|
10
|
-
| Properties | Attributes | Modifiers | Type
|
|
11
|
-
| ---------- | ---------- | --------- |
|
|
12
|
-
|
|
|
13
|
-
|
|
|
14
|
-
|
|
|
15
|
-
|
|
|
16
|
-
|
|
|
17
|
-
|
|
|
18
|
-
| utc | utc | | string | | Pass in ISO 8601 UTC formatted time code |
|
|
19
|
-
| weekday | weekday | | `short` \| `long` | `short` | Defines format of weekday |
|
|
10
|
+
| Properties | Attributes | Modifiers | Type | Default | Description |
|
|
11
|
+
| ---------- | ---------- | --------- | ------------------------------------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
12
|
+
| locale | locale | | string | `en-US` | BCP 47 language tag for locale-aware date/time formatting (e.g. 'en-GB', 'de-DE', 'ja-JP'). |
|
|
13
|
+
| month | month | | `short` \| `long` | `short` | Defines format of month |
|
|
14
|
+
| timeZone | timeZone | | string | | Pass in string to define [timeZone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).<br>When set, the moment described by `value` is converted into this IANA zone for display.<br>When unset, the wall-clock time from the input string is rendered as-is. |
|
|
15
|
+
| type | type | | `date` \| `time` \| `year` \| `month` \| `weekday` \| `day` \| `numeric` | | Defines type of data to render |
|
|
16
|
+
| value | value | | string | | ISO 8601 date or date-time string. Examples:<br>- `2022-07-14T08:00:00-07:00` (with offset)<br>- `2022-07-14T08:00:00Z` (UTC)<br>- `2022-07-14T08:00:00` (no offset)<br>- `2022-07-14` (date only)<br><br>When omitted, the component renders today's date.<br>Invalid input is logged as a warning and renders nothing. |
|
|
17
|
+
| weekday | weekday | | `short` \| `long` | `short` | Defines format of weekday |
|
|
20
18
|
|
|
21
19
|
### Methods
|
|
22
20
|
|
|
@@ -72,39 +70,18 @@ The `auro-datetime` element is for the purposes of providing an easy to use date
|
|
|
72
70
|
|
|
73
71
|
## Property & Attribute Examples
|
|
74
72
|
|
|
75
|
-
### Time with Capitalization
|
|
76
|
-
|
|
77
|
-
Using the `cap` attribute will return the basic time string with a capitalized `AM` or `PM`.
|
|
78
|
-
|
|
79
|
-
<div class="exampleWrapper">
|
|
80
|
-
<!-- AURO-GENERATED-CONTENT:START (FILE:src=../apiExamples/cap.html) -->
|
|
81
|
-
<!-- The below content is automatically added from ../apiExamples/cap.html -->
|
|
82
|
-
<auro-datetime type="time" cap></auro-datetime>
|
|
83
|
-
<!-- AURO-GENERATED-CONTENT:END -->
|
|
84
|
-
</div>
|
|
85
|
-
<auro-accordion alignRight>
|
|
86
|
-
<span slot="trigger">See code</span>
|
|
87
|
-
<!-- AURO-GENERATED-CONTENT:START (CODE:src=../apiExamples/cap.html) -->
|
|
88
|
-
<!-- The below code snippet is automatically added from ../apiExamples/cap.html -->
|
|
89
|
-
|
|
90
|
-
```html
|
|
91
|
-
<auro-datetime type="time" cap></auro-datetime>
|
|
92
|
-
```
|
|
93
|
-
<!-- AURO-GENERATED-CONTENT:END -->
|
|
94
|
-
</auro-accordion>
|
|
95
|
-
|
|
96
73
|
### International Date Formatting
|
|
97
74
|
|
|
98
|
-
Use the `locale` attribute with a [BCP 47 language tag](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#locales_argument) to render dates and times in
|
|
75
|
+
Use the `locale` attribute with a [BCP 47 language tag](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#locales_argument) to render dates and times in a specific locale (e.g. `en-GB`, `de-DE`, `ja-JP`). When omitted, the component defaults to `en-US` formatting. The `locale` attribute controls **output formatting only** (month names, separators, 12/24-hour clock); it does not perform timezone conversion. Invalid tags are logged as a warning and fall back to `en-US`.
|
|
99
76
|
|
|
100
77
|
#### Locale with type="date"
|
|
101
78
|
|
|
102
79
|
<div class="exampleWrapper">
|
|
103
80
|
<!-- AURO-GENERATED-CONTENT:START (FILE:src=../apiExamples/locale-date.html) -->
|
|
104
81
|
<!-- The below content is automatically added from ../apiExamples/locale-date.html -->
|
|
105
|
-
<auro-datetime type="date" locale="en-GB"
|
|
106
|
-
<auro-datetime type="date" locale="de-DE"
|
|
107
|
-
<auro-datetime type="date" locale="ja-JP"
|
|
82
|
+
<auro-datetime type="date" locale="en-GB" value="2020-09-22T01:38:22Z"></auro-datetime><br>
|
|
83
|
+
<auro-datetime type="date" locale="de-DE" value="2020-09-22T01:38:22Z"></auro-datetime><br>
|
|
84
|
+
<auro-datetime type="date" locale="ja-JP" value="2020-09-22T01:38:22Z"></auro-datetime>
|
|
108
85
|
<!-- AURO-GENERATED-CONTENT:END -->
|
|
109
86
|
</div>
|
|
110
87
|
<auro-accordion alignRight>
|
|
@@ -113,9 +90,9 @@ Use the `locale` attribute with a [BCP 47 language tag](https://developer.mozill
|
|
|
113
90
|
<!-- The below code snippet is automatically added from ../apiExamples/locale-date.html -->
|
|
114
91
|
|
|
115
92
|
```html
|
|
116
|
-
<auro-datetime type="date" locale="en-GB"
|
|
117
|
-
<auro-datetime type="date" locale="de-DE"
|
|
118
|
-
<auro-datetime type="date" locale="ja-JP"
|
|
93
|
+
<auro-datetime type="date" locale="en-GB" value="2020-09-22T01:38:22Z"></auro-datetime><br>
|
|
94
|
+
<auro-datetime type="date" locale="de-DE" value="2020-09-22T01:38:22Z"></auro-datetime><br>
|
|
95
|
+
<auro-datetime type="date" locale="ja-JP" value="2020-09-22T01:38:22Z"></auro-datetime>
|
|
119
96
|
```
|
|
120
97
|
<!-- AURO-GENERATED-CONTENT:END -->
|
|
121
98
|
</auro-accordion>
|
|
@@ -125,9 +102,9 @@ Use the `locale` attribute with a [BCP 47 language tag](https://developer.mozill
|
|
|
125
102
|
<div class="exampleWrapper">
|
|
126
103
|
<!-- AURO-GENERATED-CONTENT:START (FILE:src=../apiExamples/locale-numeric.html) -->
|
|
127
104
|
<!-- The below content is automatically added from ../apiExamples/locale-numeric.html -->
|
|
128
|
-
<auro-datetime type="numeric" locale="en-GB"
|
|
129
|
-
<auro-datetime type="numeric" locale="de-DE"
|
|
130
|
-
<auro-datetime type="numeric" locale="ja-JP"
|
|
105
|
+
<auro-datetime type="numeric" locale="en-GB" value="2020-09-22T01:38:22Z"></auro-datetime><br>
|
|
106
|
+
<auro-datetime type="numeric" locale="de-DE" value="2020-09-22T01:38:22Z"></auro-datetime><br>
|
|
107
|
+
<auro-datetime type="numeric" locale="ja-JP" value="2020-09-22T01:38:22Z"></auro-datetime>
|
|
131
108
|
<!-- AURO-GENERATED-CONTENT:END -->
|
|
132
109
|
</div>
|
|
133
110
|
<auro-accordion alignRight>
|
|
@@ -136,9 +113,38 @@ Use the `locale` attribute with a [BCP 47 language tag](https://developer.mozill
|
|
|
136
113
|
<!-- The below code snippet is automatically added from ../apiExamples/locale-numeric.html -->
|
|
137
114
|
|
|
138
115
|
```html
|
|
139
|
-
<auro-datetime type="numeric" locale="en-GB"
|
|
140
|
-
<auro-datetime type="numeric" locale="de-DE"
|
|
141
|
-
<auro-datetime type="numeric" locale="ja-JP"
|
|
116
|
+
<auro-datetime type="numeric" locale="en-GB" value="2020-09-22T01:38:22Z"></auro-datetime><br>
|
|
117
|
+
<auro-datetime type="numeric" locale="de-DE" value="2020-09-22T01:38:22Z"></auro-datetime><br>
|
|
118
|
+
<auro-datetime type="numeric" locale="ja-JP" value="2020-09-22T01:38:22Z"></auro-datetime>
|
|
119
|
+
```
|
|
120
|
+
<!-- AURO-GENERATED-CONTENT:END -->
|
|
121
|
+
</auro-accordion>
|
|
122
|
+
|
|
123
|
+
#### Locale with type="time"
|
|
124
|
+
|
|
125
|
+
Time is the most format-divergent type across locales. The examples below highlight four distinct patterns: 12-hour with a Latin am/pm suffix (`en-US`), 24-hour with no marker (`de-DE`), 12-hour with a Korean period prefix (`ko-KR` → `오후`), and 12-hour with Arabic-Indic digits and an Arabic period marker (`ar-EG` → `م`).
|
|
126
|
+
|
|
127
|
+
Note: the choice of 12-hour vs 24-hour is decided by the runtime's `Intl.DateTimeFormat` per locale, not by this component. Several locales (`zh-CN`, `ja-JP`, `de-DE`, `fr-FR`, `en-GB`) default to a 24-hour clock for the short-time skeleton even though the language has 12-hour period words available — the component honors whatever the platform produces.
|
|
128
|
+
|
|
129
|
+
<div class="exampleWrapper">
|
|
130
|
+
<!-- AURO-GENERATED-CONTENT:START (FILE:src=../apiExamples/locale-time.html) -->
|
|
131
|
+
<!-- The below content is automatically added from ../apiExamples/locale-time.html -->
|
|
132
|
+
<auro-datetime type="time" locale="en-US" value="2020-09-22T14:05:00"></auro-datetime><br>
|
|
133
|
+
<auro-datetime type="time" locale="de-DE" value="2020-09-22T14:05:00"></auro-datetime><br>
|
|
134
|
+
<auro-datetime type="time" locale="ko-KR" value="2020-09-22T14:05:00"></auro-datetime><br>
|
|
135
|
+
<auro-datetime type="time" locale="ar-EG" value="2020-09-22T14:05:00"></auro-datetime>
|
|
136
|
+
<!-- AURO-GENERATED-CONTENT:END -->
|
|
137
|
+
</div>
|
|
138
|
+
<auro-accordion alignRight>
|
|
139
|
+
<span slot="trigger">See code</span>
|
|
140
|
+
<!-- AURO-GENERATED-CONTENT:START (CODE:src=../apiExamples/locale-time.html) -->
|
|
141
|
+
<!-- The below code snippet is automatically added from ../apiExamples/locale-time.html -->
|
|
142
|
+
|
|
143
|
+
```html
|
|
144
|
+
<auro-datetime type="time" locale="en-US" value="2020-09-22T14:05:00"></auro-datetime><br>
|
|
145
|
+
<auro-datetime type="time" locale="de-DE" value="2020-09-22T14:05:00"></auro-datetime><br>
|
|
146
|
+
<auro-datetime type="time" locale="ko-KR" value="2020-09-22T14:05:00"></auro-datetime><br>
|
|
147
|
+
<auro-datetime type="time" locale="ar-EG" value="2020-09-22T14:05:00"></auro-datetime>
|
|
142
148
|
```
|
|
143
149
|
<!-- AURO-GENERATED-CONTENT:END -->
|
|
144
150
|
</auro-accordion>
|
|
@@ -164,16 +170,23 @@ Use the `month="long"` attribute to display the full month name, and `weekday="l
|
|
|
164
170
|
<!-- AURO-GENERATED-CONTENT:END -->
|
|
165
171
|
</auro-accordion>
|
|
166
172
|
|
|
167
|
-
### Set date/time with
|
|
173
|
+
### Set date/time with `value`
|
|
168
174
|
|
|
169
|
-
Use the `
|
|
175
|
+
Use the `value` attribute to pass a single ISO 8601 date or date-time string into the element. The `value` attribute is locale-agnostic and replaces the previous `setDate` and `utc` attributes. Accepted shapes include:
|
|
176
|
+
|
|
177
|
+
- `2022-07-14T08:00:00-07:00` (date-time with offset)
|
|
178
|
+
- `2022-07-14T08:00:00Z` (UTC, Zulu designator)
|
|
179
|
+
- `2022-07-14T08:00:00` (date-time, no offset)
|
|
180
|
+
- `2022-07-14` (date only)
|
|
181
|
+
|
|
182
|
+
Invalid input is logged as a warning and renders nothing.
|
|
170
183
|
|
|
171
184
|
<div class="exampleWrapper">
|
|
172
185
|
<!-- AURO-GENERATED-CONTENT:START (FILE:src=../apiExamples/set-date.html) -->
|
|
173
186
|
<!-- The below content is automatically added from ../apiExamples/set-date.html -->
|
|
174
|
-
<auro-datetime
|
|
175
|
-
<auro-datetime weekday="long" month="long"
|
|
176
|
-
<auro-datetime type="time"
|
|
187
|
+
<auro-datetime value="1975-08-19T23:15:30"></auro-datetime><br>
|
|
188
|
+
<auro-datetime weekday="long" month="long" value="1975-08-19T23:15:30"></auro-datetime><br>
|
|
189
|
+
<auro-datetime type="time" value="1975-08-19T23:15:30"></auro-datetime>
|
|
177
190
|
<!-- AURO-GENERATED-CONTENT:END -->
|
|
178
191
|
</div>
|
|
179
192
|
<auro-accordion alignRight>
|
|
@@ -182,16 +195,16 @@ Use the `setDate` property to inject a specific date into the element and parse
|
|
|
182
195
|
<!-- The below code snippet is automatically added from ../apiExamples/set-date.html -->
|
|
183
196
|
|
|
184
197
|
```html
|
|
185
|
-
<auro-datetime
|
|
186
|
-
<auro-datetime weekday="long" month="long"
|
|
187
|
-
<auro-datetime type="time"
|
|
198
|
+
<auro-datetime value="1975-08-19T23:15:30"></auro-datetime><br>
|
|
199
|
+
<auro-datetime weekday="long" month="long" value="1975-08-19T23:15:30"></auro-datetime><br>
|
|
200
|
+
<auro-datetime type="time" value="1975-08-19T23:15:30"></auro-datetime>
|
|
188
201
|
```
|
|
189
202
|
<!-- AURO-GENERATED-CONTENT:END -->
|
|
190
203
|
</auro-accordion>
|
|
191
204
|
|
|
192
205
|
### Type
|
|
193
206
|
|
|
194
|
-
Use `type` to define the type of data to render. Options are `[date, time, year, month, weekday, day, numeric
|
|
207
|
+
Use `type` to define the type of data to render. Options are `[date, time, year, month, weekday, day, numeric]`.
|
|
195
208
|
|
|
196
209
|
#### Numeric Date
|
|
197
210
|
|
|
@@ -214,19 +227,17 @@ Using the `auro-datetime` element with `type=numeric` will return the **current
|
|
|
214
227
|
<!-- AURO-GENERATED-CONTENT:END -->
|
|
215
228
|
</auro-accordion>
|
|
216
229
|
|
|
217
|
-
####
|
|
230
|
+
#### Wall-clock display from offset
|
|
218
231
|
|
|
219
|
-
|
|
220
|
-
<br />
|
|
221
|
-
Use `type="tzTime"`or `type="tzDate"` with the `setDate` property to define a new date object in a specific time zone using the `YYYY-MM-DDTHH:MM:SS-HH:MM` model.
|
|
232
|
+
When the `value` attribute contains a timezone offset (or `Z`) and no `timeZone` attribute is set, the component renders the **wall-clock** components from the input verbatim. This is the right behavior for displaying local airport time on a flight schedule, where the offset describes the location of the flight rather than the viewer.
|
|
222
233
|
|
|
223
|
-
Example using `2022-07-13T21:35:00-07:00
|
|
234
|
+
Example using `2022-07-13T21:35:00-07:00`. The same string is rendered identically regardless of the viewer's location.
|
|
224
235
|
|
|
225
236
|
<div class="exampleWrapper">
|
|
226
237
|
<!-- AURO-GENERATED-CONTENT:START (FILE:src=../apiExamples/plus-minus.html) -->
|
|
227
238
|
<!-- The below content is automatically added from ../apiExamples/plus-minus.html -->
|
|
228
|
-
<auro-datetime type="
|
|
229
|
-
<auro-datetime type="
|
|
239
|
+
<auro-datetime type="time" value="2022-07-13T21:35:00-07:00"></auro-datetime><br>
|
|
240
|
+
<auro-datetime type="date" value="2022-07-13T21:35:00-07:00"></auro-datetime>
|
|
230
241
|
<!-- AURO-GENERATED-CONTENT:END -->
|
|
231
242
|
</div>
|
|
232
243
|
<auro-accordion alignRight>
|
|
@@ -235,25 +246,22 @@ Example using `2022-07-13T21:35:00-07:00` with Pacific `(-07:00)` time zone duri
|
|
|
235
246
|
<!-- The below code snippet is automatically added from ../apiExamples/plus-minus.html -->
|
|
236
247
|
|
|
237
248
|
```html
|
|
238
|
-
<auro-datetime type="
|
|
239
|
-
<auro-datetime type="
|
|
249
|
+
<auro-datetime type="time" value="2022-07-13T21:35:00-07:00"></auro-datetime><br>
|
|
250
|
+
<auro-datetime type="date" value="2022-07-13T21:35:00-07:00"></auro-datetime>
|
|
240
251
|
```
|
|
241
252
|
<!-- AURO-GENERATED-CONTENT:END -->
|
|
242
253
|
</auro-accordion>
|
|
243
254
|
|
|
244
|
-
###
|
|
255
|
+
### UTC (Zulu) input
|
|
245
256
|
|
|
246
|
-
|
|
247
|
-
`YYYY-MM-DDTHH:MM:SSZ`</auro-alert>
|
|
248
|
-
<br />
|
|
249
|
-
Using the `utc` property, be sure to only use a properly-formatted UTC code.
|
|
257
|
+
The `value` attribute also accepts ISO 8601 strings ending in the `Z` designator. Without a `timeZone` attribute, the wall-clock components are rendered as written. To convert into a viewer-meaningful timezone, also set `timeZone` (see the timezone example).
|
|
250
258
|
|
|
251
259
|
<div class="exampleWrapper">
|
|
252
260
|
<!-- AURO-GENERATED-CONTENT:START (FILE:src=../apiExamples/utc.html) -->
|
|
253
261
|
<!-- The below content is automatically added from ../apiExamples/utc.html -->
|
|
254
|
-
<auro-datetime
|
|
255
|
-
<auro-datetime type="time"
|
|
256
|
-
<auro-datetime weekday="long" month="long"
|
|
262
|
+
<auro-datetime value="2020-09-22T01:38:22Z"></auro-datetime><br>
|
|
263
|
+
<auro-datetime type="time" value="2020-09-22T01:38:22Z"></auro-datetime><br>
|
|
264
|
+
<auro-datetime weekday="long" month="long" value="2020-09-22T01:38:22Z"></auro-datetime>
|
|
257
265
|
<!-- AURO-GENERATED-CONTENT:END -->
|
|
258
266
|
</div>
|
|
259
267
|
<auro-accordion alignRight>
|
|
@@ -262,13 +270,27 @@ Using the `utc` property, be sure to only use a properly-formatted UTC code.
|
|
|
262
270
|
<!-- The below code snippet is automatically added from ../apiExamples/utc.html -->
|
|
263
271
|
|
|
264
272
|
```html
|
|
265
|
-
<auro-datetime
|
|
266
|
-
<auro-datetime type="time"
|
|
267
|
-
<auro-datetime weekday="long" month="long"
|
|
273
|
+
<auro-datetime value="2020-09-22T01:38:22Z"></auro-datetime><br>
|
|
274
|
+
<auro-datetime type="time" value="2020-09-22T01:38:22Z"></auro-datetime><br>
|
|
275
|
+
<auro-datetime weekday="long" month="long" value="2020-09-22T01:38:22Z"></auro-datetime>
|
|
268
276
|
```
|
|
269
277
|
<!-- AURO-GENERATED-CONTENT:END -->
|
|
270
278
|
</auro-accordion>
|
|
271
279
|
|
|
280
|
+
### Combining `value` and `timeZone`
|
|
281
|
+
|
|
282
|
+
How the `timeZone` attribute composes with the input depends on whether `value` carries an offset:
|
|
283
|
+
|
|
284
|
+
- **`value` has an offset (or `Z`):** the offset anchors the absolute moment; `timeZone` is the display zone. Example: `value="2022-07-14T08:00:00-04:00" timezone="US/Pacific"` renders as `5:00 am` (8am Eastern → 5am Pacific).
|
|
285
|
+
- **`value` has no offset:** the wall-clock is interpreted as being in `timeZone`, so display in that same zone matches the input verbatim. Example: `value="2022-07-14T08:00:00" timezone="US/Eastern"` renders as `8:00 am` regardless of where the viewer is. This is the recommended shape when consumers know the source zone but don't have an offset readily available (e.g. flight-schedule data keyed by airport).
|
|
286
|
+
|
|
287
|
+
#### Invalid `timeZone` and `locale` values
|
|
288
|
+
|
|
289
|
+
Both attributes are validated up-front. Invalid inputs do **not** crash the component — they fall back gracefully and log a `console.warn` (deduplicated per element):
|
|
290
|
+
|
|
291
|
+
- **Invalid `locale`** (e.g. `"xx-INVALID-tag"`) → falls back to `"en-US"`.
|
|
292
|
+
- **Invalid `timeZone`** (e.g. `"US/Pacfic"` typo) → falls back to behaving as if `timeZone` was not specified. With `value` set, that means wall-clock display from the input components — visually the same string for every viewer. With `value` unset, that means the current time in the viewer's machine zone. The warning surfaces the typo so the developer can fix it.
|
|
293
|
+
|
|
272
294
|
## Slot Examples
|
|
273
295
|
|
|
274
296
|
### Pre and Post Slots
|
|
@@ -313,8 +335,8 @@ Example using `2022-07-14T06:00:00-04:00` with Eastern `(-04:00)` time zone.
|
|
|
313
335
|
<div class="exampleWrapper">
|
|
314
336
|
<!-- AURO-GENERATED-CONTENT:START (FILE:src=../apiExamples/east-plus-minus.html) -->
|
|
315
337
|
<!-- The below content is automatically added from ../apiExamples/east-plus-minus.html -->
|
|
316
|
-
<auro-datetime type="
|
|
317
|
-
<auro-datetime type="
|
|
338
|
+
<auro-datetime type="time" value="2022-07-14T06:00:00-04:00"></auro-datetime><br>
|
|
339
|
+
<auro-datetime type="date" value="2022-07-14T06:00:00-04:00"></auro-datetime>
|
|
318
340
|
<!-- AURO-GENERATED-CONTENT:END -->
|
|
319
341
|
</div>
|
|
320
342
|
<auro-accordion alignRight>
|
|
@@ -323,8 +345,8 @@ Example using `2022-07-14T06:00:00-04:00` with Eastern `(-04:00)` time zone.
|
|
|
323
345
|
<!-- The below code snippet is automatically added from ../apiExamples/east-plus-minus.html -->
|
|
324
346
|
|
|
325
347
|
```html
|
|
326
|
-
<auro-datetime type="
|
|
327
|
-
<auro-datetime type="
|
|
348
|
+
<auro-datetime type="time" value="2022-07-14T06:00:00-04:00"></auro-datetime><br>
|
|
349
|
+
<auro-datetime type="date" value="2022-07-14T06:00:00-04:00"></auro-datetime>
|
|
328
350
|
```
|
|
329
351
|
<!-- AURO-GENERATED-CONTENT:END -->
|
|
330
352
|
</auro-accordion>
|
|
@@ -336,8 +358,8 @@ Example using `2022-07-14T08:00:00-10:00` with Hawaii `(-10:00)` time zone.
|
|
|
336
358
|
<div class="exampleWrapper">
|
|
337
359
|
<!-- AURO-GENERATED-CONTENT:START (FILE:src=../apiExamples/hawaii-plus-minus.html) -->
|
|
338
360
|
<!-- The below content is automatically added from ../apiExamples/hawaii-plus-minus.html -->
|
|
339
|
-
<auro-datetime type="
|
|
340
|
-
<auro-datetime type="
|
|
361
|
+
<auro-datetime type="time" value="2022-07-16T08:00:00-10:00"></auro-datetime><br>
|
|
362
|
+
<auro-datetime type="date" value="2022-07-16T08:00:00-10:00"></auro-datetime>
|
|
341
363
|
<!-- AURO-GENERATED-CONTENT:END -->
|
|
342
364
|
</div>
|
|
343
365
|
<auro-accordion alignRight>
|
|
@@ -346,8 +368,8 @@ Example using `2022-07-14T08:00:00-10:00` with Hawaii `(-10:00)` time zone.
|
|
|
346
368
|
<!-- The below code snippet is automatically added from ../apiExamples/hawaii-plus-minus.html -->
|
|
347
369
|
|
|
348
370
|
```html
|
|
349
|
-
<auro-datetime type="
|
|
350
|
-
<auro-datetime type="
|
|
371
|
+
<auro-datetime type="time" value="2022-07-16T08:00:00-10:00"></auro-datetime><br>
|
|
372
|
+
<auro-datetime type="date" value="2022-07-16T08:00:00-10:00"></auro-datetime>
|
|
351
373
|
```
|
|
352
374
|
<!-- AURO-GENERATED-CONTENT:END -->
|
|
353
|
-
</auro-accordion>
|
|
375
|
+
</auro-accordion>
|
|
@@ -111,6 +111,9 @@ const t=globalThis,i$1=t=>t,s$1=t.trustedTypes,e=s$1?s$1.createPolicy("lit-html"
|
|
|
111
111
|
// See LICENSE in the project root for license information.
|
|
112
112
|
|
|
113
113
|
|
|
114
|
+
const ISO_8601_REGEX =
|
|
115
|
+
/^(\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?)?)(Z|[+-]\d{2}:\d{2})?$/u;
|
|
116
|
+
|
|
114
117
|
// See https://git.io/JJ6SJ for "How to document your components using JSDoc"
|
|
115
118
|
/**
|
|
116
119
|
* The `auro-datetime` element is for the purposes of providing an easy to use date and time API.
|
|
@@ -133,12 +136,97 @@ class AuroDatetime extends i {
|
|
|
133
136
|
this.month = "short";
|
|
134
137
|
this.locale = "en-US";
|
|
135
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Tracks invalid locale inputs already warned about, so a parent that
|
|
141
|
+
* re-renders with the same bad value doesn't flood the console.
|
|
142
|
+
* @private
|
|
143
|
+
*/
|
|
144
|
+
this._warnedLocales = new Set();
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Tracks invalid timeZone inputs already warned about. Same dedup
|
|
148
|
+
* pattern as `_warnedLocales`.
|
|
149
|
+
* @private
|
|
150
|
+
*/
|
|
151
|
+
this._warnedTimeZones = new Set();
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* @private
|
|
155
|
+
*/
|
|
156
|
+
this._effectiveLocale = this._resolveLocale(this.locale);
|
|
157
|
+
|
|
136
158
|
/**
|
|
137
159
|
* @private
|
|
138
160
|
*/
|
|
139
161
|
this.runtimeUtils = new AuroLibraryRuntimeUtils();
|
|
140
162
|
}
|
|
141
163
|
|
|
164
|
+
/**
|
|
165
|
+
* Validate and canonicalize a BCP 47 locale tag. Falls back to "en-US"
|
|
166
|
+
* for empty or invalid input. The first invalid value seen per element
|
|
167
|
+
* is logged via `console.warn`; subsequent identical inputs are silent.
|
|
168
|
+
*
|
|
169
|
+
* @private
|
|
170
|
+
* @param {string} input - User-supplied locale tag.
|
|
171
|
+
* @returns {string} Canonical locale tag (e.g. "en-GB"), or "en-US" on fallback.
|
|
172
|
+
*/
|
|
173
|
+
_resolveLocale(input) {
|
|
174
|
+
if (!input) {
|
|
175
|
+
return "en-US";
|
|
176
|
+
}
|
|
177
|
+
try {
|
|
178
|
+
return Intl.getCanonicalLocales(input)[0];
|
|
179
|
+
} catch {
|
|
180
|
+
if (this._warnedLocales && !this._warnedLocales.has(input)) {
|
|
181
|
+
this._warnedLocales.add(input);
|
|
182
|
+
console.warn(
|
|
183
|
+
`auro-datetime: "${input}" is not a valid BCP 47 locale tag. Falling back to "en-US".`,
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
return "en-US";
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Validate an IANA timezone identifier. Invalid input warns once per
|
|
192
|
+
* unique value per element and resolves to `undefined`, which makes
|
|
193
|
+
* the rest of `_resolveInputDate` behave as if `timeZone` was never
|
|
194
|
+
* specified — i.e. wall-clock display from the input components.
|
|
195
|
+
*
|
|
196
|
+
* Without this guard, a typo like `"US/Pacfic"` would cause
|
|
197
|
+
* `Intl.DateTimeFormat` / `toLocaleString` to throw `RangeError` at
|
|
198
|
+
* render time and crash the component.
|
|
199
|
+
*
|
|
200
|
+
* Note: when `value` is also unset, the wall-clock branch resolves to
|
|
201
|
+
* "today's date in the viewer's machine zone," which is viewer-
|
|
202
|
+
* dependent. This narrow case is the only scenario where two viewers
|
|
203
|
+
* see different output for the same component; the warning surfaces
|
|
204
|
+
* the typo so the developer can fix it.
|
|
205
|
+
*
|
|
206
|
+
* @private
|
|
207
|
+
* @param {string | undefined} input - Consumer-supplied timezone.
|
|
208
|
+
* @returns {string | undefined} Valid timezone, or undefined on fallback.
|
|
209
|
+
*/
|
|
210
|
+
_resolveTimeZone(input) {
|
|
211
|
+
if (!input) {
|
|
212
|
+
return undefined;
|
|
213
|
+
}
|
|
214
|
+
try {
|
|
215
|
+
// Constructing the formatter is enough to surface a RangeError;
|
|
216
|
+
// we don't need to format anything yet.
|
|
217
|
+
new Intl.DateTimeFormat(undefined, { timeZone: input });
|
|
218
|
+
return input;
|
|
219
|
+
} catch {
|
|
220
|
+
if (this._warnedTimeZones && !this._warnedTimeZones.has(input)) {
|
|
221
|
+
this._warnedTimeZones.add(input);
|
|
222
|
+
console.warn(
|
|
223
|
+
`auro-datetime: "${input}" is not a valid IANA timezone. Falling back to viewer-local.`,
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
return undefined;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
142
230
|
connectedCallback() {
|
|
143
231
|
super.connectedCallback();
|
|
144
232
|
|
|
@@ -152,10 +240,7 @@ class AuroDatetime extends i {
|
|
|
152
240
|
this.timeTemplate = {
|
|
153
241
|
hour: "2-digit",
|
|
154
242
|
minute: "2-digit",
|
|
155
|
-
timeZone: this.timeZone,
|
|
156
243
|
};
|
|
157
|
-
|
|
158
|
-
this.template = {};
|
|
159
244
|
}
|
|
160
245
|
|
|
161
246
|
// function to define props used within the scope of this component
|
|
@@ -163,11 +248,6 @@ class AuroDatetime extends i {
|
|
|
163
248
|
return {
|
|
164
249
|
// ...super.properties,
|
|
165
250
|
|
|
166
|
-
/**
|
|
167
|
-
* Capitalize AM or PM designation
|
|
168
|
-
*/
|
|
169
|
-
cap: { type: Boolean },
|
|
170
|
-
|
|
171
251
|
/**
|
|
172
252
|
* BCP 47 language tag for locale-aware date/time formatting (e.g. 'en-GB', 'de-DE', 'ja-JP').
|
|
173
253
|
* @type {string}
|
|
@@ -183,25 +263,29 @@ class AuroDatetime extends i {
|
|
|
183
263
|
month: { type: String },
|
|
184
264
|
|
|
185
265
|
/**
|
|
186
|
-
* Pass in string to
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Pass in string to define [timeZone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)
|
|
266
|
+
* Pass in string to define [timeZone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
|
|
267
|
+
* When set, the moment described by `value` is converted into this IANA zone for display.
|
|
268
|
+
* When unset, the wall-clock time from the input string is rendered as-is.
|
|
192
269
|
*/
|
|
193
270
|
timeZone: { type: String },
|
|
194
271
|
|
|
195
272
|
/**
|
|
196
273
|
* Defines type of data to render
|
|
197
|
-
* @type {'date' | 'time' | 'year' | 'month' | 'weekday' | 'day' | 'numeric'
|
|
274
|
+
* @type {'date' | 'time' | 'year' | 'month' | 'weekday' | 'day' | 'numeric'}
|
|
198
275
|
*/
|
|
199
276
|
type: { type: String },
|
|
200
277
|
|
|
201
278
|
/**
|
|
202
|
-
*
|
|
279
|
+
* ISO 8601 date or date-time string. Examples:
|
|
280
|
+
* - `2022-07-14T08:00:00-07:00` (with offset)
|
|
281
|
+
* - `2022-07-14T08:00:00Z` (UTC)
|
|
282
|
+
* - `2022-07-14T08:00:00` (no offset)
|
|
283
|
+
* - `2022-07-14` (date only)
|
|
284
|
+
*
|
|
285
|
+
* When omitted, the component renders today's date.
|
|
286
|
+
* Invalid input is logged as a warning and renders nothing.
|
|
203
287
|
*/
|
|
204
|
-
|
|
288
|
+
value: { type: String },
|
|
205
289
|
|
|
206
290
|
/**
|
|
207
291
|
* Defines format of weekday
|
|
@@ -226,16 +310,7 @@ class AuroDatetime extends i {
|
|
|
226
310
|
|
|
227
311
|
willUpdate(changedProperties) {
|
|
228
312
|
if (changedProperties.has("locale")) {
|
|
229
|
-
|
|
230
|
-
this.locale = "en-US";
|
|
231
|
-
} else {
|
|
232
|
-
try {
|
|
233
|
-
Intl.getCanonicalLocales(this.locale);
|
|
234
|
-
} catch {
|
|
235
|
-
console.warn(`auro-datetime: "${this.locale}" is not a valid BCP 47 locale tag. Falling back to "en-US".`);
|
|
236
|
-
this.locale = "en-US";
|
|
237
|
-
}
|
|
238
|
-
}
|
|
313
|
+
this._effectiveLocale = this._resolveLocale(this.locale);
|
|
239
314
|
}
|
|
240
315
|
}
|
|
241
316
|
|
|
@@ -245,170 +320,230 @@ class AuroDatetime extends i {
|
|
|
245
320
|
}
|
|
246
321
|
|
|
247
322
|
/**
|
|
248
|
-
*
|
|
323
|
+
* Construct a UTC Date that, when displayed in the given IANA timezone,
|
|
324
|
+
* shows the supplied wall-clock components. Used when `value` has no
|
|
325
|
+
* offset but `timeZone` is set — the wall-clock is interpreted as being
|
|
326
|
+
* in the target zone rather than the viewer's local zone.
|
|
327
|
+
*
|
|
328
|
+
* Algorithm: parse the wall-clock as if it were UTC (a "naive" Date),
|
|
329
|
+
* ask Intl what that moment looks like in the target zone, and use the
|
|
330
|
+
* delta between the two to recover the true UTC moment.
|
|
331
|
+
*
|
|
249
332
|
* @private
|
|
250
|
-
* @
|
|
333
|
+
* @param {string} localISO - ISO string with no offset, e.g. "2022-07-14T08:00:00".
|
|
334
|
+
* @param {string} timeZone - IANA zone, e.g. "US/Eastern".
|
|
335
|
+
* @returns {Date}
|
|
251
336
|
*/
|
|
252
|
-
|
|
253
|
-
|
|
337
|
+
_zonedWallClockToUtc(localISO, timeZone) {
|
|
338
|
+
const naiveUtc = new Date(`${localISO}Z`);
|
|
339
|
+
const parts = new Intl.DateTimeFormat("en-US", {
|
|
340
|
+
timeZone,
|
|
341
|
+
hourCycle: "h23",
|
|
342
|
+
year: "numeric",
|
|
343
|
+
month: "2-digit",
|
|
344
|
+
day: "2-digit",
|
|
345
|
+
hour: "2-digit",
|
|
346
|
+
minute: "2-digit",
|
|
347
|
+
second: "2-digit",
|
|
348
|
+
}).formatToParts(naiveUtc);
|
|
349
|
+
const lookup = Object.fromEntries(
|
|
350
|
+
parts.filter((p) => p.type !== "literal").map((p) => [p.type, p.value]),
|
|
351
|
+
);
|
|
352
|
+
const seenInZone = new Date(
|
|
353
|
+
`${lookup.year}-${lookup.month}-${lookup.day}T${lookup.hour}:${lookup.minute}:${lookup.second}Z`,
|
|
354
|
+
);
|
|
355
|
+
const offsetMs = naiveUtc.getTime() - seenInZone.getTime();
|
|
356
|
+
return new Date(naiveUtc.getTime() + offsetMs);
|
|
357
|
+
}
|
|
254
358
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
359
|
+
/**
|
|
360
|
+
* Resolve the `value` and `timeZone` attributes into a Date and an optional
|
|
361
|
+
* timeZone option for `Intl.DateTimeFormat`.
|
|
362
|
+
*
|
|
363
|
+
* Behavior:
|
|
364
|
+
* - No `value`: returns today's date. `timeZone` (if any) is honored.
|
|
365
|
+
* - `value` invalid: warns and returns `{ date: null }`.
|
|
366
|
+
* - `timeZone` set + input has offset/Z: parses as an absolute moment
|
|
367
|
+
* (offset honored) and asks `toLocaleString` to convert into the target zone.
|
|
368
|
+
* - `timeZone` set + input has no offset: interprets the wall-clock as
|
|
369
|
+
* being in the target zone, so display in that zone matches the input
|
|
370
|
+
* verbatim. This is viewer-independent.
|
|
371
|
+
* - Default (no `timeZone`): strips the offset/Z from the input and treats
|
|
372
|
+
* the remaining wall-clock components as local time, so they render verbatim.
|
|
373
|
+
*
|
|
374
|
+
* @private
|
|
375
|
+
* @returns {{ date: Date | null, timeZoneOption: string | undefined }}
|
|
376
|
+
*/
|
|
377
|
+
_resolveInputDate() {
|
|
378
|
+
const resolvedTz = this._resolveTimeZone(this.timeZone);
|
|
379
|
+
|
|
380
|
+
if (!this.value) {
|
|
381
|
+
return { date: new Date(), timeZoneOption: resolvedTz };
|
|
260
382
|
}
|
|
261
383
|
|
|
262
|
-
|
|
384
|
+
const match = this.value.match(ISO_8601_REGEX);
|
|
385
|
+
if (!match) {
|
|
386
|
+
console.warn(
|
|
387
|
+
`auro-datetime: "${this.value}" is not a valid ISO 8601 string.`,
|
|
388
|
+
);
|
|
389
|
+
return { date: null, timeZoneOption: undefined };
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
const localPart = match[1];
|
|
393
|
+
const hasOffset = Boolean(match[2]);
|
|
394
|
+
const normalized = localPart.includes("T")
|
|
395
|
+
? localPart
|
|
396
|
+
: `${localPart}T00:00:00`;
|
|
397
|
+
|
|
398
|
+
// The regex only validates string shape, not value ranges — "2022-99-99"
|
|
399
|
+
// matches but produces an Invalid Date. Detect that and treat it like
|
|
400
|
+
// any other malformed input so render falls back to the documented
|
|
401
|
+
// empty output instead of "Invalid Date" or a thrown RangeError from
|
|
402
|
+
// downstream Intl calls.
|
|
403
|
+
const buildDate = () => {
|
|
404
|
+
if (resolvedTz && !hasOffset) {
|
|
405
|
+
return this._zonedWallClockToUtc(normalized, resolvedTz);
|
|
406
|
+
}
|
|
407
|
+
if (resolvedTz && hasOffset) {
|
|
408
|
+
return new Date(this.value);
|
|
409
|
+
}
|
|
410
|
+
// Wall-clock: keep the components in the input verbatim. JS parses
|
|
411
|
+
// bare "YYYY-MM-DD" as UTC midnight, which shifts the date in the
|
|
412
|
+
// viewer's timezone; appending a time forces local-time parsing.
|
|
413
|
+
return new Date(normalized);
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
const date = buildDate();
|
|
417
|
+
if (Number.isNaN(date.getTime())) {
|
|
418
|
+
console.warn(
|
|
419
|
+
`auro-datetime: "${this.value}" is not a valid ISO 8601 date.`,
|
|
420
|
+
);
|
|
421
|
+
return { date: null, timeZoneOption: undefined };
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
return { date, timeZoneOption: resolvedTz };
|
|
263
425
|
}
|
|
264
426
|
|
|
265
427
|
/**
|
|
266
|
-
* Internal function to
|
|
428
|
+
* Internal function to generate full date string.
|
|
267
429
|
* @private
|
|
268
430
|
* @returns {string} - Date string.
|
|
269
431
|
*/
|
|
270
|
-
|
|
271
|
-
|
|
432
|
+
humanDate() {
|
|
433
|
+
const { date, timeZoneOption } = this._resolveInputDate();
|
|
434
|
+
if (!date) {
|
|
435
|
+
return "";
|
|
436
|
+
}
|
|
437
|
+
const template = { ...this.dateTemplate };
|
|
438
|
+
if (timeZoneOption) {
|
|
439
|
+
template.timeZone = timeZoneOption;
|
|
440
|
+
}
|
|
441
|
+
return date.toLocaleString(this._effectiveLocale, template);
|
|
442
|
+
}
|
|
272
443
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
444
|
+
/**
|
|
445
|
+
* Internal function to format a single date part (year/month/weekday/day).
|
|
446
|
+
* @private
|
|
447
|
+
* @returns {string} - Date string.
|
|
448
|
+
*/
|
|
449
|
+
humanDateConversion() {
|
|
450
|
+
const { date, timeZoneOption } = this._resolveInputDate();
|
|
451
|
+
if (!date) {
|
|
452
|
+
return "";
|
|
453
|
+
}
|
|
454
|
+
const template = {};
|
|
455
|
+
if (timeZoneOption) {
|
|
456
|
+
template.timeZone = timeZoneOption;
|
|
278
457
|
}
|
|
279
458
|
|
|
280
459
|
switch (this.type) {
|
|
281
460
|
case "day":
|
|
282
|
-
|
|
461
|
+
template.day = "numeric";
|
|
283
462
|
break;
|
|
284
463
|
case "month":
|
|
285
|
-
|
|
464
|
+
template.month = this.month;
|
|
286
465
|
break;
|
|
287
466
|
case "year":
|
|
288
|
-
|
|
467
|
+
template.year = "numeric";
|
|
289
468
|
break;
|
|
290
469
|
case "weekday":
|
|
291
|
-
|
|
470
|
+
template.weekday = this.weekday;
|
|
292
471
|
break;
|
|
293
|
-
|
|
294
|
-
default:
|
|
295
|
-
this.template.weekday = this.template;
|
|
296
472
|
}
|
|
297
473
|
|
|
298
|
-
return
|
|
474
|
+
return date.toLocaleString(this._effectiveLocale, template);
|
|
299
475
|
}
|
|
300
476
|
|
|
301
477
|
/**
|
|
302
|
-
* Internal function generate numeric date string
|
|
478
|
+
* Internal function to generate numeric date string MM/DD/YYYY.
|
|
303
479
|
* @private
|
|
304
480
|
* @returns {string} - Date string.
|
|
305
481
|
*/
|
|
306
482
|
numericDate() {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
if (this.utc) {
|
|
312
|
-
this.dateTemplate.timeZone = "UTC";
|
|
313
|
-
newDate = new Date(this.utc);
|
|
314
|
-
} else if (this.setDate) {
|
|
315
|
-
newDate = new Date(this.setDate);
|
|
483
|
+
const { date, timeZoneOption } = this._resolveInputDate();
|
|
484
|
+
if (!date) {
|
|
485
|
+
return "";
|
|
316
486
|
}
|
|
317
|
-
|
|
318
|
-
|
|
487
|
+
const template = { ...this.dateTemplate, month: "numeric" };
|
|
488
|
+
Reflect.deleteProperty(template, "weekday");
|
|
489
|
+
if (timeZoneOption) {
|
|
490
|
+
template.timeZone = timeZoneOption;
|
|
491
|
+
}
|
|
492
|
+
return date.toLocaleString(this._effectiveLocale, template);
|
|
319
493
|
}
|
|
320
494
|
|
|
321
495
|
/**
|
|
322
|
-
* Internal function generate standard time string.
|
|
496
|
+
* Internal function to generate standard time string.
|
|
323
497
|
* @private
|
|
324
498
|
* @returns {string} - Time string.
|
|
325
499
|
*/
|
|
326
500
|
humanTime() {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
this.timeTemplate.timeZone = "UTC";
|
|
331
|
-
newTime = new Date(this.utc);
|
|
332
|
-
} else if (this.setDate) {
|
|
333
|
-
newTime = new Date(this.setDate);
|
|
501
|
+
const { date, timeZoneOption } = this._resolveInputDate();
|
|
502
|
+
if (!date) {
|
|
503
|
+
return "";
|
|
334
504
|
}
|
|
335
|
-
|
|
336
|
-
if (
|
|
337
|
-
|
|
338
|
-
.toLocaleString(this.locale, this.timeTemplate)
|
|
339
|
-
.replace(/^0+/u, "");
|
|
505
|
+
const template = { ...this.timeTemplate };
|
|
506
|
+
if (timeZoneOption) {
|
|
507
|
+
template.timeZone = timeZoneOption;
|
|
340
508
|
}
|
|
341
509
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
*/
|
|
354
|
-
tzTime(template) {
|
|
355
|
-
const scrubNumber = -6;
|
|
356
|
-
const scrubTimeZone = this.setDate.slice(0, scrubNumber);
|
|
357
|
-
const newDateTime = new Date(scrubTimeZone);
|
|
358
|
-
|
|
359
|
-
if (this.cap) {
|
|
360
|
-
return newDateTime.toLocaleString(this.locale, template).replace(/^0+/u, "");
|
|
510
|
+
const formatted = date.toLocaleString(this._effectiveLocale, template);
|
|
511
|
+
|
|
512
|
+
// Detect a 12-hour rendered output by the presence of a Latin-script
|
|
513
|
+
// period marker. The pattern matches `am`, `pm`, `a.m.`, `p.m.`
|
|
514
|
+
// (case-insensitive), so it catches en-US (`PM`), en-AU/hi-IN (`pm`),
|
|
515
|
+
// and en-CA/es-MX (`p.m.`) alike. Non-Latin period markers (ko `오후`,
|
|
516
|
+
// ar `م`, zh-TW `下午`) have no ASCII a/p+m chars and correctly fall
|
|
517
|
+
// through unchanged. 24h locales (en-GB, de-DE, fr-FR, ja-JP …) also
|
|
518
|
+
// fall through, preserving their leading zeros.
|
|
519
|
+
if (!/[ap]\.?m\.?/iu.test(formatted)) {
|
|
520
|
+
return formatted;
|
|
361
521
|
}
|
|
362
522
|
|
|
363
|
-
return
|
|
364
|
-
.toLocaleString(this.locale, template)
|
|
365
|
-
.replace(/^0+/u, "")
|
|
366
|
-
.replace("AM", "am")
|
|
367
|
-
.replace("PM", "pm");
|
|
523
|
+
return formatted.replace(/^0+/u, "").toLowerCase();
|
|
368
524
|
}
|
|
369
|
-
|
|
525
|
+
|
|
370
526
|
/**
|
|
371
527
|
* Internal function UI decision.
|
|
372
528
|
* @private
|
|
373
|
-
* @returns {
|
|
529
|
+
* @returns {string} - String determined by `type` (or full date if no type set).
|
|
374
530
|
*/
|
|
375
531
|
whichDate() {
|
|
376
|
-
let result = "";
|
|
377
|
-
|
|
378
532
|
switch (this.type) {
|
|
379
533
|
case "date":
|
|
380
|
-
|
|
381
|
-
break;
|
|
382
|
-
case "tzDate":
|
|
383
|
-
result = this.tzTime(this.dateTemplate);
|
|
384
|
-
break;
|
|
385
|
-
case "tzTime":
|
|
386
|
-
result = this.tzTime(this.timeTemplate);
|
|
387
|
-
break;
|
|
534
|
+
return this.humanDate();
|
|
388
535
|
case "time":
|
|
389
|
-
|
|
390
|
-
break;
|
|
536
|
+
return this.humanTime();
|
|
391
537
|
case "year":
|
|
392
538
|
case "month":
|
|
393
539
|
case "weekday":
|
|
394
540
|
case "day":
|
|
395
|
-
|
|
396
|
-
break;
|
|
541
|
+
return this.humanDateConversion();
|
|
397
542
|
case "numeric":
|
|
398
|
-
|
|
399
|
-
break;
|
|
543
|
+
return this.numericDate();
|
|
400
544
|
default:
|
|
401
|
-
this.humanDate();
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
if (this.setDate && !this.type) {
|
|
405
|
-
return this.humanDate();
|
|
406
|
-
}
|
|
407
|
-
if (this.utc && !this.type) {
|
|
408
|
-
return this.humanDate();
|
|
545
|
+
return this.humanDate();
|
|
409
546
|
}
|
|
410
|
-
|
|
411
|
-
return result;
|
|
412
547
|
}
|
|
413
548
|
|
|
414
549
|
// When using auroElement, use the following attribute and function when hiding content from screen readers.
|
|
@@ -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,a=t&&t.closest(e))=>t&&t!==document&&t!==window?a||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 a=/^(\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?)?)(Z|[+-]\d{2}:\d{2})?$/u;class i 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._effectiveLocale=this._resolveLocale(this.locale),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. Falling back to viewer-local.`)))}}connectedCallback(){super.connectedCallback(),this.dateTemplate={weekday:this.weekday,year:"numeric",month:this.month,day:"numeric"},this.timeTemplate={hour:"2-digit",minute:"2-digit"}}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,i)}willUpdate(e){e.has("locale")&&(this._effectiveLocale=this._resolveLocale(this.locale))}firstUpdated(){this.runtimeUtils.handleComponentTagRename(this,"auro-datetime")}_zonedWallClockToUtc(e,t){const n=new Date(`${e}Z`),a=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),i=Object.fromEntries(a.filter(e=>"literal"!==e.type).map(e=>[e.type,e.value])),o=new Date(`${i.year}-${i.month}-${i.day}T${i.hour}:${i.minute}:${i.second}Z`),s=n.getTime()-o.getTime();return new Date(n.getTime()+s)}_resolveInputDate(){const e=this._resolveTimeZone(this.timeZone);if(!this.value)return{date:new Date,timeZoneOption:e};const t=this.value.match(a);if(!t)return console.warn(`auro-datetime: "${this.value}" is not a valid ISO 8601 string.`),{date:null,timeZoneOption:void 0};const n=t[1],i=Boolean(t[2]),o=n.includes("T")?n:`${n}T00:00:00`,s=(()=>e&&!i?this._zonedWallClockToUtc(o,e):e&&i?new Date(this.value):new Date(o))();return Number.isNaN(s.getTime())?(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 n={...this.dateTemplate};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;break;case"year":n.year="numeric";break;case"weekday":n.weekday=this.weekday}return e.toLocaleString(this._effectiveLocale,n)}numericDate(){const{date:e,timeZoneOption:t}=this._resolveInputDate();if(!e)return"";const n={...this.dateTemplate,month:"numeric"};return Reflect.deleteProperty(n,"weekday"),t&&(n.timeZone=t),e.toLocaleString(this._effectiveLocale,n)}humanTime(){const{date:e,timeZoneOption:t}=this._resolveInputDate();if(!e)return"";const n={...this.timeTemplate};t&&(n.timeZone=t);const a=e.toLocaleString(this._effectiveLocale,n);return/[ap]\.?m\.?/iu.test(a)?a.replace(/^0+/u,"").toLowerCase():a}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{i as A};
|
package/dist/index.d.ts
CHANGED
|
@@ -73,39 +73,49 @@ type BaseProps<T extends HTMLElement> = {
|
|
|
73
73
|
type BaseEvents = {};
|
|
74
74
|
|
|
75
75
|
export type AuroDatetimeProps = {
|
|
76
|
-
/** Capitalize AM or PM designation */
|
|
77
|
-
cap?: AuroDatetime["cap"];
|
|
78
76
|
/** BCP 47 language tag for locale-aware date/time formatting (e.g. 'en-GB', 'de-DE', 'ja-JP'). */
|
|
79
77
|
locale?: AuroDatetime["locale"];
|
|
80
78
|
/** Defines format of month */
|
|
81
79
|
month?: AuroDatetime["month"];
|
|
82
|
-
/** Pass in string to
|
|
83
|
-
|
|
84
|
-
|
|
80
|
+
/** Pass in string to define [timeZone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
|
|
81
|
+
When set, the moment described by `value` is converted into this IANA zone for display.
|
|
82
|
+
When unset, the wall-clock time from the input string is rendered as-is. */
|
|
85
83
|
timeZone?: AuroDatetime["timeZone"];
|
|
86
84
|
/** Defines type of data to render */
|
|
87
85
|
type?: AuroDatetime["type"];
|
|
88
|
-
/**
|
|
89
|
-
|
|
86
|
+
/** ISO 8601 date or date-time string. Examples:
|
|
87
|
+
- `2022-07-14T08:00:00-07:00` (with offset)
|
|
88
|
+
- `2022-07-14T08:00:00Z` (UTC)
|
|
89
|
+
- `2022-07-14T08:00:00` (no offset)
|
|
90
|
+
- `2022-07-14` (date only)
|
|
91
|
+
|
|
92
|
+
When omitted, the component renders today's date.
|
|
93
|
+
Invalid input is logged as a warning and renders nothing. */
|
|
94
|
+
value?: AuroDatetime["value"];
|
|
90
95
|
/** Defines format of weekday */
|
|
91
96
|
weekday?: AuroDatetime["weekday"];
|
|
92
97
|
};
|
|
93
98
|
|
|
94
99
|
export type AuroDatetimeSolidJsProps = {
|
|
95
|
-
/** Capitalize AM or PM designation */
|
|
96
|
-
"prop:cap"?: AuroDatetime["cap"];
|
|
97
100
|
/** BCP 47 language tag for locale-aware date/time formatting (e.g. 'en-GB', 'de-DE', 'ja-JP'). */
|
|
98
101
|
"prop:locale"?: AuroDatetime["locale"];
|
|
99
102
|
/** Defines format of month */
|
|
100
103
|
"prop:month"?: AuroDatetime["month"];
|
|
101
|
-
/** Pass in string to
|
|
102
|
-
|
|
103
|
-
|
|
104
|
+
/** Pass in string to define [timeZone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
|
|
105
|
+
When set, the moment described by `value` is converted into this IANA zone for display.
|
|
106
|
+
When unset, the wall-clock time from the input string is rendered as-is. */
|
|
104
107
|
"prop:timeZone"?: AuroDatetime["timeZone"];
|
|
105
108
|
/** Defines type of data to render */
|
|
106
109
|
"prop:type"?: AuroDatetime["type"];
|
|
107
|
-
/**
|
|
108
|
-
|
|
110
|
+
/** ISO 8601 date or date-time string. Examples:
|
|
111
|
+
- `2022-07-14T08:00:00-07:00` (with offset)
|
|
112
|
+
- `2022-07-14T08:00:00Z` (UTC)
|
|
113
|
+
- `2022-07-14T08:00:00` (no offset)
|
|
114
|
+
- `2022-07-14` (date only)
|
|
115
|
+
|
|
116
|
+
When omitted, the component renders today's date.
|
|
117
|
+
Invalid input is logged as a warning and renders nothing. */
|
|
118
|
+
"prop:value"?: AuroDatetime["value"];
|
|
109
119
|
/** Defines format of weekday */
|
|
110
120
|
"prop:weekday"?: AuroDatetime["weekday"];
|
|
111
121
|
|
|
@@ -123,13 +133,20 @@ export type CustomElements = {
|
|
|
123
133
|
*
|
|
124
134
|
* Component attributes and properties that can be applied to the element or by using JavaScript.
|
|
125
135
|
*
|
|
126
|
-
* - `cap`: Capitalize AM or PM designation
|
|
127
136
|
* - `locale`: BCP 47 language tag for locale-aware date/time formatting (e.g. 'en-GB', 'de-DE', 'ja-JP').
|
|
128
137
|
* - `month`: Defines format of month
|
|
129
|
-
* - `
|
|
130
|
-
*
|
|
138
|
+
* - `timeZone`: Pass in string to define [timeZone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
|
|
139
|
+
* When set, the moment described by `value` is converted into this IANA zone for display.
|
|
140
|
+
* When unset, the wall-clock time from the input string is rendered as-is.
|
|
131
141
|
* - `type`: Defines type of data to render
|
|
132
|
-
* - `
|
|
142
|
+
* - `value`: ISO 8601 date or date-time string. Examples:
|
|
143
|
+
* - `2022-07-14T08:00:00-07:00` (with offset)
|
|
144
|
+
* - `2022-07-14T08:00:00Z` (UTC)
|
|
145
|
+
* - `2022-07-14T08:00:00` (no offset)
|
|
146
|
+
* - `2022-07-14` (date only)
|
|
147
|
+
*
|
|
148
|
+
* When omitted, the component renders today's date.
|
|
149
|
+
* Invalid input is logged as a warning and renders nothing.
|
|
133
150
|
* - `weekday`: Defines format of weekday
|
|
134
151
|
*
|
|
135
152
|
* ## Slots
|
|
@@ -159,13 +176,20 @@ export type CustomElementsSolidJs = {
|
|
|
159
176
|
*
|
|
160
177
|
* Component attributes and properties that can be applied to the element or by using JavaScript.
|
|
161
178
|
*
|
|
162
|
-
* - `cap`: Capitalize AM or PM designation
|
|
163
179
|
* - `locale`: BCP 47 language tag for locale-aware date/time formatting (e.g. 'en-GB', 'de-DE', 'ja-JP').
|
|
164
180
|
* - `month`: Defines format of month
|
|
165
|
-
* - `
|
|
166
|
-
*
|
|
181
|
+
* - `timeZone`: Pass in string to define [timeZone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
|
|
182
|
+
* When set, the moment described by `value` is converted into this IANA zone for display.
|
|
183
|
+
* When unset, the wall-clock time from the input string is rendered as-is.
|
|
167
184
|
* - `type`: Defines type of data to render
|
|
168
|
-
* - `
|
|
185
|
+
* - `value`: ISO 8601 date or date-time string. Examples:
|
|
186
|
+
* - `2022-07-14T08:00:00-07:00` (with offset)
|
|
187
|
+
* - `2022-07-14T08:00:00Z` (UTC)
|
|
188
|
+
* - `2022-07-14T08:00:00` (no offset)
|
|
189
|
+
* - `2022-07-14` (date only)
|
|
190
|
+
*
|
|
191
|
+
* When omitted, the component renders today's date.
|
|
192
|
+
* Invalid input is logged as a warning and renders nothing.
|
|
169
193
|
* - `weekday`: Defines format of weekday
|
|
170
194
|
*
|
|
171
195
|
* ## Slots
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{A as AuroDatetime}from"./auro-datetime-
|
|
1
|
+
export{A as AuroDatetime}from"./auro-datetime-Cml4cDmu.js";import"lit";
|
package/dist/registered.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{A as r}from"./auro-datetime-
|
|
1
|
+
import{A as r}from"./auro-datetime-Cml4cDmu.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-pr82.
|
|
10
|
+
"version": "0.0.0-pr82.6",
|
|
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 a{registerComponent(e,t){customElements.get(e)||customElements.define(e,class extends t{})}closestElement(e,t=this,a=(t,s=t&&t.closest(e))=>t&&t!==document&&t!==window?s||a(t.getRootNode().host):null){return a(t)}handleComponentTagRename(e,t){const a=t.toLowerCase();e.tagName.toLowerCase()!==a&&e.setAttribute(a,!0)}elementMatch(e,t){const a=t.toLowerCase();return e.tagName.toLowerCase()===a||e.hasAttribute(a)}getSlotText(e,t){const a=e.shadowRoot?.querySelector(`slot[name="${t}"]`);return(a?.assignedNodes({flatten:!0})||[]).map(e=>e.textContent?.trim()).join(" ").trim()||null}}class s extends e{constructor(){super(),this._initializeDefaults()}_initializeDefaults(){this.weekday="short",this.month="short",this.locale="en-US",this.runtimeUtils=new a}connectedCallback(){super.connectedCallback(),this.dateTemplate={weekday:this.weekday,year:"numeric",month:this.month,day:"numeric"},this.timeTemplate={hour:"2-digit",minute:"2-digit",timeZone:this.timeZone},this.template={}}static get properties(){return{cap:{type:Boolean},locale:{type:String},month:{type:String},setDate:{type:String},timeZone:{type:String},type:{type:String},utc:{type:String},weekday:{type:String}}}static register(e="auro-datetime"){a.prototype.registerComponent(e,s)}willUpdate(e){if(e.has("locale"))if(this.locale)try{Intl.getCanonicalLocales(this.locale)}catch{console.warn(`auro-datetime: "${this.locale}" is not a valid BCP 47 locale tag. Falling back to "en-US".`),this.locale="en-US"}else this.locale="en-US"}firstUpdated(){this.runtimeUtils.handleComponentTagRename(this,"auro-datetime")}humanDate(){let e=new Date;return this.utc?(this.dateTemplate.timeZone="UTC",e=new Date(this.utc)):this.setDate&&(e=new Date(this.setDate)),e.toLocaleString(this.locale,this.dateTemplate)}humanDateConversion(){let e=new Date;switch(this.utc?(this.template.timeZone="UTC",e=new Date(this.utc)):this.setDate&&(e=new Date(this.setDate)),this.type){case"day":this.template.day="numeric";break;case"month":this.template.month=this.month;break;case"year":this.template.year="numeric";break;case"weekday":this.template.weekday=this.weekday;break;default:this.template.weekday=this.template}return e.toLocaleString(this.locale,this.template)}numericDate(){this.dateTemplate.month="numeric",Reflect.deleteProperty(this.dateTemplate,"weekday");let e=new Date;return this.utc?(this.dateTemplate.timeZone="UTC",e=new Date(this.utc)):this.setDate&&(e=new Date(this.setDate)),e.toLocaleString(this.locale,this.dateTemplate)}humanTime(){let e=new Date;return this.utc?(this.timeTemplate.timeZone="UTC",e=new Date(this.utc)):this.setDate&&(e=new Date(this.setDate)),this.cap?e.toLocaleString(this.locale,this.timeTemplate).replace(/^0+/u,""):e.toLocaleString(this.locale,this.timeTemplate).replace(/^0+/u,"").toLowerCase()}tzTime(e){const t=this.setDate.slice(0,-6),a=new Date(t);return this.cap?a.toLocaleString(this.locale,e).replace(/^0+/u,""):a.toLocaleString(this.locale,e).replace(/^0+/u,"").replace("AM","am").replace("PM","pm")}whichDate(){let e="";switch(this.type){case"date":e=this.humanDate();break;case"tzDate":e=this.tzTime(this.dateTemplate);break;case"tzTime":e=this.tzTime(this.timeTemplate);break;case"time":e=this.humanTime();break;case"year":case"month":case"weekday":case"day":e=this.humanDateConversion();break;case"numeric":e=this.numericDate();break;default:this.humanDate()}return this.setDate&&!this.type||this.utc&&!this.type?this.humanDate():e}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{s as A};
|