{"version":3,"file":"TextLink.mjs","sources":["../../../../src/components/Link/TextLink.tsx"],"sourcesContent":["import { css } from '@emotion/css';\nimport { AnchorHTMLAttributes, forwardRef } from 'react';\n\nimport { GrafanaTheme2, locationUtil, textUtil, ThemeTypographyVariantTypes } from '@grafana/data';\n\nimport { useTheme2 } from '../../themes';\nimport { IconName, IconSize } from '../../types';\nimport { Icon } from '../Icon/Icon';\nimport { customWeight } from '../Text/utils';\n\nimport { Link } from './Link';\n\ntype TextLinkVariants = keyof Omit<ThemeTypographyVariantTypes, 'code'>;\n\ninterface TextLinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'target' | 'rel'> {\n  /** url to which redirect the user, external or internal */\n  href: string;\n  /** Color to use for text */\n  color?: keyof GrafanaTheme2['colors']['text'];\n  /** Specify if the link will redirect users to a page in or out Grafana */\n  external?: boolean;\n  /** True when the link will be displayed inline with surrounding text, false if it will be displayed as a block. Depending on this prop correspondant default styles will be applied */\n  inline?: boolean;\n  /** The default variant is 'body'. To fit another styles set the correspondent variant as it is necessary also to adjust the icon size. `code` is excluded, as it is not fit for links. */\n  variant?: TextLinkVariants;\n  /** Override the default weight for the used variant */\n  weight?: 'light' | 'regular' | 'medium' | 'bold';\n  /** Set the icon to be shown. An external link will show the 'external-link-alt' icon as default.*/\n  icon?: IconName;\n  children: React.ReactNode;\n}\n\nconst svgSizes: {\n  [key in TextLinkVariants]: IconSize;\n} = {\n  h1: 'xl',\n  h2: 'xl',\n  h3: 'lg',\n  h4: 'lg',\n  h5: 'md',\n  h6: 'md',\n  body: 'md',\n  bodySmall: 'xs',\n};\n\nexport const TextLink = forwardRef<HTMLAnchorElement, TextLinkProps>(\n  (\n    { href, color = 'link', external = false, inline = true, variant = 'body', weight, icon, children, ...rest },\n    ref\n  ) => {\n    const validUrl = textUtil.sanitizeUrl(href ?? '');\n\n    const theme = useTheme2();\n    const styles = getLinkStyles(theme, inline, variant, weight, color);\n    const externalIcon = icon || 'external-link-alt';\n\n    if (external) {\n      return (\n        <a href={validUrl} ref={ref} {...rest} target=\"_blank\" rel=\"noreferrer\" className={styles}>\n          {children}\n          <Icon size={svgSizes[variant] || 'md'} name={externalIcon} />\n        </a>\n      );\n    }\n\n    const strippedUrl = locationUtil.stripBaseFromUrl(validUrl);\n\n    return (\n      <Link ref={ref} href={strippedUrl} {...rest} className={styles}>\n        {children}\n        {icon && <Icon name={icon} size={svgSizes[variant] || 'md'} />}\n      </Link>\n    );\n  }\n);\n\nTextLink.displayName = 'TextLink';\n\nexport const getLinkStyles = (\n  theme: GrafanaTheme2,\n  inline: boolean,\n  variant?: keyof ThemeTypographyVariantTypes,\n  weight?: TextLinkProps['weight'],\n  color?: TextLinkProps['color']\n) => {\n  return css([\n    variant && {\n      ...theme.typography[variant],\n    },\n    weight && {\n      fontWeight: customWeight(weight, theme),\n    },\n    color && {\n      color: theme.colors.text[color],\n    },\n    {\n      alignItems: 'center',\n      gap: '0.25em',\n      display: 'inline-flex',\n      textDecoration: 'none',\n      '&:hover': {\n        textDecoration: 'underline',\n        color: theme.colors.text.link,\n      },\n    },\n    inline && {\n      textDecoration: 'underline',\n      '&:hover': {\n        textDecoration: 'none',\n      },\n    },\n  ]);\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;AAgCA,MAAM,QAEF,GAAA;AAAA,EACF,EAAI,EAAA,IAAA;AAAA,EACJ,EAAI,EAAA,IAAA;AAAA,EACJ,EAAI,EAAA,IAAA;AAAA,EACJ,EAAI,EAAA,IAAA;AAAA,EACJ,EAAI,EAAA,IAAA;AAAA,EACJ,EAAI,EAAA,IAAA;AAAA,EACJ,IAAM,EAAA,IAAA;AAAA,EACN,SAAW,EAAA;AACb,CAAA;AAEO,MAAM,QAAW,GAAA,UAAA;AAAA,EACtB,CACE,EAAE,IAAA,EAAM,KAAQ,GAAA,MAAA,EAAQ,WAAW,KAAO,EAAA,MAAA,GAAS,IAAM,EAAA,OAAA,GAAU,QAAQ,MAAQ,EAAA,IAAA,EAAM,UAAU,GAAG,IAAA,IACtG,GACG,KAAA;AACH,IAAA,MAAM,QAAW,GAAA,QAAA,CAAS,WAAY,CAAA,IAAA,IAAA,IAAA,GAAA,IAAA,GAAQ,EAAE,CAAA;AAEhD,IAAA,MAAM,QAAQ,SAAU,EAAA;AACxB,IAAA,MAAM,SAAS,aAAc,CAAA,KAAA,EAAO,MAAQ,EAAA,OAAA,EAAS,QAAQ,KAAK,CAAA;AAClE,IAAA,MAAM,eAAe,IAAQ,IAAA,mBAAA;AAE7B,IAAA,IAAI,QAAU,EAAA;AACZ,MAAA,uBACG,IAAA,CAAA,GAAA,EAAA,EAAE,IAAM,EAAA,QAAA,EAAU,GAAW,EAAA,GAAG,IAAM,EAAA,MAAA,EAAO,QAAS,EAAA,GAAA,EAAI,YAAa,EAAA,SAAA,EAAW,MAChF,EAAA,QAAA,EAAA;AAAA,QAAA,QAAA;AAAA,wBACD,GAAA,CAAC,QAAK,IAAM,EAAA,QAAA,CAAS,OAAO,CAAK,IAAA,IAAA,EAAM,MAAM,YAAc,EAAA;AAAA,OAC7D,EAAA,CAAA;AAAA;AAIJ,IAAM,MAAA,WAAA,GAAc,YAAa,CAAA,gBAAA,CAAiB,QAAQ,CAAA;AAE1D,IACE,uBAAA,IAAA,CAAC,QAAK,GAAU,EAAA,IAAA,EAAM,aAAc,GAAG,IAAA,EAAM,WAAW,MACrD,EAAA,QAAA,EAAA;AAAA,MAAA,QAAA;AAAA,MACA,IAAA,wBAAS,IAAK,EAAA,EAAA,IAAA,EAAM,MAAM,IAAM,EAAA,QAAA,CAAS,OAAO,CAAA,IAAK,IAAM,EAAA;AAAA,KAC9D,EAAA,CAAA;AAAA;AAGN;AAEA,QAAA,CAAS,WAAc,GAAA,UAAA;AAEhB,MAAM,gBAAgB,CAC3B,KAAA,EACA,MACA,EAAA,OAAA,EACA,QACA,KACG,KAAA;AACH,EAAA,OAAO,GAAI,CAAA;AAAA,IACT,OAAW,IAAA;AAAA,MACT,GAAG,KAAM,CAAA,UAAA,CAAW,OAAO;AAAA,KAC7B;AAAA,IACA,MAAU,IAAA;AAAA,MACR,UAAA,EAAY,YAAa,CAAA,MAAA,EAAQ,KAAK;AAAA,KACxC;AAAA,IACA,KAAS,IAAA;AAAA,MACP,KAAO,EAAA,KAAA,CAAM,MAAO,CAAA,IAAA,CAAK,KAAK;AAAA,KAChC;AAAA,IACA;AAAA,MACE,UAAY,EAAA,QAAA;AAAA,MACZ,GAAK,EAAA,QAAA;AAAA,MACL,OAAS,EAAA,aAAA;AAAA,MACT,cAAgB,EAAA,MAAA;AAAA,MAChB,SAAW,EAAA;AAAA,QACT,cAAgB,EAAA,WAAA;AAAA,QAChB,KAAA,EAAO,KAAM,CAAA,MAAA,CAAO,IAAK,CAAA;AAAA;AAC3B,KACF;AAAA,IACA,MAAU,IAAA;AAAA,MACR,cAAgB,EAAA,WAAA;AAAA,MAChB,SAAW,EAAA;AAAA,QACT,cAAgB,EAAA;AAAA;AAClB;AACF,GACD,CAAA;AACH;;;;"}