Link Preview

Enable sighted users to preview content behind a link.

Features

  • Controlled or uncontrolled
  • Ignored by screen readers
  • Custom open and close delay support
  • Positioning and alignment customization

⚠️ The Link Preview is only intended to be used with a mouse or other pointing device. It doesn't respond to touch events, and the preview content cannot be accessed via the keyboard. On touch devices, the link will be followed immediately. As it is not accessible to all users, the preview should not contain vital information.

Anatomy

  • Trigger: The element that opens the link preview on hover.
  • Content: The element containing the content for the link preview.
  • Arrow: An optional arrow component

Usage

Create a link preview using the createLinkPreview builder function.

    <script lang="ts">
  import { createLinkPreview, melt } from '@melt-ui/svelte'
  const {
    elements: { trigger, content, arrow }
  } = createLinkPreview()
</script>
	
    <script lang="ts">
  import { createLinkPreview, melt } from '@melt-ui/svelte'
  const {
    elements: { trigger, content, arrow }
  } = createLinkPreview()
</script>
	

Then you can use the trigger, content, and arrow to construct a link preview. A high level example of how to structure the link preview is shown below.

    <script lang="ts">
  import { createLinkPreview, melt } from '@melt-ui/svelte'
  const {
    elements: { trigger, content, arrow }
  } = createLinkPreview()
</script>
 
<button use:melt={$trigger}>Hover Me</button>
 
<div use:melt={$content}>
  <div>I am content inside the link preview</div>
  <div use:melt={$arrow} />
</div>
	
    <script lang="ts">
  import { createLinkPreview, melt } from '@melt-ui/svelte'
  const {
    elements: { trigger, content, arrow }
  } = createLinkPreview()
</script>
 
<button {...$trigger} use:trigger>Hover Me</button>
 
<div {...$content} use:content>
  <div>I am content inside the link preview</div>
  <div {...$arrow} use:arrow />
</div>
	

It's also possible to use Svelte Transitions, as demonstrated in the example at the top of this page.

Focus handling

By default the link preview will be shown when focused by the keyboard (or more specifically if :focus-visible would apply), and hide on blur.

You can disable this functionality by listening to and cancelling the custom m-focus and m-blur events.

    <button
  use:melt={$trigger}
  on:m-focus={(e) => {
    e.preventDefault()
  }}
  on:m-blur={(e) => {
    e.preventDefault()
  }}>
  Hover Me
</button>
	
    <button
  {...$trigger} use:trigger
  on:m-focus={(e) => {
    e.preventDefault()
  }}
  on:m-blur={(e) => {
    e.preventDefault()
  }}>
  Hover Me
</button>
	

API Reference

createLinkPreview

The builder function used to create the link preview component.

Props

Prop Default Type / Description
openDelay 700
number

The delay in milliseconds before the link preview opens.

closeDelay 300
number

The delay in milliseconds before the link preview closes.

positioning placement: 'bottom'

A configuration object which determines how the floating element is positioned relative to the trigger.

arrowSize 8
number

The size of the arrow which points to the trigger in pixels.

closeOnOutsideClick true
boolean

Whether or not to close the link preview when the user clicks outside of it.

closeOnEscape true
boolean

Whether or not to close the link preview when the escape key is pressed.

forceVisible false
boolean

Whether or not to force the link preview to always be visible. This is useful for custom transitions and animations using conditional blocks.

portal body
string | HTMLElement | null

The element or selector to render the link preview into. Nested floating elements are automatically rendered into their parent if not specified. Pass in null to disable portalling.

defaultOpen false
boolean

Whether the link preview is open by default or not.

open -
Writable<boolean>

A writable store that controls whether or not the link preview is open.

See Bring Your Own Store

onOpenChange -
ChangeFn<boolean>

A callback called when the value of the open store should be changed.

See Change Functions

ids -
Record<'trigger' | 'content', string>

Override the internally generated ids for the elements.

Elements

Element Description

The builder store used to create the link preview trigger.

The builder store used to create the link preview content.

The builder store used to create the link preview arrow.

States

State Description
open

A writable store with the open state of the link preview.

Options

Option Description
openDelay

The delay in milliseconds before the link preview opens.

closeDelay

The delay in milliseconds before the link preview closes.

positioning

A configuration object which determines how the floating element is positioned relative to the trigger.

arrowSize

The size of the arrow which points to the trigger in pixels.

closeOnOutsideClick

Whether or not to close the link preview when the user clicks outside of it.

closeOnEscape

Whether or not to close the link preview when the escape key is pressed.

forceVisible

Whether or not to force the link preview to always be visible. This is useful for custom transitions and animations using conditional blocks.

portal

The element or selector to render the link preview into. Nested floating elements are automatically rendered into their parent if not specified. Pass in null to disable portalling.

IDs

Option Description
trigger

The writable store that represents the id of the trigger element.

content

The writable store that represents the id of the content element.

trigger

The link preview trigger element.

Data Attributes

Data Attribute Value
[data-state]

'open' | 'closed'

[data-melt-link-preview-trigger]

Present on all trigger elements.

Custom Events

Event Value
m-pointerenter (e: ) => void
m-pointerleave (e: ) => void
m-focus (e: ) => void
m-blur (e: ) => void

content

The content displayed in the linkpreview

Data Attributes

Data Attribute Value
[data-state]

'open' | 'closed'

[data-melt-link-preview-content]

Present on all content elements.

Custom Events

Event Value
m-pointerdown (e: ) => void
m-pointerenter (e: ) => void
m-pointerleave (e: ) => void
m-focusout (e: ) => void

arrow

An optional arrow element which points to the menu's trigger.

Data Attributes

Data Attribute Value
[data-arrow]

'true'

[data-melt-link-preview-arrow]

Present on all arrow elements.

Accessibility

The link preview is only intended to be used with a mouse or other pointing device. The preview's content element cannot be accessed via the keyboard and is not exposed to screen readers. As a result the preview should not contain content that is otherwise not visible elsewhere.

Comparison with Tooltip

The link preview is similar to the Tooltip builder, as both have floating contents that initially are hidden, and appear when hovering over the trigger, or focusing it with the keyboard.

There are some key differences though. A Tooltip's content should not have any clickable elements inside it, while a Link Preview's content can contain them. Also, a Tooltip's content is exposed to screen readers, while a Link Preview's content is not. Keep this in mind when choosing which builder to use, as this has implications for accessibility.