@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
168 lines (167 loc) • 6.48 kB
JavaScript
"use client";
var _IconPrimary;
import withComponentMarkers from "../../shared/helpers/withComponentMarkers.js";
import React from 'react';
import clsx from 'clsx';
import E from "../../elements/Element.js";
import Context from "../../shared/Context.js";
import { makeUniqueId, extendPropsWithContext } from "../../shared/component-helper.js";
import { getOffsetTop } from "../../shared/helpers.js";
import IconPrimary from "../icon-primary/IconPrimary.js";
import Tooltip from "../tooltip/Tooltip.js";
import { launch as launchIcon } from "../../icons/index.js";
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
const defaultProps = {
noAnimation: false,
noStyle: false,
noHover: false,
noUnderline: false,
noIcon: false,
noLaunchIcon: false,
disabled: false
};
export function AnchorInstance(localProps) {
var _context$theme;
const context = React.useContext(Context);
const allProps = extendPropsWithContext(localProps, defaultProps, {
skeleton: context === null || context === void 0 ? void 0 : context.skeleton
}, context === null || context === void 0 ? void 0 : context.getTranslation(localProps).Anchor, context === null || context === void 0 ? void 0 : context.Anchor);
const fallbackRef = React.useRef(null);
if (!allProps.ref) {
allProps.ref = fallbackRef;
}
const tooltipRef = React.useRef(null);
const {
id,
element,
className,
children,
tooltip,
icon,
iconPosition = 'left',
omitClass,
ref: refProp,
targetBlankTitle,
noAnimation,
noHover,
noStyle,
noUnderline,
noIcon,
noLaunchIcon,
disabled,
...rest
} = allProps;
const attributes = rest;
const internalId = id || 'id' + makeUniqueId();
const as = element || 'a';
const isDisabled = disabled;
const hasNoHover = noHover || isDisabled;
const hasNoAnimation = noAnimation || isDisabled;
const hasNoUnderline = noUnderline || isDisabled;
const href = allProps.href || allProps.to;
const _opensNewTab = opensNewTab(allProps.target, href);
const showLaunchIcon = _opensNewTab && !isDisabled && !noIcon && !noLaunchIcon && !(className !== null && className !== void 0 && className.includes('dnb-anchor--no-icon')) && !(className !== null && className !== void 0 && className.includes('dnb-anchor--no-launch-icon')) && !omitClass;
const showTooltip = (tooltip || _opensNewTab) && !allProps.title;
if (_opensNewTab && !attributes.rel) {
attributes.rel = 'noopener noreferrer';
}
const iconNode = icon && getIcon(icon);
const suffix = iconPosition === 'right' && iconNode || showLaunchIcon && (_IconPrimary || (_IconPrimary = _jsx(IconPrimary, {
className: "dnb-anchor__launch-icon",
icon: launchIcon
})));
const prefix = iconPosition === 'left' && iconNode;
const anchorRef = React.useCallback(elem => {
tooltipRef.current = elem;
if (typeof refProp === 'function') {
refProp(elem);
} else if (refProp) {
;
refProp.current = elem;
}
}, [refProp]);
if (isDisabled) {
attributes.disabled = true;
if (as === 'a') {
attributes.tabIndex = -1;
attributes['aria-disabled'] = true;
if (attributes.href) {
delete attributes.href;
}
if (attributes.to) {
delete attributes.to;
}
attributes.onClick = event => {
event.preventDefault();
event.stopPropagation();
};
}
}
return _jsxs(_Fragment, {
children: [_jsxs(E, {
as: as,
id: id,
internalClass: as !== 'button',
className: clsx(className, omitClass !== true && clsx('dnb-anchor', prefix && 'dnb-anchor--icon-left', suffix && 'dnb-anchor--icon-right', typeof children !== 'string' && 'dnb-anchor--was-node', hasNoAnimation && 'dnb-anchor--no-animation', hasNoHover && 'dnb-anchor--no-hover', noStyle && 'dnb-anchor--no-style', hasNoUnderline && 'dnb-anchor--no-underline', isDisabled && 'dnb-anchor--disabled', noIcon && !(className !== null && className !== void 0 && className.includes('dnb-anchor--no-icon')) && 'dnb-anchor--no-icon', noLaunchIcon && !(className !== null && className !== void 0 && className.includes('dnb-anchor--no-launch-icon')) && 'dnb-anchor--no-launch-icon', (context === null || context === void 0 || (_context$theme = context.theme) === null || _context$theme === void 0 ? void 0 : _context$theme.surface) === 'dark' && 'dnb-anchor--surface-dark')),
...attributes,
ref: anchorRef,
children: [prefix, children, suffix]
}), showTooltip && _jsx(Tooltip, {
showDelay: 100,
id: internalId + '-tooltip',
targetElement: tooltipRef,
tooltip: tooltip,
children: allProps.title || targetBlankTitle
})]
});
}
function Anchor(props) {
return _jsx(AnchorInstance, {
...props
});
}
withComponentMarkers(Anchor, {
_supportsSpacingProps: true
});
export default Anchor;
export function scrollToHash(hash) {
if (typeof document === 'undefined' || !hash || !hash.includes('#')) {
return undefined;
}
const id = hash.split(/#/g).reverse()[0];
const anchorElem = document.getElementById(id);
if (anchorElem instanceof HTMLElement) {
try {
const scrollPadding = parseFloat(window.getComputedStyle(document.documentElement).scrollPaddingTop);
const top = getOffsetTop(anchorElem) - scrollPadding || 0;
window.scroll({
top
});
return {
element: anchorElem
};
} catch (error) {
console.error(error);
}
}
return undefined;
}
function getIcon(icon) {
return pickIcon(icon) || _jsx(IconPrimary, {
icon: icon
});
}
export function pickIcon(icon, className) {
var _icon$props, _icon$props2;
if (icon !== null && icon !== void 0 && (_icon$props = icon.props) !== null && _icon$props !== void 0 && _icon$props.icon || icon !== null && icon !== void 0 && (_icon$props2 = icon.props) !== null && _icon$props2 !== void 0 && (_icon$props2 = _icon$props2.className) !== null && _icon$props2 !== void 0 && _icon$props2.includes('dnb-icon')) {
var _icon$props3;
return React.createElement(icon.type, {
...icon.props,
key: 'button-icon-clone',
className: clsx((_icon$props3 = icon.props) === null || _icon$props3 === void 0 ? void 0 : _icon$props3.className, className)
});
}
return null;
}
export const opensNewTab = (target, href) => target === '_blank' && !/^(mailto|tel|sms)/.test(href);
//# sourceMappingURL=Anchor.js.map