Skip to content

Commit

Permalink
Smarts for adjusting focus on a toggle target (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
hopsoft committed Jan 9, 2023
1 parent 76453b0 commit e018a35
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 14 deletions.
14 changes: 7 additions & 7 deletions app/assets/builds/@turbo-boost/elements.js

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions app/assets/builds/@turbo-boost/elements.js.map

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions app/javascript/elements/toggle_target_element.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import TurboBoostElement from './turbo_boost_element'
import './toggle_target_focus'

export default class ToggleTargetElement extends TurboBoostElement {
connectedCallback () {
Expand Down Expand Up @@ -55,9 +56,7 @@ export default class ToggleTargetElement extends TurboBoostElement {
focus () {
clearTimeout(this.focusTimeout)
this.focusTimeout = setTimeout(() => {
if (!this.focusElement) return
this.focusElement.focus()
this.focusElement.scrollIntoView({ block: 'center', behavior: 'smooth' })
if (this.focusElement) this.focusElement.focus()
}, 50)
}

Expand Down
77 changes: 77 additions & 0 deletions app/javascript/elements/toggle_target_focus.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
function deactivateTrixAttributes (editor) {
const attributes = [
'bold',
'bullet',
'code',
'heading1',
'href',
'italic',
'number',
'quote',
'strike'
]
attributes.forEach(name => editor.deactivateAttribute(name))
}

function focusTrixEditorElement (element) {
if (element.value.length === 0) return

const editor = element.editor

// move cursor to the end
let lastRange = []
while (
lastRange[0] !== editor.getSelectedRange()[0] &&
lastRange[1] !== editor.getSelectedRange()[1]
) {
lastRange = editor.getSelectedRange()
editor.moveCursorInDirection('forward')
}

// insert an empty char and select it
editor.insertString(' ')
editor.moveCursorInDirection('forward')
editor.setSelectedRange([lastRange[1], editor.getSelectedRange()[1]])

// deactivate all trix features for the selection
deactivateTrixAttributes(editor)

// move cursor to end and collapse the selection
editor.setSelectedRange([
editor.getSelectedRange()[1],
editor.getSelectedRange()[1]
])
}

function shouldEnhanceFocus (element) {
return (
element.closest('turbo-boost-toggle-target') &&
element.tagName.match(/^input|textarea|trix-editor$/i)
)
}

function enhanceFocus (element) {
const trixEditorElement = element.closest('trix-editor')

try {
if (trixEditorElement) {
focusTrixEditorElement(trixEditorElement)
} else {
element.selectionStart = element.selectionEnd = element.value.length
}
} finally {
setTimeout(
() => element.scrollIntoView({ block: 'center', behavior: 'smooth' }),
100
)
}
}

addEventListener(
'focus',
event => {
if (shouldEnhanceFocus(document.activeElement))
enhanceFocus(document.activeElement)
},
true
)

0 comments on commit e018a35

Please sign in to comment.