(
ref: RefObject<Element | null>,
defaultOptions: FocusManagerOptions = {}
)
| 897 | * Creates a FocusManager object that can be used to move focus within an element. |
| 898 | */ |
| 899 | export function createFocusManager( |
| 900 | ref: RefObject<Element | null>, |
| 901 | defaultOptions: FocusManagerOptions = {} |
| 902 | ): FocusManager { |
| 903 | return { |
| 904 | focusNext(opts: FocusManagerOptions = {}) { |
| 905 | let root = ref.current; |
| 906 | if (!root) { |
| 907 | return null; |
| 908 | } |
| 909 | let { |
| 910 | from, |
| 911 | tabbable = defaultOptions.tabbable, |
| 912 | wrap = defaultOptions.wrap, |
| 913 | accept = defaultOptions.accept |
| 914 | } = opts; |
| 915 | let node = from || getActiveElement(getOwnerDocument(root)); |
| 916 | let walker = getFocusableTreeWalker(root, {tabbable, accept}); |
| 917 | if (nodeContains(root, node)) { |
| 918 | walker.currentNode = node!; |
| 919 | } |
| 920 | let nextNode = walker.nextNode() as FocusableElement; |
| 921 | if (!nextNode && wrap) { |
| 922 | walker.currentNode = root; |
| 923 | nextNode = walker.nextNode() as FocusableElement; |
| 924 | } |
| 925 | if (nextNode) { |
| 926 | focusElement(nextNode, true); |
| 927 | } |
| 928 | return nextNode; |
| 929 | }, |
| 930 | focusPrevious(opts: FocusManagerOptions = defaultOptions) { |
| 931 | let root = ref.current; |
| 932 | if (!root) { |
| 933 | return null; |
| 934 | } |
| 935 | let { |
| 936 | from, |
| 937 | tabbable = defaultOptions.tabbable, |
| 938 | wrap = defaultOptions.wrap, |
| 939 | accept = defaultOptions.accept |
| 940 | } = opts; |
| 941 | let node = from || getActiveElement(getOwnerDocument(root)); |
| 942 | let walker = getFocusableTreeWalker(root, {tabbable, accept}); |
| 943 | if (nodeContains(root, node)) { |
| 944 | walker.currentNode = node!; |
| 945 | } else { |
| 946 | let next = last(walker); |
| 947 | if (next) { |
| 948 | focusElement(next, true); |
| 949 | } |
| 950 | return next ?? null; |
| 951 | } |
| 952 | let previousNode = walker.previousNode() as FocusableElement; |
| 953 | if (!previousNode && wrap) { |
| 954 | walker.currentNode = root; |
| 955 | let lastNode = last(walker); |
| 956 | if (!lastNode) { |
no outgoing calls
no test coverage detected