SlopUI.Components.MarkdownEditor (SlopUI v0.1.0)

Copy Markdown View Source

A Markdown editor in the GitHub style: a textarea with a formatting toolbar, keyboard shortcuts, list continuation, a Write/Preview switch, and image upload by paste, drop or button through LiveView uploads.

Summary

Functions

Renders the editor.

Tells the editor that an uploaded image is stored at url, replacing its "Uploading" placeholder with ![name](url). Call it from your upload progress callback once the entry is consumed.

Removes the placeholder for an entry whose upload failed.

Functions

markdown_editor(assigns)

Renders the editor.

<.markdown_editor field={@form[:body]} label="Description" toolbar="simple" />

<.markdown_editor
  field={@form[:body]}
  label="Description"
  toolbar="full"
  upload={@uploads.images}
/>

Toolbar

toolbar is "simple", "full", or a list of tool names in the order you want. Available tools: heading bold italic strike code code_block quote ul ol task link image table hr, with "|" as a separator. The image tool is only rendered when upload is given. Add your own buttons with the :tool slot; they receive the textarea id in data-for.

Preview

The Preview tab renders the current value with markdown/1, so keep the value in your form assigns and let phx-change update it (the editor debounces changes). Requires the optional mdex dependency; without it the Preview tab is omitted.

Images

Pass a LiveView upload config declared with auto_upload: true and a progress callback. Pasting or dropping an image, or using the image button, hands the files to the upload and inserts an "Uploading" placeholder at the cursor. When your callback has stored the file, push the URL back and the placeholder becomes ![name](url):

# mount/3
socket
|> allow_upload(:images, accept: ~w(.png .jpg .jpeg .gif .webp), max_entries: 10,
     auto_upload: true, progress: &handle_progress/3)

# the callback
def handle_progress(:images, entry, socket) do
  if entry.done? do
    url = consume_uploaded_entry(socket, entry, fn %{path: path} -> {:ok, MyApp.Storage.put(path, entry)} end)
    {:noreply, SlopUI.Components.MarkdownEditor.push_image(socket, entry, url)}
  else
    {:noreply, socket}
  end
end

Storage is yours: local files, S3, anything that yields a URL.

Attributes

  • id (:any) - Defaults to nil.
  • name (:any)
  • value (:any)
  • label (:string) - Defaults to nil.
  • description (:string) - Defaults to nil.
  • placeholder (:string) - Defaults to nil.
  • rows (:integer) - minimum visible lines. Defaults to 8.
  • toolbar (:any) - "simple", "full", or a list of tool names. Defaults to "full".
  • upload (Phoenix.LiveView.UploadConfig) - enables image paste/drop/button. Defaults to nil.
  • preview (:boolean) - Defaults to true.
  • fullscreen (:boolean) - show the fullscreen toggle. Defaults to true.
  • field (Phoenix.HTML.FormField)
  • errors (:list) - Defaults to [].
  • required (:boolean) - Defaults to false.
  • disabled (:boolean) - Defaults to false.
  • class (:any) - Defaults to nil.
  • Global attributes are accepted. Supports all globals plus: ["phx-debounce", "maxlength", "autocomplete"].

Slots

  • tool - extra toolbar buttons; each gets data-for pointing at the textarea.

push_image(socket, entry, url)

Tells the editor that an uploaded image is stored at url, replacing its "Uploading" placeholder with ![name](url). Call it from your upload progress callback once the entry is consumed.

push_image_error(socket, entry)

Removes the placeholder for an entry whose upload failed.