Skip to content

Instantly share code, notes, and snippets.

@kloots
Created July 26, 2018 20:30
Show Gist options
  • Save kloots/8efeb39125b68c64241ebe17d6a1d579 to your computer and use it in GitHub Desktop.
Save kloots/8efeb39125b68c64241ebe17d6a1d579 to your computer and use it in GitHub Desktop.
Rich text editor with screen-reader-accessible tokens
<!doctype html>
<style type="text/css">
#textbox-1{
padding: 4px 10px;
}
.token {
background: #ccc;
border: solid 1px #999;
border-radius: 4px;
}
.token button:before {
content: 'x';
}
</style>
<div id="textbox-1" role="textbox" contenteditable="true" style="border: solid 1px #000;">
<span class="token" role="group" aria-label="Todd Kloots" contenteditable="false">
Todd Kloots
<button class="remove-token-btn" type="button" tabindex="-1" aria-label="Remove Todd Kloots" id="thing-1"></button>
</span>
<span class="token" role="group" aria-label="Lauren Bosak" contenteditable="false">
Lauren Bosak
<button class="remove-token-btn" type="button" tabindex="-1" aria-label="Remove Lauren Bosak" id="thing-2"></button>
</span>
some text
</div>
<script type="text/javascript">
(function() {
function getCaretPosition(element) {
var range = window.getSelection().getRangeAt(0);
var preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(element);
preCaretRange.setEnd(range.endContainer, range.endOffset);
return preCaretRange.toString().length;
}
var textEditor = document.getElementById('textbox-1');
textEditor.addEventListener('keyup', function(e) {
var target = e.target;
var cursorPos = getCaretPosition(target);
var keyCode = e.keyCode;
var cursorPosToId = {
0: 'thing-1',
24: 'thing-2',
};
var leftOrRight = (keyCode == 37 || keyCode == 39);
if (leftOrRight && target.getAttribute('aria-activedescendant')){
target.removeAttribute('aria-activedescendant');
}
var id = leftOrRight && cursorPosToId[cursorPos];
if (id) {
target.setAttribute('aria-activedescendant', id);
return;
}
target.removeAttribute('aria-activedescendant');
}, false);
textEditor.addEventListener('click', function(e) {
var target = e.target;
if (target.className === 'remove-token-btn') {
e.currentTarget.removeChild(target.parentNode);
}
});
})();
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment