@atlaskit/page-layout
Version:
A collection of components which let you compose an application's page layout.
179 lines (175 loc) • 6.84 kB
JavaScript
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
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) { _defineProperty(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; }
/* eslint-disable @repo/internal/dom-events/no-unsafe-event-listeners */
/**
* @jsxRuntime classic
* @jsx jsx
*/
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
import { css, jsx } from '@emotion/react';
import Link from '@atlaskit/link';
import { easeOut, prefersReducedMotion } from '@atlaskit/motion';
import { N30A, N60A } from '@atlaskit/theme/colors';
import { DEFAULT_I18N_PROPS_SKIP_LINKS, PAGE_LAYOUT_CONTAINER_SELECTOR } from '../../common/constants';
import { useSkipLinks } from '../../controllers';
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
var prefersReducedMotionStyles = css(prefersReducedMotion());
var skipLinkStyles = css({
margin: "var(--ds-space-250, 10px)",
padding: '0.8rem 1rem',
position: 'fixed',
zIndex: -1,
background: "var(--ds-surface-overlay, white)",
border: 'none',
borderRadius: "var(--ds-border-radius, 3px)",
boxShadow: "var(--ds-shadow-overlay, ".concat("0 0 0 1px ".concat(N30A, ", 0 2px 10px ").concat(N30A, ", 0 0 20px -4px ").concat(N60A), ")"),
insetInlineStart: -999999,
opacity: 0,
transform: 'translateY(-50%)',
transition: "transform 0.3s ".concat(easeOut),
'&:focus-within': {
zIndex: 2147483640,
insetInlineStart: 0,
opacity: 1,
transform: 'translateY(0%)'
}
});
var skipLinkHeadingStyles = css({
fontWeight: "var(--ds-font-weight-semibold, 600)"
});
var skipLinkListStyles = css({
listStylePosition: 'outside',
listStyleType: 'none',
marginBlockStart: "var(--ds-space-050, 4px)",
paddingInlineStart: 0
});
var skipLinkListItemStyles = css({
marginBlockStart: 0
});
var _assignIndex = function assignIndex(num, arr) {
if (!arr.includes(num)) {
return num;
}
return _assignIndex(num + 1, arr);
};
/**
* The default label will be used when the `skipLinksLabel` attribute is not
* provided or the attribute is an empty string. If a string comprised only of
* spaces is provided, the skip link heading element will be removed, but the
* default label will still be used in `title` attribute of the skip links
* themselves.
*/
export var SkipLinkWrapper = function SkipLinkWrapper(_ref) {
var skipLinksLabel = _ref.skipLinksLabel;
var _useSkipLinks = useSkipLinks(),
skipLinksData = _useSkipLinks.skipLinksData;
if (skipLinksData.length === 0) {
return null;
}
var sortSkipLinks = 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 regularLinksWithIdx = arr.filter(function (link) {
return link.listIndex === undefined;
}).map(function (link, idx, currArr) {
var listIndex = _assignIndex(idx, usedIndexes);
usedIndexes.push(listIndex);
return _objectSpread(_objectSpread({}, link), {}, {
listIndex: listIndex
});
});
return [].concat(_toConsumableArray(customLinks), _toConsumableArray(regularLinksWithIdx)).sort(function (a, b) {
return a.listIndex - b.listIndex;
});
};
var escapeHandler = function escapeHandler(event) {
if (event.keyCode === 27) {
var container = document.querySelector("[".concat(PAGE_LAYOUT_CONTAINER_SELECTOR, "=\"true\"]"));
if (container !== null) {
container.focus();
}
}
};
var attachEscHandler = function attachEscHandler() {
return window.addEventListener('keydown', escapeHandler, false);
};
var removeEscHandler = function removeEscHandler() {
return window.removeEventListener('keydown', escapeHandler, false);
};
var emptyLabelOverride = !!(skipLinksLabel !== null && skipLinksLabel !== void 0 && skipLinksLabel.match(/^\s+$/));
var label = skipLinksLabel || DEFAULT_I18N_PROPS_SKIP_LINKS;
return (
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
jsx("div", {
onFocus: attachEscHandler,
onBlur: removeEscHandler,
css: [skipLinkStyles, prefersReducedMotionStyles],
"data-skip-link-wrapper": true
}, emptyLabelOverride ? null : jsx("p", {
css: skipLinkHeadingStyles
}, label), jsx("ol", {
css: skipLinkListStyles
}, sortSkipLinks(skipLinksData).map(function (_ref2) {
var id = _ref2.id,
skipLinkTitle = _ref2.skipLinkTitle;
return jsx(SkipLink, {
key: id,
href: "#".concat(id),
isFocusable: true
}, skipLinkTitle);
})))
);
};
var _handleBlur = function handleBlur(event) {
// @ts-ignore
event.target.removeAttribute('tabindex');
// @ts-ignore
event.target.removeEventListener('blur', _handleBlur);
};
var focusTargetRef = function focusTargetRef(href) {
return function (event) {
event.preventDefault();
var targetRef = document.querySelector(href);
// @ts-ignore
var key = event.which || event.keycode;
// if it is a keypress and the key is not
// space or enter, just ignore it.
if (key && key !== 13 && key !== 32) {
return;
}
if (targetRef) {
targetRef.setAttribute('tabindex', '-1');
// @ts-ignore
targetRef.addEventListener('blur', _handleBlur);
// @ts-ignore
targetRef.focus();
document.activeElement && document.activeElement.scrollIntoView({
behavior: 'smooth'
});
window.scrollTo(0, 0);
}
return false;
};
};
// eslint-disable-next-line @repo/internal/react/require-jsdoc
export var SkipLink = function SkipLink(_ref3) {
var href = _ref3.href,
children = _ref3.children,
isFocusable = _ref3.isFocusable;
return jsx("li", {
css: skipLinkListItemStyles
}, jsx(Link, {
tabIndex: isFocusable ? 0 : -1,
href: href,
onClick: focusTargetRef(href)
}, children));
};