UNPKG

@atlaskit/primitives

Version:

Primitives are token-backed low-level building blocks.

180 lines (175 loc) 9.91 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _react = require("react"); var _react2 = require("@emotion/react"); var _tinyInvariant = _interopRequireDefault(require("tiny-invariant")); var _analyticsNext = require("@atlaskit/analytics-next"); var _appProvider = require("@atlaskit/app-provider"); var _noop = _interopRequireDefault(require("@atlaskit/ds-lib/noop")); var _useId = require("@atlaskit/ds-lib/use-id"); var _interactionContext = _interopRequireDefault(require("@atlaskit/interaction-context")); var _visuallyHidden = _interopRequireDefault(require("@atlaskit/visually-hidden")); var _styleMaps = require("../xcss/style-maps.partial"); var _xcss = require("../xcss/xcss"); var _excluded = ["href", "children", "backgroundColor", "newWindowLabel", "padding", "paddingBlock", "paddingBlockStart", "paddingBlockEnd", "paddingInline", "paddingInlineStart", "paddingInlineEnd", "onClick", "interactionName", "componentName", "analyticsContext", "aria-label", "aria-labelledby", "style", "target", "testId", "xcss"], _excluded2 = ["className"]; /** * @jsxRuntime classic * @jsx jsx */ // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766 // TODO: duplicates FocusRing styles from `@atlaskit/focus-ring`. var focusRingStyles = (0, _react2.css)({ '&:focus, &:focus-visible': { // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values outlineColor: _styleMaps.borderColorMap['color.border.focused'], // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values outlineOffset: _styleMaps.positiveSpaceMap['space.025'], outlineStyle: 'solid', // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values outlineWidth: _styleMaps.borderWidthMap['border.width.outline'] }, // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-selectors '&:focus:not(:focus-visible)': { outline: 'none' }, '@media screen and (forced-colors: active), screen and (-ms-high-contrast: active)': { '&:focus-visible': { outline: '1px solid' } } }); var baseStyles = (0, _react2.css)({ boxSizing: 'border-box', textDecoration: 'underline' }); var IS_EXTERNAL_LINK_REGEX = /^(?:(http|https):\/\/)/; var IS_NON_HTTP_BASED = /^(((mailto|tel|sms|blob):)|(#))/; // Comma is added here to add a slight pause between announcing the anchor label and "opens in new window" var OPENS_NEW_WINDOW_LABEL = '(opens new window)'; /** * __Anchor__ * * A primitive for building custom anchor links. * * - [Examples](https://atlassian.design/components/primitives/anchor/examples) * - [Code](https://atlassian.design/components/primitives/anchor/code) * - [Usage](https://atlassian.design/components/primitives/anchor/usage) */ var AnchorNoRef = function AnchorNoRef(_ref, ref) { var href = _ref.href, children = _ref.children, backgroundColor = _ref.backgroundColor, newWindowLabel = _ref.newWindowLabel, padding = _ref.padding, paddingBlock = _ref.paddingBlock, paddingBlockStart = _ref.paddingBlockStart, paddingBlockEnd = _ref.paddingBlockEnd, paddingInline = _ref.paddingInline, paddingInlineStart = _ref.paddingInlineStart, paddingInlineEnd = _ref.paddingInlineEnd, _ref$onClick = _ref.onClick, providedOnClick = _ref$onClick === void 0 ? _noop.default : _ref$onClick, interactionName = _ref.interactionName, componentName = _ref.componentName, analyticsContext = _ref.analyticsContext, ariaLabel = _ref['aria-label'], ariaLabelledBy = _ref['aria-labelledby'], style = _ref.style, target = _ref.target, testId = _ref.testId, xcss = _ref.xcss, htmlAttributes = (0, _objectWithoutProperties2.default)(_ref, _excluded); var interactionContext = (0, _react.useContext)(_interactionContext.default); var handleClick = (0, _react.useCallback)(function (e, analyticsEvent) { interactionContext && interactionContext.tracePress(interactionName, e.timeStamp); providedOnClick(e, analyticsEvent); }, [providedOnClick, interactionContext, interactionName]); var opensNewWindowLabelId = (0, _useId.useId)(); var onClick = (0, _analyticsNext.usePlatformLeafEventHandler)({ fn: handleClick, action: 'clicked', componentName: componentName || 'Anchor', packageName: "@atlaskit/primitives", packageVersion: "14.7.3", analyticsData: analyticsContext, actionSubject: 'link' }); // This is to remove className from safeHtmlAttributes // @ts-expect-error className doesn't exist in the prop definition but we want to ensure it cannot be applied even if types are bypassed var _spreadClass = htmlAttributes.className, safeHtmlAttributes = (0, _objectWithoutProperties2.default)(htmlAttributes, _excluded2); var resolvedStyles = (0, _xcss.parseXcss)(xcss); var RouterLink = (0, _appProvider.useRouterLink)(); var isExternal = typeof href === 'string' && IS_EXTERNAL_LINK_REGEX.test(href); var isNonHttpBased = typeof href === 'string' && IS_NON_HTTP_BASED.test(href); /** * Renders a router link if: * * - a link component is set in the app provider * - it's not an external link (starting with `http://` or `https://`) * - it's not a non-HTTP-based link (e.g. emails, phone numbers, hash links etc.). */ var isRouterLink = RouterLink && !isExternal && !isNonHttpBased; var hrefObjectUsedWithoutRouterLink = RouterLink === undefined && (0, _typeof2.default)(href) === 'object'; (0, _tinyInvariant.default)(!hrefObjectUsedWithoutRouterLink, "@atlaskit/primitives: Anchor primitive cannot pass an object to 'href' unless a router link is configured in the AppProvider"); var Component = isRouterLink ? RouterLink : 'a'; return (0, _react2.jsx)(Component // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766 , (0, _extends2.default)({ style: style, ref: ref // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766 , className: resolvedStyles.static // eslint-disable-next-line @repo/internal/react/no-unsafe-spread-props }, safeHtmlAttributes, { // @ts-expect-error href: !isRouterLink && typeof href !== 'string' ? undefined : href, target: target, onClick: onClick, "aria-label": ariaLabel && target === '_blank' && !ariaLabelledBy ? //`${ariaLabel} ${OPENS_NEW_WINDOW_LABEL}` "".concat(ariaLabel, " , ").concat(newWindowLabel ? newWindowLabel : OPENS_NEW_WINDOW_LABEL) : ariaLabel, "aria-labelledby": ariaLabelledBy && target === '_blank' ? "".concat(ariaLabelledBy, " ").concat(opensNewWindowLabelId) : ariaLabelledBy, css: [baseStyles, focusRingStyles, // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766 backgroundColor && _styleMaps.backgroundColorStylesMap[backgroundColor], // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766 padding && _styleMaps.paddingStylesMap.padding[padding], // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766 paddingBlock && _styleMaps.paddingStylesMap.paddingBlock[paddingBlock], // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766 paddingBlockStart && _styleMaps.paddingStylesMap.paddingBlockStart[paddingBlockStart], // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766 paddingBlockEnd && _styleMaps.paddingStylesMap.paddingBlockEnd[paddingBlockEnd], // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766 paddingInline && _styleMaps.paddingStylesMap.paddingInline[paddingInline], // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766 paddingInlineStart && _styleMaps.paddingStylesMap.paddingInlineStart[paddingInlineStart], // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766 paddingInlineEnd && _styleMaps.paddingStylesMap.paddingInlineEnd[paddingInlineEnd], resolvedStyles.emotion], "data-testid": testId, "data-is-router-link": testId ? isRouterLink ? 'true' : 'false' : undefined }), children, target === '_blank' && (children && !ariaLabel && !ariaLabelledBy || ariaLabelledBy) && (0, _react2.jsx)(_visuallyHidden.default, { id: opensNewWindowLabelId }, ", ".concat(newWindowLabel ? newWindowLabel : OPENS_NEW_WINDOW_LABEL))); }; // Workarounds to support generic types with forwardRef /** * __Anchor__ * * Anchor is a primitive for building custom anchor links. It's a wrapper around the HTML `<a>` element that provides a consistent API for handling client-side routing and Atlassian Design System styling. * * - [Examples](https://atlassian.design/components/primitives/anchor/examples) * - [Code](https://atlassian.design/components/primitives/anchor/code) * - [Usage](https://atlassian.design/components/primitives/anchor/usage) */ var Anchor = /*#__PURE__*/(0, _react.forwardRef)(AnchorNoRef); var _default = exports.default = Anchor;