Corex.Clipboard (Corex v0.1.2)

View Source

Phoenix implementation of Zag.js Clipboard.

Set value for the initial string to copy. Use Corex.Clipboard.set_value/2 or corex:clipboard:set-value to change it on the client.

Anatomy

Minimal

<.clipboard class="clipboard" value="hello@example.com">
  <:label>Email</:label>
  <:copy>
    <.heroicon name="hero-clipboard" />
  </:copy>
  <:copied>
    <.heroicon name="hero-check" />
  </:copied>
</.clipboard>

Trigger only

<.clipboard
  class="clipboard"
  value="https://example.com/share"
  input={false}
  trigger_aria_label="Copy link"
>
  <:copy>
    <.heroicon name="hero-clipboard" />
  </:copy>
  <:copied>
    <.heroicon name="hero-check" />
  </:copied>
</.clipboard>

API

Requires a stable id on <.clipboard>.

FunctionActionReturns
copy/1Copy current value (client)%Phoenix.LiveView.JS{}
copy/2Copy current value (server)socket
set_value/2Set value to copy (client)%Phoenix.LiveView.JS{}
set_value/3Set value to copy (server)socket

Events

Pick an event name and pass it to on_* on <.clipboard>.

Server events

EventWhenPayload
on_copy="clipboard_copied"User copies%{"id" => id, "value" => value}

on_copy

<.clipboard
  class="clipboard"
  value="info@netoum.com"
  on_copy="clipboard_copied"
>
  <:label>Copy</:label>
  <:copy>
    <.heroicon name="hero-clipboard" />
  </:copy>
  <:copied>
    <.heroicon name="hero-check" />
  </:copied>
</.clipboard>
def handle_event("clipboard_copied", %{"value" => value, "id" => _id}, socket) do
  {:noreply, assign(socket, :last_copied, value)}
end

Client events

EventWhenevent.detail
on_copy_client="clipboard-copied"User copiesid, value

Style

Target parts with data-scope and data-part, or use Corex Design: import tokens and clipboard.css, then set class="clipboard" on <.clipboard>.

[data-scope="clipboard"][data-part="root"] {}
[data-scope="clipboard"][data-part="trigger"] {}
[data-scope="clipboard"][data-part="control"] {}
[data-scope="clipboard"][data-part="input"] {}
[data-scope="clipboard"][data-part="copy"] {}
[data-scope="clipboard"][data-part="copied"] {}
@import "../corex/main.css";
@import "../corex/tokens/themes/neo/light.css";
@import "../corex/components/clipboard.css";

Stack modifiers on the host (class on <.clipboard>).

Color

ModifierClasses
Defaultclipboard
Accentclipboard clipboard--accent
Brandclipboard clipboard--brand
Alertclipboard clipboard--alert
Infoclipboard clipboard--info
Successclipboard clipboard--success

Size

ModifierClasses
SMclipboard clipboard--sm
MDclipboard clipboard--md
LGclipboard clipboard--lg
XLclipboard clipboard--xl

Summary

Components

Renders a clipboard component.

API

Copy the component's current value from a control (phx-click).

Copy the current value from handle_event.

Set the string to copy from a control (phx-click).

Set the value to copy from handle_event.

Components

clipboard(assigns)

Renders a clipboard component.

Attributes

  • id (:string) - The id of the clipboard, useful for API to identify the clipboard.
  • value (:string) - The value shown in the input and copied (initial or after client set_value). Defaults to nil.
  • timeout (:integer) - The timeout in milliseconds before resetting the copied state. Defaults to nil.
  • dir (:string) - The direction of the clipboard. When nil, derived from document (html lang + config :rtl_locales). Defaults to nil. Must be one of nil, "ltr", or "rtl".
  • orientation (:string) - Layout orientation for CSS. Defaults to "horizontal". Must be one of "horizontal", or "vertical".
  • on_copy (:string) - The server event name when the value is copied. Defaults to nil.
  • on_copy_client (:string) - The client event name when the value is copied. Defaults to nil.
  • trigger_aria_label (:string) - Accessible name for the trigger button when it contains only an icon (e.g. "Copy to clipboard"). Defaults to nil.
  • input_aria_label (:string) - Accessible name for the input when it's not associated with a visible label (e.g. "Value to copy"). Defaults to nil.
  • input (:boolean) - Whether to render the input element. Set to false when using only the trigger to copy. Defaults to true.
  • input_class (:string) - Defaults to nil.
  • control_class (:string) - Defaults to nil.
  • root_class (:string) - Defaults to nil.
  • Global attributes are accepted.

Slots

  • label - Accepts attributes:
    • class (:string)
  • copy - Accepts attributes:
    • class (:string)
  • copied - Accepts attributes:
    • class (:string)
  • trigger - Accepts attributes:
    • class (:string)

API

copy(clipboard_id)

Copy the component's current value from a control (phx-click).

<.action phx-click={Corex.Clipboard.copy("my-clipboard")}>Copy</.action>
<.clipboard id="my-clipboard" class="clipboard" value="hello@example.com">
  <:label>Email</:label>
  <:copy><.heroicon name="hero-clipboard" /></:copy>
  <:copied><.heroicon name="hero-check" /></:copied>
</.clipboard>
document.getElementById("my-clipboard")?.dispatchEvent(
  new CustomEvent("corex:clipboard:copy", { bubbles: false })
);

copy(socket, clipboard_id)

Copy the current value from handle_event.

<.action phx-click="copy_email">Copy</.action>
<.clipboard id="my-clipboard" class="clipboard" value="hello@example.com">
  <:label>Email</:label>
  <:copy><.heroicon name="hero-clipboard" /></:copy>
  <:copied><.heroicon name="hero-check" /></:copied>
</.clipboard>
def handle_event("copy_email", _, socket) do
  {:noreply, Corex.Clipboard.copy(socket, "my-clipboard")}
end

set_value(clipboard_id, value)

Set the string to copy from a control (phx-click).

<.action phx-click={Corex.Clipboard.set_value("my-clipboard", "next@example.com")}>Load</.action>
<.clipboard id="my-clipboard" class="clipboard" value="hello@example.com">
  <:label>Email</:label>
  <:copy><.heroicon name="hero-clipboard" /></:copy>
  <:copied><.heroicon name="hero-check" /></:copied>
</.clipboard>
document.getElementById("my-clipboard")?.dispatchEvent(
  new CustomEvent("corex:clipboard:set-value", {
    bubbles: false,
    detail: { value: "next@example.com" },
  })
);

set_value(socket, clipboard_id, value)

Set the value to copy from handle_event.

<.action phx-click="load_clipboard" phx-value-value="next@example.com">Load</.action>
<.clipboard id="my-clipboard" class="clipboard" value="hello@example.com">
  <:label>Email</:label>
  <:copy><.heroicon name="hero-clipboard" /></:copy>
  <:copied><.heroicon name="hero-check" /></:copied>
</.clipboard>
def handle_event("load_clipboard", %{"value" => value}, socket) do
  {:noreply, Corex.Clipboard.set_value(socket, "my-clipboard", value)}
end