UNPKG

@atlaskit/navigation-system

Version:

The latest navigation system for Atlassian apps.

79 lines (75 loc) • 2.63 kB
import React, { useCallback, useMemo, useState } from 'react'; import { SkipLinksContainer } from '../../components/skip-links/skip-links-container'; import { SkipLinksContext } from './skip-links-context'; const getByDomOrderSortFunction = () => { const layoutSlots = Array.from(document.querySelectorAll(`[data-layout-slot]`)); return (a, b) => { var _a$listIndex, _b$listIndex; const indexA = (_a$listIndex = a.listIndex) !== null && _a$listIndex !== void 0 ? _a$listIndex : layoutSlots.indexOf(document.getElementById(a.id)); const indexB = (_b$listIndex = b.listIndex) !== null && _b$listIndex !== void 0 ? _b$listIndex : layoutSlots.indexOf(document.getElementById(b.id)); /** * If they are tied it is because one (or both) is * a custom skiplink with a set index. * * Give the custom skiplink priority. */ if (indexA === indexB) { if (a.listIndex !== undefined) { return -1; } else { return 1; } } return indexA - indexB; }; }; /** * Provider for skip links. Should be rendered at the top level of the application. * * - Provides the context to register/unregister skip links * - Renders the skip links container */ export function SkipLinksProvider({ children, label, triggerLabel, testId }) { const [links, setLinks] = useState([]); const registerSkipLink = useCallback(skipLinkData => { // Don't add duplicate skip links setLinks(oldLinks => { if (oldLinks.some(({ id }) => id === skipLinkData.id)) { if (process.env.NODE_ENV !== 'production') { // eslint-disable-next-line no-console console.warn(`\ Tried registering duplicate skip link for ID '${skipLinkData.id}'. If you're trying to override a slot skip link label, then use the \`skipLinkLabel\` prop instead. This error will not be shown in production, and the duplicate skip link will be ignored.`); } return oldLinks; } return [...oldLinks, skipLinkData].sort(getByDomOrderSortFunction()); }); }, []); const unregisterSkipLink = useCallback(id => { setLinks(links => links.filter(link => link.id !== id)); }, []); const contextValue = useMemo(() => { const data = { registerSkipLink, unregisterSkipLink }; return data; }, [registerSkipLink, unregisterSkipLink]); return /*#__PURE__*/React.createElement(SkipLinksContext.Provider, { value: contextValue }, /*#__PURE__*/React.createElement(SkipLinksContainer, { label: label, triggerLabel: triggerLabel, testId: testId, links: links }), children); }