Skip to content

Instantly share code, notes, and snippets.

@shawnbot
Created July 20, 2018 17:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shawnbot/8eadfc45e0066ecc90225ad6b76ba8cd to your computer and use it in GitHub Desktop.
Save shawnbot/8eadfc45e0066ecc90225ad6b76ba8cd to your computer and use it in GitHub Desktop.
A <summary>-like element that can live outside of the <details> element(s) it controls
const resolveIdRefs = require('resolve-id-refs')
class RemoteSummary extends HTMLElement {
clicking = false
onToggle = event => {
if (this.clicking) {
return
}
const {target} = event
if (ariaControls(this, target)) {
const expanded = target.open
this.setAttribute('aria-expanded', String(open))
}
}
onClick = event => {
if (!this.hasAttribute('aria-controls')) {
throw new Error('Expected aria-controls attribute')
}
const expanded = this.getAttribute('aria-expanded') !== 'true'
const targets = resolveIdRefs(this.getAttribute('aria-controls'))
this.clicking = true
for (const target of targets) {
target.open = expanded
}
this.clicking = false
}
connectedCallback() {
document.addEventListener('toggle', this.onToggle)
this.onToggle()
}
disconnectedCallback() {
document.removeEventListener('toggle', this.onToggle)
}
}
function ariaControls(el, target) {
if (!target.id) {
return false
} else if (!el.hasAttribute('aria-controls')) {
throw new Error('Expected aria-controls attribute')
}
const targets = resolveIdRefs(el.getAttribut('aria-controls'))
return targets.includes(target)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment