UNPKG

@atlaskit/primitives

Version:

Primitives are token-backed low-level building blocks.

119 lines (115 loc) 5.12 kB
/* anchor.tsx generated by @compiled/babel-plugin v0.36.1 */ import _extends from "@babel/runtime/helpers/extends"; import "./anchor.compiled.css"; import * as React from 'react'; import { ax, ix } from "@compiled/react/runtime"; import { forwardRef, useCallback, useContext } from 'react'; import { cx } from '@compiled/react'; import invariant from 'tiny-invariant'; import { usePlatformLeafEventHandler } from '@atlaskit/analytics-next'; import { useRouterLink } from '@atlaskit/app-provider'; import noop from '@atlaskit/ds-lib/noop'; import { useId } from '@atlaskit/ds-lib/use-id'; import InteractionContext from '@atlaskit/interaction-context'; import VisuallyHidden from '@atlaskit/visually-hidden'; import Focusable from './focusable'; const styles = { root: "_4bfu1r31 _1hms8stv _ajmmnqa1 _vchhusvi" }; const IS_EXTERNAL_LINK_REGEX = /^(?:(http|https):\/\/)/; const IS_NON_HTTP_BASED = /^(((mailto|tel|sms|blob):)|(#))/; /** * __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) */ const AnchorNoRef = ({ href, children, onClick: providedOnClick = noop, interactionName, componentName, analyticsContext, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, style, target, testId, xcss, newWindowLabel = '(opens new window)', ...htmlAttributes }, ref) => { const interactionContext = useContext(InteractionContext); const handleClick = useCallback((e, analyticsEvent) => { interactionContext && interactionContext.tracePress(interactionName, e.timeStamp); providedOnClick(e, analyticsEvent); }, [providedOnClick, interactionContext, interactionName]); const opensNewWindowLabelId = useId(); const onClick = 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 const { className: _spreadClass, ...safeHtmlAttributes } = htmlAttributes; const RouterLink = useRouterLink(); const isExternal = typeof href === 'string' && IS_EXTERNAL_LINK_REGEX.test(href); const 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.). */ const isRouterLink = RouterLink && !isExternal && !isNonHttpBased; const hrefObjectUsedWithoutRouterLink = RouterLink === undefined && typeof href === 'object'; invariant(!hrefObjectUsedWithoutRouterLink, `@atlaskit/primitives: Anchor primitive cannot pass an object to 'href' unless a router link is configured in the AppProvider`); const Component = isRouterLink ? RouterLink : 'a'; return /*#__PURE__*/React.createElement(Focusable // @ts-expect-error we don't allow `a` on Focusable for makers as they should use Anchor instead , _extends({ as: Component, className: xcss // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- TODO: Properly type this and allow pass-through if we can determine the type , style: style, ref: ref // eslint-disable-next-line @repo/internal/react/no-unsafe-spread-props }, safeHtmlAttributes, { href: !isRouterLink && typeof href !== 'string' ? undefined : href, target: target, onClick: onClick, "aria-label": ariaLabel && target === '_blank' && !ariaLabelledBy ? `${ariaLabel} , ${newWindowLabel}` : ariaLabel, "aria-labelledby": ariaLabelledBy && target === '_blank' ? `${ariaLabelledBy} ${opensNewWindowLabelId}` : ariaLabelledBy, xcss: cx(styles.root, xcss), testId: testId, "data-is-router-link": testId ? isRouterLink ? 'true' : 'false' : undefined }), children, target === '_blank' && (children && !ariaLabel && !ariaLabelledBy || ariaLabelledBy) && /*#__PURE__*/React.createElement(VisuallyHidden, { id: opensNewWindowLabelId }, `, ${newWindowLabel}`)); }; // 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) */ const Anchor = /*#__PURE__*/forwardRef(AnchorNoRef); export default Anchor;