Skip to content

Commit

Permalink
Merge pull request #73 from github/data_no_focus_bug
Browse files Browse the repository at this point in the history
Don't set a tabindex=0 when the toolbar has data-no-focus attribute applied
  • Loading branch information
keithamus authored Sep 22, 2023
2 parents 432d70d + 58282f3 commit 666d0c2
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 12 deletions.
33 changes: 27 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,20 +320,43 @@ function applyFromToolbar(event: Event) {
applyStyle(target, style)
}

function setFocusManagement(toolbar: MarkdownToolbarElement) {
toolbar.addEventListener('keydown', focusKeydown)
toolbar.setAttribute('tabindex', '0')
toolbar.addEventListener('focus', onToolbarFocus, {once: true})
}

function unsetFocusManagement(toolbar: MarkdownToolbarElement) {
toolbar.removeEventListener('keydown', focusKeydown)
toolbar.removeAttribute('tabindex')
toolbar.removeEventListener('focus', onToolbarFocus)
}

class MarkdownToolbarElement extends HTMLElement {
static observedAttributes = ['data-no-focus']

connectedCallback(): void {
if (!this.hasAttribute('role')) {
this.setAttribute('role', 'toolbar')
}
this.addEventListener('keydown', focusKeydown)
this.setAttribute('tabindex', '0')
this.addEventListener('focus', onToolbarFocus, {once: true})
if (!this.hasAttribute('data-no-focus')) {
setFocusManagement(this)
}
this.addEventListener('keydown', keydown(applyFromToolbar))
this.addEventListener('click', applyFromToolbar)
}

attributeChangedCallback(name: string, oldValue: string, newValue: string): void {
if (name !== 'data-no-focus') return
if (newValue === null) {
setFocusManagement(this)
} else {
unsetFocusManagement(this)
}
}

disconnectedCallback(): void {
this.removeEventListener('keydown', focusKeydown)
unsetFocusManagement(this)
}

get field(): HTMLTextAreaElement | null {
Expand All @@ -350,7 +373,6 @@ class MarkdownToolbarElement extends HTMLElement {

function onToolbarFocus({target}: FocusEvent) {
if (!(target instanceof Element)) return
if (target.hasAttribute('data-no-focus')) return
target.removeAttribute('tabindex')
let tabindex = '0'
for (const button of getButtons(target)) {
Expand All @@ -367,7 +389,6 @@ function focusKeydown(event: KeyboardEvent) {
if (key !== 'ArrowRight' && key !== 'ArrowLeft' && key !== 'Home' && key !== 'End') return
const toolbar = event.currentTarget
if (!(toolbar instanceof HTMLElement)) return
if (toolbar.hasAttribute('data-no-focus')) return
const buttons = getButtons(toolbar)
const index = buttons.indexOf(event.target as HTMLElement)
const length = buttons.length
Expand Down
8 changes: 2 additions & 6 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ describe('markdown-toolbar-element', function () {

describe('focus management', function () {
function focusFirstButton() {
document.querySelector('markdown-toolbar').focus()
const button = document.querySelector('md-bold')
button.focus()
}
Expand All @@ -111,10 +112,6 @@ describe('markdown-toolbar-element', function () {
return [...document.querySelectorAll(`markdown-toolbar [tabindex="${index}"]`)]
}

beforeEach(() => {
document.querySelector('markdown-toolbar').focus()
})

it('moves focus to next button when ArrowRight is pressed', function () {
focusFirstButton()
pushKeyOnFocussedButton('ArrowRight')
Expand All @@ -135,8 +132,7 @@ describe('markdown-toolbar-element', function () {
document.querySelector('markdown-toolbar').setAttribute('data-no-focus', '')
focusFirstButton()
pushKeyOnFocussedButton('ArrowRight')
assert.deepEqual(getElementsWithTabindex(0), [document.querySelector('md-bold')])
assert.deepEqual(getElementsWithTabindex(0), [document.activeElement])
assert.lengthOf(getElementsWithTabindex(0), 0)
})

it('cycles focus round to last element from first when ArrowLeft is pressed', function () {
Expand Down

0 comments on commit 666d0c2

Please sign in to comment.