Skip to content

Commit 61b536b

Browse files
committed
feat: add support for time-zone attribute
fixes #292
1 parent 33cde64 commit 61b536b

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

src/relative-time-element.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,14 @@ export class RelativeTimeElement extends HTMLElement implements Intl.DateTimeFor
9090
}
9191
}
9292

93+
get timeZone() {
94+
// Prefer attribute, then closest, then document
95+
const tz =
96+
this.closest('[time-zone]')?.getAttribute('time-zone') ||
97+
this.ownerDocument.documentElement.getAttribute('time-zone')
98+
return tz || undefined
99+
}
100+
93101
#renderRoot: Node = this.shadowRoot ? this.shadowRoot : this.attachShadow ? this.attachShadow({mode: 'open'}) : this
94102

95103
static get observedAttributes() {
@@ -113,6 +121,7 @@ export class RelativeTimeElement extends HTMLElement implements Intl.DateTimeFor
113121
'lang',
114122
'title',
115123
'aria-hidden',
124+
'time-zone',
116125
]
117126
}
118127

@@ -129,6 +138,7 @@ export class RelativeTimeElement extends HTMLElement implements Intl.DateTimeFor
129138
hour: 'numeric',
130139
minute: '2-digit',
131140
timeZoneName: 'short',
141+
timeZone: this.timeZone,
132142
}).format(date)
133143
}
134144

@@ -198,6 +208,7 @@ export class RelativeTimeElement extends HTMLElement implements Intl.DateTimeFor
198208
month: this.month,
199209
year: this.year,
200210
timeZoneName: this.timeZoneName,
211+
timeZone: this.timeZone,
201212
})
202213
return `${this.prefix} ${formatter.format(date)}`.trim()
203214
}

test/relative-time.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2586,4 +2586,48 @@ suite('relative-time', function () {
25862586
})
25872587
}
25882588
})
2589+
2590+
suite('[timeZone]', function () {
2591+
test('updates when the time-zone attribute is set', async () => {
2592+
const el = document.createElement('relative-time')
2593+
el.setAttribute('datetime', '2020-01-01T12:00:00.000Z')
2594+
el.setAttribute('time-zone', 'America/New_York')
2595+
el.setAttribute('format', 'datetime')
2596+
el.setAttribute('hour', 'numeric')
2597+
el.setAttribute('minute', '2-digit')
2598+
el.setAttribute('second', '2-digit')
2599+
el.setAttribute('time-zone-name', 'longGeneric')
2600+
await Promise.resolve()
2601+
assert.equal(el.shadowRoot.textContent, 'Wed, Jan 1, 2020, 7:00:00 AM Eastern Time')
2602+
})
2603+
2604+
test('updates when the time-zone attribute changes', async () => {
2605+
const el = document.createElement('relative-time')
2606+
el.setAttribute('datetime', '2020-01-01T12:00:00.000Z')
2607+
el.setAttribute('time-zone', 'America/New_York')
2608+
el.setAttribute('format', 'datetime')
2609+
el.setAttribute('hour', 'numeric')
2610+
el.setAttribute('minute', '2-digit')
2611+
el.setAttribute('second', '2-digit')
2612+
await Promise.resolve()
2613+
const initial = el.shadowRoot.textContent
2614+
el.setAttribute('time-zone', 'Asia/Tokyo')
2615+
await Promise.resolve()
2616+
assert.notEqual(el.shadowRoot.textContent, initial)
2617+
assert.equal(el.shadowRoot.textContent, "Wed, Jan 1, 2020, 9:00:00 PM")
2618+
})
2619+
2620+
test('ignores empty time-zone attributes', async () => {
2621+
const el = document.createElement('relative-time')
2622+
el.setAttribute('datetime', '2020-01-01T12:00:00.000Z')
2623+
el.setAttribute('time-zone', '')
2624+
el.setAttribute('format', 'datetime')
2625+
el.setAttribute('hour', 'numeric')
2626+
el.setAttribute('minute', '2-digit')
2627+
el.setAttribute('second', '2-digit')
2628+
await Promise.resolve()
2629+
// Should fallback to default or system time zone
2630+
assert.equal(el.shadowRoot.textContent, 'Wed, Jan 1, 2020, 4:00:00 PM')
2631+
})
2632+
})
25892633
})

0 commit comments

Comments
 (0)