UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

200 lines (199 loc) 7.61 kB
"use strict"; "use client"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AnchorComponent = AnchorComponent; exports.default = void 0; exports.isDangerousHref = isDangerousHref; exports.opensNewTab = void 0; exports.pickIcon = pickIcon; exports.scrollToHash = scrollToHash; var _includes = _interopRequireDefault(require("core-js-pure/stable/instance/includes.js")); var _withComponentMarkers = _interopRequireDefault(require("../../shared/helpers/withComponentMarkers.js")); var _react = require("react"); var _clsx = require("clsx"); var _Element = _interopRequireDefault(require("../../elements/Element.js")); var _Context = _interopRequireDefault(require("../../shared/Context.js")); var _componentHelper = require("../../shared/component-helper.js"); var _useId = _interopRequireDefault(require("../../shared/helpers/useId.js")); var _helpers = require("../../shared/helpers.js"); var _IconPrimary2 = _interopRequireDefault(require("../icon-primary/IconPrimary.js")); var _Tooltip = _interopRequireDefault(require("../tooltip/Tooltip.js")); var _index = require("../../icons/index.js"); var _jsxRuntime = require("react/jsx-runtime"); var _IconPrimary; function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } const anchorDefaultProps = { noAnimation: false, noStyle: false, noHover: false, noUnderline: false, noIcon: false, noLaunchIcon: false, disabled: false }; function AnchorComponent(localProps) { var _context, _context2, _context3, _context4; const context = (0, _react.useContext)(_Context.default); const allProps = (0, _componentHelper.extendPropsWithContext)(localProps, anchorDefaultProps, { skeleton: context?.skeleton }, context?.getTranslation(localProps).Anchor, context?.Anchor); const fallbackRef = (0, _react.useRef)(null); if (!allProps.ref) { allProps.ref = fallbackRef; } const tooltipRef = (0, _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 = (0, _useId.default)(id); const as = element || 'a'; const isDisabled = disabled; const hasNoHover = noHover || isDisabled; const hasNoAnimation = noAnimation || isDisabled; const hasNoUnderline = noUnderline || isDisabled; if (isDangerousHref(attributes.href)) { delete attributes.href; } if (isDangerousHref(attributes.to)) { delete attributes.to; } const href = attributes.href || attributes.to; const _opensNewTab = opensNewTab(allProps.target, href); const showLaunchIcon = _opensNewTab && !isDisabled && !noIcon && !noLaunchIcon && !((_context = className) == null ? void 0 : Function.call.bind((0, _includes.default)(_context), _context))?.('dnb-anchor--no-icon') && !((_context2 = className) == null ? void 0 : Function.call.bind((0, _includes.default)(_context2), _context2))?.('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 = (0, _jsxRuntime.jsx)(_IconPrimary2.default, { className: "dnb-anchor__launch-icon", icon: _index.launch }))); const prefix = iconPosition === 'left' && iconNode; const anchorRef = (0, _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 (0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, { children: [(0, _jsxRuntime.jsxs)(_Element.default, { as: as, id: id, internalClass: as !== 'button', className: (0, _clsx.clsx)(omitClass !== true && (0, _clsx.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 && !((_context3 = className) == null ? void 0 : Function.call.bind((0, _includes.default)(_context3), _context3))?.('dnb-anchor--no-icon') && 'dnb-anchor--no-icon', noLaunchIcon && !((_context4 = className) == null ? void 0 : Function.call.bind((0, _includes.default)(_context4), _context4))?.('dnb-anchor--no-launch-icon') && 'dnb-anchor--no-launch-icon', context?.theme?.surface === 'dark' && 'dnb-anchor--surface-dark'), className), ...attributes, ref: anchorRef, children: [prefix, children, suffix] }), showTooltip && (0, _jsxRuntime.jsx)(_Tooltip.default, { showDelay: 100, id: internalId + '-tooltip', targetElement: tooltipRef, tooltip: tooltip, children: allProps.title || targetBlankTitle })] }); } function Anchor(props) { return (0, _jsxRuntime.jsx)(AnchorComponent, { ...props }); } (0, _withComponentMarkers.default)(Anchor, { _supportsSpacingProps: true }); var _default = exports.default = Anchor; function scrollToHash(hash) { if (typeof document === 'undefined' || !hash || !(0, _includes.default)(hash).call(hash, '#')) { 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 = (0, _helpers.getOffsetTop)(anchorElem) - scrollPadding || 0; window.scroll({ top }); return { element: anchorElem }; } catch (error) { console.error('Anchor: Failed to scroll to element:', error); } } return undefined; } function getIcon(icon) { return pickIcon(icon) || (0, _jsxRuntime.jsx)(_IconPrimary2.default, { icon: icon }); } function pickIcon(icon, className) { var _context5; if (icon?.props?.icon || ((_context5 = icon?.props?.className) == null ? void 0 : Function.call.bind((0, _includes.default)(_context5), _context5))?.('dnb-icon')) { return (0, _react.createElement)(icon.type, { ...icon.props, key: 'button-icon-clone', className: (0, _clsx.clsx)(icon.props?.className, className) }); } return null; } const opensNewTab = (target, href) => target === '_blank' && !/^(mailto|tel|sms)/.test(href); exports.opensNewTab = opensNewTab; function isDangerousHref(href) { if (typeof href !== 'string') { return false; } let normalized = ''; for (const char of href) { const code = char.charCodeAt(0); if (code > 0x20 && code !== 0x7f && !(code >= 0x80 && code <= 0xa0)) { normalized += char; } } return /^(javascript|vbscript):/i.test(normalized); } //# sourceMappingURL=Anchor.js.map