DevactionUI.PdfViewer (devaction_ui v0.2.3)

Copy Markdown View Source

A PDF viewer with signature fields: a rail of page thumbnails, a toolbar, the page and a panel of signers.

The server owns page and zoom. The page is drawn by pdf.js in the browser when a src is given (the DevactionUI.PdfViewer hook loads pdfjs-dist with import() and takes the worker from worker_src), and the :sheet slot is the server-rendered page that shows until then, and stays when there is no src, so the viewer works, and is testable, without pdf.js. The toolbar (toolbar/1) and the panel (signatures/1) are plain function components that work without any JavaScript.

The signature fields come as a list of maps %{page, x, y, w, h, signer, state}, the box in percent of the page and the state one of :signed (green), :mine ("you sign here": amber, dashed, with a small label) and :pending (neutral). A field may carry a label (the word on it, such as "Signed"); the hook never draws fields, they are part of the markup, so they sit over the page at any zoom.

The hook sends page and zoom to the server with pushEventTo, to the events named by page_event and zoom_event, as %{"page" => 3} and %{"zoom" => 125}, which are the payloads of the buttons too. Keys: +, - and 0 zoom, PageUp, PageDown, Home and End turn pages, and the thumbnails are a listbox that the arrows move through. zoom_in/1, zoom_out/1, clamp_page/2 and my_page/1 are the server's side of that.

Summary

Functions

A page number held to 1..total.

The page of the first field the viewer's person has to sign, or nil.

The panel of signers: avatar, name, role and a status for each, a note, and the jump to my signature.

The toolbar of the viewer: the file name, the zoom, the page n of total and the jump to my signature.

A PDF viewer with a thumbnail rail, a toolbar, the page with its signature fields, and a panel.

The zoom one step in from zoom, which stops at the biggest step.

The zoom one step out from zoom, which stops at the smallest step.

Functions

clamp_page(page, total)

@spec clamp_page(integer(), integer()) :: integer()

A page number held to 1..total.

my_page(fields)

@spec my_page([map()]) :: integer() | nil

The page of the first field the viewer's person has to sign, or nil.

signatures(assigns)

@spec signatures(map()) :: Phoenix.LiveView.Rendered.t()

The panel of signers: avatar, name, role and a status for each, a note, and the jump to my signature.

Attributes

  • title (:string) (required) - the heading of the panel, such as Signatures.
  • signers (:list) (required) - %{name, role, status, status_label} per signer; status is :signed or :pending, tone is :red, :indigo, :green or :gray and mine: true marks the viewer's person.
  • jump_event (:any) - the jump to my signature: a string or a %JS{}. Defaults to nil.
  • jump_label (:string) - the text of the primary button, which shows when it is given. Defaults to nil.
  • target (:any) - Defaults to nil.
  • class (:any) - Defaults to nil.
  • Global attributes are accepted.

Slots

  • note - a note under the signers, such as where the field is.

toolbar(assigns)

@spec toolbar(map()) :: Phoenix.LiveView.Rendered.t()

The toolbar of the viewer: the file name, the zoom, the page n of total and the jump to my signature.

Attributes

  • name (:string) (required)
  • page (:integer) (required)
  • pages (:integer) (required)
  • zoom (:integer) (required)
  • zoom_event (:string) (required) - sent with zoom, the next step in or out.
  • jump_event (:any) - the jump to my signature: a string or a %JS{}. Defaults to nil.
  • target (:any) - Defaults to nil.
  • page_label (:string) (required)
  • zoom_label (:string) (required)
  • zoom_out_label (:string) (required)
  • zoom_in_label (:string) (required)
  • jump_label (:string) - names the jump button; the button shows when it is given. Defaults to nil.
  • class (:any) - Defaults to nil.
  • Global attributes are accepted.

Slots

  • jump_icon - the icon of the jump button, such as a signature.
  • zoom_out_icon - replaces the minus sign.
  • zoom_in_icon - replaces the plus sign.
  • actions - more buttons at the end, such as a download.

viewer(assigns)

@spec viewer(map()) :: Phoenix.LiveView.Rendered.t()

A PDF viewer with a thumbnail rail, a toolbar, the page with its signature fields, and a panel.

Attributes

  • id (:string) (required)
  • name (:string) (required) - the file name, shown in the toolbar.
  • page (:integer) - the current page, owned by the server. Defaults to 1.
  • pages (:integer) (required) - how many pages the file has.
  • zoom (:integer) - the zoom in percent, owned by the server. Defaults to 100.
  • fields (:list) - signature fields, %{page, x, y, w, h, signer, state} with the box in percent of the page. Defaults to [].
  • src (:string) - the URL of the PDF; pdf.js draws it. Without it the :sheet slot is the page. Defaults to nil.
  • worker_src (:string) - the URL of the pdf.js worker (pdf.worker.min.mjs), set by the host. Defaults to nil.
  • page_width (:integer) - the width of a page in px at 100%. Defaults to 420.
  • page_height (:integer) - the height of a page in px at 100%. Defaults to 560.
  • page_event (:string) (required) - sent with page by the thumbnails and the keys.
  • zoom_event (:string) (required) - sent with zoom by the buttons and the keys.
  • jump_event (:any) - the jump to my signature: a string or a %JS{}. Defaults to nil.
  • field_event (:any) - sent by a field when pressed, with page and signer. Defaults to nil.
  • target (:any) - a phx-target (a @myself) when used inside a LiveComponent. Defaults to nil.
  • pages_label (:string) (required) - names the rail of thumbnails.
  • page_label (:string) (required) - the word for a page, such as Page.
  • zoom_label (:string) (required) - names the zoom value, such as Zoom.
  • zoom_out_label (:string) (required)
  • zoom_in_label (:string) (required)
  • jump_label (:string) - names the jump button of the toolbar. Defaults to nil.
  • mine_label (:string) - the small label on the field of the viewer's person. Defaults to nil.
  • class (:any) - the height of the viewer, 680px by default. Defaults to "h-[680px]".
  • Global attributes are accepted.

Slots

  • sheet - the server-rendered page, given the page number; it shows until pdf.js draws the file.
  • jump_icon - the icon of the jump button, such as a signature.
  • zoom_out_icon - replaces the minus sign.
  • zoom_in_icon - replaces the plus sign.
  • actions - more buttons at the end of the toolbar, such as a download.
  • panel - the right panel, usually signatures/1.

zoom_in(zoom)

@spec zoom_in(integer()) :: integer()

The zoom one step in from zoom, which stops at the biggest step.

zoom_out(zoom)

@spec zoom_out(integer()) :: integer()

The zoom one step out from zoom, which stops at the smallest step.