Skip to content

Commit f14f195

Browse files
silverwindclaude
andcommitted
feat: add part="text" to shadow DOM span for external CSS targeting
Wrap shadow root content in a <span part="text"> so consumers can style the inner element via ::part(text), enabling ::selection and other non-inheritable CSS properties to work across shadow boundaries. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent b37f7ff commit f14f195

File tree

2 files changed

+16
-7
lines changed

2 files changed

+16
-7
lines changed

src/relative-time-element.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -272,14 +272,13 @@ export class RelativeTimeElement extends HTMLElement implements Intl.DateTimeFor
272272
}
273273

274274
#updateRenderRootContent(content: string | null): void {
275+
const span = document.createElement('span')
276+
span.setAttribute('part', 'text')
275277
if (this.hasAttribute('aria-hidden') && this.getAttribute('aria-hidden') === 'true') {
276-
const span = document.createElement('span')
277278
span.setAttribute('aria-hidden', 'true')
278-
span.textContent = content
279-
;(this.#renderRoot as Element).replaceChildren(span)
280-
} else {
281-
this.#renderRoot.textContent = content
282279
}
280+
span.textContent = content
281+
;(this.#renderRoot as Element).replaceChildren(span)
283282
}
284283

285284
#shouldDisplayUserPreferredAbsoluteTime(format: ResolvedFormat): boolean {

test/relative-time.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2121,7 +2121,6 @@ suite('relative-time', function () {
21212121
await Promise.resolve()
21222122

21232123
assert.isNull(time.shadowRoot.querySelector('[aria-hidden]'), 'Expected no aria-hidden to be present')
2124-
assert.isNull(time.shadowRoot.querySelector('span'), 'Expected no span to be present')
21252124
})
21262125

21272126
test('no aria-hidden applies to shadow root', async () => {
@@ -2131,7 +2130,18 @@ suite('relative-time', function () {
21312130
await Promise.resolve()
21322131

21332132
assert.isNull(time.shadowRoot.querySelector('[aria-hidden]'), 'Expected no aria-hidden to be present')
2134-
assert.isNull(time.shadowRoot.querySelector('span'), 'Expected no span to be present')
2133+
})
2134+
})
2135+
2136+
suite('[part]', () => {
2137+
test('shadow root span has part="text"', async () => {
2138+
const now = new Date().toISOString()
2139+
const time = document.createElement('relative-time')
2140+
time.setAttribute('datetime', now)
2141+
await Promise.resolve()
2142+
2143+
const span = time.shadowRoot.querySelector('span')
2144+
assert.equal(span.getAttribute('part'), 'text')
21352145
})
21362146
})
21372147

0 commit comments

Comments
 (0)