EmbedPDF

Menus

A menu is a list of items in sections, with a line between sections. Add one with addMenu(), and open it from a button: a command with menu instead of run.

{
  commands: [
    { id: 'acme:share', label: 'Share', icon: 'link', menu: 'share' },
    { id: 'acme:copy-link', label: 'Copy link', icon: 'copy', run: copyLink },
    { id: 'acme:email', label: 'Email a link', icon: 'message', run: emailLink },
  ],
  layout: (layout) =>
    layout
      .addMenu('share', [['acme:copy-link', 'acme:email'], ['document:download']])
      .add('acme:share', { to: 'main', section: 'end' }),
}

Each row is a command, so it shows its icon, label and shortcut, is disabled when the command can’t run, and is gone when the command isn’t visible.

This menu goes to the document’s chapters, with a line before its last row:

Loading live preview…

chapters.svelte
<script lang="ts">
  import { PDFViewer, type ViewerConfig } from '@embedpdf/viewer-svelte';

  const welcome = '/pdfs/welcome.pdf';

  const config: ViewerConfig = {
    commands: [
      { id: 'acme:chapters', label: 'Chapters', icon: 'book', menu: 'chapters' },
      { id: 'acme:origins', label: 'Origins', run: ({ get }) => get('stage').goToPage(1) },
      { id: 'acme:timeline', label: 'Timeline', run: ({ get }) => get('stage').goToPage(2) },
      { id: 'acme:workflows', label: 'Workflows', run: ({ get }) => get('stage').goToPage(3) },
      { id: 'acme:cover', label: 'Back to the cover', run: ({ get }) => get('stage').goToPage(0) },
    ],
    layout: (layout) =>
      layout
        .addMenu('chapters', [['acme:origins', 'acme:timeline', 'acme:workflows'], ['acme:cover']])
        .add('acme:chapters', { to: 'main', section: 'end' }),
  };
</script>

<PDFViewer src={welcome} {...config} style="height: 100%" />

Try it: open Chapters, the book at the end of the toolbar, and pick Timeline to go to the timeline on page 3. Back to the cover, under the line, goes back to the title page.

Where a menu opens#

You don’t choose. A menu opens away from the edge its bar sits on, toward the pages:

The button is inThe menu opens
A bar at the topBelow it
A bar at the bottomAbove it
A bar at the start or endBeside it, toward the pages
A floating barAway from the corner or edge it floats at
A bar over a selectionAway from the selection, so it never covers it, flipping when there’s no room

When there’s no room on that side, it opens on the other. A menu can reach past the viewer’s edge, like a menu in any app, and it never goes off the screen. On a phone, every menu opens as a sheet from the bottom of the viewer.

Change a built-in menu#

The built-in menus are document, view, zoom, outline-item, attachment-item, comment-item and page. Add to them and remove from them like a bar:

layout
  .add('acme:export-word', { to: 'document', after: 'document:print' })
  .remove('view:fullscreen', { from: 'document' });
MenuIts buttonWhat’s in it
documentmenu:documentOpen (with the local engine), download, print; full screen
viewmenu:viewOne page, two pages, cover page; vertical or horizontal scrolling, or page by page; rotate the view; full screen
zoommenu:zoom50% to 400%; zoom in and out, and the marquee zoom tool; fit page, fit width, automatic
outline-itemmenu:outline-item, on each row of the outline panel, and a right-click on the rowAdd an item after or inside; rename, set the destination, properties; delete
attachment-itemmenu:attachment-item, on each file of the attachments panel, and a right-click on the fileSave, go to a page’s file; delete
comment-itemmenu:comment-item, on each card of the comments panel, and a right-click on the cardThe thread’s status: accepted, rejected, cancelled, completed or none; delete the thread
pagemenu:page, on each page of the thumbnails panel and in its header, a right-click and a long press on a pageRotate either way; insert a blank page or a PDF, duplicate; extract; delete

Sections with a title#

A section is an array, or an object when it has a title:

layout.addMenu('export', [
  { title: 'Export as', items: ['acme:export-word', 'acme:export-excel'] },
  ['document:download'],
]);

A menu in a menu#

An item whose command has a menu opens that menu beside it, as a submenu. On a phone, it slides in over the first one, with a back button.

// acme:share has `menu: 'share'`, so it opens the share menu beside it
layout.add('acme:share', { to: 'document', after: 'document:download' });

Choices#

A command that’s active is marked in a menu with the accent color, like an active toolbar button. The view menu uses this for one page or two, and for the scrolling direction, so the current choice is always marked.

Over a selection#

Three bars appear over what’s selected:

BarAppears overWhat’s in it
selectionSelected textCopy, highlight, underline, strike out
annotationSelected annotationsComment, style, link, group, delete
snapshotThe box the snapshot tool holdsCopy, save image

They’re bars, so the same edits work. Add your own action, or remove one:

layout
  .add('acme:explain', { to: 'selection' })
  .remove(['annotation:group', 'annotation:ungroup'], { from: 'annotation' });

A selection bar appears when the selection is made, not while the mouse is still dragging. The bar for text sits above it, and the bars for annotations and the snapshot below them. Each flips to the other side when there’s no room, and on a touch screen the text bar keeps clear of the handles. Each item is shown only for a selection it works on: Comment isn’t offered on a link, and Group only when more than one annotation is selected.

The “More” menu#

When a bar runs out of room, what doesn’t fit goes into a “More” menu at its end, in the bar’s own order, with the bar’s groups as sections. The viewer builds it, so there’s nothing to set: change the bar, and the “More” menu follows.

Good to know#

Keyboard#

Arrow keys move through a menu, Enter picks, typing jumps to the first item that starts with that letter, and Escape closes it and puts focus back on its button. Each command’s shortcut shows next to its label.

Disabled or hidden#

A command that can’t run now, such as Copy with nothing selected, shows greyed out. A command that’s not visible isn’t in the menu at all, and a section with nothing left disappears with its line.

Your own menu component#

To draw a menu yourself, with your own rows, use Menu and MenuItem from Your own components. They open the same way these do.

Was this page helpful?

Your feedback goes directly to the documentation team.