# presentation/components/clipboard.component.ts

> 39 lines of code and 5 definitions.

Tree: Site tree
Language: typescript
Layer: product
Canonical: https://banes-lab.com/anatomy/tree#file-presentation-components-clipboard-component-ts
Source text: https://banes-lab.com/assets/sources/source.24c9d5a894746030ceb028e031099bbfff2dfd0ded30aafb572e928c13be1b3b.generated.txt

## Definitions

- `createCopyButton` (lexical_declaration, line 21, exported)
- `flash` (lexical_declaration, line 12)
- `iconClass` (lexical_declaration, line 8)
- `icon` (lexical_declaration, line 26, exported)
- `button` (lexical_declaration, line 27, exported)

## Uses

- [core/reporters/failure.reporter.ts](https://banes-lab.com/source/tree/core/reporters/failure.reporter.ts.md)

## Used by

- [presentation/components/code.component.ts](https://banes-lab.com/source/tree/presentation/components/code.component.ts.md)
- [presentation/renderers/page.renderer.ts](https://banes-lab.com/source/tree/presentation/renderers/page.renderer.ts.md)
- [presentation/renderers/section.renderer.ts](https://banes-lab.com/source/tree/presentation/renderers/section.renderer.ts.md)

## Source

```typescript
import { CHECK_ICON, CLIPBOARD_ICON, CROSS_ICON, ICON_BASE_CLASS } from "#configuration/icons/element.icons";
import { COPIED_CLASS, COPY_FEEDBACK_MS } from "#configuration/constants/clipboard.constants";
import { COPY_REFUSED } from "#configuration/strings/report.strings";
import { COPY_TITLE } from "#configuration/strings/clipboard.strings";
import { createElement } from "#core/factories/element.factory";
import { reportFailure } from "#core/reporters/failure.reporter";

const iconClass = function iconClass(icon: string): string {
    return `${ICON_BASE_CLASS} ${icon}`;
};

const flash = function flash(button: HTMLButtonElement, icon: HTMLElement, result: string): void {
    icon.className = iconClass(result);
    button.classList.toggle(COPIED_CLASS, result === CHECK_ICON);
    setTimeout(() => {
        icon.className = iconClass(CLIPBOARD_ICON);
        button.classList.remove(COPIED_CLASS);
    }, COPY_FEEDBACK_MS);
};

export const createCopyButton = function createCopyButton(
    text: () => string,
    className: string,
    title: string = COPY_TITLE,
): HTMLButtonElement {
    const icon = createElement("i", { className: iconClass(CLIPBOARD_ICON) });
    const button = createElement("button", { attributes: { title, type: "button" }, children: [icon], className });
    button.addEventListener("click", (event) => {
        event.preventDefault();
        event.stopPropagation();
        navigator.clipboard
            .writeText(text())
            .then(() => {
                flash(button, icon, CHECK_ICON);
            })
            .catch((error: unknown) => {
                reportFailure(COPY_REFUSED, error);
                flash(button, icon, CROSS_ICON);
            });
    });
    return button;
};
```
