Text Link

Inline underlined text link with a trailing icon. Polymorphic — renders a Next.js Link when href is provided, or a button when used with onClick. Used in the footer ('See my profile') and on the homepage testimonials toggle ('View more reviews').

Default (link mode)

Default icon is ArrowUpRight. Use this style for navigation — e.g. the footer's "Open to new roles — See my profile" row.

Open to new roles — See my profile

tsx
<TextLink href="/about">See my profile</TextLink>

Toggle (button mode)

Omit href and pass onClick to render a button. Pair with ChevronDown and a rotate-180 transform on iconClassName for an expand/collapse affordance — exactly the pattern used by the mobile testimonials "View more reviews" toggle.

tsx
const [expanded, setExpanded] = useState(false)

<TextLink
  icon={ChevronDown}
  iconClassName={cn('transition-transform', expanded && 'rotate-180')}
  onClick={() => setExpanded((v) => !v)}
  aria-expanded={expanded}
>
  {expanded ? 'View less' : 'View more reviews'}
</TextLink>

Custom icon

Pass any Lucide icon via the icon prop.

Browse all work

See my profile (default ArrowUpRight)

tsx
<TextLink href="/work" icon={ArrowRight}>Browse all work</TextLink>
<TextLink href="/about">See my profile</TextLink>

Props

PropTypeDefaultDescription
hrefstring-When provided, renders a Next.js Link. Omit to render a <button> (use with onClick).
onClick() => void-Click handler. Available when no href is provided (button mode).
iconLucideIconArrowUpRightTrailing icon. Defaults to ArrowUpRight; pass any Lucide icon (e.g. ChevronDown for expand affordances).
iconClassNamestring-Classes applied to the icon — useful for transforms like rotate-180 on toggles.
classNamestring-Additional classes merged into the link/button root.
children*ReactNode-The link text.

Import

tsx
import { TextLink } from '@/components/ui/TextLink'