2024-10-30 21:36:02 +03:00
export function toAbsoluteLocaleDate ( date : string , lang? : string , opts? : Intl.DateTimeFormatOptions ) {
// only use the date part, it is guaranteed to be in ISO format (YYYY-MM-DDTHH:mm:ss.sssZ) or (YYYY-MM-DD)
// if there is an "Invalid Date" error, there must be something wrong in code and should be fixed.
// TODO: there is a root problem in backend code: the date "YYYY-MM-DD" is passed to backend without timezone (eg: deadline),
// then backend parses it in server's timezone and stores the parsed timestamp into database.
// If the user's timezone is different from the server's, the date might be displayed in the wrong day.
const dateSep = date . indexOf ( 'T' ) ;
date = dateSep === - 1 ? date : date.substring ( 0 , dateSep ) ;
return new Date ( ` ${ date } T00:00:00 ` ) . toLocaleString ( lang || [ ] , opts ) ;
2024-03-15 12:13:01 +03:00
}
2024-03-15 05:05:31 +03:00
window . customElements . define ( 'absolute-date' , class extends HTMLElement {
2024-03-13 01:37:02 +03:00
static observedAttributes = [ 'date' , 'year' , 'month' , 'weekday' , 'day' ] ;
2024-10-30 12:50:19 +03:00
initialized = false ;
2024-03-13 01:37:02 +03:00
update = ( ) = > {
2024-10-30 12:50:19 +03:00
const opt : Intl.DateTimeFormatOptions = { } ;
for ( const attr of [ 'year' , 'month' , 'weekday' , 'day' ] ) {
if ( this . getAttribute ( attr ) ) opt [ attr ] = this . getAttribute ( attr ) ;
}
2024-03-13 01:37:02 +03:00
const lang = this . closest ( '[lang]' ) ? . getAttribute ( 'lang' ) ||
2024-03-15 12:13:01 +03:00
this . ownerDocument . documentElement . getAttribute ( 'lang' ) || '' ;
2024-03-13 01:37:02 +03:00
if ( ! this . shadowRoot ) this . attachShadow ( { mode : 'open' } ) ;
2024-10-30 21:36:02 +03:00
this . shadowRoot . textContent = toAbsoluteLocaleDate ( this . getAttribute ( 'date' ) , lang , opt ) ;
2024-03-13 01:37:02 +03:00
} ;
2024-10-31 17:57:40 +03:00
attributeChangedCallback ( _name : string , oldValue : string | null , newValue : string | null ) {
2024-03-13 01:37:02 +03:00
if ( ! this . initialized || oldValue === newValue ) return ;
this . update ( ) ;
}
connectedCallback() {
this . initialized = false ;
this . update ( ) ;
this . initialized = true ;
}
} ) ;