Corex.SignaturePad
(Corex v0.1.0-alpha.29)
View Source
Phoenix implementation of Zag.js Signature Pad.
Examples
Basic Usage
<.signature_pad id="my-signature-pad" class="signature-pad">
<:label>Sign here</:label>
<:clear_trigger>
<.icon name="hero-x-mark" />
</:clear_trigger>
</.signature_pad>With Callback
<.signature_pad
id="my-signature-pad"
on_draw_end="signature_drawn"
class="signature-pad">
<:label>Sign here</:label>
<:clear_trigger>
<.icon name="hero-x-mark" />
</:clear_trigger>
</.signature_pad>def handle_event("signature_drawn", %{"paths" => paths}, socket) do
{:noreply, put_flash(socket, :info, "Signature drawn with #{length(paths)} paths")}
endCustom Drawing Options
<.signature_pad
id="my-signature-pad"
drawing_fill="blue"
drawing_size={3}
drawing_simulate_pressure
class="signature-pad">
<:label>Sign here</:label>
<:clear_trigger>
<.icon name="hero-x-mark" />
</:clear_trigger>
</.signature_pad>Phoenix Form Integration
When using with Phoenix forms, you must add an id to the form using the Corex.Form.get_form_id/1 function.
Controller
defmodule MyAppWeb.PageController do
use MyAppWeb, :controller
def home(conn, params) do
form = Phoenix.Component.to_form(Map.get(params, "user", %{}), as: :user)
render(conn, :home, form: form)
end
end<.form :let={f} as={:user} for={@form} id={get_form_id(@form)} method="get">
<.signature_pad field={f[:signature]} id="my-signature-pad" class="signature-pad">
<:label>Sign here</:label>
<:clear_trigger>
<.icon name="hero-x-mark" />
</:clear_trigger>
<:error :let={msg}>
<.icon name="hero-exclamation-circle" class="icon" />
{msg}
</:error>
</.signature_pad>
<button type="submit">Submit</button>
</.form>Live View
When using Phoenix form in a Live view you must also add controlled mode. This allows the Live view to be the source of truth and the component to be in sync accordingly.
defmodule MyAppWeb.SignaturePadLive do
use MyAppWeb, :live_view
def mount(_params, _session, socket) do
form = to_form(%{"signature" => nil}, as: :user)
{:ok, assign(socket, :form, form)}
end
def render(assigns) do
~H"""
<.form as={:user} for={@form} id={get_form_id(@form)}>
<.signature_pad
field={@form[:signature]}
id="my-signature-pad"
class="signature-pad"
controlled
>
<:label>Sign here</:label>
<:clear_trigger>
<.icon name="hero-x-mark" />
</:clear_trigger>
<:error :let={msg}>
<.icon name="hero-exclamation-circle" class="icon" />
{msg}
</:error>
</.signature_pad>
<button type="submit">Submit</button>
</.form>
"""
end
endWith Ecto changeset
First create your schema and changeset:
defmodule MyApp.Accounts.User do
use Ecto.Schema
import Ecto.Changeset
schema "users" do
field :name, :string
field :signature, :text
timestamps(type: :utc_datetime)
end
def changeset(user, attrs) do
user
|> cast(attrs, [:name, :signature])
|> validate_required([:name, :signature])
end
enddefmodule MyAppWeb.UserLive do
use MyAppWeb, :live_view
alias MyApp.Accounts.User
def mount(_params, _session, socket) do
{:ok, assign(socket, :form, to_form(User.changeset(%User{}, %{})))}
end
def handle_event("validate", %{"user" => user_params}, socket) do
changeset = User.changeset(%User{}, user_params)
{:noreply, assign(socket, form: to_form(changeset, action: :validate))}
end
def render(assigns) do
~H"""
<.form for={@form} id={get_form_id(@form)} phx-change="validate">
<.signature_pad
field={@form[:signature]}
id="my-signature-pad"
class="signature-pad"
>
<:label>Sign here</:label>
<:clear_trigger>
<.icon name="hero-x-mark" />
</:clear_trigger>
<:error :let={msg}>
<.icon name="hero-exclamation-circle" class="icon" />
{msg}
</:error>
</.signature_pad>
</.form>
"""
end
endAPI Control
In order to use the API, you must use an id on the component
Client-side
<button phx-click={Corex.SignaturePad.clear("my-signature-pad")}>
Clear Signature
</button>Server-side
def handle_event("clear_signature", _, socket) do
{:noreply, Corex.SignaturePad.clear(socket, "my-signature-pad")}
endStyling
Use data attributes to target elements:
[data-scope="signature-pad"][data-part="root"] {}
[data-scope="signature-pad"][data-part="label"] {}
[data-scope="signature-pad"][data-part="control"] {}
[data-scope="signature-pad"][data-part="segment"] {}
[data-scope="signature-pad"][data-part="guide"] {}
[data-scope="signature-pad"][data-part="clear-trigger"] {}
[data-scope="signature-pad"][data-part="hidden-input"] {}If you wish to use the default Corex styling, you can use the class signature-pad on the component.
This requires to install Mix.Tasks.Corex.Design first and import the component css file.
@import "../corex/main.css";
@import "../corex/tokens/themes/neo/light.css";
@import "../corex/components/signature-pad.css";You can then use modifiers
<.signature_pad class="signature-pad signature-pad--accent signature-pad--lg">Learn more about modifiers and Corex Design
Summary
Components
Renders a signature pad component.
API
Clears the signature pad from client-side. Returns a Phoenix.LiveView.JS command.
Clears the signature pad from server-side. Pushes a LiveView event.
Components
Renders a signature pad component.
Attributes
id(:string) - The id of the signature pad, useful for API to identify the signature pad.drawing_fill(:string) - The fill color for drawing strokes. Defaults to"black".drawing_size(:integer) - The size/thickness of drawing strokes. Defaults to2.drawing_simulate_pressure(:boolean) - Whether to simulate pressure for drawing strokes. Defaults tofalse.drawing_smoothing(:float) - Smoothing factor for drawing strokes (0–1, perfect-freehand option). Defaults to0.9.drawing_easing(:string) - Easing function for drawing strokes (perfect-freehand option). Defaults tonil.drawing_thinning(:float) - Thinning factor for drawing strokes (perfect-freehand option). Defaults tonil.drawing_streamline(:float) - Streamline factor for drawing strokes (perfect-freehand option). Defaults to0.1.dir(:string) - The direction of the signature pad. When nil, derived from document (html lang + config :rtl_locales). Defaults tonil. Must be one ofnil,"ltr", or"rtl".on_draw_end(:string) - The server event name when drawing ends. Defaults tonil.on_draw_end_client(:string) - The client event name when drawing ends. Defaults tonil.controlled(:boolean) - Whether the signature pad is controlled. Defaults tofalse.paths(:any) - The initial paths or the controlled paths of the signature pad. Can be a list or a JSON string. Defaults tonil.name(:string) - The name of the signature pad input for form submission.errors(:list) - List of error messages to display. Defaults to[].field(Phoenix.HTML.FormField) - A form field struct retrieved from the form, for example: @form[:signature]. Automatically sets id, name, value, and errors from the form field.- Global attributes are accepted.
Slots
label- Accepts attributes:class(:string)
clear_trigger- Accepts attributes:class(:string)aria_label(:string) - Accessibility label for the clear button. Defaults to 'Clear signature' if not provided.
error- Accepts attributes:class(:string)
API
Clears the signature pad from client-side. Returns a Phoenix.LiveView.JS command.
Examples
<button phx-click={Corex.SignaturePad.clear("my-signature-pad")}>
Clear
</button>
Clears the signature pad from server-side. Pushes a LiveView event.
Examples
def handle_event("clear_signature", _params, socket) do
{:noreply, Corex.SignaturePad.clear(socket, "my-signature-pad")}
end