UNPKG

@atlaskit/navigation-system

Version:

The latest navigation system for Atlassian apps.

137 lines (133 loc) • 6.35 kB
/* skip-links-container.tsx generated by @compiled/babel-plugin v3.0.2 */ "use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.SkipLinksContainer = SkipLinksContainer; require("./skip-links-container.compiled.css"); var _react = _interopRequireWildcard(require("react")); var React = _react; var _runtime = require("@compiled/react/runtime"); var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _fg = require("@atlaskit/platform-feature-flags/fg"); var _text = require("@atlaskit/primitives/compiled/text"); var _skipLink = require("./skip-link"); var _skipLinksPopup = require("./skip-links-popup"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } var styles = { root: "_zulp1b66 _2rko12b0 _1rjcutpp _18zrutpp _1e0c1txw _2lx21bp4 _kqsw1n9t _1e02v47k _152tv47k _bfhk1bhr _16qs130s _1pby1mrw _tzy4idpf _lcxvglyw _1digjh3g _1mygkb7n _18eu1wug", skipLinkList: "_zulp1b66 _1e0c1txw _2lx21bp4 _1x8w11lx _2mzuglyw _1pfhze3t _bozgze3t" }; /** * Keydown handler to hide the skip links when escape is pressed. * * TODO: consider removing this, it doesn't make a lot of sense. * The skip links look like a popup but in reality they aren't. * Even though we hide them when the user presses Escape, when * they press TAB it will reopen the list and move to the next one... * * One potential option is to use a tree walker to focus on the * next focusable element in the DOM (outside the skip links * container). */ var closeOnEscape = function closeOnEscape(event) { if (event.key !== 'Escape') { return; } var activeElement = document.activeElement; if (activeElement instanceof HTMLElement) { activeElement.blur(); } }; var _assignIndex = function assignIndex(num, arr) { if (!arr.includes(num)) { return num; } return _assignIndex(num + 1, arr); }; /** * Sorts an array of skip links by list indexes. * * Skip links with custom list indexes are positioned first, followed by regular skip links, * which are automatically assigned available index positions to avoid conflicts. */ function sortSkipLinks(arr) { var customLinks = arr.filter(function (link) { return Number.isInteger(link.listIndex); }); if (customLinks.length === 0) { return arr; } var usedIndexes = customLinks.map(function (a) { return a.listIndex; }); var regularLinksWithIndex = arr.filter(function (link) { return link.listIndex === undefined; }).map(function (link, index) { var listIndex = _assignIndex(index, usedIndexes); usedIndexes.push(listIndex); return _objectSpread(_objectSpread({}, link), {}, { listIndex: listIndex }); }); return [].concat((0, _toConsumableArray2.default)(customLinks), (0, _toConsumableArray2.default)(regularLinksWithIndex)).sort(function (a, b) { return a.listIndex - b.listIndex; }); } var isOnlyWhitespaceRegex = /^\s*$/; /** * A container element for the skip links. * * The container element is always rendered in the DOM, but is only visible when * focus is within the container. * * The label is used as the heading of the skip links container. If the provided label is a string * comprised only of only whitespace (e.g. '' or ' '), the skip link heading element will be removed. * * When `platform_dst_nav4_skip_link_a11y_1` is enabled, rendering is delegated to `SkipLinksPopup`. */ function SkipLinksContainer(_ref) { var label = _ref.label, triggerLabel = _ref.triggerLabel, testId = _ref.testId, links = _ref.links; var sortedLinks = (0, _react.useMemo)(function () { return sortSkipLinks(links); }, [links]); if (sortedLinks.length === 0) { return null; } var isEmptyLabel = isOnlyWhitespaceRegex.test(label); if ((0, _fg.fg)('platform_dst_nav4_skip_link_a11y_1')) { return /*#__PURE__*/React.createElement(_skipLinksPopup.SkipLinksPopup, { label: label, triggerLabel: triggerLabel, testId: testId, links: sortedLinks }); } return /*#__PURE__*/React.createElement("div", { onKeyDown: closeOnEscape, "data-testid": testId ? "".concat(testId, "--skip-links-container") : undefined, className: (0, _runtime.ax)([styles.root]) }, !isEmptyLabel && /*#__PURE__*/React.createElement(_text.Text, { weight: "bold", testId: testId ? "".concat(testId, "--skip-links-container--label") : undefined }, label), /*#__PURE__*/React.createElement("ol", { className: (0, _runtime.ax)([styles.skipLinkList]) }, sortedLinks.map(function (_ref2) { var id = _ref2.id, label = _ref2.label, onBeforeNavigate = _ref2.onBeforeNavigate; return /*#__PURE__*/React.createElement(_skipLink.SkipLink, { key: id, id: id, onBeforeNavigate: onBeforeNavigate }, label); }))); }