fix(portal): Fix copy-paste buttons (#7033)

- Added semi-transparent shadow to the button so that it's more visible
when text is overlapping it. Padding did not look well because it
required scrollbar to be moved inside the parent container and it looked
very ugly
- Replaced custom phx hook with a new native Tailwind component

Closes #5973
This commit is contained in:
Andrew Dryga
2024-10-14 14:05:14 -06:00
committed by GitHub
parent 05e895525b
commit f89cc67fda
2 changed files with 35 additions and 54 deletions

View File

@@ -64,41 +64,6 @@ Hooks.Refocus = {
},
};
Hooks.Copy = {
mounted() {
this.el.addEventListener("click", (ev) => {
ev.preventDefault();
let inner_html = ev.currentTarget
.querySelector("[data-copy]")
.innerHTML.trim();
let doc = new DOMParser().parseFromString(inner_html, "text/html");
let text = doc.documentElement.textContent;
let content = ev.currentTarget.querySelector("[data-content]");
let icon_cl = ev.currentTarget.querySelector("[data-icon]").classList;
navigator.clipboard.writeText(text).then(() => {
icon_cl.add("hero-clipboard-document-check");
icon_cl.add("hover:text-accent-500");
icon_cl.remove("hero-clipboard-document");
if (content) {
content.innerHTML = "Copied";
}
});
setTimeout(() => {
icon_cl.remove("hero-clipboard-document-check");
icon_cl.remove("hover:text-accent-500");
icon_cl.add("hero-clipboard-document");
if (content) {
content.innerHTML = "Copy";
}
}, 2000);
});
},
};
/* The phx-disable-with attribute on submit buttons only applies to liveview forms.
* However, we need to disable the submit button for regular forms as well to prevent
* double submissions and cases where the submit handler is slow (e.g. constant-time auth).

View File

@@ -69,7 +69,7 @@ defmodule Web.CoreComponents do
def code_block(assigns) do
~H"""
<div id={@id} phx-hook="Copy" class="relative">
<div id={@id} class="relative">
<div id={"#{@id}-nested"} class={[~w[
text-sm text-left text-neutral-50
inline-flex items-center
@@ -77,23 +77,32 @@ defmodule Web.CoreComponents do
bg-neutral-800
overflow-x-auto
], @class]} {@rest}>
<code class="block w-full no-scrollbar whitespace-pre rounded-b" data-copy phx-no-format><%= render_slot(@inner_block) %></code>
<code
id={"#{@id}-code"}
class="block w-full no-scrollbar whitespace-pre rounded-b"
phx-no-format
><%= render_slot(@inner_block) %></code>
</div>
<span title="Click to copy" class={~w[
absolute top-1 right-1
items-center
cursor-pointer
rounded
p-1
text-xs
text-neutral-50
hover:bg-neutral-50
hover:text-neutral-900
hover:opacity-50
]}>
<button
type="button"
data-copy-to-clipboard-target={"#{@id}-code"}
data-copy-to-clipboard-content-type="innerHTML"
data-copy-to-clipboard-html-entities="true"
title="Click to copy"
class={[
"absolute top-1 right-1",
"items-center",
"cursor-pointer",
"rounded",
"p-1",
"bg-neutral-50/25",
"text-xs text-neutral-50",
"hover:bg-neutral-50 hover:text-neutral-900 hover:opacity-50"
]}
>
<.icon name="hero-clipboard-document" data-icon class="h-4 w-4" />
</span>
</button>
</div>
"""
end
@@ -114,11 +123,18 @@ defmodule Web.CoreComponents do
def copy(assigns) do
~H"""
<div id={@id} phx-hook="Copy" class={@class} {@rest}>
<code data-copy phx-no-format><%= render_slot(@inner_block) %></code>
<span class={~w[text-neutral-400 cursor-pointer rounded]}>
<div id={@id} class={@class} {@rest}>
<code id={"#{@id}-code"} phx-no-format><%= render_slot(@inner_block) %></code>
<button
type="button"
class={~w[text-neutral-400 cursor-pointer rounded]}
data-copy-to-clipboard-target={"#{@id}-code"}
data-copy-to-clipboard-content-type="innerHTML"
data-copy-to-clipboard-html-entities="true"
title="Copy to clipboard"
>
<.icon name="hero-clipboard-document" data-icon class="h-4 w-4" />
</span>
</button>
</div>
"""
end