@aurodesignsystem-dev/auro-datetime 0.0.0-pr82.6 → 0.0.0-pr82.7

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.
@@ -361,8 +361,13 @@ class AuroDatetime extends i {
361
361
  * timeZone option for `Intl.DateTimeFormat`.
362
362
  *
363
363
  * Behavior:
364
- * - No `value`: returns today's date. `timeZone` (if any) is honored.
365
- * - `value` invalid: warns and returns `{ date: null }`.
364
+ * - `value` omitted (null/undefined): returns today's date. `timeZone`
365
+ * (if any) is honored.
366
+ * - `value` invalid (including empty string ""): warns and returns
367
+ * `{ date: null }`. Empty is *not* the same as omitted — Lit reflects
368
+ * `value=""` as the empty string, which is not a valid ISO 8601
369
+ * form, so we surface it as a typo rather than silently rendering
370
+ * today's date.
366
371
  * - `timeZone` set + input has offset/Z: parses as an absolute moment
367
372
  * (offset honored) and asks `toLocaleString` to convert into the target zone.
368
373
  * - `timeZone` set + input has no offset: interprets the wall-clock as
@@ -377,7 +382,10 @@ class AuroDatetime extends i {
377
382
  _resolveInputDate() {
378
383
  const resolvedTz = this._resolveTimeZone(this.timeZone);
379
384
 
380
- if (!this.value) {
385
+ // Only true "omitted" inputs (null/undefined) get the today's-date
386
+ // treatment. Empty string falls through to ISO validation, which will
387
+ // fail and produce the documented warn + empty render.
388
+ if (this.value == null) {
381
389
  return { date: new Date(), timeZoneOption: resolvedTz };
382
390
  }
383
391
 
@@ -391,6 +399,19 @@ class AuroDatetime extends i {
391
399
 
392
400
  const localPart = match[1];
393
401
  const hasOffset = Boolean(match[2]);
402
+
403
+ // The regex permits an offset/Z suffix on a bare date (e.g. "2020-09-22Z"
404
+ // or "2020-09-22-07:00"). Those forms are not valid ISO 8601 — an offset
405
+ // is only meaningful with a time component — and the wall-clock branch
406
+ // would silently drop the offset, producing surprising output. Reject
407
+ // them up front so the consumer sees a warning.
408
+ if (hasOffset && !localPart.includes("T")) {
409
+ console.warn(
410
+ `auro-datetime: "${this.value}" is not a valid ISO 8601 string (offset/Z requires a time component).`,
411
+ );
412
+ return { date: null, timeZoneOption: undefined };
413
+ }
414
+
394
415
  const normalized = localPart.includes("T")
395
416
  ? localPart
396
417
  : `${localPart}T00:00:00`;
@@ -0,0 +1,6 @@
1
+ import{LitElement as e,html as t}from"lit";class n{registerComponent(e,t){customElements.get(e)||customElements.define(e,class extends t{})}closestElement(e,t=this,n=(t,i=t&&t.closest(e))=>t&&t!==document&&t!==window?i||n(t.getRootNode().host):null){return n(t)}handleComponentTagRename(e,t){const n=t.toLowerCase();e.tagName.toLowerCase()!==n&&e.setAttribute(n,!0)}elementMatch(e,t){const n=t.toLowerCase();return e.tagName.toLowerCase()===n||e.hasAttribute(n)}getSlotText(e,t){const n=e.shadowRoot?.querySelector(`slot[name="${t}"]`);return(n?.assignedNodes({flatten:!0})||[]).map(e=>e.textContent?.trim()).join(" ").trim()||null}}const i=/^(\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?)?)(Z|[+-]\d{2}:\d{2})?$/u;class a extends e{constructor(){super(),this._initializeDefaults()}_initializeDefaults(){this.weekday="short",this.month="short",this.locale="en-US",this._warnedLocales=new Set,this._warnedTimeZones=new Set,this._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,a)}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`),i=new Intl.DateTimeFormat("en-US",{timeZone:t,hourCycle:"h23",year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"}).formatToParts(n),a=Object.fromEntries(i.filter(e=>"literal"!==e.type).map(e=>[e.type,e.value])),o=new Date(`${a.year}-${a.month}-${a.day}T${a.hour}:${a.minute}:${a.second}Z`),s=n.getTime()-o.getTime();return new Date(n.getTime()+s)}_resolveInputDate(){const e=this._resolveTimeZone(this.timeZone);if(null==this.value)return{date:new Date,timeZoneOption:e};const t=this.value.match(i);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],a=Boolean(t[2]);if(a&&!n.includes("T"))return 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=n.includes("T")?n:`${n}T00:00:00`,s=(()=>e&&!a?this._zonedWallClockToUtc(o,e):e&&a?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 i=e.toLocaleString(this._effectiveLocale,n);return/[ap]\.?m\.?/iu.test(i)?i.replace(/^0+/u,"").toLowerCase():i}whichDate(){switch(this.type){case"date":default:return this.humanDate();case"time":return this.humanTime();case"year":case"month":case"weekday":case"day":return this.humanDateConversion();case"numeric":return this.numericDate()}}render(){return t`
2
+ <slot name="pre"></slot>
3
+ <span class="yield">${this.whichDate()}</span>
4
+ <slot name="post"></slot>
5
+ <slot></slot>
6
+ `}}export{a as A};
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- export{A as AuroDatetime}from"./auro-datetime-Cml4cDmu.js";import"lit";
1
+ export{A as AuroDatetime}from"./auro-datetime-Cq0WDk5L.js";import"lit";
@@ -1 +1 @@
1
- import{A as r}from"./auro-datetime-Cml4cDmu.js";import"lit";r.register();
1
+ import{A as r}from"./auro-datetime-Cq0WDk5L.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.6",
10
+ "version": "0.0.0-pr82.7",
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 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};