Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript Support #11

Open
jdgamble555 opened this issue Nov 27, 2022 · 6 comments
Open

TypeScript Support #11

jdgamble555 opened this issue Nov 27, 2022 · 6 comments

Comments

@jdgamble555
Copy link

Please add TypeScript types!

This seems awesome, but unusable for me without types.

Thanks for writing this!

J

@jdgamble555
Copy link
Author

This would be the declaration module (theoretically), but you need to have a default export:

declare module 'highlightjs-copy' {
    class CopyButtonPlugin {
        constructor(options?: { hook?: Function, callback?: Function });
    };
    export = CopyButtonPlugin;
}

J

@jdgamble555
Copy link
Author

Ok, here is full TypeScript version, please add to repo :)

/* eslint-disable @typescript-eslint/no-non-null-assertion */
/* eslint-disable @typescript-eslint/ban-types */
/**
 *  @file highlight-copy.js
 *  @author Arron Hunt <[email protected]>
 *  @copyright Copyright 2021. All rights reserved.
 */

/**
 * Adds a copy button to highlightjs code blocks
 */
export class CopyButtonPlugin {

    hook!: Function | undefined;
    callback!: Function | undefined;

    /**
     * Create a new CopyButtonPlugin class instance
     * @param {Object} [options] - Functions that will be called when a copy event fires
     * @param {CopyCallback} [options.callback]
     * @param {Hook} [options.hook]
     */
    constructor({ hook, callback }: { hook?: Function | undefined, callback?: Function | undefined } = {}) {
        this.hook = hook;
        this.callback = callback;
    }
    "after:highlightElement"({ el, text }: { el: Element, text: string }) {
        // Create the copy button and append it to the codeblock.
        const button = Object.assign(document.createElement("button"), {
            innerHTML: "Copy",
            className: "hljs-copy-button",
        });
        button.dataset.copied = 'false';
        el.parentElement!.classList.add("hljs-copy-wrapper");
        el.parentElement!.appendChild(button);

        // Add a custom proprety to the code block so that the copy button can reference and match its background-color value.
        el.parentElement!.style.setProperty(
            "--hljs-theme-background",
            window.getComputedStyle(el).backgroundColor
        );

        const hook = this.hook;
        const callback = this.callback;

        button.onclick = function () {
            if (!navigator.clipboard) return;

            let newText = text;
            if (hook && typeof hook === "function") {
                newText = hook(text, el) || text;
            }

            navigator.clipboard
                .writeText(newText)
                .then(function () {
                    
                    button.innerHTML = "Copied!";
                    button.dataset.copied = 'true';
                    

                    let alert: HTMLDivElement | null = Object.assign(document.createElement("div"), {
                        role: "status",
                        className: "hljs-copy-alert",
                        innerHTML: "Copied to clipboard",
                    });
                    el.parentElement!.appendChild(alert);

                    setTimeout(() => {
                        if (alert) {
                            button.innerHTML = "Copy";
                            button.dataset.copied = "false";
                            el.parentElement!.removeChild(alert);
                            alert = null;
                        }
                    }, 2000);
                })
                .then(function () {
                    if (typeof callback === "function") return callback(newText, el);
                });
        };
    }
}

/**
 * @typedef {function} CopyCallback
 * @param {string} text - The raw text copied to the clipboard.
 * @param {HTMLElement} el - The code block element that was copied from.
 * @returns {undefined}
 */
/**
 * @typedef {function} Hook
 * @param {string} text - The raw text copied to the clipboard.
 * @param {HTMLElement} el - The code block element that was copied from.
 * @returns {string|undefined}
 */

J

@arronhunt
Copy link
Owner

Hey @jdgamble555, please open a PR with your code changes :)

@jdgamble555
Copy link
Author

You would need to add TS Support in the package.

J

@thdoan
Copy link

thdoan commented Oct 30, 2023

@jdgamble555 for now I guess you can add to https://github.com/DefinitelyTyped/DefinitelyTyped

@marucjmar
Copy link

I created PR for TS support #25

I publish this in npm.

github: https://github.com/marucjmar/highlightjs-copy
npm package: highlightjs-copy-ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants