Skip to content

Commit

Permalink
refactor: migrate addon to TypeScript
Browse files Browse the repository at this point in the history
  • Loading branch information
dannycalleri committed Oct 6, 2023
1 parent 88c1019 commit 79c07da
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 70 deletions.
70 changes: 0 additions & 70 deletions ember-autofocus-modifier/src/modifiers/autofocus.js

This file was deleted.

71 changes: 71 additions & 0 deletions ember-autofocus-modifier/src/modifiers/autofocus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { modifier } from "ember-modifier";
import { next } from "@ember/runloop";

const focusableElements = [
"BUTTON",
"SUMMARY",
"IFRAME",
"INPUT",
"SELECT",
"TEXTAREA",
] as const;

const DEFAULT_SELECTOR =
"input:not([disabled]):not([readonly]),textarea:not([disabled]):not([readonly])";

export default modifier(function autofocus(
element: HTMLElement,
[selector = DEFAULT_SELECTOR]: string[],
{ disabled }: { disabled: boolean },
) {
if (disabled) {
return;
}

// Instead of selecting a child element by default, should this (in a major),
// be a behavior that is changed via a passed flag?
const targetElement: HTMLElement = element.querySelector(selector) || element;
const isChildElement = targetElement !== element;

/**
* Only applies to the element that {{autofocus}} is applied to.
* opts-out if we're selecting a child element.
*/
const shouldMoveFocus =
!isChildElement &&
!focusableElements.some(
(item) =>
element.tagName === item ||
element.isContentEditable ||
element.hasAttribute("aria-disabled") ||
element.hasAttribute("href") ||
element.hasAttribute("tabindex"),
);

/**
* if {{autofocus}} is applied to a non-focusable element,
* For A11y purposes, this is used to move focus to the non-focusable element.
* This is helpful when new elements are inserted on to the screen (yet not focus-trapped),
* and we want the tab-behavior to move "near" the inserted content.
*
* This still prevents the non-focusable element from being tabbed to, as non-focusable
* elements are still not focusable.
*
* But this is a behavior we can use to help out screen readers and keyboard users alike to
* more smoothly interact with newly-inserted content (without needing to focus an interactive-specifically
* maybe the inserted contents are just buttons, for example).
*/
if (shouldMoveFocus) {
element.setAttribute("tabindex", "-1");
}

next(function () {
targetElement.focus();
});

return (): void => {
if (shouldMoveFocus) {
element.removeAttribute("tabindex");
}
};
});

0 comments on commit 79c07da

Please sign in to comment.