import { html, LitElement, TemplateResult } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import ButtonHostStyles from './button-host.css'; import CopyStyles from './code-copy.css'; const supportsClipboard = 'clipboard' in navigator; /** * @csspart copy-button - copy button * * @cssprop --code-button-active-color - button background when focused * @cssprop [--code-button-background=var(--markdown-table-row-odd-background-color)] - button background * @cssprop [--code-button-color=inherit] - button text color * @cssprop [--code-button-focus-background=var(--primary-lines-color)] - button background when focused * @cssprop [--code-button-focus-color=inherit] - button text color when focused * @cssprop [--code-border-radius=6px] - border radius for code-copy and code-tabs * * @slot copy-icon - Button content * @slot success-icon - Button content which alerts on copying. Use `role="alert"` if overriding default. * @event {CustomEvent} copy - when successfully copying */ @customElement('code-copy') export class CodeCopy extends LitElement { static readonly is = 'code-copy'; static readonly styles = [ButtonHostStyles, CopyStyles]; static readonly shadowRootOptions: ShadowRootInit = { mode: 'open', delegatesFocus: true, } static copyIcon = html` `; /** The element to copy text from. */ @state() host: HTMLElement = this; @state() success = 'pending'; /** Number of milliseconds to wait after successfully copying before restoring the copy button's icon to 'pending'. */ @property({ type: Number }) timeout = 2000; render(): TemplateResult { return html` `; } private async onCopy(): Promise { const { textContent } = this.host; await navigator.clipboard.writeText(textContent.trim()); this.success = 'copied'; this.dispatchEvent(new CustomEvent('copy', { detail: textContent })); setTimeout(() => { this.success = 'pending'; }, this.timeout); } }