@atlaskit/navigation-system
Version:
The latest navigation system for Atlassian apps.
82 lines (80 loc) • 3.17 kB
JavaScript
/* skip-link.tsx generated by @compiled/babel-plugin v3.0.2 */
import "./skip-link.compiled.css";
import { ax, ix } from "@compiled/react/runtime";
import React, { useCallback } from 'react';
import { fg } from '@atlaskit/platform-feature-flags/fg';
import { Anchor } from '@atlaskit/primitives/compiled/anchor';
import { focusElement } from './focus-element';
const styles = {
skipLinkListItem: "_1pfhze3t",
skipLinkListItemNew: "_1rjcu2gc"
};
/**
* A link that moves current tab position to a different element
*
* This component is rendered internally and is not exported publicly.
*/
export const SkipLink = ({
id,
children,
onBeforeNavigate,
navigate
}) => {
const href = `#${id}`;
const handleClick = useCallback(event => {
event.preventDefault();
if (navigate && fg('platform_dst_nav4_skip_link_a11y_1')) {
/**
* The consumer takes over the navigation effect (e.g. expanding the
* side nav and focusing the first nav item). The universal pre/post
* work below (e.g. `window.scrollTo`) still runs around it.
*/
navigate();
} else {
// Intentionally not using `document.querySelector` because many valid IDs are not valid selectors.
const target = document.getElementById(id);
if (!target) {
return;
}
/**
* Legacy `onBeforeNavigate` hook. Intentionally NOT called when
* `platform_dst_nav4_skip_link_a11y_1` is enabled — under the gate the
* gate-on path delegates state mutation + focus management to `navigate`,
* and `SkipLinksPopup` injects its popup-close behavior into the
* `navigate` wrapper instead of relying on this hook.
*
* This callback can be removed entirely on gate cleanup.
*/
if (!fg('platform_dst_nav4_skip_link_a11y_1')) {
onBeforeNavigate === null || onBeforeNavigate === void 0 ? void 0 : onBeforeNavigate();
}
focusElement(target);
}
/**
* We should look into removing this, or only calling it in specific cases.
*
* It means if the skip link element is in the window scroll container
* then it might not get scrolled into view properly.
*
* This is not an issue for the default slots on desktop, but could break custom skip links or
* even `Aside` on mobile.
*
* Keeping existing behavior for now because resetting the window scroll is actually good for some cases.
* E.g. jumping to main / aside it makes sense to look at the start of the content.
*/
window.scrollTo(0, 0);
}, [id, onBeforeNavigate, navigate]);
return /*#__PURE__*/React.createElement("li", {
className: ax([styles.skipLinkListItem, fg('platform_dst_nav4_skip_link_a11y_1') && styles.skipLinkListItemNew])
}, /*#__PURE__*/React.createElement(Anchor
/**
* It looks like Safari handles link clicks during `pointerdown` unless it has an explicit `tabIndex={0}` :/
*
* Adding this explicitly makes the behavior consistent between browsers and lets us `event.preventDefault()`
* in the `onClick` handler.
*/, {
tabIndex: 0,
href: href,
onClick: handleClick
}, children));
};