# Кнопка копії для Highlight.js

<!--category-- DaisyUI, Tailwind, Highlight.js, Javascript -->
<datetime class="hidden">2024-09-28T14:15</datetime>

# Введение

На цій сайті я використовую Hightlight.js, щоб відтворити фрагменти коду з боку клієнта . Мені подобається це, бо воно зберігає чистий і простий код з боку мого сервера МSK2 Тим не менше M SK3 Я хотів додати копійну кнопку до кожного фрагменту коду, щоб користувачі могли легко скопіювати код на своєму кліпboardі . Це проста робота, але я подумав, що я зможу задокументувати її тут для будь-кого іншого, хто може зробити те ж саме.

# Мета

В кінцевому підсумку ми маємо таку копію на сайті:
![Кнопка копії](copybutton.png)

**NOTE: Все, що заслуговує на цю статтю - [Фараз Патанкар](https://dev.to/farazpatankar/highlightjs-copy-button-plugin-3dld) я просто хотів задокументувати зміни, які я зробив до нього тут для мого власного опису і поділитися ними з іншими**

[TOC]

# Опції

Є декілька способів зробити це: [плагин для копіювання кнопок](https://github.com/arronhunt/highlightjs-copy) для Higlight.js, але я вирішив, що хочу більше контролю над кнопкою та дизайном [цей artykuł](https://dev.to/farazpatankar/highlightjs-copy-button-plugin-3dld) для додавання копії кнопки.

## Проблеми

Ця стаття - чудовий підхід, але вона мала декілька недоліків, які перестали бути ідеальними для мене.

1. Він використовує шрифт, який я не користуюся на своєму сайті.

```javascript
  // Lucide copy icon
    copyButton.innerHTML = `<svg class="h-4 w-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-copy"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>`;
```

В той час, як це працює, Я вже користуюся BoxIcons на цій сайті, який має [копіювати іконку вже там](https://icon-sets.iconify.design/bx/copy/).

2. Вона використовує тостову бібліотеку, яку я не маю на цьому сайті.

```javascript
  // Notify user that the content has been copied
      toast.success("Copied to clipboard", {
        description: "The code block content has been copied to the clipboard.",
      });
```

3. Він викидає y- перетік на блок коду і поміщає значок внизу, який я не хотів.

# Мої адаптації

## Головна функція

Цей плагин підключається до `after:highlightElement` і додає кнопку до кодового блоку.

Спочатку я копіював код Faraz', а потім зробив наступні зміниM SK1

1. Замість того, щоб застосувати його до кінця кодового блоку, я підготував його до початку.
2. Замість SVG я скористалася версією BoxIcons, просто додавши ці класи до вставленої кнопки &, встановивши текстову величину до `text-xl`.
3. Я видалив повідомлення про тост і замінив його простим `showToast` функцію, яку я маю на своєму сайті (гляньмо пізнішеM SK1
4. Я додав `aria-label` і `title` до кнопки для доступності ( і щоб дати гарний ефект виліту МSK1

```javascript
hljs.addPlugin({
    "after:highlightElement": ({ el, text }) => {
        const wrapper = el.parentElement;
        if (wrapper == null) {
            return;
        }

        /**
         * Make the parent relative so we can absolutely
         * position the copy button
         */
        wrapper.classList.add("relative");
        const copyButton = document.createElement("button");
        copyButton.classList.add(
            "absolute",
            "top-2",
            "right-1",
            "p-2",
            "text-gray-500",
            "hover:text-gray-700",
            "bx",
            "bx-copy",
            "text-xl",
            "cursor-pointer"
        );
        copyButton.setAttribute("aria-label", "Copy code to clipboard");
        copyButton.setAttribute("title", "Copy code to clipboard");

        copyButton.onclick = () => {
            navigator.clipboard.writeText(text);

            // Notify user that the content has been copied
            showToast("The code block content has been copied to the clipboard.", 3000, "success");

        };
        // Append the copy button to the wrapper
        wrapper.prepend(copyButton);
    },
});
```

## `showToast` Функція

Це залежить від частини бритви, яку я додав до мого проекту.
Ця частина використовує [Компонент DaisyUI Toast](https://daisyui.com/components/toast/) щоб показати повідомлення користувачам.
Мені подобається цей підхід, тому що він зберігає Javascript чистим і простим і дозволяє мені відобразити тост-сообщение так само, як і решта веб-сайту.

```html
<div id="toast" class="toast toast-bottom fixed z-50 hidden overflow-y-hidden">
    <div id="toast-message" class="alert">
        <div>
            <span id="toast-text">Notification message</span>
        </div>
    </div>
    <p class="hidden right-1 bx-copy  cursor-pointer alert-success alert-warning alert-error alert-info"></p>
</div>
```

Ви помітите, що це також є дивним прихованим `p` позначка внизу, це тільки для Tailwind, щоб розібрати ці класи, коли він будує сайт

Функція Javascript проста, вона просто показує тост-повідомлення на певний час, а потім знову приховує його.

```javascript
window.showToast = function(message, duration = 3000, type = 'success') {
    const toast = document.getElementById('toast');
    const toastText = document.getElementById('toast-text');
    const toastMessage = document.getElementById('toast-message');

    // Set message and type
    toastText.innerText = message;
    toastMessage.className = `alert alert-${type}`; // Change alert type (success, warning, error)

    // Show the toast
    toast.classList.remove('hidden');

    // Hide the toast after specified duration
    setTimeout(() => {
        toast.classList.add('hidden');
    }, duration);
}
```

Тоді ми можемо назвати це `showToast` функція в `copyButton.onclick` події.

```javascript
showToast("The code block content has been copied to the clipboard.", 3000, "success");
```

Я додав цю частину прямо на вершині мого `_Layout.cshtml` файл, так що він' доступний на кожній сторінціM SK1

```html
<partial name="_Toast"  />``
```

Тепер, коли ми показуємо блогові статті, кодові блоки мають
![Кнопка копії](copybutton.png)

# На завершення

Я сподіваюся, що це допоможе комусь іншому.