{"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/ThemeContext';\nimport { IconName, IconSize } from '../../types/icon';\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\n/**\n * The TextLink component renders an anchor tag `<a>` that takes users to another page, external or internal to Grafana.\n *\n * https://developers.grafana.com/ui/latest/index.html?path=/docs/foundations-textlink--docs\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,QAAA,GAEF;AAAA,EACF,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI,IAAA;AAAA,EACJ,IAAA,EAAM,IAAA;AAAA,EACN,SAAA,EAAW;AACb,CAAA;AAOO,MAAM,QAAA,GAAW,UAAA;AAAA,EACtB,CACE,EAAE,IAAA,EAAM,KAAA,GAAQ,MAAA,EAAQ,WAAW,KAAA,EAAO,MAAA,GAAS,IAAA,EAAM,OAAA,GAAU,QAAQ,MAAA,EAAQ,IAAA,EAAM,UAAU,GAAG,IAAA,IACtG,GAAA,KACG;AACH,IAAA,MAAM,QAAA,GAAW,QAAA,CAAS,WAAA,CAAY,IAAA,IAAA,IAAA,GAAA,IAAA,GAAQ,EAAE,CAAA;AAEhD,IAAA,MAAM,QAAQ,SAAA,EAAU;AACxB,IAAA,MAAM,SAAS,aAAA,CAAc,KAAA,EAAO,MAAA,EAAQ,OAAA,EAAS,QAAQ,KAAK,CAAA;AAClE,IAAA,MAAM,eAAe,IAAA,IAAQ,mBAAA;AAE7B,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,uBACE,IAAA,CAAC,GAAA,EAAA,EAAE,IAAA,EAAM,QAAA,EAAU,GAAA,EAAW,GAAG,IAAA,EAAM,MAAA,EAAO,QAAA,EAAS,GAAA,EAAI,YAAA,EAAa,SAAA,EAAW,MAAA,EAChF,QAAA,EAAA;AAAA,QAAA,QAAA;AAAA,wBACD,GAAA,CAAC,QAAK,IAAA,EAAM,QAAA,CAAS,OAAO,CAAA,IAAK,IAAA,EAAM,MAAM,YAAA,EAAc;AAAA,OAAA,EAC7D,CAAA;AAAA,IAEJ;AAEA,IAAA,MAAM,WAAA,GAAc,YAAA,CAAa,gBAAA,CAAiB,QAAQ,CAAA;AAE1D,IAAA,uBACE,IAAA,CAAC,QAAK,GAAA,EAAU,IAAA,EAAM,aAAc,GAAG,IAAA,EAAM,WAAW,MAAA,EACrD,QAAA,EAAA;AAAA,MAAA,QAAA;AAAA,MACA,IAAA,wBAAS,IAAA,EAAA,EAAK,IAAA,EAAM,MAAM,IAAA,EAAM,QAAA,CAAS,OAAO,CAAA,IAAK,IAAA,EAAM;AAAA,KAAA,EAC9D,CAAA;AAAA,EAEJ;AACF;AAEA,QAAA,CAAS,WAAA,GAAc,UAAA;AAEhB,MAAM,gBAAgB,CAC3B,KAAA,EACA,MAAA,EACA,OAAA,EACA,QACA,KAAA,KACG;AACH,EAAA,OAAO,GAAA,CAAI;AAAA,IACT,OAAA,IAAW;AAAA,MACT,GAAG,KAAA,CAAM,UAAA,CAAW,OAAO;AAAA,KAC7B;AAAA,IACA,MAAA,IAAU;AAAA,MACR,UAAA,EAAY,YAAA,CAAa,MAAA,EAAQ,KAAK;AAAA,KACxC;AAAA,IACA,KAAA,IAAS;AAAA,MACP,KAAA,EAAO,KAAA,CAAM,MAAA,CAAO,IAAA,CAAK,KAAK;AAAA,KAChC;AAAA,IACA;AAAA,MACE,UAAA,EAAY,QAAA;AAAA,MACZ,GAAA,EAAK,QAAA;AAAA,MACL,OAAA,EAAS,aAAA;AAAA,MACT,cAAA,EAAgB,MAAA;AAAA,MAChB,SAAA,EAAW;AAAA,QACT,cAAA,EAAgB,WAAA;AAAA,QAChB,KAAA,EAAO,KAAA,CAAM,MAAA,CAAO,IAAA,CAAK;AAAA;AAC3B,KACF;AAAA,IACA,MAAA,IAAU;AAAA,MACR,cAAA,EAAgB,WAAA;AAAA,MAChB,SAAA,EAAW;AAAA,QACT,cAAA,EAAgB;AAAA;AAClB;AACF,GACD,CAAA;AACH;;;;"}