diff --git a/src/components/accessibility/skip_link/skip_link.test.tsx b/src/components/accessibility/skip_link/skip_link.test.tsx
index b307d5f6eff..8b6fcf1e2ca 100644
--- a/src/components/accessibility/skip_link/skip_link.test.tsx
+++ b/src/components/accessibility/skip_link/skip_link.test.tsx
@@ -82,15 +82,40 @@ describe('EuiSkipLink', () => {
<>
Skip to content
-
I am content
+
>
);
fireEvent.click(getByText('Skip to content'));
+ // Unlike the array behavior, querySelector always picks *the first node in the DOM tree* found
+ // vs. the first item in the selector comma string
+ const expectedFocus = document.querySelector('.appWrapper');
+ expect(document.activeElement).toEqual(expectedFocus);
+ });
+
+ it('supports an array of query selectors', () => {
+ const { getByText } = render(
+ <>
+
+ Skip to content
+
+
+ >
+ );
+ fireEvent.click(getByText('Skip to content'));
+
+ // Array syntax allows us to prioritize preferred selectors
const expectedFocus = document.querySelector('[role=main]');
expect(document.activeElement).toEqual(expectedFocus);
});
diff --git a/src/components/accessibility/skip_link/skip_link.tsx b/src/components/accessibility/skip_link/skip_link.tsx
index a0379093685..8dc8ab60027 100644
--- a/src/components/accessibility/skip_link/skip_link.tsx
+++ b/src/components/accessibility/skip_link/skip_link.tsx
@@ -30,11 +30,15 @@ interface EuiSkipLinkInterface extends EuiButtonProps {
*/
destinationId: string;
/**
- * If no destination ID element exists or can be found, you may provide a string of
- * query selectors to fall back to (e.g. a `main` or `role="main"` element)
+ * If no destination ID element exists or can be found, you may provide a query selector
+ * string to fall back to.
+ *
+ * For complex applications with potentially variable layouts per page, an array of
+ * query selectors can be passed, e.g. `['main', '[role=main]', '.appWrapper']`, which
+ * prioritizes looking for multiple fallbacks based on array order.
* @default main
*/
- fallbackDestination?: string;
+ fallbackDestination?: string | string[];
/**
* If default HTML anchor link behavior is not desired (e.g. for SPAs with hash routing),
* setting this flag to true will manually scroll to and focus the destination element
@@ -83,7 +87,14 @@ export const EuiSkipLink: FunctionComponent = ({
const hasValidId = !!destinationEl;
// Check the fallback destination if not
if (!destinationEl && fallbackDestination) {
- destinationEl = document.querySelector(fallbackDestination);
+ if (Array.isArray(fallbackDestination)) {
+ for (let i = 0; i < fallbackDestination.length; i++) {
+ destinationEl = document.querySelector(fallbackDestination[i]);
+ if (destinationEl) break; // Stop once the first fallback has been found
+ }
+ } else {
+ destinationEl = document.querySelector(fallbackDestination);
+ }
}
if ((overrideLinkBehavior || !hasValidId) && destinationEl) {
diff --git a/upcoming_changelogs/6646.md b/upcoming_changelogs/6646.md
new file mode 100644
index 00000000000..5462ffd2179
--- /dev/null
+++ b/upcoming_changelogs/6646.md
@@ -0,0 +1 @@
+- Updated `EuiSkipLink`'s `fallbackDestination` prop to support an array of query selector strings