@aurodesignsystem-dev/auro-datetime 0.0.0-pr110.0 → 0.0.0-pr112.0

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/index.min.js CHANGED
@@ -114,16 +114,29 @@ const t=globalThis,i$1=t=>t,s$1=t.trustedTypes,e=s$1?s$1.createPolicy("lit-html"
114
114
  const ISO_8601_REGEX =
115
115
  /^(\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?)?)(Z|[+-]\d{2}:\d{2})?$/u;
116
116
 
117
- // See https://git.io/JJ6SJ for "How to document your components using JSDoc"
118
117
  /**
119
- * The `auro-datetime` element is for the purposes of providing an easy to use date and time API.
118
+ * Shows a date or time as text, formatted for a language and region you choose and, optionally, a specific time zone.
119
+ *
120
+ * **Key capabilities**
121
+ * - **What to show**: `type` picks the full date, the time, a numeric date, or a single part, such as the year or weekday.
122
+ * - **Date and time to show**: `value` takes an ISO 8601 date or date-time; without it, the element shows the current date and time.
123
+ * - **Language formatting**: `locale` formats month names, separators, and the 12- or 24-hour clock for a language, such as `de-DE`.
124
+ * - **Time zones**: `timezone` shows the moment in a time zone, such as `America/Los_Angeles`.
125
+ * - **Name length**: `month="long"` and `weekday="long"` spell out the month and weekday names.
126
+ *
127
+ * **Example**
128
+ * ```html
129
+ * <auro-datetime type="date" value="2022-07-14T08:00:00"></auro-datetime>
130
+ * ```
131
+ *
132
+ * @summary Date or time text formatted by language and time zone, with full, numeric, and single-part formats.
120
133
  * @customElement auro-datetime
121
134
  *
122
- * @slot pre - Content that comes before the `post` content
123
- * @slot post - Content that comes after the `pre` content
135
+ * @slot pre - Content shown before the date or time, such as "Departs". The element doesn't currently let content sit right against the date or time: this content, or text right before the element, always shows with a space between it and the date or time. {@category ui}
136
+ * @slot post - Content shown after the date or time, such as "local time". The element doesn't currently let content sit right against the date or time: this content, or text right after the element, always shows with a space between them, so a period or comma can't follow the date or time directly. {@category ui}
137
+ * @slot - Content shown after the `post` slot's content, such as the end of a sentence that includes the date. {@category ui}
124
138
  */
125
139
 
