Popover

Displays rich content in a portal, triggered by a button.

Features

  • Full keyboard navigation
  • Customize positioning of popover
  • Can be controlled or uncontrolled
  • Focus is fully managed
  • Supports an optional arrow component

Anatomy

  • Trigger: The button(s) which open/close the popover.
  • Content: The content area viewed when the trigger is clicked.
  • Arrow: An optional arrow component
  • Close: A button which closes the popover

Usage

To create a popover, use the createPopover builder function. Follow the anatomy or the example above to create your popover.

Default open state

To specify that the popover should be open by default, set the defaultOpen prop to true.

    const {
  /** ... */
} = createPopover({
  defaultOpen: true
})
	
    const {
  /** ... */
} = createPopover({
  defaultOpen: true
})
	

Controlled usage

To control the popover directly, you can use the onOpenChange prop, which accepts a callback.

The callback will be called with an object containing two properties: prev and next. Prev indicates the previous open state, and next indicates the next open state that would take place in uncontrolled usage. The value returned by the callback will be used as the next open state.

    const popover = createPopover({
  onOpenChange: ({ curr, next }) => {
  // Do something with the open state
  if (/* some condition */) {
    return false
  }
  return next
  }
})
	
    const popover = createPopover({
  onOpenChange: ({ curr, next }) => {
  // Do something with the open state
  if (/* some condition */) {
    return false
  }
  return next
  }
})
	

You can also pass in your own store to control the open state. This is useful when you want to control the open state from outside the popover, or use an outside store that is already being used elsewhere in your application.

If you don't pass an open prop, the builder will create a store for you, and return it.

    const open = writable(false)
 
const popover = createPopover({
  open
})
	
    const open = writable(false)
 
const popover = createPopover({
  open
})
	

Modal Behavior

To give the popover modal behavior, where body scrolling is disabled and an overlay is rendered behind the popover to prevent interaction with the rest of the page, use the preventScroll prop and overlay builder element.

    <script lang="ts">
  import { createPopover, melt } from '@melt-ui/svelte'
 
  const {
    elements: { content, trigger, overlay, close, arrow }
  } = createPopover({
    preventScroll: true
  })
</script>
 
<button type="button" use:melt={$trigger}> Open </button>
<div use:melt={$overlay} />
<div use:melt={$content}>
  <div use:melt={$arrow} />
  <div>
    <!-- ... -->
  </div>
  <button use:melt={$close}> Close </button>
</div>
	
    <script lang="ts">
  import { createPopover, melt } from '@melt-ui/svelte'
 
  const {
    elements: { content, trigger, overlay, close, arrow }
  } = createPopover({
    preventScroll: true
  })
</script>
 
<button type="button" {...$trigger} use:trigger> Open </button>
<div {...$overlay} use:overlay />
<div {...$content} use:content>
  <div {...$arrow} use:arrow />
  <div>
    <!-- ... -->
  </div>
  <button {...$close} use:close> Close </button>
</div>
	

The Modal Popover example below demonstrates this behavior in action.

Example Components

Nested Popovers

Modal Popover

API Reference

createPopover

The builder function used to create the popover component.

Props

Prop Default Type / Description
positioning placement: 'bottom'

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

disableFocusTrap false
boolean

Whether to disable the focus trap.

arrowSize 8
number

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

escapeBehavior 'close'
'close' | 'ignore' | 'defer-otherwise-close' | 'defer-otherwise-ignore'

Defines how the popover reacts when the Escape key is pressed.

  • close: Closes the popover immediately.
  • ignore: Prevents the popover from closing and also blocks the parent element from closing in response to the Escape key.
  • defer-otherwise-close: Delegates the action to the parent element. If no parent is found, it closes the element.
  • defer-otherwise-ignore: Delegates the action to the parent element. If no parent is found, nothing is done.
  • closeOnOutsideClick true
    boolean

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

    preventScroll true
    boolean

    Whether or not to prevent scrolling of the document when the popover is open.

    preventTextSelectionOverflow true
    boolean

    Whether to prevent text selection overflowing the popover when it is the top layer.

    portal body
    string | HTMLElement | null

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

    forceVisible false
    boolean

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

    openFocus -

    Override the default focus behavior on open

    closeFocus -

    Override the default focus behavior on close

    defaultOpen false
    boolean

    Whether the popover is open by default or not.

    open -
    Writable<boolean>

    A writable store that controls whether or not the popover 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 popover trigger.

    The builder store used to create the popover content.

    The builder store used to create the popover overlay.

    The builder store used to create the popover close button.

    The builder store used to create the popover arrow.

    States

    State Description
    open

    A writable store which represents the open state of the popover.

    Options

    Option Description
    positioning

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

    disableFocusTrap

    Whether to disable the focus trap.

    arrowSize

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

    escapeBehavior

    Defines how the popover reacts when the Escape key is pressed.

  • close: Closes the popover immediately.
  • ignore: Prevents the popover from closing and also blocks the parent element from closing in response to the Escape key.
  • defer-otherwise-close: Delegates the action to the parent element. If no parent is found, it closes the element.
  • defer-otherwise-ignore: Delegates the action to the parent element. If no parent is found, nothing is done.
  • closeOnOutsideClick

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

    preventScroll

    Whether or not to prevent scrolling of the document when the popover is open.

    preventTextSelectionOverflow

    Whether to prevent text selection overflowing the popover when it is the top layer.

    portal

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

    forceVisible

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

    openFocus

    Override the default focus behavior on open

    closeFocus

    Override the default focus behavior on close

    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 button(s) which open/close the popover.

    Data Attributes

    Data Attribute Value
    [data-state]

    'open' | 'closed'

    [data-melt-popover-trigger]

    Present on all trigger elements.

    Custom Events

    Event Value
    m-click (e: ) => void
    m-keydown (e: ) => void

    content

    The popover content.

    Data Attributes

    Data Attribute Value
    [data-side]

    'top' | 'right' | 'bottom' | 'left'

    [data-align]

    'start' | 'center' | 'end'

    [data-state]

    'open' | 'closed'

    [data-melt-popover-content]

    Present on all content elements.

    overlay

    The optional popover overlay element, which can be used to give the popover modal-like behavior where the user cannot interact with the rest of the page while the popover is open.

    Data Attributes

    Data Attribute Value
    [data-state]

    'open' | 'closed'

    [data-melt-popover-overlay]

    Present on all overlay elements.

    close

    The button(s) which close the popover.

    Data Attributes

    Data Attribute Value
    [data-melt-popover-close]

    Present on all close elements.

    Custom Events

    Event Value
    m-click (e: ) => void
    m-keydown (e: ) => void

    arrow

    The optional arrow element.

    Data Attributes

    Data Attribute Value
    [data-side]

    'top' | 'right' | 'bottom' | 'left'

    [data-arrow]

    'true'

    [data-melt-popover-arrow]

    Present on all arrow elements.

    Accessibility

    Adheres to the Dialog WAI-ARIA design pattern

    Key Behavior
    Space

    Toggles the popover.

    Enter

    Toggles the popover.

    Tab

    Moves focus to the next focusable element; all focusable elements in the popover are included in the page Tab sequence.

    Shift + Tab

    Moves focus to the previous focusable element; all focusable elements in the popover are included in the page Tab sequence.

    Esc

    Closes the popover and moves focus to the trigger element.