foundation.ts 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. import BaseFoundation, { DefaultAdapter } from '../base/foundation';
  2. import { handlePrevent, setFocusToFirstItem, setFocusToLastItem } from '../utils/a11y';
  3. export interface DropdownAdapter extends Partial<DefaultAdapter> {
  4. setPopVisible(visible: boolean): void;
  5. notifyVisibleChange(visible: boolean): void
  6. }
  7. export default class DropdownFoundation extends BaseFoundation<DropdownAdapter> {
  8. handleVisibleChange(visible: boolean) {
  9. this._adapter.setPopVisible(visible);
  10. this._adapter.notifyVisibleChange(visible);
  11. }
  12. getMenuItemNodes(target: any): HTMLElement[] {
  13. const id = target.attributes['data-popupid'].value;
  14. const menuWrapper = document.getElementById(id);
  15. // if has dropdown item, the item must wrapped by li
  16. return menuWrapper ? Array.from(menuWrapper.getElementsByTagName('li')).filter(item => item.ariaDisabled === "false") : null;
  17. }
  18. setFocusToFirstMenuItem(target: any): void {
  19. const menuItemNodes = this.getMenuItemNodes(target);
  20. menuItemNodes && setFocusToFirstItem(menuItemNodes);
  21. }
  22. setFocusToLastMenuItem(target: any): void {
  23. const menuItemNodes = this.getMenuItemNodes(target);
  24. menuItemNodes && setFocusToLastItem(menuItemNodes);
  25. }
  26. handleKeyDown(event: any): void {
  27. switch (event.key) {
  28. case ' ':
  29. case 'Enter':
  30. event.target.click();
  31. // user may use input to be the trigger and bind some key event on it, so do not stoppropagation
  32. // handlePrevent(event);
  33. break;
  34. case 'ArrowDown':
  35. this.setFocusToFirstMenuItem(event.target);
  36. handlePrevent(event);
  37. break;
  38. case 'ArrowUp':
  39. this.setFocusToLastMenuItem(event.target);
  40. handlePrevent(event);
  41. break;
  42. default:
  43. break;
  44. }
  45. }
  46. }