github.com/iqoqo/nomad@v0.11.3-0.20200911112621-d7021c74d101/ui/app/components/popover-menu.js (about) 1 import Component from '@ember/component'; 2 import { run } from '@ember/runloop'; 3 4 const TAB = 9; 5 const ARROW_DOWN = 40; 6 const FOCUSABLE = [ 7 'a:not([disabled])', 8 'button:not([disabled])', 9 'input:not([disabled]):not([type="hidden"])', 10 'textarea:not([disabled])', 11 '[tabindex]:not([disabled]):not([tabindex="-1"])', 12 ].join(', '); 13 14 export default Component.extend({ 15 classnames: ['popover'], 16 17 triggerClass: '', 18 isOpen: false, 19 isDisabled: false, 20 label: '', 21 22 dropdown: null, 23 24 capture(dropdown) { 25 // It's not a good idea to grab a dropdown reference like this, but it's necessary 26 // in order to invoke dropdown.actions.close in traverseList as well as 27 // dropdown.actions.reposition when the label or selection length changes. 28 this.set('dropdown', dropdown); 29 }, 30 31 didReceiveAttrs() { 32 const dropdown = this.dropdown; 33 if (this.isOpen && dropdown) { 34 run.scheduleOnce('afterRender', () => { 35 dropdown.actions.reposition(); 36 }); 37 } 38 }, 39 40 actions: { 41 openOnArrowDown(dropdown, e) { 42 if (!this.isOpen && e.keyCode === ARROW_DOWN) { 43 dropdown.actions.open(e); 44 e.preventDefault(); 45 } else if (this.isOpen && (e.keyCode === TAB || e.keyCode === ARROW_DOWN)) { 46 const optionsId = this.element.querySelector('.popover-trigger').getAttribute('aria-owns'); 47 const popoverContentEl = document.querySelector(`#${optionsId}`); 48 const firstFocusableElement = popoverContentEl.querySelector(FOCUSABLE); 49 50 if (firstFocusableElement) { 51 firstFocusableElement.focus(); 52 e.preventDefault(); 53 } 54 } 55 }, 56 }, 57 });