126
- // build the component class
127
140
  class AuroDatetime extends i {
128
141
  constructor() {
129
142
  super();
@@ -131,6 +144,11 @@ class AuroDatetime extends i {
131
144
  this._initializeDefaults();
132
145
  }
133
146
 
147
+ /**
148
+ * Sets the element's default values.
149
+ * @private
150
+ * @returns {void}
151
+ */
134
152
  _initializeDefaults() {
135
153
  this.weekday = "short";
136
154
  this.month = "short";
@@ -144,15 +162,15 @@ class AuroDatetime extends i {
144
162
  this._warnedLocales = new Set();
145
163
 
146
164
  /**
147
- * Tracks invalid timeZone inputs already warned about. Same dedup
148
- * pattern as `_warnedLocales`.
165
+ * Tracks invalid `timezone` values this element has already warned
166
+ * about, so the same bad value logs only one warning.
149
167
  * @private
150
168
  */
151
169
  this._warnedTimeZones = new Set();
152
170
 
153
171
  /**
154
- * Tracks invalid value inputs already warned about. Same dedup
155
- * pattern as `_warnedLocales`.
172
+ * Tracks invalid `value` inputs this element has already warned about,
173
+ * so the same bad value logs only one warning.
156
174
  * @private
157
175
  */
158
176
  this._warnedValues = new Set();
@@ -174,13 +192,13 @@ class AuroDatetime extends i {
174
192
  }
175
193
 
176
194
  /**
177
- * Validate and canonicalize a BCP 47 locale tag. Falls back to "en-US"
178
- * for empty or invalid input. The first invalid value seen per element
179
- * is logged via `console.warn`; subsequent identical inputs are silent.
195
+ * Checks a BCP 47 locale tag and returns its canonical form. Empty or invalid
196
+ * input falls back to "en-US". Each invalid value logs a console warning the
197
+ * first time this element sees it.
180
198
  *
181
199
  * @private
182
- * @param {string} input - User-supplied locale tag.
183
- * @returns {string} Canonical locale tag (e.g. "en-GB"), or "en-US" on fallback.
200
+ * @param {string} input - The locale tag set on the element.
201
+ * @returns {string} The canonical locale tag, such as "en-GB", or "en-US" for empty or invalid input.
184
202
  */
185
203
  _resolveLocale(input) {
186
204
  if (!input) {
@@ -200,121 +218,92 @@ class AuroDatetime extends i {
200
218
  }
201
219
 
202
220
  /**
203
- * Validate an IANA timezone identifier. Invalid input warns once per
204
- * unique value per element and resolves to `undefined`, which makes
205
- * the rest of `_resolveInputDate` behave as if `timezone` was never
206
- * specified — i.e. wall-clock display from the input components.
207
- *
208
- * Without this guard, a typo like `"US/Pacfic"` would cause
209
- * `Intl.DateTimeFormat` / `toLocaleString` to throw `RangeError` at
210
- * render time and crash the component.
211
- *
212
- * Note: when `value` is also unset, the wall-clock branch resolves to
213
- * "today's date in the viewer's machine zone," which is viewer-
214
- * dependent. This narrow case is the only scenario where two viewers
215
- * see different output for the same component; the warning surfaces
216
- * the typo so the developer can fix it.
221
+ * Checks an IANA time zone name. An invalid name logs a console warning
222
+ * the first time this element sees it and returns `undefined`, so the
223
+ * element acts as if `timezone` isn't set.
217
224
  *
218
225
  * @private
219
- * @param {string | undefined} input - Consumer-supplied timezone.
220
- * @returns {string | undefined} Valid timezone, or undefined on fallback.
226
+ * @param {string | undefined} input - The time zone name set on the element.
227
+ * @returns {string | undefined} The time zone name if it's valid; otherwise, `undefined`.
221
228
  */
222
229
  _resolveTimeZone(input) {
223
230
  if (!input) {
224
231
  return undefined;
225
232
  }
226
233
  try {
227
- // Constructing the formatter is enough to surface a RangeError;
228
- // we don't need to format anything yet.
234
+ // Creating the formatter is enough to catch an invalid name. Without
235
+ // this check, a typo such as "America/Los_Angles" makes
236
+ // Intl.DateTimeFormat and toLocaleString throw a RangeError at render
237
+ // time.
229
238
  new Intl.DateTimeFormat(undefined, { timeZone: input });
230
239
  return input;
231
240
  } catch {
232
241
  if (this._warnedTimeZones && !this._warnedTimeZones.has(input)) {
233
242
  this._warnedTimeZones.add(input);
234
243
  console.warn(
235
- `auro-datetime: "${input}" is not a valid IANA timezone. Falling back to viewer-local.`,
244
+ `auro-datetime: "${input}" is not a valid IANA timezone. Ignoring it.`,
236
245
  );
237
246
  }
238
247
  return undefined;
239
248
  }
240
249
  }
241
250
 
242
- connectedCallback() {
243
- super.connectedCallback();
244
-
245
- this.dateTemplate = {
246
- weekday: this.weekday,
247
- year: "numeric",
248
- month: this.month,
249
- day: "numeric",
250
- };
251
-
252
- this.timeTemplate = {
253
- hour: "2-digit",
254
- minute: "2-digit",
255
- };
256
- }
257
-
258
- // function to define props used within the scope of this component
259
251
  static get properties() {
260
252
  return {
261
- // ...super.properties,
262
-
263
253
  /**
264
- * BCP 47 language tag for locale-aware date/time formatting (e.g. 'en-GB', 'de-DE', 'ja-JP').
254
+ * 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.
265
255
  * @type {string}
266
- * @default 'en-US'
256
+ * @default "en-US"
257
+ * @category ui
267
258
  */
268
259
  locale: { type: String },
269
260
 
270
261
  /**
271
- * Defines format of month
272
- * @type {'short' | 'long'}
273
- * @default 'short'
262
+ * 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"`.
263
+ * @type {"short" | "long"}
264
+ * @default "short"
265
+ * @category ui
274
266
  */
275
267
  month: { type: String },
276
268
 
277
269
  /**
278
- * Pass in string to define [timezone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
279
- * When set, the moment described by `value` is converted into this IANA zone for display.
280
- * When unset, the wall-clock time from the input string is rendered as-is.
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.
271
+ * @type {string}
272
+ * @category behavior
281
273
  */
282
274
  timezone: { type: String },
283
275
 
284
276
  /**
285
- * Defines type of data to render
286
- * @type {'date' | 'time' | 'year' | 'month' | 'weekday' | 'day' | 'numeric'}
277
+ * 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.
278
+ * @type {"date" | "time" | "year" | "month" | "weekday" | "day" | "numeric"}
279
+ * @category ui
287
280
  */
288
281
  type: { type: String },
289
282
 
290
283
  /**
291
- * ISO 8601 date or date-time string. Examples:
292
- * - `2022-07-14T08:00:00-07:00` (with offset)
293
- * - `2022-07-14T08:00:00Z` (UTC)
294
- * - `2022-07-14T08:00:00` (no offset)
295
- * - `2022-07-14` (date only)
296
- *
297
- * When omitted, the component renders today's date.
298
- * Invalid input is logged as a warning and renders nothing.
284
+ * Sets the date or time to show, as an ISO 8601 date or date-time, 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, logs a console warning and shows nothing.
285
+ * @type {string}
286
+ * @category behavior
299
287
  */
300
288
  value: { type: String },
301
289
 
302
290
  /**
303
- * Defines format of weekday
304
- * @type {'short' | 'long'}
305
- * @default 'short'
291
+ * 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"`.
292
+ * @type {"short" | "long"}
293
+ * @default "short"
294
+ * @category ui
306
295
  */
307
296
  weekday: { type: String },
308
297
  };
309
298
  }
310
299
 
311
300
  /**
312
- * This will register this element with the browser.
313
- * @param {string} [name="auro-datetime"] - The name of the element that you want to register.
301
+ * Registers the element with the browser under a tag name. Use a custom name to run more than one version of the element on the same page. If the tag name is already registered, it does nothing.
302
+ * @param {string} [name="auro-datetime"] - The tag name to register the element under, such as `custom-datetime`.
303
+ * @returns {void}
314
304
  *
315
305
  * @example
316
- * AuroDatetime.register("custom-datetime") // this will register this element to <custom-datetime/>
317
- *
306
+ * AuroDatetime.register("custom-datetime"); // registers <custom-datetime>
318
307
  */
319
308
  static register(name = "auro-datetime") {
320
309
  AuroLibraryRuntimeUtils.prototype.registerComponent(name, AuroDatetime);
@@ -330,24 +319,24 @@ class AuroDatetime extends i {
330
319
  }
331
320
 
332
321
  firstUpdated() {
333
- // Add the tag name as an attribute if it is different than the component name
322
+ // Adds the tag name as an attribute when it differs from auro-datetime.
334
323
  this.runtimeUtils.handleComponentTagRename(this, "auro-datetime");
335
324
  }
336
325
 
337
326
  /**
338
- * Construct a UTC Date that, when displayed in the given IANA timezone,
339
- * shows the supplied wall-clock components. Used when `value` has no
340
- * offset but `timeZone` is set — the wall-clock is interpreted as being
341
- * in the target zone rather than the viewer's local zone.
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.
342
331
  *
343
- * Algorithm: parse the wall-clock as if it were UTC (a "naive" Date),
344
- * ask Intl what that moment looks like in the target zone, and use the
345
- * delta between the two to recover the true UTC moment.
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.
346
335
  *
347
336
  * @private
348
- * @param {string} localISO - ISO string with no offset, e.g. "2022-07-14T08:00:00".
349
- * @param {string} timeZone - IANA zone, e.g. "US/Eastern".
350
- * @returns {Date}
337
+ * @param {string} localISO - The ISO 8601 date-time with no offset, such as "2022-07-14T08:00:00".
338
+ * @param {string} timeZone - The IANA time zone name, such as "America/New_York".
339
+ * @returns {Date} The moment that reads as `localISO` in `timeZone`.
351
340
  */
352
341
  _zonedWallClockToUtc(localISO, timeZone) {
353
342
  const naiveUtc = new Date(`${localISO}Z`);
@@ -372,34 +361,33 @@ class AuroDatetime extends i {
372
361
  }
373
362
 
374
363
  /**
375
- * Resolve the `value` and `timezone` attributes into a Date and an optional
376
- * timeZone option for `Intl.DateTimeFormat`.
377
- *
378
- * Behavior:
379
- * - `value` omitted (null/undefined): returns today's date. `timezone`
380
- * (if any) is honored.
381
- * - `value` invalid (including empty string ""): warns and returns
382
- * `{ date: null }`. Empty is *not* the same as omitted — Lit reflects
383
- * `value=""` as the empty string, which is not a valid ISO 8601
384
- * form, so we surface it as a typo rather than silently rendering
385
- * today's date.
386
- * - `timezone` set + input has offset/Z: parses as an absolute moment
387
- * (offset honored) and asks `toLocaleString` to convert into the target zone.
388
- * - `timezone` set + input has no offset: interprets the wall-clock as
389
- * being in the target zone, so display in that zone matches the input
390
- * verbatim. This is viewer-independent.
391
- * - Default (no `timezone`): strips the offset/Z from the input and treats
392
- * the remaining wall-clock components as local time, so they render verbatim.
364
+ * Gets the Date to show and the `timeZone` option for `Intl.DateTimeFormat`,
365
+ * from `value` and `timezone`. Returns `{ date: null }` for invalid input,
366
+ * including an empty string.
393
367
  *
394
368
  * @private
395
- * @returns {{ date: Date | null, timeZoneOption: string | undefined }}
369
+ * @returns {{ date: Date | null, timeZoneOption: string | undefined }} The Date to show, or `null` for invalid input, and the `timeZone` option to format it with.
396
370
  */
397
371
  _resolveInputDate() {
372
+ // How each case resolves:
373
+ // - `value` not set (null or undefined): the current date and time, in
374
+ // `timezone` if it's set.
375
+ // - `value` invalid, including an empty string: logs a warning and
376
+ // returns { date: null }. An empty string isn't the same as not set:
377
+ // Lit gives value="" as an empty string, which isn't valid ISO 8601,
378
+ // so it's reported as a likely mistake instead of showing the
379
+ // current date.
380
+ // - `timezone` set and `value` has an offset or Z: reads `value` as an
381
+ // exact moment and has toLocaleString convert it into `timezone`.
382
+ // - `timezone` set and `value` has no offset: reads `value` as a time
383
+ // already in `timezone`, so every viewer sees it as written.
384
+ // - `timezone` not set: drops any offset or Z and reads the rest as
385
+ // local time, so it shows as written.
398
386
  const resolvedTz = this._effectiveTimeZone;
399
387
 
400
- // Only true "omitted" inputs (null/undefined) get the today's-date
401
- // treatment. Empty string falls through to ISO validation, which will
402
- // fail and produce the documented warn + empty render.
388
+ // Only true "omitted" inputs (null/undefined) get the current-date
389
+ // treatment. Empty string falls through to ISO validation, which
390
+ // fails and produces the documented warning and empty output.
403
391
  if (this.value == null) {
404
392
  return { date: new Date(), timeZoneOption: resolvedTz };
405
393
  }
@@ -418,9 +406,9 @@ class AuroDatetime extends i {
418
406
  const localPart = match[1];
419
407
  const hasOffset = Boolean(match[2]);
420
408
 
421
- // The regex permits an offset/Z suffix on a bare date (e.g. "2020-09-22Z"
422
- // or "2020-09-22-07:00"). Those forms are not valid ISO 8601 — an offset
423
- // is only meaningful with a time component — and the wall-clock branch
409
+ // The regex permits an offset/Z suffix on a bare date (such as "2020-09-22Z"
410
+ // or "2020-09-22-07:00"). Those forms are not valid ISO 8601: an offset
411
+ // is only meaningful with a time component, and the wall-clock branch
424
412
  // would silently drop the offset, producing surprising output. Reject
425
413
  // them up front so the consumer sees a warning.
426
414
  if (hasOffset && !localPart.includes("T")) {
@@ -437,7 +425,7 @@ class AuroDatetime extends i {
437
425
  ? localPart
438
426
  : `${localPart}T00:00:00`;
439
427
 
440
- // The regex only validates string shape, not value ranges — "2022-99-99"
428
+ // The regex only validates string shape, not value ranges: "2022-99-99"
441
429
  // matches but produces an Invalid Date. Detect that and treat it like
442
430
  // any other malformed input so render falls back to the documented
443
431
  // empty output instead of "Invalid Date" or a thrown RangeError from
@@ -470,16 +458,22 @@ class AuroDatetime extends i {
470
458
  }
471
459
 
472
460
  /**
473
- * Internal function to generate full date string.
461
+ * Formats the full date, such as "Thu, Jul 14, 2022", with the current `month` and `weekday` settings.
474
462
  * @private
475
- * @returns {string} - Date string.
463
+ * @returns {string} The formatted date, or an empty string when `value` is invalid.
476
464
  */
477
465
  humanDate() {
478
466
  const { date, timeZoneOption } = this._resolveInputDate();
479
467
  if (!date) {
480
468
  return "";
481
469
  }
482
- const template = { ...this.dateTemplate };
470
+ // Read month and weekday on every render so later changes show up.
471
+ const template = {
472
+ weekday: this.weekday || "short",
473
+ year: "numeric",
474
+ month: this.month || "short",
475
+ day: "numeric",
476
+ };
483
477
  if (timeZoneOption) {
484
478
  template.timeZone = timeZoneOption;
485
479
  }
@@ -487,9 +481,9 @@ class AuroDatetime extends i {
487
481
  }
488
482
 
489
483
  /**
490
- * Internal function to format a single date part (year/month/weekday/day).
484
+ * Formats the single date part that `type` names: the year, month, weekday, or day.
491
485
  * @private
492
- * @returns {string} - Date string.
486
+ * @returns {string} The formatted date, or an empty string when `value` is invalid.
493
487
  */
494
488
  humanDateConversion() {
495
489
  const { date, timeZoneOption } = this._resolveInputDate();
@@ -506,13 +500,13 @@ class AuroDatetime extends i {
506
500
  template.day = "numeric";
507
501
  break;
508
502
  case "month":
509
- template.month = this.month;
503
+ template.month = this.month || "short";
510
504
  break;
511
505
  case "year":
512
506
  template.year = "numeric";
513
507
  break;
514
508
  case "weekday":
515
- template.weekday = this.weekday;
509
+ template.weekday = this.weekday || "short";
516
510
  break;
517
511
  }
518
512
 
@@ -520,17 +514,16 @@ class AuroDatetime extends i {
520
514
  }
521
515
 
522
516
  /**
523
- * Internal function to generate numeric date string MM/DD/YYYY.
517
+ * Formats the date in numbers, in the order and with the separators `locale` uses, such as "7/14/2022" for `en-US`.
524
518
  * @private
525
- * @returns {string} - Date string.
519
+ * @returns {string} The formatted date, or an empty string when `value` is invalid.
526
520
  */
527
521
  numericDate() {
528
522
  const { date, timeZoneOption } = this._resolveInputDate();
529
523
  if (!date) {
530
524
  return "";
531
525
  }
532
- const template = { ...this.dateTemplate, month: "numeric" };
533
- Reflect.deleteProperty(template, "weekday");
526
+ const template = { year: "numeric", month: "numeric", day: "numeric" };
534
527
  if (timeZoneOption) {
535
528
  template.timeZone = timeZoneOption;
536
529
  }
@@ -538,16 +531,16 @@ class AuroDatetime extends i {
538
531
  }
539
532
 
540
533
  /**
541
- * Internal function to generate standard time string.
534
+ * Formats the hour and minute. When the time ends in AM or PM, it lowercases the period and drops a leading zero.
542
535
  * @private
543
- * @returns {string} - Time string.
536
+ * @returns {string} The formatted time, or an empty string when `value` is invalid.
544
537
  */
545
538
  humanTime() {
546
539
  const { date, timeZoneOption } = this._resolveInputDate();
547
540
  if (!date) {
548
541
  return "";
549
542
  }
550
- const template = { ...this.timeTemplate };
543
+ const template = { hour: "2-digit", minute: "2-digit" };
551
544
  if (timeZoneOption) {
552
545
  template.timeZone = timeZoneOption;
553
546
  }
@@ -559,8 +552,8 @@ class AuroDatetime extends i {
559
552
  // (case-insensitive), so it catches en-US (`PM`), en-AU/hi-IN (`pm`),
560
553
  // and en-CA/es-MX (`p.m.`) alike. Non-Latin period markers (ko `오후`,
561
554
  // ar `م`, zh-TW `下午`) have no ASCII a/p+m chars and correctly fall
562
- // through unchanged. 24h locales (en-GB, de-DE, fr-FR, ja-JP …) also
563
- // fall through, preserving their leading zeros.
555
+ // through unchanged. 24h locales (en-GB, de-DE, fr-FR, ja-JP, and
556
+ // others) also fall through, preserving their leading zeros.
564
557
  if (!/[ap]\.?m\.?/iu.test(formatted)) {
565
558
  return formatted;
566
559
  }
@@ -569,9 +562,9 @@ class AuroDatetime extends i {
569
562
  }
570
563
 
571
564
  /**
572
- * Internal function UI decision.
565
+ * Gets the text to show for the current `type`.
573
566
  * @private
574
- * @returns {string} - String determined by `type` (or full date if no type set).
567
+ * @returns {string} The formatted text; the full date when `type` isn't set or isn't recognized.
575
568
  */
576
569
  whichDate() {
577
570
  switch (this.type) {
@@ -591,10 +584,6 @@ class AuroDatetime extends i {
591
584
  }
592
585
  }
593
586
 
594
- // When using auroElement, use the following attribute and function when hiding content from screen readers.
595
- // aria-hidden="${this.hideAudible(this.hiddenAudible)}"
596
-
597
- // function that renders the HTML and CSS into the scope of the component
598
587
  render() {
599
588
  return b`
600
589
  <slot name="pre"></slot>
package/demo/readme.md CHANGED
@@ -12,7 +12,7 @@ The following sections are editable by making changes to the following files:
12
12
  | SECTION | DESCRIPTION | FILE LOCATION |
13
13
  |------------------------|---------------------------------------------------|-------------------------------------|
14
14
  | Description | Description of the component | `./docs/partials/description.md` |
15
- | Use Cases | Examples for when to use this component | `./docs/partials/useCases.md` |
15
+ | Use cases | Examples for when to use this component | `./docs/partials/useCases.md` |
16
16
  | Additional Information | For use to add any component specific information | `./docs/partials/readmeAddlInfo.md` |
17
17
  | Component Example Code | HTML sample code of the components use | `./apiExamples/basic.html` |
18
18
  -->
@@ -21,20 +21,22 @@ The following sections are editable by making changes to the following files:
21
21
 
22
22
  <!-- AURO-GENERATED-CONTENT:START (FILE:src=./docs/partials/description.md) -->
23
23
  <!-- The below content is automatically added from ./docs/partials/description.md -->
24
- The `<auro-datetime>` custom element makes it really easy to add dates to your web app with a simple HTML API.
24
+ The `<auro-datetime>` element shows a date or time as text, formatted for a language and region you choose and, optionally, a specific time zone. Set `type` to choose the full date, the time, a numeric date, or a single part, such as the weekday.
25
25
  <!-- AURO-GENERATED-CONTENT:END -->
26
26
  <!-- AURO-GENERATED-CONTENT:START (FILE:src=./docs/partials/readmeAddlInfo.md) -->
27
27
  <!-- The below content is automatically added from ./docs/partials/readmeAddlInfo.md -->
28
28
  <!-- AURO-GENERATED-CONTENT This file is to be used for any additional content that should be included in the README.md which is specific to this component. -->
29
29
  <!-- AURO-GENERATED-CONTENT:END -->
30
30
 
31
- ## Use Cases
31
+ ## Use cases
32
32
 
33
33
  <!-- AURO-GENERATED-CONTENT:START (FILE:src=./docs/partials/useCases.md) -->
34
34
  <!-- The below content is automatically added from ./docs/partials/useCases.md -->
35
- The `<auro-datetime>` element should be used in situations where users may:
35
+ Use `<auro-datetime>` to:
36
36
 
37
- * A date and/or time is required
37
+ * Show a date or time, such as a departure date or arrival time.
38
+ * Show a time in a specific time zone, such as a flight's local time at its airport.
39
+ * Format a date for a language and region, such as `de-DE` or `ja-JP`.
38
40
  <!-- AURO-GENERATED-CONTENT:END -->
39
41
 
40
42
  ## Install
@@ -49,10 +51,10 @@ The `<auro-datetime>` element should be used in situations where users may:
49
51
 
50
52
  <!-- AURO-GENERATED-CONTENT:END -->
51
53
 
52
- ### Define Dependency in Project
54
+ ### Define dependency in project
53
55
 
54
56
  <!-- AURO-GENERATED-CONTENT:START (REMOTE:url=https://raw.githubusercontent.com/AlaskaAirlines/auro-templates/main/templates/default/partials/usage/componentImportDescription.md) -->
55
- Defining the dependency within each project that is using the `<auro-datetime>` component.
57
+ Import the component in each project that uses `<auro-datetime>`.
56
58
 
57
59
  <!-- AURO-GENERATED-CONTENT:END -->
58
60
  <!-- AURO-GENERATED-CONTENT:START (REMOTE:url=https://raw.githubusercontent.com/AlaskaAirlines/auro-templates/main/templates/default/partials/usage/componentImport.md) -->
@@ -64,41 +66,40 @@ Defining the dependency within each project that is using the `<auro-datetime>`
64
66
  ### Use CDN
65
67
 
66
68
  <!-- AURO-GENERATED-CONTENT:START (REMOTE:url=https://raw.githubusercontent.com/AlaskaAirlines/auro-templates/main/templates/default/partials/usage/bundleInstallDescription.md) -->
67
- In cases where the project is not able to process JS assets, there are pre-processed assets available for use. Legacy browsers such as IE11 are no longer supported.
69
+ If your project can't process JS assets, use the pre-processed assets. Legacy browsers, such as IE11, aren't supported.
68
70
 
69
- <pre class="language-html"><code class="language-html">&lt;script type="module" src="https://cdn.jsdelivr.net/npm/@aurodesignsystem/auro-datetime@latest/+esm"&gt;&lt;/script&gt;</code></pre>
71
+ <pre class="language-html"><code class="language-html">&lt;script type="module" src="https://cdn.jsdelivr.net/npm/@aurodesignsystem/auro-datetime@latest/+esm"&gt;&lt;/script&gt;</code></pre>
70
72
 
71
73
  <!-- AURO-GENERATED-CONTENT:END -->
72
74
 
73
- ## Basic Example
75
+ ## Basic example
74
76
 
75
77
  <!-- AURO-GENERATED-CONTENT:START (CODE:src=./apiExamples/basic.html) -->
76
78
  <!-- The below code snippet is automatically added from ./apiExamples/basic.html -->
77
79
 
78
- <pre class="language-html"><code class="language-html">&lt;auro-datetime type="date"&gt;&lt;/auro-datetime&gt;</code></pre>
80
+ <pre class="language-html"><code class="language-html">&lt;auro-datetime type="date"&gt;&lt;/auro-datetime&gt;</code></pre>
79
81
  <!-- AURO-GENERATED-CONTENT:END -->
80
82
 
81
- ## Custom Component Registration for Version Management
83
+ ## Custom component registration for version management
82
84
 
83
- There are two key parts to every Auro component: the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes">class</a> and the custom element definition.
85
+ Every Auro component has two key parts: the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes">class</a> and the custom element definition.
84
86
  The class defines the component’s behavior, while the custom element registers it under a specific name so it can be used in HTML.
85
87
 
86
- When you install the component as described on the `Install` page, the class is imported automatically, and the component is registered globally for you.
88
+ Installing the component as described in the Install section imports the class and registers the component globally for you.
87
89
 
88
- However, if you need to load multiple versions of the same component on a single page (for example, when two projects depend on different versions), you can manually register the class under a custom element name to avoid conflicts.
90
+ However, if you need to load multiple versions of the same component on a single page (for example, when two projects depend on different versions), register the class manually under a custom element name to avoid conflicts.
89
91
 
90
- You can do this by importing only the component class and using the `register(name)` method with a unique name:
92
+ To do this, import only the component class and call the `register(name)` method with a unique name:
91
93
 
92
94
  <!-- AURO-GENERATED-CONTENT:START (FILE:src=./docs/partials/customRegistration.md) -->
93
95
  <!-- The below content is automatically added from ./docs/partials/customRegistration.md -->
94
96
 
95
97
  <pre class="language-js"><code class="language-js">// Import the class only
96
98
  import { AuroDatetime } from '@aurodesignsystem/auro-datetime/class';
97
- ​
98
- // Register with a custom name if desired
99
+ &#10;// Register it under a custom name
99
100
  AuroDatetime.register('custom-datetime');</code></pre>
100
101
 
101
- This will create a new custom element `<custom-datetime>` that behaves exactly like `<auro-datetime>`, allowing both to coexist on the same page without interfering with each other.
102
+ `<custom-datetime>` then works the same as `<auro-datetime>`, and both can run on the same page without affecting each other.
102
103
  <!-- AURO-GENERATED-CONTENT:END -->
103
104
  <div class="exampleWrapper exampleWrapper--flex">
104
105
  <!-- AURO-GENERATED-CONTENT:START (FILE:src=./apiExamples/custom.html) -->
@@ -111,6 +112,6 @@ This will create a new custom element `<custom-datetime>` that behaves exactly l
111
112
  <!-- AURO-GENERATED-CONTENT:START (CODE:src=./apiExamples/custom.html) -->
112
113
  <!-- The below code snippet is automatically added from ./apiExamples/custom.html -->
113
114
 
114
- <pre class="language-html"><code class="language-html">&lt;custom-datetime type="date"&gt;&lt;/custom-datetime&gt;</code></pre>
115
+ <pre class="language-html"><code class="language-html">&lt;custom-datetime type="date"&gt;&lt;/custom-datetime&gt;</code></pre>
115
116
  <!-- AURO-GENERATED-CONTENT:END -->
116
117
  </auro-accordion>
@@ -0,0 +1,6 @@
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};