Link

A link allows a user to navigate to a page inside or outside the application.

Usage

LinkExample.tsx
  1. 1

Here's the <Link /> component in action.

IDFIRST NAMELAST NAMEEMAILPHONE
0RodrigoJordesonrjordesonrr@nbcnews.com596-412-7883
1JessamynEspinazojespinazo0@chicagotribune.com162-166-0977
2IsacTooheritooher1@psu.edu655-567-3619
3TabbathaProschketproschke2@weibo.com327-612-4850
4NinettaMabbnmabb3@canalblog.com971-296-0911
5DanniWallentindwallentin4@comcast.net983-297-0506
6NeelyPurkinsnpurkins5@mediafire.com379-119-4237
7JessikaKinkaidjkinkaid6@eventbrite.com771-888-6284
8JuliannaSwindalljswindall7@aol.com252-614-0486
9CorrinneGeevecgeeve8@wisc.edu450-872-8646

Features

  • Supports client-side routing.

Source

link.tsx
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
import { NavLink, type NavLinkProps } from '@remix-run/react'
import { type ElementRef, forwardRef, useRef, type MutableRefObject, type RefCallback } from 'react'
import { useLink, mergeProps, type AriaLinkOptions, useHover, useFocusRing } from 'react-aria'
import { cn } from '#app/utils/tailwind-merge.ts'
export interface LinkProps extends AriaLinkOptions, Omit<NavLinkProps, 'download' | 'onBlur' | 'onFocus' | 'onKeyDown' | 'onKeyUp' | 'to'> {
to?: NavLinkProps['to']
variant?: 'default' | 'typographical' | 'unstyled' | 'button' | 'ghost'
buttonVariant?: 'primary' | 'secondary' | 'danger' | 'ghost'
size?: 'sm' | 'md' | 'lg'
}
const Link = forwardRef<ElementRef<typeof NavLink>, LinkProps>(({ to = '/', variant = 'default', buttonVariant = 'primary', size, children, className, ...props }, ref) => {
const privateRef = useRef(null)
const { linkProps, isPressed } = useLink(props, privateRef)
const { hoverProps, isHovered } = useHover(props)
const { focusProps, isFocused, isFocusVisible } = useFocusRing()
const mergedProps = mergeProps(props, linkProps, hoverProps, focusProps)
return (
<NavLink
ref={mergeRefs(privateRef, ref)}
to={to}
className={cn('link', variant, variant === 'button' ? buttonVariant : null, size, className)}
{...mergedProps}
data-focused={isFocused || undefined}
data-hovered={isHovered || undefined}
data-pressed={isPressed || undefined}
data-focus-visible={isFocusVisible || undefined}
data-current={!!props['aria-current'] || undefined}
data-disabled={props.isDisabled || undefined}
>
{children}
</NavLink>
)
})
Link.displayName = 'Link'
type MutableRefList<T> = Array<RefCallback<T> | MutableRefObject<T> | undefined | null>
export function mergeRefs<T>(...refs: MutableRefList<T>): RefCallback<T> {
return (val: T) => {
setRef(val, ...refs)
}
}
export function setRef<T>(val: T, ...refs: MutableRefList<T>): void {
refs.forEach(ref => {
if (typeof ref === 'function') {
ref(val)
} else if (ref != null) {
ref.current = val
}
})
}
export { Link }