Een kopieerknop voor highlight.js (Nederlands (Dutch))

Een kopieerknop voor highlight.js

Comments

NOTE: Apart from English (and even then it's questionable, I'm Scottish). These are machine translated in languages I don't read. If they're terrible please contact me.
You can see how this translation was done in this article.

Saturday, 28 September 2024

//

5 minute read

Inleiding

Op deze site gebruik ik Hightlight.js om code knipsels client kant te renderen. Ik hou van dit als het houdt mijn server zijcode schoon en eenvoudig. Ik wilde echter een kopieerknop toevoegen aan elke code knipsel zodat gebruikers de code gemakkelijk konden kopiëren naar hun klembord. Dit is een eenvoudige taak, maar ik dacht dat ik het hier zou documenteren voor iedereen die hetzelfde zou willen doen.

Oh en dit is allemaal wachten tot ik het toevoegen van de nieuwsbrief functionaliteit om daadwerkelijk te verschijnen op de site. Zodra ik de energie heb om dat te doen, voeg ik dit toe.

Het eindpunt is dat we een kopieerknop als deze op de site hebben: Kopiëren-knop

OPMERKING: Alle krediet voor dit artikel gaat naar Faraz Patankar Wiens artikel ik gebruikte om deze te maken. Ik wilde alleen de wijzigingen die ik hier heb aangebracht vastleggen voor mijn eigen verwijzing en met anderen delen.

De opties

Er zijn een aantal manieren om dit te doen, bijvoorbeeld er is een knopplugin kopiëren voor Higlight.js maar ik besloot dat ik meer controle wilde over de knop en de styling. Dus ik kwam... dit artikel voor het toevoegen van een kopieerknop.

De problemen

Terwijl dat artikel is een geweldige aanpak het had een paar problemen die stopte het perfect voor mij:

  1. Het maakt gebruik van een lettertype dat ik niet gebruik op mijn site (maar dan handmatig heeft de SVG ook, niet zeker waarom).
  // 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>`;

Terwijl dit werkt, gebruik ik al BoxIcons op deze site die een kopieer pictogram er al in.

  1. Het maakt gebruik van een toastbibliotheek die ik niet heb op deze site.
  // Notify user that the content has been copied
      toast.success("Copied to clipboard", {
        description: "The code block content has been copied to the clipboard.",
      });
  1. Het schakelt de y-overflow uit op het codeblok en zet het pictogram onderaan wat ik niet wilde. Dus de mijne is rechtsboven.

Mijn aanpassingen

De belangrijkste functie

Deze plugin haken in de after:highlightElement event en voegt een knop toe aan het codeblok.

Dus eerst heb ik Faraz's code gekopieerd en daarna de volgende wijzigingen aangebracht:

  1. In plaats van het toe te voegen aan het einde van het code blok heb ik het aan het begin voorbereid.
  2. In plaats van de SVG heb ik de BoxIcons versie gebruikt door gewoon die klassen toe te voegen aan de ingevoegde knop en de textsize op te zetten text-xl.
  3. Ik verwijderde de toast notificatie en vervangen door een eenvoudige showToast functie die ik heb in mijn site (zie later)
  4. Ik voegde een aria-label en title op de knop voor toegankelijkheid (en om een mooi zweefeffect te geven).
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 Functie

Dit berust op een scheermesdeel dat ik aan mijn project heb toegevoegd. Dit deel maakt gebruik van de DaisyUI Toast component om een bericht aan de gebruiker te tonen. Ik hou van deze aanpak als het houdt de Javascript schoon en eenvoudig en stelt me in staat om de toast bericht op dezelfde manier als de rest van de site te stijlen.

<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>

Je zult merken dat dit ook een vreemde verborgen heeft. p tag aan de onderkant, dit is gewoon voor Tailwind om deze klassen te ontleden wanneer het bouwt de site CSS.

De Javascript-functie is eenvoudig, het toont gewoon het toastbericht voor een bepaalde tijd en verbergt het dan opnieuw.

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);
}

We kunnen dit dan noemen met behulp van de showToast functie in de copyButton.onclick event.

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

Ik voegde deze gedeeltelijke recht aan de bovenkant van mijn _Layout.cshtml bestand dus het is beschikbaar op elke pagina.

<partial name="_Toast"  />``

Nu wanneer we tonen blog posts de code blokken hebben: Kopiëren-knop

Conclusie

Dus dat is het, een simpele wijziging in Faraz's code om het voor mij te laten werken. Ik hoop dat dit iemand anders helpt.

logo

©2024 Scott Galloway