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