UNPKG

@veracity/vui

Version:

Veracity UI is a React component library crafted for use within Veracity applications and pages. Based on Styled Components and @xstyled.

110 lines (106 loc) 3.5 kB
import { isReactText, isString } from "../utils/assertion.js"; import { filterUndefined } from "../utils/object.js"; import { cs } from "../utils/styles.js"; import { useStyleConfig } from "../core/theme.js"; import styled from "../core/styled.js"; import vui from "../core/vui.js"; import { T } from "../t/t.js"; import { LinkProvider } from "./context.js"; import { LinkIcon } from "./linkIcon.js"; import { LinkText } from "./linkText.js"; import { useEffect, useMemo } from "react"; import { jsx, jsxs } from "react/jsx-runtime"; //#region src/link/link.tsx const linkSwipeAnimation = ` @keyframes linkSwipe { from { background-size: 0 1px; } to { background-size: 100% 1px; } } `; const LinkBase = styled.aBox.attrs((props) => ({ isUnderlined: props.isUnderlined || false }))` ${linkSwipeAnimation} display: inline; cursor: pointer; position: relative; line-height: 1.5; outline: none; width: fit-content; text-decoration: none; &:not(.vui-linkNoUnderline) > .vui-t { position: relative; background: linear-gradient(to right, currentcolor, currentcolor); background-size: ${({ isUnderlined }) => isUnderlined ? "100% 1px" : "0 1px"}; background-position: 0 100%; background-repeat: no-repeat; text-decoration: none; padding-bottom: 2px; line-height: 1.2; } &:hover > .vui-t { animation: ${({ isUnderlined }) => isUnderlined ? "linkSwipe 0.5s ease forwards" : "linkSwipe 0.3s ease forwards"}; background-size: 100% 1px; } `; const Link = vui((props, ref) => { const { children, className, fontWeight, startIcon, endIcon, iconLeft, iconRight, isExternal, isUnderlined, size, text, variant, weight, ...rest } = props; const resolvedStartIcon = startIcon ?? iconLeft; const resolvedEndIcon = endIcon ?? iconRight; const styles = useStyleConfig("Link", props); const context = useMemo(() => filterUndefined({ size, variant }), [size, variant]); const iconPadding = size === "xs" ? "1.2rem" : "1.5rem"; const aliasedProps = filterUndefined({ fontWeight: weight || fontWeight, rel: isExternal ? "noopener" : void 0, target: isExternal ? "_blank" : void 0, pl: resolvedStartIcon ? iconPadding : void 0, pr: resolvedEndIcon ? iconPadding : void 0 }); useEffect(() => { if (iconLeft !== void 0) console.warn("[Link] `iconLeft` is deprecated. Use `startIcon` instead."); if (iconRight !== void 0) console.warn("[Link] `iconRight` is deprecated. Use `endIcon` instead."); }, [iconLeft, iconRight]); return /* @__PURE__ */ jsx(LinkProvider, { value: context, "data-size": context.size, "data-variant": context.variant, children: /* @__PURE__ */ jsxs(LinkBase, { className: cs("vui-link", className), focusRing: 2, isUnderlined, ref, ...styles.container, ...aliasedProps, ...rest, children: [ isString(resolvedStartIcon) ? /* @__PURE__ */ jsx(LinkIcon, { mr: 1, left: 0, name: resolvedStartIcon }) : resolvedStartIcon, children ? /* @__PURE__ */ jsx(T, { fontSize: "inherit", children }) : isReactText(text) && /* @__PURE__ */ jsx(LinkText, { text }), isString(resolvedEndIcon) ? /* @__PURE__ */ jsx(LinkIcon, { ml: 1, right: 0, name: resolvedEndIcon }) : resolvedEndIcon ] }) }); }); Link.Icon = LinkIcon; Link.Text = LinkText; Link.displayName = "Link"; //#endregion export { Link, Link as default, LinkBase }; globalThis.__vuiVersion__ = "5.3.1" //# sourceMappingURL=link.js.map