import React, { CSSProperties } from 'react' import { browserCheck } from '@ta-interaktiv/browsercheck' import { parseHostname } from '@ta-interaktiv/parse-hostname' import { placeholderColor } from '../settings' import './styles.scss' const validURL = (str: string) => { const pattern = new RegExp( '^(https?:\\/\\/)?' + // protocol '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path '(\\?[;&a-z\\d%_.~+=-]*)?' + // query string '(\\#[-a-z\\d_]*)?$', 'i' ) // fragment locator return !!pattern.test(str) } const isnum = (val: string) => { return /^\d+$/.test(val) } export interface LinkProps { /** Url to open */ href?: string /** Semantic Ui Icon to show, uses SVG-Icon if not provided */ icon?: string /** hide the icon */ hideIcon?: boolean | false /** Link target [mobile,not mobile] */ target?: [string, string] | string /** CSS-Class for Link */ className?: string /** Inline css for the link */ style?: CSSProperties /** Linktext */ children?: string | React.ReactNode /** Linktext */ allowWordWrap?: boolean /** Other Props passed to the link */ [key: string]: any // eslint-disable-line } /** * Displays a Link with Semantic-UI-Icon. The link opens in _parent on mobile and in _blank on others by default. * */ export const Link = ({ href = '', icon, hideIcon = false, target = ['_parent', '_blank'], className = 'cbLink', style = { whiteSpace: 'nowrap' }, children = 'Link', allowWordWrap = true, ...props }: LinkProps) => { /* If href is not a url, consists of onyl digits and has a length of 8 or 12 create a tenant link to current publication domanin */ let hrefIsArticleID = false if (!validURL(href)) { if (isnum(href) && (href.length === 8 || href.length === 12)) { href = 'https://www.' + parseHostname().publicationDomain + '/' + href hrefIsArticleID = true } } /* If children/linktext are not provided but href is provided, the href becomes the children/linktext. */ if (children === 'Link' && href) children = href /* If children/linktext are not provided. Link is shown as placeholder */ const placeholderMode = children === 'Link' const noWrap: CSSProperties = { whiteSpace: allowWordWrap ? 'normal' : 'nowrap' } let openIn: string if (typeof target === 'object') { openIn = browserCheck.isMobile ? target[0] : target[1] } else { openIn = target } /* Do not wrap between last word an icon */ const kids = React.Children.toArray(children) const head: any = (kids[0] as string).split(' ') const tail: any = (head.length > 1 ? ' ' : '') + head.pop() // if (typeof head === 'string') { // tail = head.slice(1).concat(tail) // head = head[0] // } return ( {head.join(' ')} {tail} {!hideIcon && !hrefIsArticleID && !icon && ( // )} {!hideIcon && !hrefIsArticleID && icon && ( <> {' '} )} ) } // Icon after link text, Icon loaded as SVG, Icon only when href is not ArticleID, allowWordWrap default to true Link.defaultProps = { href: '', hideIcon: false, target: ['_parent', '_blank'], className: 'cbLink', style: { whiteSpace: 'nowrap' }, children: 'Link', allowWordWrap: true } const LinkIcon = () => ( 1 Element/Icon/14/External_Story Link_narrow@1.5x )