krautzource / aria-tree-walker

A lightweight walker for labeled ARIA trees
https://krautzource.github.io/aria-tree-walker/
Apache License 2.0
2 stars 0 forks source link

consider subtitles #34

Closed pkra closed 3 years ago

pkra commented 3 years ago

Similar to #27, subtitles help visual users access descriptions.

pkra commented 3 years ago

At least a demo for the docs might be nice.

pkra commented 3 years ago

A quick hack with popperjs is fairly easy to add to the navigator. Imagine you have popper in the page alongside some div with id "subtitle".

diff --git a/lib/navigator.js b/lib/navigator.js
index a7d9e37..bef52f4 100644
--- a/lib/navigator.js
+++ b/lib/navigator.js
@@ -12,15 +12,20 @@ export function attachNavigator(node) {
 class navigator {
   constructor(node) {
     this.node = node;
     this.tree = extractAbstractTree(node);
     this.node.addEventListener('keydown', this.move.bind(this));
     this.node.addEventListener('focusin', () => {
       this.node.setAttribute('tabindex', '-1');
       this.highlight(true);
+      this.popper = Popper.createPopper(this.node, subtitle, { placement: 'bottom-start'});
     });
     this.node.addEventListener('focusout', () => {
       this.highlight(false);
       this.node.setAttribute('tabindex', '0');
+      this.popper.destroy();
     });
   }

@@ -56,6 +61,17 @@ class navigator {
     this.highlight(true);
   }

   highlightSubtree(boolean, node) {
     if (!node) return;
     if (boolean === true) {
@@ -78,10 +94,16 @@ class navigator {
       activedescendant.setAttribute('tabindex', '0');
       activedescendant.classList.add('is-activedescendant');
       activedescendant.focus();
+      document.getElementById('subtitle').innerHTML = activedescendant.getAttribute('aria-label');
     }
     if (boolean === false) {
       activedescendant.setAttribute('tabindex', '-1');
       activedescendant.classList.remove('is-activedescendant');
+      document.getElementById('subtitle').innerHTML = '';
     }
   }
 }

But like with #27 I'd rather start with demos that are separate.


addendum: here's what you might add to the html in addition to the above.

    <style>
      #subtitle {
        background-color: #333;
        color: white;
        padding: 5px 10px;
        border-radius: 4px;
        font-size: 13px;
      }
    </style>

    <div id="subtitle" role="tooltip">I'm a tooltip</div>

    <script src="https://unpkg.com/@popperjs/core@2"></script>
pkra commented 3 years ago

Along the lines of https://github.com/krautzource/aria-tree-walker/issues/27#issuecomment-835505608, here's an approach using mutation observers

const subtitle = document.createElement('div');
subtitle.setAttribute('style', 'position: fixed; bottom:0; left: 0; background-color: black; color: white; max-width: 100%');      
document.body.appendChild(subtitle);

const observer = new MutationObserver(function(mutationRecordArray) {
  const activeDescendantRecord = mutationRecordArray.find(record => record.target.getAttribute('tabindex') === '0');
  if (!activeDescendantRecord) {
    subtitle.innerHTML  = '';
    return;
  }
  const activeDescendant = activeDescendantRecord.target;
  if (!activeDescendant.getAttribute('aria-label') || activeDescendant !== document.activeElement) {
    subtitle.innerHTML  = '';
    return;
  }
  subtitle.innerHTML  = activeDescendant.getAttribute('aria-label');
});

document.querySelectorAll('[data-treewalker]').forEach(node => observer.observe(node, {subtree: true, attributeFilter: ['tabindex']}));

Super simple, with easy ways to improve the subtitling (e.g., using popper) without adding any burden on the treewalker side.