Copy message to clipboard on click

This commit is contained in:
pk committed 2026-10-25 12:51:21 +01:00
1 parent 8af6c51058
commit 8877361fdc
1 file changed
+36 -1
+36 -1
View File
@@ -5,6 +5,7 @@ Copyright (c) 2023 EDV Wasmeier
import '@tp/tp-timeout-strip/tp-timeout-strip.js';
import { EventHelpers } from '@tp/helpers/event-helpers.js';
import { copyToClipboard } from '@tp/helpers/clipboard.js';
import { LitElement, html, css, svg } from 'lit';
class TpToast extends EventHelpers(LitElement) {
@@ -76,7 +77,7 @@ class TpToast extends EventHelpers(LitElement) {
<div class="icon" part="type-icon-wrap">
<tp-icon part="type-icon" .icon=${icon || TpToast[this.type + 'Icon']}></tp-icon>
</div>
<div class="content" part="content">
<div class="content" part="content" @click=${this._copyContent}>
<slot></slot>
</div>
${!sticky ? html`
@@ -107,6 +108,14 @@ class TpToast extends EventHelpers(LitElement) {
*/
delay: { type: Number },
/**
* If true (default), clicking the message copies the toast content to the clipboard
* and fires a `toast-copied` event.
* Disable via property binding (`.copyOnClick=${false}`) — a present boolean attribute
* always converts to true.
*/
copyOnClick: { type: Boolean },
/**
* If true, the toast cant be dismissed manually.
*/
@@ -122,6 +131,7 @@ class TpToast extends EventHelpers(LitElement) {
super();
this.type = 'info';
this.delay = 5000;
this.copyOnClick = true;
this.translateY = -150;
this.dismiss = this.dismiss.bind(this);
}
@@ -167,6 +177,31 @@ class TpToast extends EventHelpers(LitElement) {
this.style.opacity = '0';
}
/**
* Copies the toast content (slotted light-dom text) to the clipboard.
* Fires a bubbling, composed `toast-copied` event with `detail.text` on success.
* Skipped when `copyOnClick` is false, when the content is empty, or when the user
* made a manual text selection inside the toast (don't clobber their own copy).
*/
async _copyContent() {
if (!this.copyOnClick) return;
const selection = window.getSelection();
if (selection && selection.toString()) return;
const text = this.textContent.trim();
if (!text) return;
const success = await copyToClipboard(text);
if (success) {
this.dispatchEvent(new CustomEvent('toast-copied', {
detail: { text },
bubbles: true,
composed: true,
}));
}
}
/**
* Starts the delay timeout to dismiss the toast automatically.
*/