@frank-auth/react
Version:
Flexible and customizable React UI components for Frank Authentication
1 lines • 11.2 kB
Source Map (JSON)
{"version":3,"file":"link.cjs","sources":["../../../../../src/components/ui/link/link.tsx"],"sourcesContent":["import { useTheme } from \"@/theme/context\";\nimport { type StyledProps, getColorVariant } from \"@/theme/styled\";\nimport { css } from \"@emotion/react\";\nimport styled from \"@emotion/styled\";\nimport React from \"react\";\n\nexport interface LinkProps\n\textends React.AnchorHTMLAttributes<HTMLAnchorElement> {\n\t/** Link color theme */\n\tcolor?:\n\t\t| \"primary\"\n\t\t| \"secondary\"\n\t\t| \"success\"\n\t\t| \"warning\"\n\t\t| \"danger\"\n\t\t| \"foreground\";\n\t/** Link size */\n\tsize?: \"sm\" | \"md\" | \"lg\";\n\t/** Link underline behavior */\n\tunderline?: \"none\" | \"hover\" | \"always\" | \"active\" | \"focus\";\n\t/** Link variant */\n\tvariant?: \"solid\" | \"underlined\" | \"light\";\n\t/** External link indicator */\n\tisExternal?: boolean;\n\t/** Disabled state */\n\tisDisabled?: boolean;\n\t/** Block level link */\n\tisBlock?: boolean;\n\t/** Custom class name */\n\tclassName?: string;\n\t/** Custom styles */\n\tcss?: any;\n}\n\ntype StyledLinkProps = StyledProps<LinkProps>;\n\nconst getLinkColorStyles = (props: StyledLinkProps) => {\n\tconst { theme, color = \"primary\", variant = \"solid\", isDisabled } = props;\n\n\tif (isDisabled) {\n\t\treturn css`\n color: ${theme.colors.text.tertiary};\n cursor: not-allowed;\n pointer-events: none;\n opacity: 0.5;\n `;\n\t}\n\n\tif (color === \"foreground\") {\n\t\treturn css`\n color: ${theme.colors.text.primary};\n\n &:hover {\n opacity: 0.8;\n }\n\n &:active {\n opacity: 0.6;\n }\n `;\n\t}\n\n\tconst baseColor = getColorVariant(theme, color, 500);\n\tconst hoverColor = getColorVariant(theme, color, 600);\n\tconst activeColor = getColorVariant(theme, color, 700);\n\tconst lightColor = getColorVariant(theme, color, 50);\n\n\tswitch (variant) {\n\t\tcase \"solid\":\n\t\t\treturn css`\n color: ${baseColor};\n\n &:hover {\n color: ${hoverColor};\n }\n\n &:active {\n color: ${activeColor};\n }\n `;\n\n\t\tcase \"underlined\":\n\t\t\treturn css`\n color: ${baseColor};\n text-decoration: underline;\n text-underline-offset: 2px;\n\n &:hover {\n color: ${hoverColor};\n }\n\n &:active {\n color: ${activeColor};\n }\n `;\n\n\t\tcase \"light\":\n\t\t\treturn css`\n color: ${baseColor};\n background-color: transparent;\n padding: ${theme.spacing[1]} ${theme.spacing[2]};\n border-radius: ${theme.borderRadius.sm};\n\n &:hover {\n background-color: ${lightColor};\n }\n\n &:active {\n background-color: ${getColorVariant(theme, color, 100)};\n }\n `;\n\n\t\tdefault:\n\t\t\treturn css``;\n\t}\n};\n\nconst getLinkSizeStyles = (props: StyledLinkProps) => {\n\tconst { theme, size = \"md\" } = props;\n\n\tswitch (size) {\n\t\tcase \"sm\":\n\t\t\treturn css`\n font-size: ${theme.fontSizes.sm};\n `;\n\t\tcase \"md\":\n\t\t\treturn css`\n font-size: ${theme.fontSizes.base};\n `;\n\t\tcase \"lg\":\n\t\t\treturn css`\n font-size: ${theme.fontSizes.lg};\n `;\n\t\tdefault:\n\t\t\treturn css`\n font-size: ${theme.fontSizes.base};\n `;\n\t}\n};\n\nconst getLinkUnderlineStyles = (props: StyledLinkProps) => {\n\tconst { underline = \"hover\" } = props;\n\n\tswitch (underline) {\n\t\tcase \"none\":\n\t\t\treturn css`\n text-decoration: none;\n\n &:hover {\n text-decoration: none;\n }\n `;\n\n\t\tcase \"hover\":\n\t\t\treturn css`\n text-decoration: none;\n\n &:hover {\n text-decoration: underline;\n text-underline-offset: 2px;\n }\n `;\n\n\t\tcase \"always\":\n\t\t\treturn css`\n text-decoration: underline;\n text-underline-offset: 2px;\n `;\n\n\t\tcase \"active\":\n\t\t\treturn css`\n text-decoration: none;\n\n &:active {\n text-decoration: underline;\n text-underline-offset: 2px;\n }\n `;\n\n\t\tcase \"focus\":\n\t\t\treturn css`\n text-decoration: none;\n\n &:focus {\n text-decoration: underline;\n text-underline-offset: 2px;\n }\n `;\n\n\t\tdefault:\n\t\t\treturn css``;\n\t}\n};\n\nconst StyledLink = styled.a<StyledLinkProps>`\n display: ${(props) => (props.isBlock ? \"block\" : \"inline-flex\")};\n align-items: center;\n gap: ${(props) => props.theme.spacing[1]};\n font-family: inherit;\n font-weight: ${(props) => props.theme.fontWeights.medium};\n line-height: ${(props) => props.theme.lineHeights.normal};\n cursor: pointer;\n transition: all ${(props) => props.theme.transitions.fast};\n position: relative;\n outline: none;\n\n &:focus-visible {\n outline: 2px solid ${(props) => props.theme.colors.border.focus};\n outline-offset: 2px;\n border-radius: ${(props) => props.theme.borderRadius.sm};\n }\n\n ${getLinkColorStyles}\n ${getLinkSizeStyles}\n ${getLinkUnderlineStyles}\n\n /* Custom CSS prop */\n ${(props) => props.css}\n`;\n\nconst ExternalIcon = styled.svg<{ size?: \"sm\" | \"md\" | \"lg\" }>`\n width: ${(props) => {\n\t\tswitch (props.size) {\n\t\t\tcase \"sm\":\n\t\t\t\treturn \"12px\";\n\t\t\tcase \"lg\":\n\t\t\t\treturn \"18px\";\n\t\t\tdefault:\n\t\t\t\treturn \"14px\";\n\t\t}\n\t}};\n height: ${(props) => {\n\t\tswitch (props.size) {\n\t\t\tcase \"sm\":\n\t\t\t\treturn \"12px\";\n\t\t\tcase \"lg\":\n\t\t\t\treturn \"18px\";\n\t\t\tdefault:\n\t\t\t\treturn \"14px\";\n\t\t}\n\t}};\n opacity: 0.7;\n`;\n\nexport const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(\n\t(\n\t\t{\n\t\t\tchildren,\n\t\t\tcolor = \"primary\",\n\t\t\tsize = \"md\",\n\t\t\tunderline = \"hover\",\n\t\t\tvariant = \"solid\",\n\t\t\tisExternal = false,\n\t\t\tisDisabled = false,\n\t\t\tisBlock = false,\n\t\t\tclassName,\n\t\t\tcss,\n\t\t\thref,\n\t\t\ttarget,\n\t\t\trel,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst { theme } = useTheme();\n\n\t\t// Auto-detect external links\n\t\tconst isExternalLink =\n\t\t\tisExternal ||\n\t\t\t(href &&\n\t\t\t\t(href.startsWith(\"http\") ||\n\t\t\t\t\thref.startsWith(\"mailto:\") ||\n\t\t\t\t\thref.startsWith(\"tel:\")));\n\n\t\tconst linkProps = {\n\t\t\t...props,\n\t\t\tcolor,\n\t\t\tsize,\n\t\t\tunderline,\n\t\t\tvariant,\n\t\t\tisDisabled,\n\t\t\tisBlock,\n\t\t\tclassName,\n\t\t\tcss,\n\t\t\thref: isDisabled ? undefined : href,\n\t\t\ttarget: isExternalLink ? \"_blank\" : target,\n\t\t\trel: isExternalLink ? \"noopener noreferrer\" : rel,\n\t\t};\n\n\t\treturn (\n\t\t\t<StyledLink theme={theme} ref={ref} {...linkProps}>\n\t\t\t\t{children}\n\t\t\t\t{isExternalLink && !isDisabled && (\n\t\t\t\t\t<ExternalIcon\n\t\t\t\t\t\tsize={size}\n\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\tstrokeWidth=\"2\"\n\t\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n\t\t\t\t\t\t<polyline points=\"15,3 21,3 21,9\" />\n\t\t\t\t\t\t<line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\n\t\t\t\t\t</ExternalIcon>\n\t\t\t\t)}\n\t\t\t</StyledLink>\n\t\t);\n\t},\n);\n\nLink.displayName = \"Link\";\n"],"names":["getLinkColorStyles","props","theme","color","variant","isDisabled","css","baseColor","getColorVariant","hoverColor","activeColor","lightColor","getLinkSizeStyles","size","getLinkUnderlineStyles","underline","StyledLink","styled","ExternalIcon","Link","React","children","isExternal","isBlock","className","href","target","rel","ref","useTheme","isExternalLink","linkProps","jsxs","jsx"],"mappings":"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"}