Skip to content

Commit 33cde64

Browse files
authored
Merge pull request #315 from github/kh-support-aria-hidden
fix: Ensure aria-hidden applies to shadow root
2 parents 8e59fda + a2ab717 commit 33cde64

File tree

3 files changed

+68
-2
lines changed

3 files changed

+68
-2
lines changed

examples/index.html

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,14 @@ <h2>Localised Dates</h2>
200200
</relative-time>
201201
</p>
202202

203+
<h2>With Aria Hidden</h2>
204+
205+
<button class="js-toggle-aria-hidden">
206+
With aria-hidden
207+
<relative-time aria-hidden="true" datetime="1970-01-01T00:00:00.000Z">
208+
</relative-time>
209+
</button>
210+
203211
<!-- <script type="module" src="../dist/index.js"></script> -->
204212
<script type="module" src="https://unpkg.com/@github/relative-time-element@latest/dist/bundle.js"></script>
205213
<script>
@@ -213,6 +221,17 @@ <h2>Localised Dates</h2>
213221
setTimeout(() => {
214222
document.getElementById('lazy').setAttribute('datetime', new Date().toJSON())
215223
}, 1000)
224+
225+
const toggleAriaHidden = (event) => {
226+
const relativeTimeElement = event.currentTarget.querySelector('relative-time')
227+
if (relativeTimeElement.getAttribute('aria-hidden') === 'true') {
228+
relativeTimeElement.setAttribute('aria-hidden', 'false')
229+
} else {
230+
relativeTimeElement.setAttribute('aria-hidden', 'true')
231+
}
232+
}
233+
const button = document.querySelector('.js-toggle-aria-hidden')
234+
button.addEventListener('click', toggleAriaHidden)
216235
</script>
217236
</body>
218237
</html>

src/relative-time-element.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ export class RelativeTimeElement extends HTMLElement implements Intl.DateTimeFor
112112
'datetime',
113113
'lang',
114114
'title',
115+
'aria-hidden',
115116
]
116117
}
117118

@@ -201,6 +202,17 @@ export class RelativeTimeElement extends HTMLElement implements Intl.DateTimeFor
201202
return `${this.prefix} ${formatter.format(date)}`.trim()
202203
}
203204

205+
#updateRenderRootContent(content: string | null): void {
206+
if (this.hasAttribute('aria-hidden') && this.getAttribute('aria-hidden') === 'true') {
207+
const span = document.createElement('span')
208+
span.setAttribute('aria-hidden', 'true')
209+
span.textContent = content
210+
;(this.#renderRoot as Element).replaceChildren(span)
211+
} else {
212+
this.#renderRoot.textContent = content
213+
}
214+
}
215+
204216
#onRelativeTimeUpdated: ((event: RelativeTimeUpdatedEvent) => void) | null = null
205217
get onRelativeTimeUpdated() {
206218
return this.#onRelativeTimeUpdated
@@ -459,10 +471,10 @@ export class RelativeTimeElement extends HTMLElement implements Intl.DateTimeFor
459471
}
460472

461473
if (newText) {
462-
this.#renderRoot.textContent = newText
474+
this.#updateRenderRootContent(newText)
463475
} else if (this.shadowRoot === this.#renderRoot && this.textContent) {
464476
// Ensure invalid dates fall back to lightDOM text content
465-
this.#renderRoot.textContent = this.textContent
477+
this.#updateRenderRootContent(this.textContent)
466478
}
467479

468480
if (newText !== oldText || newTitle !== oldTitle) {

test/relative-time.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ suite('relative-time', function () {
130130
...Object.getOwnPropertyNames(HTMLElement.prototype),
131131
]
132132
const observedAttributes = new Set(RelativeTimeElement.observedAttributes)
133+
observedAttributes.delete('aria-hidden') // Standard HTML attribute, no need for custom getter
133134
for (const member of members) observedAttributes.delete(member)
134135
assert.empty([...observedAttributes], 'observedAttributes that arent class members')
135136
})
@@ -1872,6 +1873,40 @@ suite('relative-time', function () {
18721873
}
18731874
})
18741875

1876+
suite('[aria-hidden]', async () => {
1877+
test('[aria-hidden="true"] applies to shadow root', async () => {
1878+
const now = new Date().toISOString()
1879+
const time = document.createElement('relative-time')
1880+
time.setAttribute('datetime', now)
1881+
time.setAttribute('aria-hidden', 'true')
1882+
await Promise.resolve()
1883+
1884+
const span = time.shadowRoot.querySelector('span')
1885+
assert.equal(span.getAttribute('aria-hidden'), 'true')
1886+
})
1887+
1888+
test('[aria-hidden="false"] applies to shadow root', async () => {
1889+
const now = new Date().toISOString()
1890+
const time = document.createElement('relative-time')
1891+
time.setAttribute('datetime', now)
1892+
time.setAttribute('aria-hidden', 'false')
1893+
await Promise.resolve()
1894+
1895+
assert.isNull(time.shadowRoot.querySelector('[aria-hidden]'), 'Expected no aria-hidden to be present')
1896+
assert.isNull(time.shadowRoot.querySelector('span'), 'Expected no span to be present')
1897+
})
1898+
1899+
test('no aria-hidden applies to shadow root', async () => {
1900+
const now = new Date().toISOString()
1901+
const time = document.createElement('relative-time')
1902+
time.setAttribute('datetime', now)
1903+
await Promise.resolve()
1904+
1905+
assert.isNull(time.shadowRoot.querySelector('[aria-hidden]'), 'Expected no aria-hidden to be present')
1906+
assert.isNull(time.shadowRoot.querySelector('span'), 'Expected no span to be present')
1907+
})
1908+
})
1909+
18751910
suite('legacy formats', function () {
18761911
const referenceDate = '2022-10-24T14:46:00.000Z'
18771912
const tests = new Set([

0 commit comments

Comments
 (0)